如何从以毫秒为单位的长度中找到音符的帧、字节和整数长度

How to find a note's length in frames, bytes, and ints from its length in milliseconds

我需要在 Java 中创建一个函数,为音频添加特定频率和长度的音符。我的频率是双倍的,音符长度以毫秒为单位。

完整功能说明:

This method takes one AudioInputStream and adds the sound of a certain pure frequency to the FRONT of it, lasting a certain length of time. So the method takes two additional parameters: frequency and noteLengthInMilliseconds. The amplitude of the additional sound should be 64*256.

但是,我需要在 Frames 以及 Bytes 和 Ints 中找到音符的长度。

此外,关于如何将笔记创建为样本数据数组(我使用 java.sound.sampled 包)的任何建议都会有所帮助。

帧和采样率:44100.0hz
编码:PCM_SIGNED

由于您的帧率和采样率相同,我们假设您指的是 PCM 帧。 PCM 帧是每个通道一个样本。如果你只有一个音频通道,每个样本 16 位,你每两个字节得到一帧。如果您有每个样本 16 位的立体声音频,则每四个字节获得一帧。

要计算出长度,请取采样率并将其除以。如果我的采样率为 44.1 kHz,并且我希望音符持续半秒:

44,100 * 0.5 = 22,050 samples (22,050 frames)

从那里如果你知道音频是 16 位,并且只有一个声道:

22,050 * 2 (bytes per channel) * 1 (channels) = 44,100 bytes

以帧为单位的长度是一个简单的计算,它依赖于 AudioFormat 中的信息。具体来说,检查 属性 "frameRate"。 frameSize 属性 涵盖每帧的字节数。

制作音频数据数组需要几个步骤。纯音的值可以通过 运行 和 Math.sin 函数创建。 Math.PI * 2 相当于一个完整的循环(我希望你已经知道这一点——这是非常初级的),所以用除法算出每一步的增量有多小。

Math.sin 函数的结果是 -1 和 1 之间的双精度数。您必须将此数字转换为适合分配的数据范围。这是通过将音频值乘以一个因子来完成的。例如,乘以 32767 将产生一个填充短整型或 16 位带符号的范围。

从 Short 到字节的转换部分取决于您是大端还是小端。您还必须管理是否有多个轨道(例如,立体声很常见)。所有这些步骤都已在其他 Whosebug 帖子中介绍。

获得数据数组后如何处理它,它如何与现有音频结合,部分取决于您是输出为音频还是尝试创建新的 wav 文件以导出。 Java 教程的 Audio Trail 部分包含播放、保存文件以及有关文件格式和格式转换的精彩部分(强烈建议您阅读此内容)。