Question

I'm trying to encode the raw PCM data from microphone to MP3 using AudioToolbox framework and Lame. And although everything seems to run fine, there is this problem with "clicks" and "distortions" present in the encoded stream. I'm not sure that I setup AudioQueue correctly and also that I process the encoded buffer in the right wat... My code to setup audio recording:

    AudioStreamBasicDescription streamFormat;
    memset(&streamFormat, 0, sizeof(AudioStreamBasicDescription));
    streamFormat.mSampleRate = 44100;
    streamFormat.mFormatID = kAudioFormatLinearPCM;
    streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger|kLinearPCMFormatFlagIsPacked;
    streamFormat.mBitsPerChannel = 16;
    streamFormat.mChannelsPerFrame = 1;
    streamFormat.mBytesPerPacket = 2;
    streamFormat.mBytesPerFrame = 2;
    streamFormat.mFramesPerPacket = 1;
    streamFormat.mReserved = 0;        

    AudioQueueNewInput(&streamFormat, InputBufferCallback, (__bridge void*)(self), nil, nil, 0, &mQueue);
    UInt32 bufferByteSize = 44100;
    memset(&mEncodedBuffer, 0, sizeof(mEncodedBuffer)); //mEncoded buffer is 
                                                        //unsigned char [72000]
    AudioQueueBufferRef buffer;
    for (int i=0; i<3; i++) {
         AudioQueueAllocateBuffer(mQueue, bufferByteSize, &buffer);      
         AudioQueueEnqueueBuffer(mQueue, buffer, 0, NULL);
    }
    AudioQueueStart(mQueue, nil);

Then the AudioQueue callback function calls to lame_encode_buffer and then writes the encoded buffer to file:

void InputBufferCallback (void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumPackets, const AudioStreamPacketDescription* inPacketDesc) {
      memset(&mEncodedBuffer, 0, sizeof(mEncodedBuffer));
      int encodedBytes = lame_encode_buffer(glf, (short*)inBuffer->mAudioData, NULL, inBuffer->mAudioDataByteSize, mEncodedBuffer, 72000);
      //What I don't understand is that if I write the full 'encodedBytes' data,  then there are A LOT of distortions and original sound is seriously broken 
      NSData* data = [NSData dataWithBytes:mEncodedBuffer length:encodedBytes/2]; 
      [mOutputFile writeData:data];
}

And when I afterward try to play the file which contains Lame encoded data with AVAudioPlayer I clearly hear original sound but with some clicks and distortions around.

Can anybody advise what's wrong here?

Was it helpful?

Solution

Your code does not appear to be paying attention to inNumPackets, which is the amount of actual audio data given the callback.

Also, doing a long operation, such as running an encoder, inside an audio callback might not be fast enough and thus may violate response requirements. Any long function calls should be done outside the callback.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top