lundi 19 mai 2014

c ++ - CoreAudio AudioUnitSetProperty échoue toujours définir la fréquence d'échantillonnage - Stack Overflow


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



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.




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



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


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.



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


0 commentaires:

Enregistrer un commentaire