点击,而在iOS中使用LAME为en code来自PCM的MP3 [英] Clicks while using LAME to encode from PCM to MP3 in iOS
问题描述
我不是第一个有这种类型的问题,但是,我没有能够解决这个问题。
我在编码iOS版LinearPCM为MP3。据工作虽然我每个缓冲区之间经历的点击。
memset的(安培;男人codedBuffer,0,sizeof的(男性codedBuffer));INT EN codedBytes = lame_en code_buffer(GFP,(短*)inBuffer-> mAudioData,NULL,inNumberPacketDescriptions,男人codedBuffer,MP3_BUFFER_SIZE);NSData的*数据= [NSData的dataWithBytes:C $ cdBuffer长度男人$:连接codedBytes]。
然后,我将与缓冲区如下:
AudioQueueEnqueueBuffer(vc.recordState.queue,inBuffer,0,NULL);
我已经打过电话lame_en code_buffer后添加以下行:
连接codedBytes + = lame_en code_flush(GFP,男人codedBuffer + EN codedBytes,0);
不过,这将导致一个暂时现象也(我猜它一定的输入0一帧的结束)。试图让我意识到,我不编码一些inBuffer-> mAudioData的最后音频数据包,并可能导致的点击。但是,我不知道如何计算有多少被留下(如果我知道,我可以简单地在保存这些数据包一个遗留缓冲区是prepended到输入下一个缓冲区)。
下面是我设置更多的信息:
我有以下的InputFormat:
- (无效)setupSourceAudioFormat:(AudioStreamBasicDescription *)格式
{
格式化> mFormatID = kAudioFormatLinearPCM; 格式化> mSampleRate = 44100;
格式化> mFramesPerPacket = 1;
格式化> mChannelsPerFrame = 1;
格式化> mBytesPerFrame = 2;
格式化> mBytesPerPacket = 2;
格式化> mBitsPerChannel = 16;
格式化> mReserved = 0;
格式化> mFormatFlags = kLinearPCMFormatFlagIsBigEndian |
kLinearPCMFormatFlagIsSignedInteger |
kLinearPCMFormatFlagIsPacked;
}
和我设置瘸是这样的:
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);
我previously称为lame_init()每次我带codeD的缓冲区。
在我感动的是设置code出一次问题是固定的被称为
我猜发生了什么事是在时间的MP3必须设有code。至少1152帧和lame_t EN codeR跟踪,这不是恩在最后调用codeD数据。所以,在这里我们离开lame_en code_buffer可以开始了。
lame_en code_flush应该只在一个文件的最后使用(或最后几帧将得到砍掉,除非帧的数量是1152的整数倍 - 不太可能)。
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);
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).
这篇关于点击,而在iOS中使用LAME为en code来自PCM的MP3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!