CoreAudio AudioUnitSetProperty always fails to set Sample Rate

牧云@^-^@ 提交于 2019-12-21 12:21:13

问题


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);
}

回答1:


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.




回答2:


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!!!



来源:https://stackoverflow.com/questions/2170523/coreaudio-audiounitsetproperty-always-fails-to-set-sample-rate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!