OS X AudioUnit: kAudio_ParamError when setting misc properties on a Generator

547 views Asked by At

I'm building a simple AudioUnit app which should use an AUGraph to connect a generator (which generates, say, a sine wave) to a format converter (because that seems like what I need) to an output device.

Code snippets:

{
    AudioComponentDescription desc ;
    desc.componentType          =   kAudioUnitType_Generator ;
    desc.componentSubType       =   kAudioUnitSubType_ScheduledSoundPlayer ;
    desc.componentFlags         =   0 ;
    desc.componentFlagsMask     =   0 ;
    desc.componentManufacturer  =   kAudioUnitManufacturer_Apple ;

    status = AUGraphAddNode ( mGraph , &desc , &mGeneratorNode ) ;
    checkOSStatus ( "creating generator node" , status ) ;
}

I do similarly for mConverterNode with kAudioUnitType_FormatConverter/kAudioUnitSubType_AUConverter and for mOutputNode with kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput.

I then open the graph:

AUGraphOpen ( mGraph ) ; // error checking code omitted from example

I then get references to them:

AUGraphNodeInfo ( mGraph , mGeneratorNode , 0,&mGeneratorRef ) ; // error checking code omitted from example

I then set the format:

{
    AudioStreamBasicDescription format ;
    format.mSampleRate          =   mSamplingRate ;
    format.mFormatID            =   kAudioFormatLinearPCM ;
    format.mFormatFlags         =   kAudioFormatFlagIsSignedInteger ;
    format.mFramesPerPacket     =   1 ;
    format.mChannelsPerFrame    =   1 ; // mono
    format.mBitsPerChannel      =   16 ;
    format.mBytesPerFrame       =   format.mBitsPerChannel*format.mChannelsPerFrame/8 ;
    format.mBytesPerPacket      =   format.mBytesPerFrame*format.mFramesPerPacket ;

    status = AudioUnitSetProperty ( mGeneratorRef , kAudioUnitProperty_StreamFormat , kAudioUnitScope_Output , kOutputBus , &format,sizeof(format) ) ;
    checkOSStatus ( "setting output format" , status ) ;
}

(Note: kOutputBus is an enum to 0; it's an anachronism from a previous example I found. Also, mSamplingRate is a size_t whose value is 48000)

And set the render callback:

{
    AURenderCallbackStruct cb ;
    cb.inputProc = &_callbackProxy ;
    cb.inputProcRefCon = static_cast<void*> ( this ) ;
    status = AudioUnitSetProperty ( mGeneratorRef , kAudioUnitProperty_SetRenderCallback , kAudioUnitScope_Output , 0 , &cb,sizeof(cb) ) ;
    checkOSStatus ( "setting the generator callback" , status ) ;
}

However, for both the stream format and the render callback I get kAudio_ParamError back as the resultant status.

No matter what I do (mono/stereo, when I place that command, etc), I cannot make it work.

Note: I later do this:

AUGraphConnectNodeInput ( mGraph , mGeneratorNode,0 , mConverterNode,0 ) ;
AUGraphConnectNodeInput ( mGraph , mConverterNode,0 , mOutputNode,0 ) ;
AUGraphInitialize ( mGraph ) ;
AUGraphStart ( mGraph ) ;
// again, error-checking code omitted from example

And it works........ But I can't set those properties and therefore can't generate audio.

What am I missing?

(To people with 1500+ reputation: please make an "osx-sierra" tag; I'm a bit shy of that mark)

1

There are 1 answers

0
iAdjunct On

From an obscure comment at the end of this:

https://discussions.apple.com/thread/1989797?tstart=0

I ran AUGraphOpen at the very beginning before creating things (why?) and it worked.

But then I was getting invalid format errors, so I set the format on the input of the converter instead of the output of the generator.

But then it wasn't calling the render callback, so I removed the generator altogether and put the render callback on the input of the converter.

At this point, it worked and is generating my sound.

I hope this helps somebody else in the future with this so-horribly-documented API.