Rag*_*nar 8 c audio signal-processing mixing pcm
我试图将2个16位线性PCM音频流混合在一起,我似乎无法克服噪音问题.我认为将样品混合在一起时它们会溢出.
我有以下功能......
short int mix_sample(short int sample1, short int sample2)
{
return #mixing_algorithm#;
}
Run Code Online (Sandbox Code Playgroud)
......这就是我尝试过的#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
Run Code Online (Sandbox Code Playgroud)
其中一些产生了比其他产品更好的结果,但即使是最好的结果也包含了很多噪音.
任何想法如何解决?
Mal*_*ous 11
我发现的最佳解决方案由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;
Run Code Online (Sandbox Code Playgroud)
使用此算法意味着几乎不需要剪切输出,因为它只是在一个范围内的一个值.与直线平均不同,即使另一个源静音,也不会减少一个源的音量.
这是一个描述性的实现:
short int mix_sample(short int sample1, short int sample2) {
const int32_t result(static_cast<int32_t>(sample1) + static_cast<int32_t>(sample2));
typedef std::numeric_limits<short int> Range;
if (Range::max() < result)
return Range::max();
else if (Range::min() > result)
return Range::min();
else
return result;
}
Run Code Online (Sandbox Code Playgroud)
混合,它只是添加和剪辑!
为避免剪切伪像,您需要使用饱和度或限制器.理想情况下,您将拥有一个int32_t
带有少量前瞻的小缓冲区.这将引入延迟.
比限制在任何地方更常见的是在信号中留下一些"净空"值.
归档时间: |
|
查看次数: |
9018 次 |
最近记录: |