JDK-5085008 : Clip does not play WAV files
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.sound
  • Affected Version: 1.4.2,5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_98,windows_xp
  • CPU: x86
  • Submitted: 2004-08-10
  • Updated: 2005-08-09
  • Resolved: 2005-08-09
Related Reports
Duplicate :  
Description
Name: rmT116609			Date: 08/10/2004


FULL PRODUCT VERSION :
java version "1.4.2_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_05-b04)
Java HotSpot(TM) Client VM (build 1.4.2_05-b04, mixed mode)

java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Windows 98 [Version 4.10.2222]


A DESCRIPTION OF THE PROBLEM :
Ordinary WAV files are played very infrequently by the PlayClip.java
program given below. Perhaps once out of 10 times, the sound
is played.

There's nothing wrong with the files, since I can play them with
sound applications, such as WavePad.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the code given below, and then run with a WAV file.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The WAV file supplied on the command line should play once.
e.g
> java PlayClip sample.wav
ACTUAL -
C>java PlayClip sample.wav
Playing...
Waiting
Exiting...

There is a delay which lasts for the duration of the audio file before
the "Exiting..." line appears, but no sound is played.

REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------

// PlayClip.java

import java.io.*;
import javax.sound.sampled.*;


public class PlayClip implements LineListener
{
  private Clip clip = null;


  public PlayClip(String fnm)
  {
    loadClip(fnm);
    
    if (clip != null) {
      System.out.println("Playing...");
      clip.start();   // start playing
    }

    // wait for the sound to finish playing; guess at 10 mins!
    System.out.println("Waiting");
    try {
      Thread.sleep(600000);   // 10 mins in ms
    }
    catch(InterruptedException e)
    { System.out.println("Sleep Interrupted"); }
  } // end of PlayClip()


  private void loadClip(String fnm)
  {
    try {
      // link an audio stream to the sound clip's file
      AudioInputStream stream = AudioSystem.getAudioInputStream(
                          getClass().getResource(fnm) );

      AudioFormat format = stream.getFormat();
      DataLine.Info info = new DataLine.Info(Clip.class, format);

      // make sure sound system supports data line
      if (!AudioSystem.isLineSupported(info)) {
        System.out.println("Unsupported Clip File: " + fnm);
        System.exit(0);
      }

      // get clip line resource
      clip = (Clip) AudioSystem.getLine(info);

      // listen to clip for events
      clip.addLineListener(this);

      clip.open(stream);    // open the sound file as a clip
      stream.close(); // we're done with the input stream
    } // end of try block

    catch (Exception e) {
      System.out.println(e);
      System.exit(0);
    }
  } // end of loadClip()


  public void update(LineEvent lineEvent)
  // called when the clip's line detects open, close, start, stop events
  {
    // has the clip has reached its end?
    if (lineEvent.getType() == LineEvent.Type.STOP) {
      System.out.println("Exiting...");
      clip.stop();
      System.exit(0);
    }
  } // end of update()

  // --------------------------------------------------

  public static void main(String[] args)
  {
    if (args.length != 1) {
      System.out.println("Usage: java PlayClip <clip file>");
      System.exit(0);
    }
    new PlayClip(args[0]);
  } // end of main()

} // end of PlayClip.java

---------- END SOURCE ----------

A Workaround
------------
The problem is to do with the _duration_ of the sound. 
 
If the WAV file is less than a second long then no  
sound is played. 
 
My hacky solution is to obtain the duration of the 
sound with: 
   double duration = clip.getMicrosecondLength()/1000000.0; 
 
Then calculate a count which is used to loop the 
sound so it plays for a total of 1 second or more. 
 
 loopCount = (int) (1.0 / duration); 
 
 
 // clip.start();   // start playing 
 clip.loop(loopCount); 
(Incident Review ID: 296054) 
======================================================================
###@###.### 2004-08-12

Comments
EVALUATION We may need the sound files to investigate further. Since there is a workaround, this is a low priority bug, and that the late date, we do not plan on fixing for Tiger. ###@###.### 2004-08-13 p.s. Please attach the .wav file ----- The cause of the bug is in DirectSound drain() implementation (likely in native code) Need more investigation/debugging ###@###.### 2005-07-19 08:37:45 GMT
19-07-2005