用两个字节表示音频样本的正确方法是什么?
What is the proper way to represent an audio sample in two bytes?
我正在开发一个应用程序,该应用程序生成代表正弦波的数字序列,并将正弦波保存在 .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
的范围是-1
到1
。如果您使用的是具有不同范围的其他值,则需要先对其进行归一化:
result = DST_TYPE_MAX * original / ORIGINAL_MAX;
这还假设原始值的范围围绕 0
对称。如果没有,你需要做:
result = DST_TYPE_MAX * (original - ORIGINAL_MIN) / (ORIGINAL_MAX-ORIGINAL_MIN)
这仅适用于范围有限的值。你不能对像 tangent
这样的函数进行这种归一化,因为它的范围是无限的。
我正在开发一个应用程序,该应用程序生成代表正弦波的数字序列,并将正弦波保存在 .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
的范围是-1
到1
。如果您使用的是具有不同范围的其他值,则需要先对其进行归一化:
result = DST_TYPE_MAX * original / ORIGINAL_MAX;
这还假设原始值的范围围绕 0
对称。如果没有,你需要做:
result = DST_TYPE_MAX * (original - ORIGINAL_MIN) / (ORIGINAL_MAX-ORIGINAL_MIN)
这仅适用于范围有限的值。你不能对像 tangent
这样的函数进行这种归一化,因为它的范围是无限的。