Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreAudio AudioUnitSetProperty always fails to set Sample Rate

I need to change the output sample rate from 44.1 to 32.0, but it always throws an error, Out: AudioUnitSetProperty-SF=\217\325\377\377, -10865. I don't know why it will let me set it for input, but then not set it for output.

My code is:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

OSStatus MyRenderer(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp   *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){
 NSLog(@"Running...");
 ioData->mBuffers[0].mDataByteSize = 2048;
 ioData->mBuffers[0].mData = lbuf;
 ioData->mBuffers[0].mNumberChannels = 1;

 return noErr;
}

void CreateDefaultAU(){
 OSStatus err = noErr;

 // Open the default output unit
 AudioComponentDescription desc;
 desc.componentType = kAudioUnitType_Output;
 desc.componentSubType = kAudioUnitSubType_DefaultOutput;
 desc.componentFlags = 0;
 desc.componentFlagsMask = 0;
 desc.componentManufacturer = 0;

 AudioComponent comp = AudioComponentFindNext(NULL, &desc);
 if (comp == NULL) { printf ("FindNextComponent\n"); return; }

 err = AudioComponentInstanceNew(comp, &gOutputUnit);
 if (comp == NULL) { printf ("OpenAComponent=%ld\n", err); return; }

 // Set up a callback function to generate output to the output unit
 AURenderCallbackStruct input;
 input.inputProc = MyRenderer;
 input.inputProcRefCon = NULL;

 err = AudioUnitSetProperty(gOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, sizeof(input));

 if (err) { printf ("AudioUnitSetProperty-CB=%ld\n", err); return; }

 AudioStreamBasicDescription streamFormat;
 streamFormat.mSampleRate = 32000.00;        // the sample rate of the audio stream
 streamFormat.mFormatID = kAudioFormatLinearPCM;     // the specific encoding type of audio stream
 streamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger;//kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsNonMixable;
 streamFormat.mFramesPerPacket = 1;
 streamFormat.mChannelsPerFrame = 1;
 streamFormat.mBitsPerChannel = 16;
 streamFormat.mBytesPerPacket = 2;
 streamFormat.mBytesPerFrame = 2;

 err = AudioUnitSetProperty(gOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, sizeof(streamFormat));
 if (err) { printf ("In:  AudioUnitSetProperty-SF=%4.4s, %ld\n", (char*)&err, err); return; }

 err = AudioUnitSetProperty(gOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamFormat, sizeof(streamFormat));
 if (err) { printf ("Out: AudioUnitSetProperty-SF=%4.4s, %ld\n", (char*)&err, err); return; }
}

void TestDefaultAU(){
 OSStatus err = noErr;

 // Initialize unit
 err = AudioUnitInitialize(gOutputUnit);
 if (err) { printf ("AudioUnitInitialize=%ld\n", err); return; }

 Float64 outSampleRate;
 UInt32 size = sizeof(Float64);
 err = AudioUnitGetProperty(gOutputUnit, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, 0, &outSampleRate, &size);

 printf("Out srate %f\n",outSampleRate);
 if (err) { printf ("AudioUnitSetProperty-GF=%4.4s, %ld\n", (char*)&err, err); return; }
 AudioOutputUnitStart (gOutputUnit);
 if (err) { printf ("AudioOutputUnitStart=%ld\n", err); return; }
 AudioUnitReset (gOutputUnit, kAudioUnitScope_Input, 0);
}
like image 326
Matthew Callis Avatar asked Jan 31 '10 04:01

Matthew Callis


2 Answers

With the DefaultOuput AudioUnit you only set the input side of the AudioUnit to the format you wish to render. The output side of the unit will match what you specify on the input side but you cannot set it yourself.

Try this after you have set the input stream format and you'll see that you are all set to go...

Float64 outSampleRate = 0.0;
UInt32 size = sizeof(Float64);
AudioUnitGetProperty (gOutputUnit,
                      kAudioUnitProperty_SampleRate,
                      kAudioUnitScope_Output,
                      0,
                      &outSampleRate,
                      &size);
NSLog(@"Output sample rate is now at %f Hz", outSampleRate);

You can also look at the Audio Unit Component Services Reference to see that error code -10865 is kAudioUnitErr_PropertyNotWritable.

like image 77
VoidPointer Avatar answered Sep 20 '22 23:09

VoidPointer


The documentation states that when you set the Sample rate property, you are actually requesting a value (which the system may not be able to give you).

The system will then set the best approximation it can.

You then need to follow up with a call to retrieve the sampling rate that was actually set.

As I understand, it is not possible to specify any arbitrary sample rate.

I would love to be wrong on this!!!

like image 28
P i Avatar answered Sep 18 '22 23:09

P i