7

我正在使用 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);

这是怎么回事?我在这里想念什么?

4

3 回答 3

8

不确定您是否仍在寻找 Dave L 以外的答案,但咔哒声来自 LAME 意外编码音频文件中的标题。根据您生成的 WAV 文件,标头可能是 44 字节。我在转换我录制的 PCM 文件时遇到了类似的问题,但在我的情况下,这些标头是 4096 字节。如果它是一个真正的 wav 文件(因此具有 44 字节的标题),只需使用

fseek(pcm,44,0);

在您打开文件后立即跳过标题内容。我还建议在您的一个 WAV 文件上使用十六进制编辑器来验证标题的大小。

一旦我跳过它(再次,我的标题是 4096b),点击噪音就消失了。

于 2013-01-27T20:47:00.770 回答
3

任何运气解决这个问题?

我遇到了类似的问题,我尝试在写入输出文件时跳过前 1024 个字节(即,在开始将 LAME 的输出写入输出文件之前,我只是丢弃了这些字节)。这消除了录制开始时的“咔哒”声,但这有点小技巧,但似乎可以正常工作。

于 2012-10-06T03:59:17.923 回答
0

跳过标题对于避免此类点击很重要,但固定大小例如。44 字节是一个不起作用的解决方案。

我的典型 WAV 文件具有 80 字节的标头。

无论如何,您应该解析 WAV 文件以找到真正的标头大小。这对于获取一些额外的东西也很有意义,例如每个样本的位数、通道数等,这些东西可用于为 lame 设置正确的参数或提供一些有用的默认参数。

为了让事情变得更容易,你不能从头开始开发所有这些东西。可以使用 Lame 源中包含的前端(查找文件 get_audio.c 和函数parse_wave_header(lame_global_flags * gfp, FILE * sf)

如果您只需要标头大小,您当然可以修改此功能以满足您的需求。

于 2015-06-15T10:22:48.990 回答