混合音频信号而不削波的算法


49

我想以忠实于声音的方式(最好是近实时)(意味很少或根本没有预见)以数字方式混合两个或多个PCM音频通道(例如,记录的样本)。

物理上“正确”的方法是对样本求和。但是,当您添加两个任意样本时,结果值可能高达最大值的两倍。

例如,如果您的样本是16位值,则结果最多为65536 * 2。这导致剪裁。

幼稚的解决方案是除以N,其中N是要混合的声道数。然而,这导致每个样本的响度仅为1 / Nth,这是完全不现实的。在现实世界中,当两个乐器同时演奏时,每个乐器的音量不会变成一半。

从阅读的角度来看,一种常见的混合方法是:结果= A + B-AB,其中A和B是要混合的两个归一化样本,而AB是确保更大声的声音越来越“柔和”的术语。

但是,这会导致信号失真。这种失真水平在高质量音频合成中可以接受吗?

还有什么其他方法可以解决此问题?我对高效的低质量算法以及低效率的高质量算法感兴趣。

我是在数字音乐合成的背景下问我的问题,目的是将多个乐器音轨混合在一起。音轨可以是合成音频,预先录制的样本或实时麦克风输入。


我不知道通过仅对信号进行一点时间偏移就能避免削波的频率。
塞巴斯蒂安·赖歇尔

好主意,尽管我怀疑它不是那么简单,尤其是当您没有太多前瞻(例如实时)时。问题是,您必须事先了解样本才能知道哪种时移是合适的。就是说,在大多数音乐中,您具有很高的相关概率,因此,进行一些随机时移可能会很好。有人在这里有经验吗?
bryhoyt 2012年

2
@bryhoyt:真正的混音器将信号加在一起。而已。无需时间延迟或非线性处理。剪裁不是问题,因为原始信号并没有那么响亮。
endolith 2013年

2
16 + 16bit = 17bits ;-)
nikwal

1
只要将其除以输入数量,便无法进行裁剪。如果声音太安静,请打开放大器……
Sarge Borsch

Answers:


14

在不知道问题背景的情况下,很难将您指向相关技术。

显而易见的答案是告诉您调整每个样本的增益,这样就很少发生削波。假设音乐家在合奏中的演奏会比被要求独奏时演奏的柔和并不是不现实的。

由A + B-AB引入的失真是不可接受的。它在B的谐波的每一侧创建A的镜像-等效于环调制-如果A和B具有丰富的频谱且谐波不是整数倍,则这非常糟糕。例如,在220和400 Hz的两个方波上尝试一下。

tanh函数是在每个样本的基础上工作的更“自然”的裁剪函数,它实际上与某些模拟元素的软限制行为相匹配。除此之外,您还可以研究经典的动态压缩技术-如果您的系统可以向前看并提前看到峰值,则更好。


4
添加和硬剪辑。只要看看任何开源的mod播放器即可。使用加法进行混音,并适当调整输入比例以最大程度地减少削波,然后是硬限制器(可选为软限制器),这不是正常的情况……
pichenettes 2012年

4
在大多数情况下,这不是开发人员解决问题的责任。您为用户/作曲家提供了调整每个通道的音量的可能性,并且由用户来进行混音,以便剪辑对他们来说是可接受的。例如,在Renoise中,默认情况下,每个乐器/音符的增益为1,并且在添加音轨时开始严重削波-用户可以调整模块中的音符或乐器的音量,以防止削波。掌握曲目(除非需要)。这是显示以下内容的屏幕截图:i.imgur.com/KVxDt.png
pichenettes 2012年

2
IIRC,FastTracker比较保守,因为它在每个轨道上都施加了衰减,然后在从x1到x32的首选项对话框中具有全局的“化妆增益”。我记得当我不得不将所有模块呈现为.WAV的CD时,我不得不尝试增益的值,直到找到不会引起削波的最低增益...
pichenettes 2012年

2
关于衰减级别,如果您无法让用户参与讨论;1/32是绝对安全的水平(无削波)。假设通道不相关(对于音乐来说不是很正确-混合背景氛围时更正确),则值为1 / sqrt(32)将是响度和削波概率之间的良好折衷。最好的解决方案仍然是使用1/32,然后使用动态压缩器对样品进行后处理。
pichenettes 2012年

3
加法。那就是硬件调音台要做的事情,也是人们期望事情表现的方式。系统级混音器只需剪辑即可。如果系统驱动程序实施任何类型的非线性处理,那将是一个大问题-我可以想象,掌握工程师试图弄清楚他们听到的是他们的压缩机插件设置还是某些系统级动态处理的痛苦。音乐制作软件提供了广泛的动态压缩插件,取决于用户以确保他们的混音不会被剪切。
pichenettes 2012年

16

物理上“正确”的方法是对样本求和。但是,当您添加两个任意样本时,结果值可能高达最大值的两倍。...幼稚的解决方案是除以N,其中N是要混合的通道数。

那不是唯一的解决方案“天真的”解决方案。那就是每个模拟和数字混音器的功能,因为它是空气的功能,也是您的大脑的功能。

不幸的是,这似乎是一种常见的误解,如以下其他不正确的非线性“混合”(失真)算法所示:

“除以N”称为净空;在波形的RMS电平以上分配给峰值的额外空间。信号所需的净空量由信号的波峰因数决定。(对数字信号电平和净空的误解可能部分归因响度大战Elephunk。)

在模拟硬件中,净空可能为20 dB。在硬件DSP中,通常使用具有固定净空的定点。例如,AD的SigmaDSP的净空为24 dB。在计算机软件中,音频处理通常在32位浮点中执行,因此空间很大。

理想情况下,您根本不需要除以N,只需将信号求和即可,因为首先不会在0 dBFS处生成信号。

请注意,无论如何,大多数信号都不相互关联,因此混频器的所有通道在同一时刻相长地相长干扰并不罕见。是的,混合10个相同的同相正弦波会使峰值电平增加10倍(20 dB),但是混合10个非相干噪声源只会使峰值电平增加3.2倍(10 dB)。对于真实信号,该值将介于这些极限之间。

为了在不削波的情况下将混合信号从DAC中取出,您只需降低混合增益即可。如果要在没有硬削波的情况下保持较高的混频RMS电平,则需要应用某种类型的压缩来限制波形的峰值,但这不是混频的一部分,这是一个单独的步骤。首先混合,留有足够的空间,然后再根据需要进行动态范围压缩。


1
我了解这些概念,但不确定它是否正确。当然,如果我添加一堆16位样本,则32位给了我大量的数字空间。但是我仍然必须在真实的​​声音系统上以规范化的音量播放最终的混音。我想要2个声道听起来要比单独播放的每个声道都响亮,但是我不想剪辑。用32位甚至64位来求和对这没有帮助。也许我开始回答自己的问题:原始样本应在比最大幅度更安静的水平上进行归一化。如您所建议,保留一些混合空间。
bryhoyt 2012年

3
@bryhoyt:是的,但是您还必须记住,这些波很少相互关联,因此将5种声音加在一起并不会使峰值达到5倍。
endolith

1
谢谢@endolith,我想这实际上是所有这些问题的核心,并向我解释了为什么它没有我最初想到的那么大。
bryhoyt 2012年

因此,如果10个非相干信号源给出10 dB,除以sqrt(信号源数量)是否合理?也就是说,如果您有3个来源,请将它们相加并除以sqrt(3)?(抱歉对一个古老的
话题

@ nerdfever.com这就是RMS级别的组合方式,所以...可能吗?
endlith

6

公式

result=A+BAB

即使您的意思不是,也没有任何意义。您需要考虑的一件事是声音在零之上和之下变化。考虑它的更好方法是这样的:AB=AB

result=g(A+B)

其中。g1

最简单的方法是说,它是保守的,线性的,并且始终有效,但可能不会像您想要的那样“响亮”。是“通常有效”且“大声”的一种不太保守的方法。使用这种方法扩展到更多渠道的效果更好。g=0.5g=1/2

另外,可以随时间变化,在这种情况下,通常是压缩器/限制器算法的结果。然后,您真的有了一个差分方程:g

result[i]=g[i](A[i]+B[i])

g[i]是先前,,和的函数。ABgresult

也许这:

g[i]=f(A[i]+B[i],g[i1])

更新:如hotpaw2所建议,您可以延迟输入信号,但不能延迟增益抑制。这称为“超前限制器”。


“ AB”是指“ A * B”。我确实知道幅度可以是正值或负值。没错,对于包含负振幅的组合,我的方程式没有多大意义。
bryhoyt 2012年

我必须混合8至10(N)个不同的窦波。根据经验,我知道正确的值约为0.3 ... 1 /√N似乎正确...与该公式为何正确的任何链接?
Zibri

5

对于非实时混音,可以使用前瞻性AGC来完成此操作,在这种情况下,一个或两个通道的增益会在总和幅度超过削波限制之前以难以感知的速率降低。可用的前瞻次数越少,AGC增益调整将变得更容易听见,或者用于更软的增益调整斜坡的最大增益将在极限处越来越接近每个通道0.5。对于具有一定可预测性的声源,还可以使用有关包络随时间变化的统计信息来自适应地猜测增益极限,但是有一定的失败概率(这可能是突然的AGC增益调整)。


这是一个超前限制器,而不是超前AGC。
比约恩·罗奇

2
@BjornRoche:限制器不能视为一种AGC吗?
endlith 2013年

一些限制器是AGC,但超前限制器不是AGC。
Bjorn Roche

1
@BjornRoche很好,它是自动的并且可以控制增益...
Olli Niemitalo

2

我曾与1990年代末和2000年代初的调音台设计师进行过交谈,当时这是一个数字浪潮((起脚尖之后)。我认为这家伙是SPL的设计师,但也许不是那么大,我绝对不记得这个名字和这个品牌,我只记得这台机器真的非常大而且很昂贵。

我们聊了很长时间,最后谈到了真正保证其64/128 @ 24bit通道混合在一起的技术,从而保持24位准确的混合输出通道而不会削波的技术。

他解释的技术相当简单。在一个48位通道中添加了64个音轨(24位),其中不会发生剪辑。直行。

我无法说出该信号是如何从48位抖动回24位的。也许那是应用棘手的厨房食谱的地方。

也许有很多技术可以实现这一点,最重要的是,无论是实时完成还是使用已经用高峰值记录的所有信号,都可以轻松确定……各种类型的归一化,我想像一下。


2

降低全局音量。脉冲跟踪器通常默认情况下以最大33%的音量输出声道。

对于少频道的音乐(4频道Amiga MOD)来说似乎足够响亮,而对于50频道的歌曲似乎足够柔和(因为频道内容通常不相关,因此音量不会超过某个水平而快速累加...再加上少数几个通道将以最大音量输出,并进行大量的操作)。它还为左硬或右硬平移通道(使用了该范围的66%)留有足够的空间。

另外,您也不想将通道以16位相加,而是要将通道以32位相加,然后剪切结果并最终减少到16位。您将需要更大的范围,以便在进行数学运算时不会回绕。另一种选择是使用32位浮点(方便进行滤镜,效果等操作)。


0

我认为关键是,如果您有16位值并且将2个值加起来可能比最大值更大,那么您有2个选项:

1)将两者都强制转换为32位加法,如果加法超过该最大值,则返回最大值。然后将其转换回16位。例如,如果您的值是32768和34567,则它超过65535,并且关键是要返回65535。如果在最小值的末尾使用带符号的值,则您将执行相同的操作。

2)压缩两个值,然后将它们加在一起。

第一个本质上是硬裁剪,第二个是软裁剪。模拟系统都是硬性限制。


0

如果两条轨道中的频率在空间上占据相同的空间频率,它们将仅是空间的两倍。使用eq和压缩通过为每种声音划出频谱区域并控制声音的瞬变和延音来解决此问题,以便一切都在适当的地方进行。也许那并不能回答问题。您可以将低频信号延迟最多2 ms。它不会通过相位抵消,因为波长比更高的频率更长,并且会增加空间,因为瞬态变化与耗电的低音信号并不完全同步。线性地增加更多延迟的信号越低,测试起来就越有趣。


-1
A + B + {
    (|A| = A) = (|B| = B) = true: -AB;
    (|A| = A) = (|B| = B) = false: AB;
    else: 0
}

也就是说,如果A和B都共享一个符号,则应用限制偏移量。偏移量的大小是A和B的乘积。偏移量的方向与A和B的方向相反。

如果A和B不共享符号,则没有限制,因为没有溢出的方法。


请注意,这不是可交换的。如果要混合两个以上的声音,则必须一次混合所有声音。在这种情况下,应沿一个方向“平整”所有内容(如果太高,则将负值向下平整正值;如果太低,请将正值向下平整负值)。一旦考虑了偏移量(按比例应用于剩余值);使用二进制方法,但根据混合值的数量缩放限制器。
Rich Remer

-1

我的建议:

  1. 将轨道音频格式从16位固定点转换为32位浮点。
  2. 添加要混合的所有轨道的当前样本值。
  3. 别做别的。

用户可能希望在抖动和重新转换为16位定点格式之前使用压缩和/或限制来处理此混合流(假设此转换...交递给母带工程师的混音通常留给更高分辨率的格式)


2
您好,欢迎访问DSP.se。感谢您为我们做出的贡献,但我感觉这样根本无法回答OP的问题。OP并未提及其系统的“用户”:他可能自己玩,也可能是根据特定要求编写程序。不好意思,我很抱歉:如果您的回答更加明确,我很乐意修改我的投票。另外,请注意格式设置:查看常见问题解答,了解如何编写正确的答案。
penelope 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.