【问题标题】:Addition of PCM Audio Files - Mixing Audio添加 PCM 音频文件 - 混合音频
【发布时间】:2018-07-17 08:49:43
【问题描述】:

我的任务是混合来自音频文件的原始数据。我目前正在努力通过混合数据来获得干净的声音,我不断收到失真或白噪声。

假设我有一个来自两个 AudioInputStream 的两字节数据数组。 AIS 用于从给定的音频文件流式传输字节数组。在这里,我可以使用 SourceDataLine 的 write 方法播放单个音频文件。我想同时播放两个音频文件,因此我知道我需要执行某种 PCM 添加。

谁能推荐这个加法应该用浮点值还是字节值来完成?此外,当涉及到添加 3,4 个或更多音频文件时,我猜我的问题会更加困难!我是否需要除以一定数量以避免这种溢出?假设我要添加两个 16 位音频文件(最小 -32,768,最大 32,767)。

我承认,我之前对此有过一些建议,但似乎无法让它发挥作用!我有我尝试过的代码,但我没有!

任何建议都会很棒。

谢谢

【问题讨论】:

  • 另外,我的主要问题是我的混合数组的大小应该是多少?它应该是要混合的最大音频文件的大小吗?!
  • 你好lvaan!在对多个信号求和时确实需要小心,因为任何总和超过最小/最大阈值的东西都会增加噪声/失真。您是否需要将此作为实时问题解决,还是可以预先计算(非实时)?对于非实时,您是否也尝试过标准化音频?您可以使用字节或浮点值求和。我建议在开始时将值转换为浮动到范围 -1 和 1 以保持简单/易于理解我相信对于等功率求和,您应该将求和信号乘以 (1/sqrt(2))^(n-1),对于 n 个信号。
  • 您好,感谢您的回复!目前,我一直在尝试实现非实时。我知道我需要将我的值剪辑为 n 位数字的最小和最大表示。我确实一直在尝试使用从 -1 到 1 的标准化浮点值进行加法。因此,如果我想将两个字节数组的数据添加到一个字节数组中,我将执行总和或所有索引位置并将此函数添加到如您所说的结果( (1/sqrt(2))^(n-1), for n 个信号)。你能确认一下为什么以及在哪里找到这个计算吗?
  • 我的问题是我想播放输出轨道作为与单个音频文件相对应的。但是,我不知道输出中的数据数组应该有多大(显然要添加的不同音频文件的大小不同)。
  • 对于感知响度建模,功率方程比线性值更匹配。如果需要,可以在添加之前将功率变换应用于输入。但我认为最好建议 OP 让更简单的信号线性加法首先工作。

标签: audio pcm mixing


【解决方案1】:

首先,我怀疑您是否真的在使用完全解码的 PCM 数据值。如果您直接添加字节,那只有在声音以 8 位分辨率录制时才有意义,而这种分辨率越来越少。如今,音频更普遍地记录为 16 位值或更多值。我认为有些情况不需要那么多频率内容,但在当前系统中,节省 cpu 并不那么重要,因此人们选择至少保持“CD 质量”(16 位分辨率、立体声、41000 fps )。

因此,第一步,您必须确保正确地将字节流转换为有效的 PCM。例如,如果是 16 位编码,则必须以正确的顺序(可能是大端或小端)附加两个字节,并使用结果值。

一旦处理得当,通常只需简单地添加值并施加最小和最大过滤器就足够了,以确保信号不会超出定义的范围。我可以想到这起作用的两个原因:(a)音频通常以足够低的音量录制,求和不会导致溢出,(b)信号足够随机,具有正值和负值,所有沿着正面或负面方向排列的贡献者是罕见且短暂的。

使用最小值和最大值会“削波”信号,并且会引入一些可听失真,但它的声音远没有溢出那么可怕!如果您的信号源经常达到最小值和最大值,您可以简单地将音量因子(在 0 到 1 范围内)乘以一个或多个作为一个整体的贡献信号,以降低音频值。

对于 16 位数据,它可以直接对两个字节附加在一起(-32768 到 32767)产生的有符号整数执行操作。但更常见的做法是“规范化”这些值,即将 16 位整数转换为 -1 到 1 范围内的浮点数,在该级别执行操作,然后转换回 -32768 到 32767 范围内的整数并将这些整数分解为字节对。

有一本关于数字信号处理的免费书籍非常值得一读:Steven Smith 的“数字信号处理的科学家和工程师指南”。它将提供更多细节和背景。

【讨论】:

  • 您好菲尔,感谢您的回复。我正在使用 16 位音频,我也在实现 24 位音频。我设法让立体声分离器正常工作,这样我就可以左右演奏了。我知道前两位/3 位和后两位/3 位分别用于 16 位/24 位音频的左右
  • 我使用的数据是 16 位有符号的小端序,因为它最适合 Javasound - 我将在以后研究解码和转换数据类型
  • 我确实已经将我的音频从字节转换为在 -1 和 1 之间标准化的浮点数。问题是我正在尝试实现非实时音频。所以我想简单地将一个字节的数据数组添加到另一个字节数组(现在只有 2 个)。这两个字节数组表示通过 AudioInputStream 的音频数据流。问题是这两个音频文件的字节数组大小不同。因此,当我添加它们时,我不确定我的输出字节数组的大小应该是多少?它应该是最大音频文件的大小,并将 0 附加到较短的音频文件吗??
  • 确认:对于16位,两个字节左边组合一个值,两个字节组合右边一个值,交替。对于 24 位,三个而不是两个组合在一起。第二点,不要添加字节数组!相反,添加浮点数组。第三点,添加大小不等的数组时使用对应的帧数。如果您需要附加 0 以使您的数组具有相同的长度以便进行数组加法,那应该会给出正确的结果。
  • 太棒了!谢谢菲尔,我现在得到了我需要的结果。原来我是一个字节一个字节地添加,但是,我需要将两个字节存储为一个 16 位数字,然后转换,浮动,然后进行添加。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 1970-01-01
  • 2019-09-24
  • 2015-04-25
  • 2021-02-13
  • 2019-10-07
相关资源
最近更新 更多