试图混合两个PCM音频源

时间:2015-02-24 09:53:48

标签: c++ audio ffmpeg libsndfile

我使用libsndfile读取了两个音频文件。

SNDFILE* file1 = sf_open("D:\\audio1.wav", SFM_READ, &info);
SNDFILE* file2 = sf_open("D:\\audio2.wav", SFM_READ, &info2);

在我完成之前的I样本x样本之后:

//Buffers that will hold the samples
short* buffer1 = new short[2 * sizeof(short) * 800000];
short* buffer2 = new short[2 * sizeof(short) * 800000];

// Read the samples using libsndfile
sf_readf_short(file1, buffer1, 800000);
sf_readf_short(file2, buffer2, 800000);

现在,我想混合这两个。我读到你需要分别得到左右声道然后总结它们。我尝试这样做:

short* mixdown = new short[channels * sizeof(short) * 800000];
for (int t = 0; t < 800000; ++t)
{
    mixdown[t] = buffer1[t] + buffer2[t] - ((buffer1[t]*buffer2[t]) / 65535);
    t++;
    mixdown[t] = buffer1[t] + buffer2[t] - ((buffer1[t]*buffer2[t]) / 65535);
}

之后我使用ffmpeg:

对新音频进行了编码
FILE* process2 = _popen("ffmpeg -y -f s16le -acodec pcm_s16le -ar 44100 -ac 2 -i - -f vob -ac 2 D:\\audioMixdown.wav", "wb");
fwrite(mixdown, 2 * sizeof(short) * 800000, 1, process2);

现在,问题是来自buffer1的音频在混音中听起来不错,但唯一的事情是#34;添加&#34;当我将混音编码为文件时,新音频就是噪音(就好像它是一个旧的音频录音)。

如果我只将两个中的一个编码到一个文件中,它就能完美运行。

我不知道它为什么会出错。我猜这显然与混音有关,但我不知道我做错了什么。我得到了混合算法here,但它并没有给我预期的结果。

我还阅读了有关人们有类似问题的其他信息,但我无法用这些来解决这些问题。

提前致谢

2 个答案:

答案 0 :(得分:3)

你的混音代码非常奇怪 - 你似乎在添加一个会导致失真的非线性项 - 它似乎是专门用于8位PCM的黑客,其动态范围非常有限,但你可能不会# 39;对于16位PCM需要担心这个问题。对于基本混音,你只需要这个:

for (int t = 0; t < 800000 * 2; ++t)
{
    mixdown[t] = (buffer1[t] + buffer2[t]) / 2;
}

请注意,当您有两个满量程信号时,除以2是必要的,以防止失真。另请注意,我已删除了2x循环展开。

答案 1 :(得分:1)

您的算法是正确的,但您错过了一个重点:PCM的范围是-3276832767。因此,您必须除以32768,而不是65535