点击,而在iOS中使用LAME为en code来自PCM的MP3 [英] Clicks while using LAME to encode from PCM to MP3 in iOS

查看:260
本文介绍了点击,而在iOS中使用LAME为en code来自PCM的MP3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不是第一个有这种类型的问题,但是,我没有能够解决这个问题。

我在编码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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆