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

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

double sample = Math.Sin(2.0 * Math.PI * frequency * i * (1.0 / samplesPerSecond));

生成的.wav文件的深度为16位。意思是,每个样本由2个字节(short)表示。 double占用8个字节。

sample编码为结果byte[]的正确方法是什么,在其中只能占用2个字节?

最佳答案

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

short sample_short = SHORT_MAX * sample;

会有一些舍入误差,但这对于将值压缩为不太精确的数据类型是必需的。

公式很简单,因为sine的范围是-11。如果您正在使用其他具有不同范围的值,则需要首先对其进行规范化:
result = DST_TYPE_MAX * original / ORIGINAL_MAX;

这也假设原始值的范围围绕0对称。如果不是,则需要执行以下操作:
result = DST_TYPE_MAX * (original - ORIGINAL_MIN) / (ORIGINAL_MAX-ORIGINAL_MIN)

这仅适用于范围有限的值。您无法对tangent这样的函数进行这种标准化,因为它的范围是无限的。

关于arrays - 用两个字节表示音频样本的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28639171/

10-09 09:46