将 pcm 转换为 mp3(使用 LAME)会导致 mp3 文件中"clicks"
Converting pcm to mp3 (using LAME) causes "clicks" in mp3 file
我的应用程序使用LAME将原始PCM数据编码为mp3。但是我有一个问题 - 输出 mp3 包含持续一段时间内的"点击"。像这样:
声音。。。"咔嚓"声.."咔嚓"声.."咔嚓"等...
我尝试了不同版本的LAME,并尝试更改了许多LAME设置,但没有成功。我的应用程序还可以将 pcm 转换为 wav 和 ogg,但此转换器不会导致"点击"。
有一个编码代码(pcm输入包含一个通道数据,pcm已经重采样到44100频率):
初始化:
lame = lame_init();
lame_set_in_samplerate(lame, 44100);
lame_set_VBR(lame, vbr_abr);//vbr_default
lame_init_params(lame);
//Samples count (do not have any effect on output)
dwSamples=1024;
//mp3 buffer size, if it do not equals dwSamples*2 than output sound getting scaled
dwMP3Buffer=dwSamples*2;
pMP3Buffer = new BYTE[dwMP3Buffer];
写入 pcm 数据
int Mp3Stream :: Write(short * _data, int _size)
{
if (_size > 0)
{
for(int curPos = 0; curPos < _size; curPos += dwMP3Buffer)
{
//int size = dwMP3Buffer;
//if (_size - curPos < dwMP3Buffer)
// size = _size - curPos;
int bytes = lame_encode_buffer(lame, (short *)((char *)_data + curPos), (short *)((char *)_data + curPos), dwSamples, pMP3Buffer, 0);
IPF_TRACE(1, "MP3 encoder wrote "<<bytes<<" bytes");
if (bytes<0)
{
IPF_TRACE(1, "MP3 encoding failed with code "<<bytes);
return bytes;
}
BOOL bResult = WriteFile(hFile, pMP3Buffer, bytes, &bw, NULL);
if (!bResult || bytes != bw)
{
IPF_TRACE(1, "MP3 write to file failed with code "<<bytes);
}
};
}
}
敲定
int bytes = lame_encode_flush(lame, pMP3Buffer, 0);
if (bytes<0)
{
IPF_TRACE(1, "MP3 flush failed with code "<<bytes);
}
BOOL bResult = WriteFile(hFile, pMP3Buffer, bytes, &bw, NULL);
if (!bResult || bytes != bw)
{
IPF_TRACE(1, "MP3 write to file failed with code "<<bytes);
}
int ret = lame_close(lame);
if (ret < 0)
{
IPF_TRACE(1, "MP3 lame close failed with code "<<ret);
}
delete []pMP3Buffer;
声音 -> 单击 -> 声音 -> 单击模式很可能意味着您一次只写入缓冲区的一半,另一半在写入调用中的每个循环中保持零。
原因是您的循环增量器基于 dwSamples*2 的 dwMP3Buffer 值。
for(int curPos = 0; curPos < _size; curPos += dwMP3Buffer){
这意味着您实际上并没有对所有输入值进行编码,因为 dwMP3Buffer 是您实际传递给lame_encode_buffer调用 (dwSamples) 的样本数的两倍。
lame_encode_buffer(lame, (short *)((char *)_data + curPos),
(short *)((char *)_data + curPos), dwSamples, pMP3Buffer, 0);
尝试将循环增量器更改为以下内容:
for(int curPos = 0; curPos < _size; curPos += dwSamples){
试试这个,
void AQRecorder::MyInputBufferHandler( void * inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription* inPacketDesc)
{
AQRecorder *aqr = (AQRecorder *)inUserData;
// NSLog(@"%f",inStartTime->mSampleTime);
try
{
if (inNumPackets > 0)
{
AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize, inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData);
aqr->mRecordPacket += inNumPackets;
int MP3_SIZE =inBuffer->mAudioDataByteSize * 4;
unsigned char mp3_buffer[MP3_SIZE];
AppDelegate *delegate =[[UIApplication sharedApplication]delegate];
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 44100);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
// int encodedBytes=lame_encode_buffer_interleaved(lame, (short int *)inBuffer->mAudioData , inNumPackets, mp3_buffer, MP3_SIZE);
int encodedBytes = lame_encode_buffer(lame, (short*)inBuffer->mAudioData, (short*)inBuffer->mAudioData, inNumPackets, mp3_buffer, MP3_SIZE);
[delegate.mp3AudioData appendBytes:mp3_buffer length:encodedBytes];
if (inBuffer->mAudioDataByteSize != 0) {
}
else
{
int encode=lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
[delegate.mp3AudioData appendBytes:mp3_buffer length:encode];
}
lame_close(lame);
}
if (aqr->IsRunning())
{
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}
} catch (CAXException e)
{
char buf[256];
fprintf(stderr, "Error: %s (%s)n", e.mOperation, e.FormatError(buf));
}
}
我会尝试设置
dwSamples = 1152
1152 - 是 MPEG1Audio 编码器的音频帧大小(以样本为单位)。看起来LAME通过帧多个块处理数据
相关文章:
- 如何添加mp3文件作为资源,然后播放
- QML多媒体播放文件夹中的所有mp3
- 如何将MP3文件上传到QT(QMediaPlayer)上
- 正确读取被ID3标签干扰的MP3文件
- 无法在QTreeView中显示.mp3文件
- 从二进制数据还原mp3文件
- 在NACL中播放MP3文件
- 如何计算没有标签信息的 mp3 文件的哈希值
- 如何使用C ++在VLC中播放MP3文件
- 将 pcm 转换为 mp3(使用 LAME)会导致 mp3 文件中"clicks"
- 在窗口上播放和暂停.wav或.mp3文件
- 有没有办法暂停/停止使用 mcisendstring 播放 mp3 文件"wait"选项?
- 二进制读取mp3文件的ID3标记
- 从哪里开始制作将MP3文件转换为iphone有声读物(M4B)格式的程序
- 在FMOD中改变MIDI或WAV/MP3文件的速度
- 如何使用taglib - c++从MP3文件中读取XingHeaders, VBRIHeaders和sampleCoun
- MP3 文件长度显示不正确
- 使用c++程序播放Mp3文件
- 有没有简单的方法来播放mp3文件
- c++扫描硬盘中的MP3文件,并将其写入文本文件