尝试混合两个 PCM 音频源
Trying to mix two PCM audio sources
我使用 libsndfile 读取了两个音频文件。
SNDFILE* file1 = sf_open("D:\audio1.wav", SFM_READ, &info);
SNDFILE* file2 = sf_open("D:\audio2.wav", SFM_READ, &info2);
在完成之前的操作后,我采样了 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);
现在,问题是来自缓冲区 1 的音频在混音中听起来不错,但是当我将混音编码为文件时,唯一“添加”到新音频的是噪音(就像它是旧录音一样) .
如果我只将两者之一编码到一个文件中,它就可以完美地工作。
我不知道为什么会出错。我想这显然与混合有关,但我不知道我做错了什么。我得到了混合算法 here 但它没有给我预期的结果。
我还阅读了关于 SO 的其他信息,了解有类似问题的人,但我无法用这些信息解决问题。
你的混音代码很奇怪——你似乎添加了一个会导致失真的非线性项——它似乎是专门针对动态范围非常有限的 8 位 PCM 的 hack,但你可能对于 16 位 PCM,无需担心这一点。对于基本混合你只需要这个:
for (int t = 0; t < 800000 * 2; ++t)
{
mixdown[t] = (buffer1[t] + buffer2[t]) / 2;
}
请注意,当您有两个满刻度信号时,必须除以 2 以防止失真。另请注意,我已经删除了 2x 循环展开。
你的算法是正确的,但是你忽略了一个重点:你的 PCM 范围是从 -32768
到 32767
。因此,您必须除以 32768
,而不是 65535
。
我使用 libsndfile 读取了两个音频文件。
SNDFILE* file1 = sf_open("D:\audio1.wav", SFM_READ, &info);
SNDFILE* file2 = sf_open("D:\audio2.wav", SFM_READ, &info2);
在完成之前的操作后,我采样了 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);
现在,问题是来自缓冲区 1 的音频在混音中听起来不错,但是当我将混音编码为文件时,唯一“添加”到新音频的是噪音(就像它是旧录音一样) .
如果我只将两者之一编码到一个文件中,它就可以完美地工作。
我不知道为什么会出错。我想这显然与混合有关,但我不知道我做错了什么。我得到了混合算法 here 但它没有给我预期的结果。
我还阅读了关于 SO 的其他信息,了解有类似问题的人,但我无法用这些信息解决问题。
你的混音代码很奇怪——你似乎添加了一个会导致失真的非线性项——它似乎是专门针对动态范围非常有限的 8 位 PCM 的 hack,但你可能对于 16 位 PCM,无需担心这一点。对于基本混合你只需要这个:
for (int t = 0; t < 800000 * 2; ++t)
{
mixdown[t] = (buffer1[t] + buffer2[t]) / 2;
}
请注意,当您有两个满刻度信号时,必须除以 2 以防止失真。另请注意,我已经删除了 2x 循环展开。
你的算法是正确的,但是你忽略了一个重点:你的 PCM 范围是从 -32768
到 32767
。因此,您必须除以 32768
,而不是 65535
。