c - 混合 16 位线性 PCM 流并避免剪辑/溢出

标签 c audio signal-processing pcm mixing

我试图将 2 个 16 位线性 PCM 音频流混合在一起,但我似乎无法克服噪音问题。我认为它们是在将 sample 混合在一起时溢出的。

我有以下功能......

short int mix_sample(short int sample1, short int sample2)
{
    return #mixing_algorithm#;
}

...这是我尝试过的#mixing_algorithm#

sample1/2 + sample2/2
2*(sample1 + sample2) - 2*(sample1*sample2) - 65535
(sample1 + sample2) - sample1*sample2
(sample1 + sample2) - sample1*sample2 - 65535
(sample1 + sample2) - ((sample1*sample2) >> 0x10) // same as divide by 65535

其中一些产生了比其他更好的结果,但即使是最好的结果也包含相当多的噪音。

有什么解决办法吗?

最佳答案

我找到的最佳解决方案是 given by Viktor Toth .他为 8 位无符号 PCM 提供了一个解决方案,并将其更改为 16 位有符号 PCM,产生了这个:

int a = 111; // first sample (-32768..32767)
int b = 222; // second sample
int m; // mixed result will go here

// Make both samples unsigned (0..65535)
a += 32768;
b += 32768;

// Pick the equation
if ((a < 32768) || (b < 32768)) {
    // Viktor's first equation when both sources are "quiet"
    // (i.e. less than middle of the dynamic range)
    m = a * b / 32768;
} else {
    // Viktor's second equation when one or both sources are loud
    m = 2 * (a + b) - (a * b) / 32768 - 65536;
}

// Output is unsigned (0..65536) so convert back to signed (-32768..32767)
if (m == 65536) m = 65535;
m -= 32768;

使用此算法意味着几乎不需要裁剪输出,因为它只差一个值在范围内。与直接平均不同,一个声源的音量即使在另一个声源静音时也不会降低。

关于c - 混合 16 位线性 PCM 流并避免剪辑/溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12089662/

相关文章:

iphone - WAV停止在我的iPhone应用程序上使用AudioServices吗?

c# - Dicomize 心电图原始信号数据

linux - 从任意音频文件中提取语音部分的好方法是什么?

c - 在C中将函数之间的多个变量返回到

Petzold 的编程窗口中的代码(制作窗口错误)

c - C11 是否允许在函数中的任何位置声明变量?

c - .bss 与 .data : static q32 vs static int

c - 为什么 clEnqueueMapBuffer 返回随机数据?

android - 通过耳机插孔的输出引脚记录立体声音频,而不是编写USB音频驱动器

audio - 手机之间的实时音频流