【发布时间】:2014-07-23 21:47:49
【问题描述】:
我正在玩 Java 中的音频。我发现常用的AudioFormat 使用两个字节。但是,我不知道如何将字节放在一个 int 中。所以我试着反过来做:
public class SineWave {
public static void main(String[] args) throws LineUnavailableException {
int hz = 440;
int samplerate = 16384;
int amplitude = 127;
AudioFormat format = new AudioFormat((float) samplerate, 16, 1, true, true);
SourceDataLine sdl = AudioSystem.getSourceDataLine(format);
sdl.open(format, samplerate * 2);
sdl.start();
while (true) {
byte[] toWrite = new byte[samplerate * 2];
for (int x = 0; x < samplerate; x++) {
int y = (int) Math.round(amplitude * Math.sin(2 * Math.PI * x * hz / samplerate));
byte b1 = (byte) (y & 0xFF);
byte b2 = (byte) ((y >> 8) & 0xFF);
toWrite[2 * x] = b1;
toWrite[2 * x + 1] = b2;
// System.out.printf("%d %d%n", b1, b2);
}
sdl.write(toWrite, 0, toWrite.length);
}
}
}
但是,这只适用于127 的幅度。当System.out.printf未注释时,很明显这个幅度只使用了1个字节。当我上升到128 时,我会得到这样的输出(和丑陋的声音):
0 0
21 0
42 0
62 0
80 0
96 0
109 0
118 0
125 0
-128 0
127 0
123 0
115 0
104 0
90 0
73 0
55 0
35 0
13 0
负值类似,符号不变,第二个字节总是-1
我推断这是因为有符号字节和二进制补码,但我仍然无法弄清楚我可以做些什么来解决这个问题。
Java 是如何编写它的音频的?
【问题讨论】: