Hi all,
I want to do a very basic CoreAudio setup using the AUHal AudioUnit component. The output should be 16kHz, 16-bit signed samples, 1 channel. See the code below. In the callback, AudioUnitRender is called, but that one fails with "Cannot do in current context". What is going wrong?
AudioStreamBasicDescription inDesiredStreamFormat; AudioConverterRef captureConverter;
inDesiredStreamFormat.mChannelsPerFrame = 1; inDesiredStreamFormat.mSampleRate = 16000; inDesiredStreamFormat.mFramesPerPacket = 1; inDesiredStreamFormat.mBitsPerChannel = 16; inDesiredStreamFormat.mBytesPerFrame = (inDesiredStreamFormat.mBitsPerChannel >> 3) * (inDesiredStreamFormat.mChannelsPerFrame); inDesiredStreamFormat.mBytesPerPacket = inDesiredStreamFormat.mBytesPerFrame; inDesiredStreamFormat.mFormatID = kAudioFormatLinearPCM; inDesiredStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian;
AudioComponentDescription cd; cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_HALOutput; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0;
AudioComponent cp = AudioComponentFindNext(0, &cd); AudioComponentInstance auHal;
err = AudioComponentInstanceNew(cp, &auHal); UInt32 enable = 1; AudioUnitSetProperty(auHal, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, //input element; 0 = output element &enable, sizeof(enable));
enable = 0;
AudioUnitSetProperty(auHal, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, //output element &enable, sizeof(enable));
AURenderCallbackStruct cb; cb.inputProc = inputCallback; cb.inputProcRefCon = auHal; AudioUnitSetProperty(auHal, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &cb, sizeof(cb));
//retrieve default input device //and set it on the audio unit AudioUnitSetProperty(auHal, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &defaultInputId, sizeof(AudioDeviceID));
AudioUnitSetProperty(auHal, kAudioUnitProperty_StreamFormat, AudioUnitScope_Input, 0, &inDesiredStreamFormat, sizeof(inDesiredStreamFormat));
AudioUnitSetProperty(auHal, kAudioUnitProperty_StreamFormat, AudioUnitScope_Output, 1, &inDesiredStreamFormat, sizeof(inDesiredStreamFormat));
AudioUnitInitialize(auHal); AudioUnitStart(auHal);
The audio callback looks as follows: OSStatus inputCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { OSStatus err = noErr; AudioComponentInstance auHal = static_cast<AudioComponentInstance>(inRefCon); err = AudioUnitRender(auHal, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, gAudioBufferList); if (err != noErr) { qDebug() << "Error rendering:" << getAudioUnitError(err); } }
I also tried to use an AudioConverter, leaving the input as is, but then I get "cracks" in the converted audio.
Can someone provide me a simple example of how I could record 16kHz audio, signed 16-bit, 1 channel?
Thanks. |