JDK-5001959 : Short tick sound after finished playing with SourceDataLine
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.sound
  • Affected Version: 5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2004-02-24
  • Updated: 2004-04-09
  • Resolved: 2004-04-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 beta2Fixed
Description

Name: fb126949			Date: 02/24/2004


Reported from a user on javasound-interest:

When I play sounds I often get a very short tick 
shortly after writing the sound data to the 
SourceDataLine.  I wrote this short program below for 
another purpose but it demonstrates it clearly.  I 
would be curious to know if others hear the tick as 
well or if it is just my computer/soundcard.  Higher 
sample rates make the tick less pronounced.  Larger 
buffers cause the tick to come later.


import javax.sound.sampled.*;

public class test {
 public static void main(String[] args) {
  int seconds = 2;
  int sampleRate = 8000;
  double frequency = 1000.0;
  double RAD = 2.0 * Math.PI;
  try {
   AudioFormat af = 
     new AudioFormat((float)sampleRate,8,1,true,true);
   DataLine.Info info = 
     new DataLine.Info(SourceDataLine.class,af);
   SourceDataLine source =
     (SourceDataLine)AudioSystem.getLine(info);
   source.open(af);
   source.start();
   byte[] buf = new byte[sampleRate * seconds];
   for (int i=0; i<buf.length; i++) {
    buf[i] =
     (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0);
//  System.out.println(buf[i]);
   }
   source.write(buf,0,buf.length);
   source.drain();
   source.stop();
   source.close();
  } catch (Exception e) {
   System.out.println(e);
  }
  System.exit(0);
 }
}


======================================================================

More info from submitter:
The file I've been using is the 1-welcome.wav file that came with JavaSound 1.2 or 1.3.  It is attached.  The problem is related to the Clip.  If I try to play the same file by writing bytes to a SourceDataLine it works fine.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-beta2
14-06-2004

WORK AROUND I found 2 ways to work around this issue. See the modified test program: import javax.sound.sampled.*; public class TickAtEndOfPlay { static boolean WorkAround1 = false; static boolean WorkAround2 = false; public static void main(String[] args) throws Exception { System.out.println("This test should only be run on Windows."); System.out.println("Make sure that the speakers are connected and the volume is up."); System.out.println("Close all other programs that may use the soundcard."); System.out.println("You'll hear a 2-second tone. when the tone finishes,"); System.out.println(" there should be no noise. If you hear a short tick/noise,"); System.out.println(" the bug still applies."); System.out.println("Press ENTER to continue."); System.in.read(); for (int i = 0; i < args.length; i++) { if (args[i].equals("1")) WorkAround1 = true; if (args[i].equals("2")) WorkAround2 = true; } if (WorkAround1) System.out.println("Using work around1: appending silence"); if (WorkAround2) System.out.println("Using work around2: waiting before close"); int zerolen = 0; // how many 0-bytes will be appended to playback if (WorkAround1) zerolen = 1000; int seconds = 2; int sampleRate = 8000; double frequency = 1000.0; double RAD = 2.0 * Math.PI; AudioFormat af = new AudioFormat((float)sampleRate,8,1,true,true); System.out.println("Format: "+af); DataLine.Info info = new DataLine.Info(SourceDataLine.class,af); SourceDataLine source = (SourceDataLine)AudioSystem.getLine(info); System.out.println("Line: "+source); if (source.toString().indexOf("MixerSourceLine")>=0) { System.out.println("This test only applies to non-Java Sound Audio Engine!"); return; } System.out.println("Opening..."); source.open(af); System.out.println("Starting..."); source.start(); int datalen = sampleRate * seconds; byte[] buf = new byte[datalen+zerolen]; for (int i=0; i<datalen; i++) { buf[i] = (byte)(Math.sin(RAD*frequency/sampleRate*i)*127.0); } System.out.println("Writing..."); source.write(buf,0,buf.length); System.out.println("Draining..."); source.drain(); System.out.println("Stopping..."); source.stop(); if (WorkAround2) { System.out.println("Waiting 200 millis..."); Thread.sleep(200); } System.out.println("Closing..."); source.close(); System.out.println("Done."); } }
11-06-2004

PUBLIC COMMENTS The tick can be reproduced with tiger beta1 (make sure to stop all other programs that may use the soundcard!). See work-arounds. Fixed for tiger-beta2. ###@###.### 2004-04-09
09-04-2004

EVALUATION Should be resolved what is happening. Seems only to apply to old SourceDataLine implementation. ###@###.### 2004-02-24 Indeed, only applies to new (DirectAudio) implementation. With build 46 and later it is fixed, presumably along with the fix for 4997635: "Win: SourceDataLine playback loops endlessly unless you manually stop()". Will be publicly available with tiger-beta2. ###@###.### 2004-04-09
09-04-2004