Audio wave file playing/pausing/stoping

Hi all,

I’m developing audio mixer to play audio (wave files) and to have control on it.
I’m able to play and stop the audio with AudioInputStream and SourceDataLine. But unable to pause and resume the playing/running audio file. :frowning:
Can any on help me how to get the control on audio file like pause, resume and forward/rewind (5sec, 10sec,…). :-[ .

I’m attaching the code, which I’m using for my application.


/*
 * Created on Aug 5, 2005
 */
package Samples.audio;

import java.io.File;
import java.io.IOException;

import java.net.URL;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.FloatControl;
/**
 * @author vinesh
 */
public class FoundationAudioStream 
	implements	Runnable{
		// better size
		private static final int	EXTERNAL_BUFFER_SIZE = 4000 * 4;

		private Thread				m_thread = null;
		private Object				m_dataSource;
		private AudioInputStream	m_audioInputStream;
		private SourceDataLine		m_sourceDataLine;
		public static long 			lastMicrosecondPosition=0;
		public static long 			currentMicrosecondPosition=0;
		
		private boolean 			pauseFlag=false;
		private int 				pauseCount;
		private int 				bufferSize;
		private int 				audioLength;         	// Length of the sound.
		public static	int 		audioPosition = 0;   	// Current position within the sound
		/**	This variable is used to distinguish stopped state from paused state. */
		private boolean			m_bRunning;

		protected FoundationAudioStream()
		{
			m_dataSource = null;
			m_audioInputStream = null;
			m_sourceDataLine = null;
			m_gainControl = null;
			m_panControl = null;
		}

		protected void setDataSource(File file)
			throws	UnsupportedAudioFileException, LineUnavailableException, IOException
		{
			m_dataSource = file;
			initAudioInputStream();
		}

		private void initAudioInputStream()
			throws	UnsupportedAudioFileException, LineUnavailableException, IOException{
			if (m_dataSource instanceof File)initAudioInputStream((File) m_dataSource);
		}

		private void initAudioInputStream(File file)
			throws	UnsupportedAudioFileException, IOException{
				m_audioInputStream = AudioSystem.getAudioInputStream(file);
				bufferSize = (int)file.length();
		}

		protected void initLine()
			throws	LineUnavailableException{
			if (m_sourceDataLine == null){
				createLine();
				openLine();
			}else{
				AudioFormat	lineAudioFormat = m_sourceDataLine.getFormat();
				AudioFormat	audioInputStreamFormat = m_audioInputStream == null ? null : m_audioInputStream.getFormat();
				if (!lineAudioFormat.equals(audioInputStreamFormat)){
					m_sourceDataLine.close();
					openLine();
				}
			}
		}

		private void createLine()
			throws	LineUnavailableException{
			if (m_sourceDataLine != null)return;
			AudioFormat	audioFormat = m_audioInputStream.getFormat();
			DataLine.Info	info = 
				new DataLine.Info(SourceDataLine.class, audioFormat, AudioSystem.NOT_SPECIFIED);
			m_sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
			
			/** reseting the lastMicrosecondPosition for progress bar. */
			lastMicrosecondPosition=0;
		}

		private void openLine()
			throws	LineUnavailableException{
			if (m_sourceDataLine == null)return;
			AudioFormat	audioFormat = m_audioInputStream.getFormat();
			m_sourceDataLine.open(audioFormat, m_sourceDataLine.getBufferSize());
		}

		/** Start the audio */
		public void start()
		{
			if (!(m_thread == null || !m_thread.isAlive()))
					out("WARNING: old thread still running!!");
			m_thread = new Thread(this);
			m_thread.start();
			m_sourceDataLine.start();
		}

		/** Stop the audio. */
		protected void stop()
		{
			if (m_bRunning)
			{
				if (m_sourceDataLine != null)
				{
					lastMicrosecondPosition=m_sourceDataLine.getMicrosecondPosition();
					m_sourceDataLine.stop();
					m_sourceDataLine.flush();
				}
				m_bRunning = false;
				/**	We re-initialize the AudioInputStream. */
				try{
					initAudioInputStream();
				}catch (UnsupportedAudioFileException e){}
				 catch (LineUnavailableException e){}
				 catch (IOException e){}
			}
		}

		/** Pause the audio */
		public void pause(){
			m_sourceDataLine.stop();}

		/** Continue playing audio after pause */
		public void resume(){
			m_sourceDataLine.start();}

	    /** Stop playing the audio and reset the position to 0 on progress bar */
	    public void resetAudio( ) {
	        stop( );
	        audioPosition = 0; 
	        TestAudioPlayer.songPerMillisecond.setValue(0);
	    }
	    
		public void run()
		{
			int	nBytesRead = 0;
			m_bRunning = true;
			byte[]	abData = new byte[EXTERNAL_BUFFER_SIZE];
			int currentCount=0;
			while (nBytesRead != -1 && m_bRunning)
			{
				try{
					nBytesRead = m_audioInputStream.read(abData, 0, abData.length);
				}catch (IOException e){
					e.printStackTrace();}
				if (nBytesRead >= 0 )
					int	nBytesWritten = m_sourceDataLine.write(abData, 0, nBytesRead);
			}
			/** for pause to lock the song played */
			if(pauseFlag)pauseCount=currentCount;
			m_sourceDataLine.drain();
			stop();

			/** Reset the progress bar position after audio is completed. */
			lastMicrosecondPosition=m_sourceDataLine.getMicrosecondPosition();
			if(!TestAudioPlayer.start.isEnabled())TestAudioPlayer.start.setEnabled(true);
			if(!TestAudioPlayer.select.isEnabled())TestAudioPlayer.select.setEnabled(true);
		}

		private static void out(String strMessage){
			System.out.println(strMessage);
		}

}


When I call pause method the audio will stop playing, but when I call resume method the audio will drain and stop playing. :frowning:

-vinesh

I am just beginning to understand the audiosystem of java. But maybe i can help.
In the run() Method you have a while construct which reads all of the sound bytes, right?
Why don’t you put a boolean as a flag in this, not in the header but in an if-clause to control the
sound.

Hi Soulfly,

Thank you for your suggestion, I have already set the boolean flag in run () method to control the pause and resume, but there is a delay while pausing the sound.

I am looking for the method similar to the Clip.setMicrosecondPosition (), which return the long as a position to continue the clip. This is normally to forward and rewind the sound by specified number of seconds/millisecond. This i was struggling to find the solution for last three weeks but unable to find the solution. :frowning:

Yes, my while construct reads all sound bytes data and writes to the mixer via source data line.

Hi There,

for your case i have found a nice solution on another forum. here

http://forum.java.sun.com/thread.jspa?threadID=365207&messageID=1539548

hope this helps you with your problem.
greeting

Thank you for the reply, and the url of other forum.
This URL is for AudioPlayer where we can play clip files (like small wave files 2MB in size) using javax.sound.sampled.Clip interface. This application I have already developed (its the part of my application) and it has the features like select, play, stop, pause, resume, forward (5sec), rewind (5sec), skip (skipping the song on slider bar) and also have some advance features like pan control (left and right speakers volume control), gain control (volume control). But these all is to play the audio files of size around 2MB :frowning: .
Now in my further implementation I have to run wave file above 2MB size with all the above features. For doing this javax.sound.sampled.Clip interface will not support. So, I have to use javax.sound.sampled.DataLine/javax.sound.sampled.SourceDataLine explicitly for implementing this. Now i am able to do with this select, play, stop, pause, and resume. I’m struggling for forward, rewind and tempo adjustment :-[ .

Can you share your code for achieving pause and resume?I am trying to do similar thing but once I pause and then resume the sound doesn’t play fine.

Now I got solution to my self, the problem was, I was using j2sdk1.4 version to run the clip audio wave files, which has some buffer limitations to run the loaded clip. I tried the same application with JDK1.5 it’s working fine. :slight_smile:

Now I want to do tempo adjustment for the playing clip audio. Can any one help me.