注意:我不想“读取音频文件foo.bar并播放它”。
我想以编程方式即时生成音频文件并进行播放。
Java是否为此内置了库,还是属于依赖系统的库?
谢谢!
使用(Andrew)的方法,下面是一个示例,该示例具有相同的调节范围。
import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; public class Tone { public static void main(String[] args) throws LineUnavailableException { final AudioFormat af = new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true); SourceDataLine line = AudioSystem.getSourceDataLine(af); line.open(af, Note.SAMPLE_RATE); line.start(); for (Note n : Note.values()) { play(line, n, 500); play(line, Note.REST, 10); } line.drain(); line.close(); } private static void play(SourceDataLine line, Note note, int ms) { ms = Math.min(ms, Note.SECONDS * 1000); int length = Note.SAMPLE_RATE * ms / 1000; int count = line.write(note.data(), 0, length); } } enum Note { REST, A4, A4$, B4, C4, C4$, D4, D4$, E4, F4, F4$, G4, G4$, A5; public static final int SAMPLE_RATE = 16 * 1024; // ~16KHz public static final int SECONDS = 2; private byte[] sin = new byte[SECONDS * SAMPLE_RATE]; Note() { int n = this.ordinal(); if (n > 0) { double exp = ((double) n - 1) / 12d; double f = 440d * Math.pow(2d, exp); for (int i = 0; i < sin.length; i++) { double period = (double)SAMPLE_RATE / f; double angle = 2.0 * Math.PI * i / period; sin[i] = (byte)(Math.sin(angle) * 127f); } } } public byte[] data() { return sin; } }
这种低级方法可能适用于能力较弱的旧平台。还考虑javax.sound.midi; 一个完整的例子显示在这里和声音合成教程引用在这里。
javax.sound.midi