2

I am trying to set different sampling rates (like 32kHz, 24kHz etc..) to the input stream of Remote I/O audio unit. But the output is always played at one of these sampling rates - 22.05kHz, 33.1kHz, 11.0kHz irrespective of what I set. And surprisingly, when I call AudioUnitGetProperty on kAudioUnitScope_Output for kAudioUnitProperty_SampleRate, it always returns 44.1kHz

- (void)startToneUnit
{
    AudioComponentDescription defaultOutputDescription;
    defaultOutputDescription.componentType = kAudioUnitType_Output;
    defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
    defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
    defaultOutputDescription.componentFlags = 0;
    defaultOutputDescription.componentFlagsMask = 0;

        // Get the default playback output unit
    AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription);
    NSAssert(defaultOutput, @"Can't find default output");

        // Create a new unit based on this that we'll use for output
    OSErr err = AudioComponentInstanceNew(defaultOutput, &toneUnit);
    NSAssert1(toneUnit, @"Error creating unit: %hd", err);

        // Set our tone rendering function on the unit
    AURenderCallbackStruct input;
    input.inputProc = RenderTone;
    input.inputProcRefCon = (__bridge void *)(self);
    err = AudioUnitSetProperty(toneUnit,
                               kAudioUnitProperty_SetRenderCallback,
                               kAudioUnitScope_Input,
                               0,
                               &input,
                               sizeof(input));
    NSAssert1(err == noErr, @"Error setting callback: %hd", err);

        // Set the format to 32 bit, single channel, floating point, linear PCM
    const int four_bytes_per_float = 4;
    const int eight_bits_per_byte = 8;

    AudioStreamBasicDescription streamFormat;
    streamFormat.mSampleRate = SAMPLE_RATE;
    streamFormat.mFormatID = kAudioFormatLinearPCM;
    streamFormat.mFormatFlags =
    kAudioFormatFlagsNativeFloatPacked;
    streamFormat.mBytesPerPacket = four_bytes_per_float;
    streamFormat.mFramesPerPacket = 1;
    streamFormat.mBytesPerFrame = four_bytes_per_float;
    streamFormat.mChannelsPerFrame = 1;
    streamFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;
    err = AudioUnitSetProperty (toneUnit,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Input,
                                0,
                                &streamFormat,
                                sizeof(AudioStreamBasicDescription));

    NSAssert1(err == noErr, @"Error setting stream format: %hd", err);

        // Stop changing parameters on the unit
    err = AudioUnitInitialize(toneUnit);
    NSAssert1(err == noErr, @"Error initializing unit: %hd", err);

        // Start playback
    err = AudioOutputUnitStart(toneUnit);
    NSAssert1(err == noErr, @"Error starting unit: %hd", err);

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

   }

What are all the possible output sampling rates supported for Audio Units? Any reference to Apple's documentation on this will be greatly helpful

Thanks

srinivas
  • 55
  • 1
  • 5

1 Answers1

5

AudioUnits, in general, can run at whatever sample rate you specify. The RemoteIO (or HAL on Mac OS X) AudioUnits, being facades for hardware, are more restricted -- varispeed clock generators, sample rate generators that can run at any arbitrary sample rate, are very expensive and generally not appropriate for telephones :)

Different iOS hardware, models of hardware, or lines of hardware or revisions may support different sample rates. RemoteIO just accepts the rate you request and sets the onboard converter to the rate that is closest to the one you request. You always have to do a AudioUnitGetProperty to see what you're actually getting. If you want to record or work at a different rate, you need to then employ an converter plugin.

iluvcapra
  • 9,436
  • 2
  • 30
  • 32
  • Thanks!!! But calling the `AudioUnitGetProperty` for sampling rate always returns 44.1kHz even though audio is actually being played at a different frequency like 22.05kHz or 33.1kHz or 11kHz (found these frequencies by dividing total samples rendered by duration of audio playback). Any thing wrong with my code?? – srinivas Mar 20 '13 at 05:46
  • 1
    A detail--- you know when you set the input properties of RemoteIO you must address them to bus `1`, right? When you're doing all those `SetProperty`calls to `kAudioUnitScope_Input` but bus `0`, they aren't setting the properties on the correct entity. – iluvcapra Mar 20 '13 at 16:58