将双精度转换为声音字节输出的微妙之处

问题描述 投票:1回答:2

我希望将范围为-1到1的双数组转换为字节输出,并以WAVE格式保存。为了论证,我将专注于一个简单的8位波。

据我所知,有两种竞争方式可以做到这一点,两者都提供了非常不同的结果,而且细微之处非常复杂。


方法1:输出=(字节)(输入* 128.0 + 128)。在这种情况下,不允许值1作为输入,否则,非法值256将是输出。结果被截断以适合一个字节。示范结果:

  • -1 --------> 0
  • -0.5 ------> 64
  • 0 ---------> 128
  • 0.5 -------> 192
  • 1-(1/128) -> 255
  • 0.999999 - > 255(等于255.999872截断,合法)
  • 1 ---------> 256(非法)

方法2:输出=(字节)舍入(输入* 127.5 + 127.5)。在这种情况下,值1 IS允许为输入,给定输出255。与以前不同,结果是四舍五入。示范结果:

  • -1 --------> 0
  • -0.5 ------> 64(等于63.75舍入)
  • 0 ---------> 128(等于127.5舍入)
  • 0.5 -------> 191(等于191.25舍入)
  • 1-(1/128) - > 254(等于254.00390625四舍五入)
  • 0.999999 - > 255(等于254.9998725舍入)
  • 1 ---------> 255(合法)

他们似乎都提供了缺点和优势。

使用第一种方法,不需要舍入,输出是干净的,结果一直到最终位置。不幸的是,1不是允许的输入,因此(例如)正弦输入可能是个问题。用户必须确保输入永远不等于1,或者最好,函数只需确保位置255上的任何内容被截断回255。

使用第二种方法,+ 1是一个允许的输入,所以不用担心产生256的非法输出。不幸的是,简单的输入结果似乎有点难看。它们需要被舍入,从64到128的跳跃与从128到191的跳跃不同(这是63的差异,而不是64)。尽管输入具有相等的差异(分别为-0.5到0和0到0.5)。

我还注意到,使用第一种方法,第一个和最后一个位置的范围加倍,因为255到255.999截断到255,0到0.999截断到零。使用第二种方法,只有0到0.499截断到零,只有254.5到255截断到255.所有其他数字允许“选择”大小1.0范围(例如:42.5到43.499轮到43),所以它sorta有意义的是,字节的第一个和最后一个位置也应该允许自己的“完整”大小1.0范围。另一方面,如果255是数字行上的实际数字255,那么也可以做出一个参数,即该字节只分配了一半的范围。

所以我只是在寻找两个系统的更多见解和属性。这样做的正确方法是什么?

audio byte rounding truncate wave
2个回答
0
投票

乘以127(并加128)或乘以128但将产品饱和到[-128,+ 127]范围(IOW,特别处理+1.0)。

如果没有任何特殊要求的最小/最大值处理,你不应该过多地关注它们。您的信号应该很少达到这些值。当它发生时,其中一端的误差约为1/128并不重要。在整个范围内,您已经失去了相当多的信息/质量,而不仅仅是在其中一个端点。

顺便说一句,也有非线性方案。参见例如μ-law algorithm,顺便说一句,在大的范围内做了类似的事情,它们的编码比小的编码更粗糙,并且在实践中它是可以的(也就是讲话)。


0
投票

方法1是数学上正确的量化方法的开始。作为特殊情况,您只需要为最大值添加处理(Alexey's answer关于使产品饱和的第二个建议)。正如您所注意到的,此方法提供了相同大小的“桶”,包括第一个和最后一个。

一般解决方案包括两个步骤:规范化输入值,然后进行缩放。

将-1到1的输入值标准化为:

j =(输入+ 1)/ 2

将它们放入0到1的范围内。缩放这些值得出最终输出值,其中N是量化桶的数量:

输出=楼层(N * j)

Floor()相当于截断。您可以通过想象N = 2的简单情况向自己证明这是“正确的”方式。从0到1但不包括1的实际值将公平地落入2个桶中。在8位量化的情况下,我们有N = 256,所以:

如果输入<1,则输出= Floor(128 *(输入+ 1))

或者,方法1中的公式。

处理特殊情况,当j = 1时,我们需要强制输出值为N - 1.这看起来似乎是人为的,它是。但它不会造成任何扭曲;它只是在一行实数上的点值的特殊情况下的任意赋值。

如果input = 1,则输出= 255

说完所有这些之后,方法1和2的结果的差异,由于实际值分配到256级的微小差异,将是难以察觉的。正如Alexey所指出的那样,无论如何,在量化为8位值时,大量信息都会丢失。

© www.soinside.com 2019 - 2024. All rights reserved.