我正在使用LAME将WAV文件(从音频CD中提取)转换为MP3。转换结果很好,除了在文件的最开头有一个单击“咔嗒”声。在歌曲本身之前,点击几乎需要0.5秒。
char *input_file = argv[1];
char *output_file = argv[2];
FILE *pcm = fopen(input_file, "rb");
FILE *mp3 = fopen(output_file, "wb+");
size_t nread;
int ret, nwrite;
const int PCM_SIZE = 1152;
const int MP3_SIZE = 1152;
short pcm_buffer[PCM_SIZE * 2];
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
// Can not put these lines at the end of conversion
id3tag_set_title(lame, "Still reminds me");
id3tag_set_artist(lame, "Anggun");
lame_set_VBR(lame, vbr_mt);
lame_set_VBR_quality(lame, 2);
ret = lame_init_params(lame);
do {
nread = fread(pcm_buffer, sizeof(short), PCM_SIZE * 2, pcm);
if (nread != 0) {
// Is this the cause of the single click?
int nsamples = nread / 2;
short buffer_l[nsamples];
short buffer_r[nsamples];
int j = 0;
int i = 0;
for (i = 0; i < nsamples; i++) {
buffer_l[i] = pcm_buffer[j++];
buffer_r[i] = pcm_buffer[j++];
}
nwrite = lame_encode_buffer(lame, buffer_l, buffer_r, nsamples,
mp3_buffer, MP3_SIZE);
} else {
nwrite = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
}
fwrite(mp3_buffer, nwrite, 1, mp3);
} while (nread != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
发生了什么事?我在这里想念什么?
答案 0 :(得分:7)
不确定你是否还在寻找Dave L'以外的答案,但点击噪音来自LAME意外编码音频文件中的标题。根据您生成的WAV文件,标头可能是44个字节。转换我录制的PCM文件时遇到了类似的问题,但在我的情况下,这些标题是4096字节。如果它是一个真正的wav文件(因此有44字节标题),只需使用
fseek(pcm,44,0);
打开文件后跳过标题内容。我还建议在你的一个WAV文件上使用Hex编辑器来验证标题的大小。
一旦我跳过那个(再次,我的标题是4096b),点击的噪音就消失了。
答案 1 :(得分:3)
解决这个问题的运气好吗?
我遇到了类似的问题,我尝试在写入输出文件时跳过前1024个字节(即,我只是在开始将输出从LAME写入输出之前丢弃这些字节文件)。这消除了录音开始时的“点击”,但它有点像黑客,但似乎工作正常。
答案 2 :(得分:0)
跳过标题对于避免这样的点击很重要,但是例如固定大小。 44字节是无效解决方案。
我的典型WAV文件有80字节标题。
无论如何,你应该解析WAV文件以找到真正的标题大小。这对于获取一些额外的东西也很有意义,例如每个样本的比特数,通道数等,可用于设置跛脚的正确参数或提供一些有用的默认参数。
为了使事情变得更容易,你不能从头开始开发所有这些东西。可以使用Lame源中包含的前端(查找文件get_audio.c和函数parse_wave_header(lame_global_flags * gfp, FILE * sf)
如果您只需要标题大小,您当然可以修改此功能以满足您的需求。