Writing beeps to SourceDataLIne with pauses between causes spurious noise.
843802May 5 2010 — edited May 6 2010I start a SourceDataLine and write data to its buffer, pausing between writes, so that the buffer empties before the next write, producing beeps (a Morse Code practice application). When the pause is short enough, after all the writes stop the line produces a repeating pattern of clicks and short beeps like a two-second tape-loop, indefinitely.
Is this a Java bug or a sound board bug or ? (I am running on an E-Power pc with an AMD Athlon 64 processor, operating system Windows XP 2002 SP3, Realtek AC97 Audio with driver date 1/9/04.)
I would appreciate anyone trying out the following program to see if your system has the same trouble. You will hear five beeps, and then if the bug occurs you will hear garbage.
In main(), beep duration and the pause between writes can be adjusted to affect whether the garbage is heard. The bug appears for shorter pause times, provided the beeps are still separate. For a 250 msec beep, I hear the garbage for pauses shorter than about 596 msec.
I forgot: your system may not have the SourceDataLine I specify. You may have to change the audio format or buffer size.
import javax.sound.sampled.*;
class AudioBugDemo {
AudioFormat audioF = new AudioFormat(44000, 8, 1,true,false);
SourceDataLine line;
byte[] beep;
public AudioBugDemo(int beepMillisec) { // length of beep
// open an audio data line:
try {
line = AudioSystem.getSourceDataLine(audioF);
line.open(audioF, 44000); // buffer size 44000 runs 1 sec
} catch(Exception e){
System.out.println("source data line unavailable");
return;
}
// make sound data for a tone:
beep = new byte[beepMillisec*44]; // 44 is samples per msec
double omega = 2 * Math.PI / 100; // 100 is samples per tone cycle
for(int i=0; i<beep.length; i++) {
beep[i] = (byte)(80 * Math.sin(omega*i)); // 80 is amplitude, < 128
}
} // end of constructor
public static void main() {
AudioBugDemo feeder = new AudioBugDemo(250); // beep length, msec
feeder.runBeep(350); // pause length, msec
}
public void runBeep(int pause) {
line.start();
// write 5 beeps to audio output:
for(int b=0; b<5; b++) {
try{Thread.sleep(pause);}catch(Exception e){}
line.write(beep, 0, beep.length);
}
// listen for 6 sec to see if garbage appears:
try{Thread.sleep(6000);}catch(Exception e){}
line.stop();
}
}