package javazoom.jlGui;
/**
* BasicPlayer.
*
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
import java.io.*;
import java.util.*;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFileFormat;
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;
import javax.sound.sampled.Control;
import javazoom.Util.Debug;
/**
* BasicPlayer implements basics features of a player. The playback is done
* with a thread.
* BasicPlayer is the result of jlGui 0.5 from JavaZOOM and BaseAudioStream
* from Matthias Pfisterer JavaSound examples.
*
* @author E.B from JavaZOOM
*
* Homepage : http://www.javazoom.net
*
*/
public class BasicPlayer implements Runnable
{
private static final int EXTERNAL_BUFFER_SIZE = 4000 * 4;
private Thread m_thread = null;
private Object m_dataSource;
private AudioInputStream m_audioInputStream;
private AudioFileFormat m_audioFileFormat;
private SourceDataLine m_line;
private FloatControl m_gainControl;
private FloatControl m_panControl;
/**
* These variables are used to distinguish stopped, paused, playing states.
* We need them to control Thread.
*/
private static final int PLAYING=0;
private static final int PAUSED=1;
private static final int STOPPED=2;
private static final int READY=3;
private int m_status = READY;
private long doSeek = -1;
private File _file = null;
private BasicPlayerListener m_bpl = null;
/**
* Constructs a Basic Player.
*/
public BasicPlayer()
{
m_dataSource = null;
m_audioInputStream = null;
m_audioFileFormat = null;
m_line = null;
m_gainControl = null;
m_panControl = null;
}
/**
* Constructs a Basic Player with a BasicPlayerListener.
*/
public BasicPlayer(BasicPlayerListener bpl)
{
this();
m_bpl = bpl;
}
/**
* Sets the data source as a file.
*/
protected void setDataSource(File file) throws UnsupportedAudioFileException, LineUnavailableException, IOException
{
if (file != null)
{
m_dataSource = file;
initAudioInputStream();
}
}
/**
* Sets the data source as an url.
*/
protected void setDataSource(URL url) throws UnsupportedAudioFileException, LineUnavailableException, IOException
{
if (url != null)
{
m_dataSource = url;
initAudioInputStream();
}
}
/**
* Inits Audio ressources from the data source.<br>
* - AudioInputStream <br>
* - AudioFileFormat
*/
private void initAudioInputStream() throws UnsupportedAudioFileException, LineUnavailableException, IOException
{
if (m_dataSource instanceof URL)
{
initAudioInputStream((URL) m_dataSource);
}
else if (m_dataSource instanceof File)
{
initAudioInputStream((File) m_dataSource);
}
}
/**
* Inits Audio ressources from file.
*/
private void initAudioInputStream(File file) throws UnsupportedAudioFileException, IOException
{
_file = file;
m_audioInputStream = AudioSystem.getAudioInputStream(file);
m_audioFileFormat = AudioSystem.getAudioFileFormat(file);
}
/**
* Inits Audio ressources from URL.
*/
private void initAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException
{
m_audioInputStream = AudioSystem.getAudioInputStream(url);
m_audioFileFormat = AudioSystem.getAudioFileFormat(url);
}
/**
* Inits Audio ressources from AudioSystem.<br>
* DateSource must be present.
*/
protected void initLine() throws LineUnavailableException
{
if (m_line == null)
{
createLine();
trace(1,getClass().getName(), "Create Line OK ");
openLine();
}
else
{
AudioFormat lineAudioFormat = m_line.getFormat();
AudioFormat audioInputStreamFormat = m_audioInputStream == null ? null : m_audioInputStream.getFormat();
if (!lineAudioFormat.equals(audioInputStreamFormat))
{
m_line.close();
openLine();
}
}
}
/**
* Inits a DateLine.<br>
*
* We check if the line supports Volume and Pan controls.
*
* From the AudioInputStream, i.e. from the sound file, we
* fetch information about the format of the audio data. These
* information include the sampling frequency, the number of
* channels and the size of the samples. There information
* are needed to ask JavaSound for a suitable output line
* for this audio file.
* Furthermore, we have to give JavaSound a hint about how
* big the internal buffer for the line should be. Here,
* we say AudioSystem.NOT_SPECIFIED, signaling that we don't
* care about the exact size. JavaSound will use some default
* value for the buffer size.
*/
private void createLine() throws LineUnavailableException
{
if (m_line == null)
{
AudioFormat sourceFormat = m_audioInputStream.getFormat();
trace(1,getClass().getName(), "Source format : ", sourceFormat.toString());
AudioFormat targetFormat = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
sourceFormat.getSampleRate(),
16,
sourceFormat.getChannels(),
sourceFormat.getChannels() * 2,
sourceFormat.getSampleRate(),
false);
trace(1,getClass().getName(), "Target format: " + targetFormat);
m_audioInputStream = AudioSystem.getAudioInputStream(targetFormat, m_audioInputStream);
AudioFormat audioFormat = m_audioInputStream.getFormat();
trace(1,getClass().getName(), "Create Line : ", audioFormat.toString());
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat, AudioSystem.NOT_SPECIFIED);
m_line = (SourceDataLine) AudioSystem.getLine(info);
/*-- Display supported controls --*/
Control[] c = m_line.getControls();
for (int p=0;p<c.length;p++)
{
trace(2,getClass().getName(), "Controls : "+c[p].toString());
}
/*-- Is Gain Control supported ? --*/
if (m_line.isControlSupported(FloatControl.Type.MASTER_GAIN))
{
m_gainControl = (FloatControl) m_line.getControl(FloatControl.Type.MASTER_GAIN);
trace(1,getClass().getName(), "Master Gain Control : ["+m_gainControl.getMinimum()+","+m_gainControl.getMaximum()+"]",""+m_gainControl.getPrecision());
}
/*-- Is Pan control supported ? --*/
if (m_line.isControlSupported(FloatControl.Type.PAN))
{
m_panControl = (FloatControl) m_line.getControl(FloatControl.Type.PAN);
trace(1,getClass().getName(), "Pan Control : ["+ m_panControl.getMinimum()+","+m_panControl.getMaximum()+"]",""+m_panControl.getPrecision());
}
}
}
/**
* Opens the line.
*/
private void openLine() throws LineUnavailableException
{
if (m_line != null)
{
AudioFormat audioFormat = m_audioInputStream.getFormat();
trace(1,getClass().getName(), "AudioFormat : "+audioFormat);
m_line.open(audi
评论0