-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
5.0
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Realtek AC97 Audio on motherboard
A DESCRIPTION OF THE PROBLEM :
(This is being resubmitted since I didn't get an auto-generated email the first time it was submitted.)
Audio playback within a java.sound.sampled.Clip is behaving strangely. While playing a wav (haven't tried anything else) file, if playback is paused and resumed, the audio output is repeating audio data. It kind of sounds like a skip and then it continues (eg. "Welcome <pause><resume> to Java...to Java sound"). When it get's to the end of the file the microsecond position indicates a position longer than the actual length.
Playback can be paused and resumed multiple times for a more pronounced effect.
Debugger shows that the actual Clip class is com.sun.media.sound.DirectAudioDevice$DirectClip.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the test app provided.
2. Open a wav file.
3. Click Play.
4. Click Pause, then Play again to resume.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Clip is played, paused and resumed without a problem.
ACTUAL -
No error, just a problem with the audio playback. A portion of the audio is overlapped with previously played audio.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Vector;
public class VoicePromptPlayer extends JFrame implements ActionListener
{
Player player = new Player();
AudioInputStream audioInputStream;
JButton buttonPlayPause = new JButton();
JButton buttonStop = new JButton();
JButton buttonClose = new JButton();
JLabel lblPosition = new JLabel();
JLabel lblLength = new JLabel();
JLabel lblPositionSeconds = new JLabel();
JLabel lblLengthSeconds = new JLabel();
JLabel lblSecond1 = new JLabel();
JLabel lblSecond2 = new JLabel();
JPanel topPanel = new JPanel(new BorderLayout());
JPanel positionPanel = new JPanel();
JPanel lengthPanel = new JPanel();
JPanel bottomPanel = new JPanel(new BorderLayout());
JPanel controlButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));
int lengthInMilliseconds, seconds;
Vector lines = new Vector();
public VoicePromptPlayer()
{
super("Player");
this.getContentPane().setLayout(new BorderLayout());
setupTopPanel();
buttonPlayPause.setText("Play");
buttonPlayPause.setActionCommand("Play");
buttonPlayPause.addActionListener(this);
buttonPlayPause.setEnabled(false);
buttonPlayPause.setFocusPainted(false);
buttonStop.setText("Stop");
buttonStop.setActionCommand("Stop");
buttonStop.addActionListener(this);
buttonStop.setEnabled(false);
buttonStop.setFocusPainted(false);
buttonClose.setText("Close");
buttonClose.addActionListener(this);
buttonPanel.add(buttonClose);
controlButtonPanel.add(buttonPlayPause);
controlButtonPanel.add(buttonStop);
controlButtonPanel.add(buttonPanel);
bottomPanel.add(controlButtonPanel, BorderLayout.WEST);
bottomPanel.add(buttonPanel, BorderLayout.EAST);
this.getContentPane().add(topPanel, BorderLayout.NORTH);
this.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
createAudioInputStream();
lblPosition.setText("Position: ");
lblPositionSeconds.setText(formatMilliseconds(0));
lblLength.setText("Length: ");
lblLengthSeconds.setText(formatMilliseconds((long)lengthInMilliseconds));
lblSecond1.setText(" sec.");
lblSecond2.setText(" sec.");
if (audioInputStream != null)
{
buttonPlayPause.setEnabled(true);
}
this.setResizable(false);
this.addWindowListener(new MyWindowAdapter());
this.pack();
this.setLocationRelativeTo(null);
}
private void setupTopPanel()
{
GridBagLayout gbLayout = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
positionPanel.setLayout(gbLayout);
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.gridheight = 1;
gbc.gridwidth = 1;
gbc.insets = new Insets(4, 4, 0, 0);
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.WEST;
gbLayout.setConstraints(lblPosition, gbc);
positionPanel.add(lblPosition);
gbc.insets = new Insets(4, 0, 0, 0);
gbc.gridx = 1;
positionPanel.add(lblPositionSeconds, gbc);
gbc.weightx = 1.0;
gbc.gridx = 2;
positionPanel.add(lblSecond1, gbc);
topPanel.add(positionPanel, BorderLayout.WEST);
gbLayout = new GridBagLayout();
lengthPanel.setLayout(gbLayout);
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.EAST;
lengthPanel.add(lblLength, gbc);
gbc.weightx = 0.0;
gbc.gridx = 1;
lengthPanel.add(lblLengthSeconds, gbc);
gbc.insets = new Insets(4, 0, 0, 4);
gbc.gridx = 2;
lengthPanel.add(lblSecond2, gbc);
topPanel.add(lengthPanel, BorderLayout.EAST);
}
public static void main(String args[])
{
VoicePromptPlayer player = new VoicePromptPlayer();
player.setVisible(true);
}
public String toString()
{
return ("Player");
}
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource();
if (obj.equals(buttonPlayPause))
{
if (buttonPlayPause.getActionCommand().equals("Play"))
{
// Need to start play or resume
if (player.isPaused())
player.resume();
else
player.play();
// Either way modify the button
setPauseButton();
buttonStop.setEnabled(true);
}
else
{
player.pause();
setPlayButton();
}
pack();
}
else if (obj.equals(buttonStop))
{
player.stop();
buttonStop.setEnabled(false);
if (buttonPlayPause.getActionCommand().equals("Pause"))
setPlayButton();
}
else if (obj.equals(buttonClose))
{
player.stop();
this.dispose();
}
}
private String formatMilliseconds(long milliseconds)
{
DecimalFormat format = new DecimalFormat("0.00");
double seconds = milliseconds / 1000.0;
String formattedOutput = format.format(seconds);
return formattedOutput;
}
private void setPlayButton()
{
buttonPlayPause.setText("Play");
buttonPlayPause.setActionCommand("Play");
}
private void setPauseButton()
{
buttonPlayPause.setText("Pause");
buttonPlayPause.setActionCommand("Pause");
}
public void createAudioInputStream()
{
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(ListSelectionModel.SINGLE_SELECTION);
chooser.showOpenDialog(this);
File file = chooser.getSelectedFile();
try {
audioInputStream = AudioSystem.getAudioInputStream(file);
} catch (Exception e) {}
if (audioInputStream != null)
{
player.initialize();
lengthInMilliseconds = (int)((audioInputStream.getFrameLength() * 1000) / audioInputStream.getFormat().getFrameRate());
}
}
/**
* Voice prompt player.
*/
public class Player implements ActionListener
{
Timer timer;
Clip clip;
boolean paused = false;
public Player()
{
timer = new Timer(100, this);
timer.setRepeats(true);
}
public void actionPerformed(ActionEvent e)
{
long usec = clip.getMicrosecondPosition();
System.out.println("Clip position: " + usec + " usec, isRunning: " + clip.isRunning());
System.out.println("Timer time: " + System.currentTimeMillis() + " msec");
if ( (clip.isRunning() == false))
{
// At end of playback
if (buttonStop.isEnabled())
buttonStop.doClick();
}
lblPositionSeconds.setText(formatMilliseconds((long) usec/1000));
lblPosition.repaint();
}
public boolean isPaused()
{
return paused;
}
public void play()
{
if(clip == null)
{
JOptionPane.showMessageDialog(null, "There is no loaded audio to playback.",
"Play Problem",JOptionPane.WARNING_MESSAGE);
return;
}
System.out.println("\nClip starting");
System.out.println("Clip position: " + clip.getMicrosecondPosition() + " usec, isRunning: " + clip.isRunning());
clip.start();
System.out.println("Clip started");
System.out.println("Clip position: " + clip.getMicrosecondPosition() + " usec, isRunning: " + clip.isRunning());
System.out.println("Start time: " + System.currentTimeMillis() + " msec");
timer.start();
}
public void pause()
{
if (timer != null)
timer.stop();
if (clip != null)
clip.stop();
paused = true;
}
public void resume()
{
if (clip != null)
clip.start();
if (timer != null)
timer.restart();
paused = false;
}
public void stop()
{
if (timer != null)
timer.stop();
if (clip != null)
{
clip.stop();
clip.setFramePosition(0);
}
paused = false;
}
private void shutDown(String message)
{
if (message != null)
{
System.err.println(message);
}
setPlayButton();
buttonStop.setEnabled(false);
}
public void setPosition(long microseconds)
{
clip.setMicrosecondPosition(microseconds);
}
public void initialize()
{
// make sure we have something to play
if (audioInputStream == null) {
shutDown("There is no loaded audio to playback.");
return;
}
// define the required attributes for our line,
// and make sure a compatible line is supported.
AudioFormat format = audioInputStream.getFormat();
DataLine.Info clipInfo = new DataLine.Info(Clip.class, format);
if (!AudioSystem.isLineSupported(clipInfo))
{
shutDown("A line matching desired info not supported" + ": " + clipInfo);
return;
}
// get and open the source data line for playback.
try
{
clip = (Clip)AudioSystem.getLine(clipInfo); // Create the clip
clip.open(audioInputStream);
clip.setFramePosition(0);
}
catch (IOException e)
{
shutDown("Unable to open clip" + ": " + e);
return;
}
catch (LineUnavailableException ex)
{
shutDown("Unable to open line" + ": " + ex);
return;
}
}
} // End class Player
class MyWindowAdapter extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
player.stop();
}
}
}
---------- END SOURCE ----------
###@###.### 2004-11-17 17:32:17 GMT
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Realtek AC97 Audio on motherboard
A DESCRIPTION OF THE PROBLEM :
(This is being resubmitted since I didn't get an auto-generated email the first time it was submitted.)
Audio playback within a java.sound.sampled.Clip is behaving strangely. While playing a wav (haven't tried anything else) file, if playback is paused and resumed, the audio output is repeating audio data. It kind of sounds like a skip and then it continues (eg. "Welcome <pause><resume> to Java...to Java sound"). When it get's to the end of the file the microsecond position indicates a position longer than the actual length.
Playback can be paused and resumed multiple times for a more pronounced effect.
Debugger shows that the actual Clip class is com.sun.media.sound.DirectAudioDevice$DirectClip.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the test app provided.
2. Open a wav file.
3. Click Play.
4. Click Pause, then Play again to resume.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Clip is played, paused and resumed without a problem.
ACTUAL -
No error, just a problem with the audio playback. A portion of the audio is overlapped with previously played audio.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Vector;
public class VoicePromptPlayer extends JFrame implements ActionListener
{
Player player = new Player();
AudioInputStream audioInputStream;
JButton buttonPlayPause = new JButton();
JButton buttonStop = new JButton();
JButton buttonClose = new JButton();
JLabel lblPosition = new JLabel();
JLabel lblLength = new JLabel();
JLabel lblPositionSeconds = new JLabel();
JLabel lblLengthSeconds = new JLabel();
JLabel lblSecond1 = new JLabel();
JLabel lblSecond2 = new JLabel();
JPanel topPanel = new JPanel(new BorderLayout());
JPanel positionPanel = new JPanel();
JPanel lengthPanel = new JPanel();
JPanel bottomPanel = new JPanel(new BorderLayout());
JPanel controlButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));
int lengthInMilliseconds, seconds;
Vector lines = new Vector();
public VoicePromptPlayer()
{
super("Player");
this.getContentPane().setLayout(new BorderLayout());
setupTopPanel();
buttonPlayPause.setText("Play");
buttonPlayPause.setActionCommand("Play");
buttonPlayPause.addActionListener(this);
buttonPlayPause.setEnabled(false);
buttonPlayPause.setFocusPainted(false);
buttonStop.setText("Stop");
buttonStop.setActionCommand("Stop");
buttonStop.addActionListener(this);
buttonStop.setEnabled(false);
buttonStop.setFocusPainted(false);
buttonClose.setText("Close");
buttonClose.addActionListener(this);
buttonPanel.add(buttonClose);
controlButtonPanel.add(buttonPlayPause);
controlButtonPanel.add(buttonStop);
controlButtonPanel.add(buttonPanel);
bottomPanel.add(controlButtonPanel, BorderLayout.WEST);
bottomPanel.add(buttonPanel, BorderLayout.EAST);
this.getContentPane().add(topPanel, BorderLayout.NORTH);
this.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
createAudioInputStream();
lblPosition.setText("Position: ");
lblPositionSeconds.setText(formatMilliseconds(0));
lblLength.setText("Length: ");
lblLengthSeconds.setText(formatMilliseconds((long)lengthInMilliseconds));
lblSecond1.setText(" sec.");
lblSecond2.setText(" sec.");
if (audioInputStream != null)
{
buttonPlayPause.setEnabled(true);
}
this.setResizable(false);
this.addWindowListener(new MyWindowAdapter());
this.pack();
this.setLocationRelativeTo(null);
}
private void setupTopPanel()
{
GridBagLayout gbLayout = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
positionPanel.setLayout(gbLayout);
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.gridheight = 1;
gbc.gridwidth = 1;
gbc.insets = new Insets(4, 4, 0, 0);
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.WEST;
gbLayout.setConstraints(lblPosition, gbc);
positionPanel.add(lblPosition);
gbc.insets = new Insets(4, 0, 0, 0);
gbc.gridx = 1;
positionPanel.add(lblPositionSeconds, gbc);
gbc.weightx = 1.0;
gbc.gridx = 2;
positionPanel.add(lblSecond1, gbc);
topPanel.add(positionPanel, BorderLayout.WEST);
gbLayout = new GridBagLayout();
lengthPanel.setLayout(gbLayout);
gbc.gridx = 0;
gbc.anchor = GridBagConstraints.EAST;
lengthPanel.add(lblLength, gbc);
gbc.weightx = 0.0;
gbc.gridx = 1;
lengthPanel.add(lblLengthSeconds, gbc);
gbc.insets = new Insets(4, 0, 0, 4);
gbc.gridx = 2;
lengthPanel.add(lblSecond2, gbc);
topPanel.add(lengthPanel, BorderLayout.EAST);
}
public static void main(String args[])
{
VoicePromptPlayer player = new VoicePromptPlayer();
player.setVisible(true);
}
public String toString()
{
return ("Player");
}
public void actionPerformed(ActionEvent e)
{
Object obj = e.getSource();
if (obj.equals(buttonPlayPause))
{
if (buttonPlayPause.getActionCommand().equals("Play"))
{
// Need to start play or resume
if (player.isPaused())
player.resume();
else
player.play();
// Either way modify the button
setPauseButton();
buttonStop.setEnabled(true);
}
else
{
player.pause();
setPlayButton();
}
pack();
}
else if (obj.equals(buttonStop))
{
player.stop();
buttonStop.setEnabled(false);
if (buttonPlayPause.getActionCommand().equals("Pause"))
setPlayButton();
}
else if (obj.equals(buttonClose))
{
player.stop();
this.dispose();
}
}
private String formatMilliseconds(long milliseconds)
{
DecimalFormat format = new DecimalFormat("0.00");
double seconds = milliseconds / 1000.0;
String formattedOutput = format.format(seconds);
return formattedOutput;
}
private void setPlayButton()
{
buttonPlayPause.setText("Play");
buttonPlayPause.setActionCommand("Play");
}
private void setPauseButton()
{
buttonPlayPause.setText("Pause");
buttonPlayPause.setActionCommand("Pause");
}
public void createAudioInputStream()
{
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(ListSelectionModel.SINGLE_SELECTION);
chooser.showOpenDialog(this);
File file = chooser.getSelectedFile();
try {
audioInputStream = AudioSystem.getAudioInputStream(file);
} catch (Exception e) {}
if (audioInputStream != null)
{
player.initialize();
lengthInMilliseconds = (int)((audioInputStream.getFrameLength() * 1000) / audioInputStream.getFormat().getFrameRate());
}
}
/**
* Voice prompt player.
*/
public class Player implements ActionListener
{
Timer timer;
Clip clip;
boolean paused = false;
public Player()
{
timer = new Timer(100, this);
timer.setRepeats(true);
}
public void actionPerformed(ActionEvent e)
{
long usec = clip.getMicrosecondPosition();
System.out.println("Clip position: " + usec + " usec, isRunning: " + clip.isRunning());
System.out.println("Timer time: " + System.currentTimeMillis() + " msec");
if ( (clip.isRunning() == false))
{
// At end of playback
if (buttonStop.isEnabled())
buttonStop.doClick();
}
lblPositionSeconds.setText(formatMilliseconds((long) usec/1000));
lblPosition.repaint();
}
public boolean isPaused()
{
return paused;
}
public void play()
{
if(clip == null)
{
JOptionPane.showMessageDialog(null, "There is no loaded audio to playback.",
"Play Problem",JOptionPane.WARNING_MESSAGE);
return;
}
System.out.println("\nClip starting");
System.out.println("Clip position: " + clip.getMicrosecondPosition() + " usec, isRunning: " + clip.isRunning());
clip.start();
System.out.println("Clip started");
System.out.println("Clip position: " + clip.getMicrosecondPosition() + " usec, isRunning: " + clip.isRunning());
System.out.println("Start time: " + System.currentTimeMillis() + " msec");
timer.start();
}
public void pause()
{
if (timer != null)
timer.stop();
if (clip != null)
clip.stop();
paused = true;
}
public void resume()
{
if (clip != null)
clip.start();
if (timer != null)
timer.restart();
paused = false;
}
public void stop()
{
if (timer != null)
timer.stop();
if (clip != null)
{
clip.stop();
clip.setFramePosition(0);
}
paused = false;
}
private void shutDown(String message)
{
if (message != null)
{
System.err.println(message);
}
setPlayButton();
buttonStop.setEnabled(false);
}
public void setPosition(long microseconds)
{
clip.setMicrosecondPosition(microseconds);
}
public void initialize()
{
// make sure we have something to play
if (audioInputStream == null) {
shutDown("There is no loaded audio to playback.");
return;
}
// define the required attributes for our line,
// and make sure a compatible line is supported.
AudioFormat format = audioInputStream.getFormat();
DataLine.Info clipInfo = new DataLine.Info(Clip.class, format);
if (!AudioSystem.isLineSupported(clipInfo))
{
shutDown("A line matching desired info not supported" + ": " + clipInfo);
return;
}
// get and open the source data line for playback.
try
{
clip = (Clip)AudioSystem.getLine(clipInfo); // Create the clip
clip.open(audioInputStream);
clip.setFramePosition(0);
}
catch (IOException e)
{
shutDown("Unable to open clip" + ": " + e);
return;
}
catch (LineUnavailableException ex)
{
shutDown("Unable to open line" + ": " + ex);
return;
}
}
} // End class Player
class MyWindowAdapter extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
player.stop();
}
}
}
---------- END SOURCE ----------
###@###.### 2004-11-17 17:32:17 GMT
- duplicates
-
JDK-5070081 REGRESSION: javax.sound.sampled.Clip loses position when stopped
-
- Resolved
-