Lame中的Cliks和扭曲编码了Mp3文件

时间:2012-06-04 17:36:58

标签: objective-c xcode mp3 core-audio lame

我正在尝试使用AudioToolbox框架和Lame将原始PCM数据从麦克风编码为MP3。虽然一切似乎运行良好,但编码流中存在“点击”和“扭曲”的问题。 我不确定我是否正确设置了AudioQueue,并且我在正确的wat中处理编码缓冲区... 我设置录音的代码:

    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);

然后AudioQueue回调函数调用lame_encode_buffer,然后将编码缓冲区写入文件:

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];
}

当我后来尝试使用AVAudioPlayer播放包含Lame编码数据的文件时,我清楚地听到了原始声音,但有一些点击和扭曲。

有人可以告诉我这里有什么问题吗?

1 个答案:

答案 0 :(得分:2)

您的代码似乎没有关注inNumPackets,这是给定回调的实际音频数据量。

此外,在音频回调中进行长时间操作(例如运行编码器)可能不够快,因此可能违反响应要求。任何长函数调用都应该在回调之外完成。