JDK-4842416 : REGRESSION: WinXP: Recording hangs
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.sound
  • Affected Version: 1.3.1,1.4.2
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000,windows_xp
  • CPU: x86
  • Submitted: 2003-04-03
  • Updated: 2003-08-02
  • Resolved: 2003-05-04
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
1.4.2 b23Fixed
Related Reports
Duplicate :  
Description

Name: fb126949			Date: 04/03/2003


This bug is reported by several users of Java Sound on the javasound-interest mailing list. It seems to only happen on Windows XP.

Run the following program with 
   java TrivialRecord 500
The problem manifests itself by not responding anymore after the line that prints "Try to close..." (it may take several runs). Only CTRL-C can stop this state, finishing the VM. This bug can be reproduced with 1.4.2. It does not occur with 1.3.0 or 1.3.1.

This is a trimmed thread dump:


"Headspace mixer frame proc thread" daemon prio=10 
      tid=0x00a2c868 nid=0xd04 runnable [2d8f000..2d8fd94]
  at com.sun.media.sound.MixerThread.runNative(Native Method)
  at com.sun.media.sound.MixerThread.run(Unknown Source)

"Java Sound event dispatcher" prio=5 tid=0x00a220a8 
      nid=0xd50 in Object.wait() [2d4f000..2d4fd94]
  at java.lang.Object.wait(Native Method)
  - waiting on <0x100a00a8> (a com.sun.media.sound.EventDispatcher)
  at java.lang.Object.wait(Unknown Source)
  at com.sun.media.sound.EventDispatcher.dispatchEvents(Unknown Source)
  - locked <0x100a00a8> (a com.sun.media.sound.EventDispatcher)
  at com.sun.media.sound.EventDispatcher.run(Unknown Source)
  at java.lang.Thread.run(Unknown Source)

"main" prio=5 tid=0x000352c0 nid=0xcdc runnable [7f000..7fc3c]
  at com.sun.media.sound.SimpleInputDevice.nClose(Native Method)
  at com.sun.media.sound.SimpleInputDevice.implClose(Unknown Source)
  at com.sun.media.sound.AbstractMixer.close(Unknown Source)
  - locked <0x10010f40> (a com.sun.media.sound.SimpleInputDevice)
  at com.sun.media.sound.AbstractMixer.close(Unknown Source)
  - locked <0x10010f40> (a com.sun.media.sound.SimpleInputDevice)
  at com.sun.media.sound.AbstractDataLine.close(Unknown Source)
  - locked <0x10010f40> (a com.sun.media.sound.SimpleInputDevice)
  at com.softsynth.testjsound.TrivialRecord.recordSound(TrivialRecord.java:88)
  at com.softsynth.testjsound.TrivialRecord.runTests(TrivialRecord.java:97)
  at com.softsynth.testjsound.TrivialRecord.main(TrivialRecord.java:110)


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

TrivialRecord.java:

/**
 * Record sound to test hang in close.
 * @author Phil Burk (C) 2003 SoftSynth.com
 * @author Florian Bomers
 * @bug 4842416
 * @bug 4383457
 * @bug 4635534
 * @version 0.2
 */

import javax.sound.sampled.*;

public class TrivialRecord {
 TargetDataLine inLine;
 final int SAMPLE_RATE = 11025;
 final int NUM_SECONDS = 1;
 final int TOTAL_FRAMES = NUM_SECONDS * SAMPLE_RATE;
 final int FRAMES_PER_BUFFER = 64;
 final int SAMPLES_PER_FRAME = 2;
 byte bytes[];
 AudioFormat format;
 Mixer.Info[] mixers;

 public TrivialRecord() {
  // allocate enough bytes for buffer
  bytes = new byte[ TOTAL_FRAMES * SAMPLES_PER_FRAME * 2 ]; 
  // float sampleRate, int sampleSizeInBits, int channels, 
  // boolean signed, boolean bigEndian
  format = new AudioFormat((float) SAMPLE_RATE, 16, 
                           SAMPLES_PER_FRAME, true, false );
  mixers = AudioSystem.getMixerInfo();
 }

 boolean openInputLine(int num)
      throws LineUnavailableException {
  // format is an AudioFormat object
  DataLine.Info info = new 
     DataLine.Info(TargetDataLine.class, format);
  // Obtain and open a outLine.
  if (num < 0) {
   if (!AudioSystem.isLineSupported(info)) {
    System.out.println("TargetDataLine is not supported "
                      +"by default mixer.");
    return false;
   }
   inLine = (TargetDataLine) AudioSystem.getLine(info);
  } else {
   Mixer mixer = AudioSystem.getMixer(mixers[num]);
   if (!mixer.isLineSupported(info)) {
    System.out.println("TargetDataLine is not supported "
                      +"by this mixer.");
    return false;
   }
   inLine = (TargetDataLine) mixer.getLine(info);
  }
  inLine.open(format);
  return true;
 }

 private boolean recordSound(int num)
      throws LineUnavailableException {
  if (!openInputLine(num)) {
   return false;
  }
  try {
   System.out.println("Got line: "+inLine);
   System.out.println("Start recording....." );
   inLine.start();
 
   int bytesRead = 0;
   int numLeft = bytes.length;
   int cursor = 0;
   System.out.print("Reading... (bytes to go: "
                    +numLeft+")          \r");
   while( numLeft > 0 ) {
    int numToRead = (numLeft > 2048) ? 2048 : numLeft;
    bytesRead = inLine.read( bytes, cursor, numToRead );
    numLeft -= bytesRead;
    cursor += bytesRead;
    System.out.print("Reading... (bytes to go: "
                     +numLeft+")          \r");
   }
   System.out.println("Read "+cursor+" bytes "
                     +"successfully.            ");
  } finally {
   if (inLine.isActive()) {
       inLine.flush();
       System.out.println("Stopping line");
       inLine.stop();
   }
   System.out.println("Try to close line. "
                     +"Might hang here if JDK 1.4.1" );
   inLine.close();
   System.out.println("Line closed" );
  }
  return true;
 }

 public void runTests(int testRuns) {
  if (mixers.length > 0) {
   for (int num = -1; num < mixers.length; num++) {
    try {
     if (num<0) {
      System.out.println("------Using default line...." );
     } else {
      System.out.println("------Using line "+num
                        +" from mixer "+mixers[num]+"...");
     }
     for (int testRun = 0; testRun < testRuns; testRun++) {
      if (testRuns>1) {
       System.out.println("--Run "+(testRun+1)
                         +"/"+testRuns+":");
      }
      if (!recordSound(num)) {
       break;
      }
     }
    } catch (Exception ex) {
    System.out.println("Caught " + ex );
    }
    System.out.println("---------------------------"
                      +"---------------------------");
   }
  }
 }

 public static void main(String[] args) {
  System.out.println("Test TrivialRecord");
  TrivialRecord app = new TrivialRecord();
  int testRuns = 1;
  if (args.length > 0) {
   try {
    testRuns = Integer.parseInt(args[0]);
   } catch (NumberFormatException nfe) {
    System.out.println("Usage: java TrivialRecord "
                      +"[number of runs]");
    System.out.println("Parameters ignored.");
   }
  }
  app.runTests(testRuns);
  System.exit(0);
 }
}

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

EVALUATION ###@###.### 2003-04-03 Serious regression. Should get fixed for 1.4.2-GA. ###@###.### 2003-04-17 As reported in duplicate bug 4849790, this problem also occurs on some NT4SP6 and Windows 2000 systems. ###@###.### 2003-05-01 Finally could reproduce this bug on an XP system. A fix is ready in private workspace.
01-05-2003