How to resemple pcm data in iOS

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;

}

Replies

Best to start by looking at a standard sample AudioConverter implementation Audio Toolbox Convert File, specifically UseAC-AF.cpp

I have the same problem ,did you sovle it finily?