【发布时间】:2014-10-18 06:32:39
【问题描述】:
我正在使用 javax.sound 来发出声音,但是当您播放它时,它们会在背景中产生某种噪音,如果您同时演奏几个音符,甚至会克服声音。代码如下:
public final static double notes[] = new double[] {130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185,
196, 207.65, 220, 233.08, 246.94, 261.63, 277.18, 293.66,
311.13, 329.63, 349.23, 369.99, 392, 415.3, 440, 466.16,
493.88, 523.25, 554.37};
public static void playSound(int note, int type) throws LineUnavailableException { //type 0 = sin, type 1 = square
Thread t = new Thread() {
public void run() {
try {
int sound = (int) (notes[note] * 100);
byte[] buf = new byte[1];
AudioFormat af = new AudioFormat((float) sound, 8, 1, true,
false);
SourceDataLine sdl;
sdl = AudioSystem.getSourceDataLine(af);
sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af);
sdl.start();
int maxi = (int) (1000 * (float) sound / 1000);
for (int i = 0; i < maxi; i++) {
double angle = i / ((float) 44100 / 440) * 2.0
* Math.PI;
double val = 0;
if (type == 0) val = Math.sin(angle)*100;
if (type == 1) val = square(angle)*50;
buf[0] = (byte) (val * (maxi - i) / maxi);
sdl.write(buf, 0, 1);
}
sdl.drain();
sdl.stop();
sdl.close();
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
};
t.start();
}
public static double square (double angle){
angle = angle % (Math.PI*2);
if (angle > Math.PI) return 1;
else return 0;
}
【问题讨论】:
-
可能数据的速率与您在解码时使用的速率不同。试试 22000 或类似的东西。
-
实际上你的代码是为一个音符工作的,如果你演奏几个音符,那么你需要一个流,而不是每个音符一个线程
-
我写了multi-tone generator during hackathon。它适用于 Android,但原理是相同的。你可能会在那里找到一些有用的东西。我的建议是预先生成主正弦波,然后以不同的速度迭代它。通过这种方法,您可以将不需要的音频故障降至最低。