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

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

例如,如果您的样本是16位值,则结果将高达65536 * 2。这会导致削波。

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

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

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

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

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

评论

我想知道通过仅对信号进行一点时间偏移来避免削波的频率有多大。

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

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

16 + 16位= 17位;-)

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

#1 楼

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

显而易见的答案是告诉您调整每个样本的增益,以便很少发生削波。假设音乐家在合奏中的演奏会比被要求独奏时演奏的柔和不是不现实的。它在B的谐波的每一侧创建A的镜像-等效于环调制-如果A和B具有丰富的频谱且谐波不是整数倍,则这非常糟糕。例如,在220和400 Hz的两个方波上进行尝试。一些模拟元素的极限行为。除此之外,您还可以研究经典的动态压缩技术-如果您的系统可以向前看并提前看到峰值,那么效果会更好。

评论


$ \ begingroup $
添加和硬剪辑。只要看看任何开源的mod播放器即可。使用加法进行混音,并适当调整输入比例以最大程度地减少削波,然后硬限制(可选为软限制)成为规范,并非例外...
$ \ endgroup $
–小食
2012年10月7日19:12



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

$ \ begingroup $
IIRC,FastTracker较为保守,因为它在每个音轨上施加了衰减,然后在从x1到x32的首选项对话框中具有全局的“化妆增益”。我记得当我不得不将所有模块呈现为.WAV的CD时,我不得不尝试增益的值,直到找到不会引起削波的最低增益为止。
$ \ endgroup $
–小食
2012年10月8日9:40



$ \ begingroup $
关于衰减级别,如果您无法让用户加入环路; 1/32是绝对安全的水平(无削波)。假设通道不相关(对于音乐而言不是很正确-混合背景氛围时更正确),则值为1 / sqrt(32)将是响度和削波概率之间的良好折衷。最好的解决方案仍然是使用1/32,然后使用动态压缩器对样品进行后处理。
$ \ endgroup $
–小食
2012年10月8日,9:43

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

#2 楼


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


那不是“朴素”解决方案,它是唯一的解决方案。这就是每个模拟和数字混音器的功能,因为这是空气的功能,也是您的大脑的功能。 “混合”(失真)算法:



混合数字音频(错误的方式)

一种快速,肮脏的音频样本混合技术避免裁剪(不要这样做)

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

在模拟硬件中,净空可能为20 dB。在硬件DSP中,通常使用具有固定净空的定点。例如,AD的SigmaDSP的净空为24 dB。在计算机软件中,音频处理通常是在32位浮点数上执行的,因此其净空很大。一起发出信号,因为首先不会产生0 dBFS的信号。

请注意,无论如何,大多数信号都不相互关联,因此混频器的所有通道在同一时刻相长地相长干扰并不常见。是的,混合10个相同的同相正弦波会使峰值电平增加10倍(20 dB),但是混合10个非相干噪声源只会使峰值电平增加3.2倍(10 dB)。对于真实信号,该值将在这些极端之间。如果要在不进行硬削波的情况下保持较高的混频RMS电平,则需要应用某种类型的压缩来限制波形的峰值,但这不是混频的一部分,这是一个单独的步骤。您可以首先混合,并留有足够的净空,然后再根据需要对其进行动态范围压缩。

评论


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

$ \ begingroup $
@bryhoyt:是的,但是您还必须记住,这些波很少相互关联,因此将5种声音加在一起并不会使峰值达到5倍。
$ \ endgroup $
– Endolith
2012年10月15日在2:57

$ \ begingroup $
@endolith,谢谢,我想这确实是所有这些问题的核心,并向我解释了为什么它并不是我最初想到的那么大的问题。
$ \ endgroup $
– bryhoyt
2012年10月15日19:04

$ \ begingroup $
因此,如果10个非相干信号源给出10 dB,将sqrt(信号源数量)除以合理的试探法是否可行?也就是说,如果您有3个来源,请将它们相加并除以sqrt(3)? (很抱歉对古代话题发表评论)
$ \ endgroup $
–nerdfever.com
17年6月11日在18:42

$ \ begingroup $
@ nerdfever.com这就是RMS级别的组合方式,所以...可能吗?
$ \ endgroup $
– Endolith
17年6月11日在21:42

#3 楼

公式

$$ \ text {结果} = A + B-AB $$

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

$$ \ text {result} = g(A + B)$$

其中$ g \ le 1 $ 。

最简单的方法是说$ g = 0.5 $,它是保守的,线性的并且总是有效的,但是可能并没有您想要的“响亮”。 $ g = 1 / \ sqrt {2} $是“通常有效”且“大声”的一种不太保守的方法。用这种方法扩展到更多的通道效果更好。那么您真的有了一个差分方程:

$$ \ text {result} [i] = g [i](A [i] + B [i])$$

$ g [i] $是先前$ A $,$ B $,$ g $和$ \ text {result} $的函数。

也许是这样的:

$$ g [i] = f(A [i] + B [i],g [i-1])$$

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

评论


$ \ begingroup $
“ AB”是指“ A * B”。我确实知道幅度可以是正值或负值。没错,对于包含负振幅的组合,我的方程式没有多大意义。
$ \ endgroup $
– bryhoyt
2012年10月14日8:43



$ \ begingroup $
我必须混合8至10(N)个不同的窦波。根据经验,我知道正确的值约为0.3 ... 1 /√N似乎正确...与该公式为何正确的任何链接?
$ \ endgroup $
– Zibri
19-09-12在15:03



#4 楼

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

评论


$ \ begingroup $
这是一个先行限制器,而不是先行AGC。
$ \ endgroup $
–比约恩·罗氏(Bjorn Roche)
2012年10月8日17:34

$ \ begingroup $
@BjornRoche:限制器不能视为一种AGC吗?
$ \ endgroup $
– Endolith
13年4月12日在18:04

$ \ begingroup $
有些限制器是AGC,但超前限制器不是AGC。
$ \ endgroup $
–比约恩·罗氏(Bjorn Roche)
13年4月12日在21:31

$ \ begingroup $
@BjornRoche很好,它是自动的,可以控制增益...
$ \ endgroup $
–奥利·尼米塔洛(Olli Niemitalo)
16/09/13在7:49

#5 楼

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

我们聊了很久,最后谈到了真正保证将它们的64/128 @ 24bits通道混合在一起的技术,从而保持了24位准确的混合输出通道而没有削波的技术。

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

我不能说信号是如何从48位抖动回24位的。
也许这就是应用棘手的厨房食谱的地方。

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

#6 楼

降低全局音量。脉冲跟踪器通常默认情况下以最大33%的最大音量输出声道。频道内容通常是不相关的,因此音量不会超过某个水平而迅速加起来。。。。。。。。。。。。。它还为硬左或硬右平移通道(使用了66%的范围)留有足够的空间。将它们以32位相加,然后裁剪结果并最终减少到16位。您将需要更大的范围,以便在进行数学运算时不会回绕。另一种选择是使用32位浮点(方便进行滤镜,效果等操作)。

#7 楼

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

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

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

第一个是硬剪辑,第二个是软剪辑。模拟系统都是硬性限制。

#8 楼

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

#9 楼

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


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

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

评论


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

#10 楼

我的建议:


将轨道音频格式从16位固定点转换为32位浮点。
添加要混合的所有轨道的当前样本值。
不能做其他任何事情。

用户可能希望在抖动和重新转换为16位定点格式之前(假设此转换...向下混合以转换为母版处理工程师通常会保留较高的分辨率格式)

评论


$ \ begingroup $
您好,欢迎访问DSP.se。感谢您为我们做出的贡献,但我感觉这根本无法回答OP的问题。 OP并未提及其系统的“用户”:他可能是自己使用它,或者是根据特定要求编写程序。不好意思,我很抱歉:如果您的回答更加明确,我很乐意修改我的投票。另外,请注意格式设置:查看常见问题解答,了解如何编写正确的答案。
$ \ endgroup $
–佩内洛普
2014年1月21日,10:28