音长不变

Tone Length not Changing

我有一个音频程序,它获取一个频率并以特定的毫秒数播放它。这是播放它的程序:

package instruments;

import javax.sound.sampled.SourceDataLine;

import note.Note;

@FunctionalInterface
public interface Instrument {
    int SAMPLE_RATE = 16 * 1024;

    public void play(Note note, int millis, SourceDataLine line);

    public static Instrument load(Formula formula) {
        return (Note note, int millis, SourceDataLine line) -> {
            byte[] bytes = new byte[millis * Instrument.SAMPLE_RATE];
            for (int i = 0; i < bytes.length; i++) {
                double period = Instrument.SAMPLE_RATE / note.frequency;
                double angle = 2.0 * Math.PI * i / period;
                bytes[i] = formula.get(angle);
            }
            line.write(bytes, 0, millis * bytes.length);
        };
    }
}

公式类型在这里:

package instruments;

@FunctionalInterface
public interface Formula {
    public static final Formula sine = (double angle) -> (byte) ((int) (Math
            .sin(angle) * 127));

    public byte get(double angle);
}

现在的问题是,当我在毫秒参数中输入 1 时,我听到了大约 1 秒长的哔哔声。如果我输入负数,代码会抛出 NegativeArrySizeException(这是预期的)。但是,如果我输入一个正的非整数(它需要一个整数),它会抛出一个 ArrayIndexOutOfBoundsException

我想知道为什么会有ArrayIndexOutOfBoundsException。提前致谢!

编辑:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 1638
    at com.sun.media.sound.DirectAudioDevice$DirectDL.write(Unknown Source)
    at instruments.Instrument.play(Instrument.java:44)
    at Main.main(Main.java:17)  // Here is where I play the tone

错误原因在这一行:

line.write(bytes, 0, millis * bytes.length);

您需要删除 millis *。回想一下 bytes 的长度已经乘以该值。

顺便提一下 - 您将毫秒和秒混为一谈令人困惑。如果我为 millis 参数输入 1,我希望声音播放 1 毫秒,而不是 1 秒。