Arrays 以两个字节表示音频样本的正确方式是什么?

Arrays 以两个字节表示音频样本的正确方式是什么?,arrays,file,audio,byte,Arrays,File,Audio,Byte,我正在开发一个应用程序,它生成一系列表示正弦波的数字,并将正弦波保存在.wav文件中,以作为音频播放 以下代码行生成音频波形中单个样本的值: double sample = Math.Sin(2.0 * Math.PI * frequency * i * (1.0 / samplesPerSecond)); 生成的.wav文件的深度为16位。也就是说,每个示例由2个字节(short)表示双字节但是会占用8个字节 将样本编码成只能占用2个字节的结果字节[]的正确方法是什么?由于正弦具有有限的范围

我正在开发一个应用程序,它生成一系列表示正弦波的数字,并将正弦波保存在
.wav
文件中,以作为音频播放

以下代码行生成音频波形中单个样本的值:

double sample = Math.Sin(2.0 * Math.PI * frequency * i * (1.0 / samplesPerSecond));
生成的
.wav
文件的深度为16位。也就是说,每个示例由2个字节(
short
)表示<代码>双字节但是会占用8个字节


样本
编码成只能占用2个字节的结果
字节[]
的正确方法是什么?

由于
正弦
具有有限的范围
[-1.0,1.0]
,因此可以将该范围内的值映射到16位整数的范围
[-32768,32767]

short sample_short = SHORT_MAX * sample;
会有一些舍入错误,但这是将值压缩到不太精确的数据类型中所必需的

公式之所以如此简单,是因为
sine
的范围是从
-1
1
。如果使用的是其他具有不同范围的值,则需要首先对其进行规格化:

result = DST_TYPE_MAX * original / ORIGINAL_MAX;
这还假设原始值的范围围绕
0
对称。如果没有,您需要执行以下操作:

result = DST_TYPE_MAX * (original - ORIGINAL_MIN) / (ORIGINAL_MAX-ORIGINAL_MIN)

这仅适用于范围有限的值。您不能对像“切线”这样的函数执行这种规格化,因为它的范围是无限的。

出于音频目的,如果您要从float转换为int16,您还需要应用抖动。虽然对于一个简单的正弦波来说没什么大不了的,但你肯定会注意到与更复杂的声音的区别。它是有效的!非常感谢。问:一般来说,在处理这样的情况时,我必须将某种类型的值压缩到一定数量的字节中,这是常用的方法吗<代码>dst类型结果=dst类型最大*原始?或者它会因情况不同而有所不同?我在答案中添加了概括。