Reputation: 977
I am not the first to have this type of issue, however, I have no been able to solve it.
I am encoding a LinearPCM to MP3 in iOS. It is working though I am experiencing clicks between each buffer.
memset(&mEncodedBuffer, 0, sizeof(mEncodedBuffer));
int encodedBytes = lame_encode_buffer(gfp, (short*)inBuffer->mAudioData, NULL, inNumberPacketDescriptions, mEncodedBuffer, MP3_BUFFER_SIZE);
NSData* data = [NSData dataWithBytes:mEncodedBuffer length:encodedBytes];
Then, I do the following with the buffer:
AudioQueueEnqueueBuffer(vc.recordState.queue, inBuffer, 0, NULL);
I have tried adding the following line after calling lame_encode_buffer:
encodedBytes += lame_encode_flush(gfp, mEncodedBuffer+encodedBytes, 0);
However, this will cause a blip also (I guess it input some 0's at the end of a frame). Trying that made me realize that I am not encoding some of the last audio packets of the inBuffer->mAudioData and that may be causing the click. However, I am not sure how to compute how many of those are left (if I knew, I could simply save these packets in a "left-over" buffer that is prepended to the incoming next buffer).
Here is a bit more information on my settings:
I have the following inputFormat:
- (void)setupSourceAudioFormat:(AudioStreamBasicDescription*)format
{
format->mFormatID = kAudioFormatLinearPCM;
format->mSampleRate = 44100;
format->mFramesPerPacket = 1;
format->mChannelsPerFrame = 1;
format->mBytesPerFrame = 2;
format->mBytesPerPacket = 2;
format->mBitsPerChannel = 16;
format->mReserved = 0;
format->mFormatFlags = kLinearPCMFormatFlagIsBigEndian |
kLinearPCMFormatFlagIsSignedInteger |
kLinearPCMFormatFlagIsPacked;
}
and I setup lame this way:
lame_t gfp = lame_init();
lame_set_num_channels(gfp, 1);
lame_set_in_samplerate(gfp, 44100);
lame_set_mode(gfp, MONO);
lame_set_brate(gfp, 64);
lame_init_params(gfp);
Upvotes: 3
Views: 2072
Reputation: 977
I previously called lame_init() each time I encoded a buffer.
Once I moved that setup code out to be called only once the issue was fixed.
I guess what is happening is that mp3 must encode at least 1152 frames at a time, and the lame_t encoder keeps track of data that was not encoded at the last call. So lame_encode_buffer can start where we left off.
lame_encode_flush should only be used at the very end of a file (or the last few frames would get chopped off, unless the number of frames was an exact multiple of 1152--unlikely).
Upvotes: 3