使用浮点数时,用于表示音频样本的值范围是多少
When using floating point numbers, what is the range of values used to represent audio samples
我了解什么是 浮动 点数,以及使用它们表示声音样本的优势。但是阅读介绍性文档this or that我无法准确找到存储和内部处理常用的比例。
所以在使用浮点数的时候,通常存储的是samples*:
- 在[0.0,-1.0]范围内,0.0对应0dBFS
- 在[1.0,-1.0]范围内,0.0对应0dBFS
- 在[1.0,0.0]范围内,1.0对应0dBFS
- 还有别的吗?
似乎没有什么能与 2 的补码有符号整数范围的不对称性质完美匹配。
* 不包括 超出规模的 个样本
来自@fdcpp 的评论,"floating-point audio is in the range of [-1.0, 1.0]"。请注意边界是包容性的。
在转换 from/to 有符号整数时,这会使事情变得异常复杂。问题是,比如说,16 位有符号整数,最大正值为 32767,但最小值为 -32768:
>>> int.from_bytes(b"\x7F\xFF", 'big', signed=True)
32767
>>> int.from_bytes(b"\x80\x00", 'big', signed=True)
-32768
无论位长是多少,当使用2的补码符号整数时,负值总是比正值多一个。因此,使用简单的除法(resp。乘法)你 cannot 同时:
- 将完整的整数范围映射到(分别从)到完整的 [-1;+1] 范围
- 和 将 int(0) 映射到 float(0.0)。
对于保留 0 -> 0.0 映射的简单实现,请查看以下代码:
FLOAT32 = 'f'
FLOAT64 = 'd'
def simple_conv_test(nbits, floatFormat):
""" Map the full scale of nbit signed integers to float
and back to int. Display if the process is transparent
(i.e. there is no loss of precision)
"""
input = array('l', [-(1<<nbits-1), -1, 0, 1, (1<<nbits-1)-1])
for factor in -input[0], input[-1]:
print('Factor=', factor)
int2float = array(floatFormat, [i/factor for i in input])
float2int = array('l', [int(i*factor) for i in int2float])
print(input)
print(int2float)
print(float2int)
print("Transparent?", float2int == input)
你可以看到是否使用两个明显的因素(16 位的 32768 或 32767)中的任何一个,我们不使用 float 表示中的 [-1;+1] 范围满刻度:
>>> simple_conv_test(16, FLOAT32)
Factor= 32768
array('l', [-32768, -1, 0, 1, 32767])
array('f', [-1.0, -3.0517578125e-05, 0.0, 3.0517578125e-05, 0.999969482421875])
array('l', [-32768, -1, 0, 1, 32767])
Transparent? True
Factor= 32767
array('l', [-32768, -1, 0, 1, 32767])
array('f', [-1.000030517578125, -3.0518509447574615e-05, 0.0, 3.0518509447574615e-05, 1.0])
array('l', [-32767, 0, 0, 0, 32767])
Transparent? False
我让你测试其他位大小。但是当使用 float32 中间表示时,除以 (1<<nbits-1)-1
最多只能透明 24 位。
另一方面,如果要将全范围映射到全范围,则必须牺牲 0 到 0.0 映射:
>>> [(v+0.5)/(32767.5) for v in [-32768, -1, 0, 1, 32767]]
[-1.0, -1.5259021896696422e-05, 1.5259021896696422e-05, 4.5777065690089265e-05, 1.0]
选择一种解决方案而不是另一种解决方案完全是权衡问题。在 blog post by Bjorn Roche 上有更好的解释,但似乎没有一个完善的约定来将声音样本从有符号整数映射到浮点数并返回。而且不同的硬件制造商或软件开发商似乎会做出不同的选择。
我了解什么是 浮动 点数,以及使用它们表示声音样本的优势。但是阅读介绍性文档this or that我无法准确找到存储和内部处理常用的比例。
所以在使用浮点数的时候,通常存储的是samples*:
- 在[0.0,-1.0]范围内,0.0对应0dBFS
- 在[1.0,-1.0]范围内,0.0对应0dBFS
- 在[1.0,0.0]范围内,1.0对应0dBFS
- 还有别的吗?
似乎没有什么能与 2 的补码有符号整数范围的不对称性质完美匹配。
* 不包括 超出规模的 个样本
来自@fdcpp 的评论,"floating-point audio is in the range of [-1.0, 1.0]"。请注意边界是包容性的。
在转换 from/to 有符号整数时,这会使事情变得异常复杂。问题是,比如说,16 位有符号整数,最大正值为 32767,但最小值为 -32768:
>>> int.from_bytes(b"\x7F\xFF", 'big', signed=True)
32767
>>> int.from_bytes(b"\x80\x00", 'big', signed=True)
-32768
无论位长是多少,当使用2的补码符号整数时,负值总是比正值多一个。因此,使用简单的除法(resp。乘法)你 cannot 同时:
- 将完整的整数范围映射到(分别从)到完整的 [-1;+1] 范围
- 和 将 int(0) 映射到 float(0.0)。
对于保留 0 -> 0.0 映射的简单实现,请查看以下代码:
FLOAT32 = 'f'
FLOAT64 = 'd'
def simple_conv_test(nbits, floatFormat):
""" Map the full scale of nbit signed integers to float
and back to int. Display if the process is transparent
(i.e. there is no loss of precision)
"""
input = array('l', [-(1<<nbits-1), -1, 0, 1, (1<<nbits-1)-1])
for factor in -input[0], input[-1]:
print('Factor=', factor)
int2float = array(floatFormat, [i/factor for i in input])
float2int = array('l', [int(i*factor) for i in int2float])
print(input)
print(int2float)
print(float2int)
print("Transparent?", float2int == input)
你可以看到是否使用两个明显的因素(16 位的 32768 或 32767)中的任何一个,我们不使用 float 表示中的 [-1;+1] 范围满刻度:
>>> simple_conv_test(16, FLOAT32)
Factor= 32768
array('l', [-32768, -1, 0, 1, 32767])
array('f', [-1.0, -3.0517578125e-05, 0.0, 3.0517578125e-05, 0.999969482421875])
array('l', [-32768, -1, 0, 1, 32767])
Transparent? True
Factor= 32767
array('l', [-32768, -1, 0, 1, 32767])
array('f', [-1.000030517578125, -3.0518509447574615e-05, 0.0, 3.0518509447574615e-05, 1.0])
array('l', [-32767, 0, 0, 0, 32767])
Transparent? False
我让你测试其他位大小。但是当使用 float32 中间表示时,除以 (1<<nbits-1)-1
最多只能透明 24 位。
另一方面,如果要将全范围映射到全范围,则必须牺牲 0 到 0.0 映射:
>>> [(v+0.5)/(32767.5) for v in [-32768, -1, 0, 1, 32767]]
[-1.0, -1.5259021896696422e-05, 1.5259021896696422e-05, 4.5777065690089265e-05, 1.0]
选择一种解决方案而不是另一种解决方案完全是权衡问题。在 blog post by Bjorn Roche 上有更好的解释,但似乎没有一个完善的约定来将声音样本从有符号整数映射到浮点数并返回。而且不同的硬件制造商或软件开发商似乎会做出不同的选择。