How can i resample audio(PCM data) using Audio Unit at runtime/live ?
I have an Audio Unit setup as follows.
- (void) setUpAudioUnit {
OSStatus status;
AudioComponentInstance audioUnit;
AudioComponent inputComponent;
AudioComponentDescription audioComponentDescription;
AudioStreamBasicDescription audioStreamBasicDescription;
// Describe audio component
audioComponentDescription.componentType = kAudioUnitType_Output;
audioComponentDescription.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
audioComponentDescription.componentFlags = 0;
audioComponentDescription.componentFlagsMask = 0;
audioComponentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
// Get component
inputComponent = AudioComponentFindNext(NULL, &audioComponentDescription);
// Get audio units
status = AudioComponentInstanceNew(inputComponent, &audioUnit);
checkStatus(status);
// Enable IO for recording
UInt32 flag = 1;
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
kInputBus,
&flag,
sizeof(flag));
checkStatus(status);
// Enable IO for playback
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
kOutputBus,
&flag,
sizeof(flag));
checkStatus(status);
// Describe format
audioStreamBasicDescription.mSampleRate = AUDIO_SAMPLE_RATE;
audioStreamBasicDescription.mFormatID = kAudioFormatLinearPCM;
audioStreamBasicDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioStreamBasicDescription.mFramesPerPacket = AUDIO_FRAMES_PER_PACKET;
audioStreamBasicDescription.mChannelsPerFrame = AUDIO_CHANNELS_PER_FRAME;
audioStreamBasicDescription.mBitsPerChannel = AUDIO_BITS_PER_CHANNEL;
audioStreamBasicDescription.mBytesPerPacket = AUDIO_BYTES_PER_PACKET;
audioStreamBasicDescription.mBytesPerFrame = AUDIO_BYTES_PER_FRAME;
// Apply format
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus,
&audioStreamBasicDescription,
sizeof(audioStreamBasicDescription));
checkStatus(status);
/* Make sure we set the correct audio category before restarting */
UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
sizeof(audioCategory),
&audioCategory);
checkStatus(status);
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
kOutputBus,
&audioStreamBasicDescription,
sizeof(audioStreamBasicDescription));
checkStatus(status);
// Set input callback
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = recordingCallback;
callbackStruct.inputProcRefCon = (__bridge void *)(self);
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
kInputBus,
&callbackStruct,
sizeof(callbackStruct));
checkStatus(status);
// Set output callback
callbackStruct.inputProc = playbackCallback;
callbackStruct.inputProcRefCon = (__bridge void *)(self);
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
kOutputBus,
&callbackStruct,
sizeof(callbackStruct));
checkStatus(status);
// Disable buffer allocation for the recorder (optional - do this if we want to pass in our own)
flag = 0;
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_ShouldAllocateBuffer,
kAudioUnitScope_Output,
kInputBus,
&flag,
sizeof(flag));
}
And the Audio settings is as follows.
kOutputBus 0
kInputBus 1
AUDIO_SAMPLE_RATE 44100
AUDIO_FRAMES_PER_PACKET 1
AUDIO_CHANNELS_PER_FRAME 1
AUDIO_BITS_PER_CHANNEL 16
AUDIO_BYTES_PER_PACKET 2
AUDIO_BYTES_PER_FRAME 2
I am receiving the PCM data from recording callback as
audioBufferList->mBuffers[0].mData
SO, how can i resample this PCM data from 44.1KHz to 8KHz and vice versa ? I have googled a lot but didn't find any code sample or straight instruction for this.
Found these thread but none of these provides clear instruction.
Any code sample or information is highly appreciated.