views:

26

answers:

2

I use the following method to playback a recorded sound, it works fine, but why it only plays once, the second time I click the play button, it does nothing, how to reset the data ?

  // Write data to the OutputChannel.
  public class Playback implements Runnable
  {
    SourceDataLine line;
    Thread thread;

    public void start()
    {
      errStr=null;
      thread=new Thread(this);
      thread.setName("Playback");
      thread.start();
    }

    public void stop() { thread=null; }

    private void shutDown(String message)
    {
      if ((errStr=message)!=null)
      {
        System.err.println(errStr);
        samplingGraph.repaint();
      }
      if (thread!=null)
      {
        thread=null;
        samplingGraph.stop();
        if (Java_Sound.Running_In_All_Permissions_Mode) captB.setEnabled(true);
        pausB.setEnabled(false);
        playB.setText("Play");
      }
    }

    public void run()
    {
      AudioFormat format=formatControls.getFormat();                                               // get an AudioInputStream of the desired format for playback
      AudioInputStream playbackInputStream=AudioSystem.getAudioInputStream(format,audioInputStream);

      if (playbackInputStream==null)
      {
        shutDown("Unable to convert stream of format "+audioInputStream+" to format "+format);
        return;
      }
      SourceDataLine.Info info=new DataLine.Info(SourceDataLine.class,format);                     // define the required attributes for our line,and make sure a compatible line is supported.

      if (AudioSystem.isLineSupported(info))
      {
         try                                                                                        // get and open the source data line for playback.
        {
          line=(SourceDataLine)AudioSystem.getLine(info);
          line.open(format,bufSize);
        }
        catch (LineUnavailableException ex)
        {
          shutDown("Unable to open the line: "+ex);
          return;
        }
        int frameSizeInBytes=format.getFrameSize();                                                // play back the captured audio data
        int bufferLengthInFrames=line.getBufferSize()/8;
        int bufferLengthInBytes=bufferLengthInFrames*frameSizeInBytes;
        byte[] data=new byte[bufferLengthInBytes];
        int numBytesRead=0;
        line.start();                                                                              // start the source data line
        while (thread!=null)
        {
          try
          {
            if ((numBytesRead=playbackInputStream.read(data))==-1) break;
            int numBytesRemaining=numBytesRead;
             while (numBytesRemaining>0) { numBytesRemaining-=line.write(data,0,numBytesRemaining); }
          }
          catch (Exception e)
          {
            shutDown("Error during playback: "+e);
            break;
          }
        }
      }
       if (thread!=null) line.drain();                                                              // we reached the end of the stream. Let the data play out,then stop and close the line.
      line.stop();
      line.close();
      line=null;
      shutDown(null);
    }
  }

After my test, I found this line is causing the problem

"if ((numBytesRead=playbackInputStream.read(data))==-1) break;"

The first time I played back, there were data, it worked fine, but the second time, it broke. Why ? How to fix it ?

A: 

Never worked with java audio, but since you are using stream, you need to either reset the stream if that option is available, or need to create new stream every time you read it.

Hemang
A: 

I figured it out, add the following line after "shutDown(null)"

 if (file==null)
   try { audioInputStream.reset(); }
   catch (Exception e) { e.printStackTrace(); }

Now it works perfect.

Frank