Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Low Latency Java Sound - playback

843802Apr 7 2008
I am currently working on a project that reads records from the serial port, interprets this data, and plays a sound (a 30 millisecond tone) if certain criteria is met. The records are currently read and interpreted about every 50ms by my program.

This project requires me to play short tones quickly with low overhead. I have been unsuccessful in my efforts so far and am looking for a bit of guidance.

My latest effort is based off of a previous post ( [located here|http://forum.java.sun.com/thread.jspa?threadID=5243872] ) by AndrewThompson64. The code below will a 30ms generated tone 10 times.
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;


public class ToneAlarm {

	private static SourceDataLine sdl = null;
	private static byte[] buf = new byte[2048];

	private static int hz = 1500;
	private static int msecs = 80;
	private static int volume = 75;
	private static float frequency = 22050;

	public ToneAlarm() {

		for (int i = 0; i < msecs * frequency / 1000; i++) {
			double angle = i / (frequency / hz) * 2.0 * Math.PI;
			buf[i] = (byte) (Math.sin(angle) * volume);
		}
	}

	public static void main(String args[]) throws Exception {
		long startTime = System.currentTimeMillis();
		ToneAlarm ta = new ToneAlarm();
		for(int i=0; i<10; i++) {
			ta.play();
		}
		long endTime = System.currentTimeMillis();
		long totalTime = endTime - startTime;
		System.out.println(totalTime);
	}

	public void play() throws InterruptedException {
		try {
			generateTone();
		} catch (LineUnavailableException e) {
			throw new RuntimeException(e);
		}
	}

	private void generateTone() throws LineUnavailableException {


		AudioFormat af = new AudioFormat(frequency, 8, 1, true, false);

		sdl = AudioSystem.getSourceDataLine(af);
		sdl.open(af);
		sdl.start();

		sdl.write(buf, 0, buf.length);
		sdl.drain();
		sdl.stop();
		sdl.close();
	}

}
I have tested this code on two different machines. On my Ubuntu Desktop (Java 1.6, Gutsy, 2.0Ghz, 1 Gb Ram), the code takes anywhere from 2600 to 3200ms to complete. On my Macbook (Java 1.5, Leopard, Dual Core 2.0Ghz, 2 Gb Ram), the code takes around 1800ms to compelete.

Either way the numbers do not work out in my favor. Even with the Macbook, I am averaging around 180ms to play 1 tone. This is simply unacceptable if I want to achieve 50ms resolution.

Can anyone recommend a faster way to go about playing a sound in short, repeated, consistent intervals in Java? Would it be faster to try and load a sound from a .wav file? Or is my 50ms resolution unattainable?
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 5 2008
Added on Apr 7 2008
0 comments
347 views