I'm trying to set up an audio unit capable of mono input and stereo output. Intend on playing a sine wave tone through the left channel output and a different sign wave periodically through the right channel out.
I am receiving the error,
'NSInternalInconsistencyException', reason: ' Error initialing unit: -50;
when I attempt to initialize my audio unit here,
// Initialize audio unit
OSErr err = AudioUnitInitialize(self.ioUnit);
NSAssert1(err == noErr, @"Error initializing unit: %hd", err);
I believe it has to do with how I am setting up the audio unit,
// Audio component description
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
// Get component
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
// Get Audio units
AudioComponentInstanceNew(inputComponent, &ioUnit);
// Enable input, which disabled by default. Output enable by default
UInt32 enableInput = 1;
AudioUnitSetProperty(ioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
kInputBus,
&enableInput,
sizeof(enableInput));
AudioStreamBasicDescription monoStreamFormat;
monoStreamFormat.mSampleRate = 44100.00;
monoStreamFormat.mFormatID = kAudioFormatLinearPCM;
monoStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
monoStreamFormat.mBytesPerPacket = 2;
monoStreamFormat.mBytesPerFrame = 2;
monoStreamFormat.mFramesPerPacket = 1;
monoStreamFormat.mChannelsPerFrame = 1;
monoStreamFormat.mBitsPerChannel = 16;
// Apply format to input of ioUnit
AudioUnitSetProperty(ioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
kInputBus,
&monoStreamFormat,
sizeof(monoStreamFormat));
AudioStreamBasicDescription stereoStreamFormat;
stereoStreamFormat.mSampleRate = 44100.00;
stereoStreamFormat.mFormatID = kAudioFormatLinearPCM;
stereoStreamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
stereoStreamFormat.mBytesPerPacket = 4;
stereoStreamFormat.mBytesPerFrame = 4;
stereoStreamFormat.mFramesPerPacket = 1;
stereoStreamFormat.mChannelsPerFrame = 2;
stereoStreamFormat.mBitsPerChannel = 32;
// Apply format to output of ioUnit
AudioUnitSetProperty(ioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kOutputBus,
&stereoStreamFormat,
sizeof(stereoStreamFormat));
// Set input callback
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = inputCallback;
callbackStruct.inputProcRefCon = (__bridge void *)(self);
AudioUnitSetProperty(ioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
kInputBus,
&callbackStruct,
sizeof(callbackStruct));
// Set output callback
callbackStruct.inputProc = outputCallback;
callbackStruct.inputProcRefCon = (__bridge void *)(self);
AudioUnitSetProperty(ioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
kOutputBus,
&callbackStruct,
sizeof(callbackStruct));
but I couldn't find anything on the error code -50 it's giving back so I'm not sure what it doesn't like. I'm on a deadline so any help it greatly appreciated.
kAudioFormatFlagsAudioUnitCanonical is 32-bit 8.24 fixed point format. That means mBytesPerFrame should be 4 for mono and 8 for stereo, and mBitsPerChannel should be 32 for both stereo and mono. Setting it to 16-bits for would probably produce this error.
That said, I doubt you want 8.24. You probably want kAudioFormatFlagsCanonical to get standard 16-bit audio. Or, if you want 32 bit, go with 32-bit float (kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved). Easier to deal with the math during your processing.
Also, you are setting the formats on the virtual inputs and outputs rather than the client inputs and outputs, which I don't think is what you want. The API here is rather confusing, but to set client input format, use kAudioUnitScope_Input, kOutputBus. The logic here is that you're setting the format of the output of the internal Core Audio input converter unit, which, from the perspective of your code, is the input audio. Confusing, I know. See Audio Unit docs for more detail. Likewise, to set client output format, use kAudioUnitScope_Output, kInputBus.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With