I want to use AudioConverterFillComplexBuffer to convert sample rate for a pcm buffer(32k to 44.1k). But i didn't know why the voice seems changed(too many noise). Here is the main code:
struct AudioFrame { int samples; //number of samples in this frame. e.g. 320 int bytesPerSample; //number of bytes per sample: 2 for PCM16. int channels; //number of channels (data are interleaved if stereo) int samplesPerSec; //sampling rate void* buffer; //data buffer }; -(void)convertAudioFrame:(AudioFrame *)buffer outPutData:(unsigned char **)outPutData outPutDataSize:(UInt32 *)outPutDataSize{ if (buffer->bytesPerSample != self.unitDescription.mBitsPerChannel || buffer->channels != self.unitDescription.mChannelsPerFrame || buffer->samplesPerSec != self.unitDescription.mSampleRate){ // describe the input format's description AudioStreamBasicDescription inputDescription = {0}; inputDescription.mFormatID = kAudioFormatLinearPCM; inputDescription.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; inputDescription.mChannelsPerFrame = buffer->channels; inputDescription.mSampleRate = buffer->samplesPerSec; inputDescription.mBitsPerChannel = 16; inputDescription.mBytesPerFrame = (inputDescription.mBitsPerChannel/8) * inputDescription.mChannelsPerFrame; inputDescription.mFramesPerPacket = 1; inputDescription.mBytesPerPacket = inputDescription.mBytesPerFrame; AudioStreamBasicDescription outputDescription = {0}; outputDescription.mSampleRate = 44100; outputDescription.mFormatID = kAudioFormatLinearPCM; outputDescription.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; outputDescription.mChannelsPerFrame = 1; outputDescription.mFramesPerPacket = 1; outputDescription.mBitsPerChannel = 16; outputDescription.mBytesPerFrame = (outputDescription.mBitsPerChannel/8) * outputDescription.mChannelsPerFrame; outputDescription.mBytesPerPacket = outputDescription.mBytesPerFrame; // create an audio converter AudioConverterRef audioConverter; OSStatus status = AudioConverterNew(&inputDescription, &outputDescription, &audioConverter); [self checkError:status errorMsg:@"AudioConverterNew error"]; if(!audioConverter) { *outPutDataSize = 0; return; } UInt32 outputBytes = outputDescription.mBytesPerPacket * (buffer->samples*buffer->bytesPerSample / inputDescription.mBytesPerPacket); unsigned char *outputBuffer = (unsigned char*)malloc(outputBytes); memset(outputBuffer, 0, outputBytes); AudioBuffer inputBuffer; inputBuffer.mNumberChannels = inputDescription.mChannelsPerFrame; inputBuffer.mDataByteSize = buffer->samples*buffer->bytesPerSample; inputBuffer.mData = buffer->buffer; AudioBufferList outputBufferList; outputBufferList.mNumberBuffers = 1; outputBufferList.mBuffers[0].mNumberChannels = outputDescription.mChannelsPerFrame; outputBufferList.mBuffers[0].mDataByteSize = outputBytes; outputBufferList.mBuffers[0].mData = outputBuffer; UInt32 outputDataPacketSize = outputBytes / outputDescription.mBytesPerPacket; self.currentBuffer = &inputBuffer; self.currentInputDescription = inputDescription; // convert OSStatus result = AudioConverterFillComplexBuffer(audioConverter, converterComplexInputDataProc, (__bridge void*)self, &outputDataPacketSize, &outputBufferList, NULL); [self checkError:result errorMsg:@"AudioConverterFillComplexBuffer error"]; *outPutData = outputBuffer; *outPutDataSize = outputBytes; AudioConverterDispose(audioConverter); } } OSStatus converterComplexInputDataProc(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** ioDataPacketDescription, void* inUserData) { XMMicAudioManager *self = (XMMicAudioManager *)inUserData; ioData->mNumberBuffers = 1; ioData->mBuffers[0] = *(self.currentBuffer); *ioNumberDataPackets = ioData->mBuffers[0].mDataByteSize / self.currentInputDescription.mBytesPerPacket; return 0; }