This discussion is archived
4 Replies Latest reply: Dec 20, 2011 7:53 AM by ptoye RSS

Timing of sound clips

ptoye Newbie
Currently Being Moderated
I'm writing a metronome application, where accurate timing to at least 10ms is essential. No problem in writing the timing code, but when it runs, the clicks are unacceptably irregular. But I've traced them using System.currentTimeMillis() and they're accurate to a millisecond (or occasionally 2).

The code to do the clicking is very simple:
clickClip.setFramePosition(0);
clickClip.start();
where clickClip is a Clip.

Is there any way to ensure that there's no (or constant) delay between issuing the command and the sound actually being output? Or is the variation in my sound card (which I'd have thought unlikely)?


<later> It's now November - no-one got any ideas?

Edited by: ptoye on 07-Nov-2011 02:52
  • 1. Re: Timing of sound clips
    gimbal2 Guru
    Currently Being Moderated
    ptoye wrote:
    <later> It's now November - no-one got any ideas?
    Unless you want to assume that people are purposely withholding information from you, that is a safe bet.


    Apparently you want control over the sound output - using high level APIs isn't going to help you there. You'll have to dig into the JavaSound API itself for playback. As it turns out, there is a whole website dedicated to it so that shouldn't take too long:

    http://www.jsresources.org/index.html
  • 2. Re: Timing of sound clips
    810200 Newbie
    Currently Being Moderated
    AFAIK, currentTimeMillis() is limited by the accuracy of OS. On Windows, for example, it is limited by a granularity of 15msecs (approximately). Something to do with a "timing interrupt signal" or some other mysterious (for me) aspect of the OS.

    System.nanoTime() is accurate, and you can use it to determine the accuracy of your currentTimeMillis().

    This thread, over at Java-Gaming.org was an attempt to deal with timing issues "once and for all".
    http://www.java-gaming.org/topics/solving-stuttering-with-fixed-timesteps-once-and-for-all/24975/view.html
    I'm not sure I would call it successful, but there are interesting ideas presented there. One is that one can sometimes make the OS use a more finely grained clock by running the command Thread.sleep(Long.MAX_VALUE); on a background thread.

    Don't ask me why it works, or if it is reliable. I think it also has the drawback of causing computers to run hotter, which is a problem if someone is running off of batteries.

    I hope you find a workable solution. I am also quite interested in making music-related desktop Java programs. I don't know if, to do so, it will require using the "real time" version of Java. Certainly the MIDI sequencer implementation (javax.sound.midi) has sufficient timing accuracy for sequencer playback.
  • 3. Re: Timing of sound clips
    gimbal2 Guru
    Currently Being Moderated
    807197 wrote:
    AFAIK, currentTimeMillis() is limited by the accuracy of OS. On Windows, for example, it is limited by a granularity of 15msecs (approximately). Something to do with a "timing interrupt signal" or some other mysterious (for me) aspect of the OS.
    Worse, it depends on the system. On some it is 10ms, on others 15ms. Windows only though.

    >
    System.nanoTime() is accurate, and you can use it to determine the accuracy of your currentTimeMillis().
    Unfortunately it does not work properly on some dual core processor architectures without a system patch.
    This thread, over at Java-Gaming.org was an attempt to deal with timing issues "once and for all".
    http://www.java-gaming.org/topics/solving-stuttering-with-fixed-timesteps-once-and-for-all/24975/view.html
    I'm not sure I would call it successful, but there are interesting ideas presented there. One is that one can sometimes make the OS use a more finely grained clock by running the command Thread.sleep(Long.MAX_VALUE); on a background thread.

    Don't ask me why it works, or if it is reliable.
    The Windows JVM has a hack built in that as long as a thread is asleep, it will keep the granularity at 1ms to make thread wakeup more accurate. Keeping a thread permanently asleep keeps the granularity at 1ms throughout the runtime of your application. This is also a bug workaround, as constantly switching the granularity can make the system clock go out of sync, at least on WindowsXP and below (don't know about Vista and up). It is a good thing to force it to stay at one setting only.
    I think it also has the drawback of causing computers to run hotter, which is a problem if someone is running off of batteries.
    Not really, a sleeping thread does not use CPU cycles. However the OS scheduler will trigger much more frequently of course so that can cause more load, but plenty of applications change the granularity already for the higher precision - it is nothing special to do so really.
  • 4. Re: Timing of sound clips
    ptoye Newbie
    Currently Being Moderated
    Thanks all. Sorry I didn't get back sooner, but for some reason I'm not being notified of replies so assumed there weren't any. I'll try out the suggestion when I have time.

    <much later> I've looked at nanotime. I put a call to it immediately before calling clip.start(). And the difference between the intervals is about 1msec, which is far less than anyone can hear. My guess is that the inaccuracy is at least 50 msec.

    I looked at the jsresources site - it's extremely out of date, and the owner of the site isn't interested any more. He tried to sell me some consultancy, though. :) Unsuccessfully. And I can't find any up-to-date tutorials.

    I found http://www.vsj.co.uk/java/display.asp?id=370 which is also out of date but has some useful stuff in it. But it's confusing - I tried the programs to display the mixers and ports, and the settings don't seem to correspond to my machine's configuration. For instance, muting the speakers or changing their volume doesn't seem to have any effect on what I'd have thought were the relevant controls. Or any controls for that matter. Obviously I'm not looking in the right place, but can't work out what that place is.

    Edited by: ptoye on 20-Dec-2011 07:52

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points