音长不变

时间:2015-04-27 00:28:46

标签: java audio

我有一个频率和播放频率的音频程序,具有特定的毫秒数。以下是播放它的程序:

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

1 个答案:

答案 0 :(得分:1)

错误的原因在于这一行:

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

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

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