我正在开发一个生成表示正弦波的数字序列的应用程序,并将正弦波保存在.wav
文件中以作为音频播放。
以下代码行生成音频波中单个样本的值:
double sample = Math.Sin(2.0 * Math.PI * frequency * i * (1.0 / samplesPerSecond));
生成的.wav
文件的深度为16位。意思是,每个样本由2个字节(short
)表示。然而,double
占用了8个字节。
将sample
编码为生成的byte[]
的正确方法是什么,它只能占用2个字节?
答案 0 :(得分:2)
由于sine
的范围有限[-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)
这仅适用于范围有限的值。对于像tangent
这样的函数,你不能进行这种规范化,因为它的范围是无限的。