📄 basicplayer.java
字号:
int nBytesCursor = 0;
byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
float nFrameSize = (float) m_line.getFormat().getFrameSize();
float nFrameRate = m_line.getFormat().getFrameRate();
float bytesPerSecond = nFrameSize*nFrameRate;
int secondsTotal = Math.round((float)m_audioFileFormat.getByteLength()/bytesPerSecond);
// E.B.
secondsTotal = (int) Math.round(getTotalLengthInSeconds());
while ( (nBytesRead != -1) && (m_status != STOPPED) )
{
if (m_status == PLAYING)
{
try
{
if (doSeek > -1 )
{
// Seek implementation. WAV format only !
if (( getAudioFileFormat() != null) && (getAudioFileFormat().getType().toString().startsWith("WAV")) )
{
if ( (secondsTotal != AudioSystem.NOT_SPECIFIED) && (secondsTotal > 0) )
{
m_line.flush();
m_line.stop();
//m_audioInputStream.reset();
m_audioInputStream.close();
m_audioInputStream = AudioSystem.getAudioInputStream(_file);
nBytesCursor = 0;
if (m_audioFileFormat.getByteLength()-doSeek < abData.length) doSeek = m_audioFileFormat.getByteLength() - abData.length;
doSeek = doSeek - doSeek%4;
int toSkip = (int) doSeek;
// skip(...) instead of read(...) runs out of memory ?!
while ( (toSkip > 0) && (nBytesRead > 0) )
{
if (toSkip > abData.length) nBytesRead = m_audioInputStream.read(abData, 0, abData.length);
else nBytesRead = m_audioInputStream.read(abData, 0, toSkip);
toSkip = toSkip - nBytesRead;
nBytesCursor = nBytesCursor + nBytesRead;
}
m_line.start();
}
else trace(1,getClass().getName(), "Seek not supported for this InputStream : "+secondsTotal);
}
else
{
trace(1,getClass().getName(), "Seek not supported for this InputStream : "+secondsTotal);
}
doSeek = -1;
}
nBytesRead = m_audioInputStream.read(abData, 0, abData.length);
}
catch (Exception e)
{
trace(1,getClass().getName(), "InputStream error : ("+nBytesRead+")",e.getMessage());
e.printStackTrace();
m_status = STOPPED;
}
if (nBytesRead >= 0)
{
if (m_bpl != null) m_bpl.updateMediaData(abData);
int nBytesWritten = m_line.write(abData, 0, nBytesRead);
nBytesCursor = nBytesCursor + nBytesWritten;
if (m_bpl != null) m_bpl.updateCursor((int) Math.round((float)nBytesCursor/bytesPerSecond),secondsTotal);
}
}
else
{
try
{
Thread.sleep(1000);
} catch (Exception e)
{
trace(1,getClass().getName(), "Thread cannot sleep : ",e.getMessage());
}
}
}
if (m_line != null)
{
try
{
m_line.drain();
m_line.stop();
m_line.close();
} catch (Exception e)
{
trace(1,getClass().getName(), "Cannot Free Audio ressources",e.getMessage());
}
finally
{
m_line = null;
}
}
trace(1,getClass().getName(), "Thread Stopped");
m_status = READY;
if (m_bpl != null) m_bpl.updateMediaState("EOM");
}
/*----------------------------------------------*/
/*-- Gain Control --*/
/*----------------------------------------------*/
/**
* Returns true if Gain control is supported.
*/
public boolean hasGainControl()
{
return m_gainControl != null;
}
/**
* Sets Gain value.
* Linear scale 0.0 <--> 1.0
* Threshold Coef. : 1/2 to avoid saturation.
*/
public void setGain(double fGain)
{
if (hasGainControl())
{
double minGainDB = getMinimum();
double ampGainDB = ((10.0f/20.0f)*getMaximum()) - getMinimum();
double cste = Math.log(10.0)/20;
double valueDB = minGainDB + (1/cste)*Math.log(1+(Math.exp(cste*ampGainDB)-1)*fGain);
//trace(1,getClass().getName(), "Gain : "+valueDB);
m_gainControl.setValue((float)valueDB);
}
}
/**
* Returns Gain value.
*/
public float getGain()
{
if (hasGainControl())
{
return m_gainControl.getValue();
}
else
{
return 0.0F;
}
}
/**
* Gets max Gain value.
*/
public float getMaximum()
{
if (hasGainControl())
{
return m_gainControl.getMaximum();
}
else
{
return 0.0F;
}
}
/**
* Gets min Gain value.
*/
public float getMinimum()
{
if (hasGainControl())
{
return m_gainControl.getMinimum();
}
else
{
return 0.0F;
}
}
/*----------------------------------------------*/
/*-- Pan Control --*/
/*----------------------------------------------*/
/**
* Returns true if Pan control is supported.
*/
public boolean hasPanControl()
{
return m_panControl != null;
}
/**
* Returns Pan precision.
*/
public float getPrecision()
{
if (hasPanControl())
{
return m_panControl.getPrecision();
}
else
{
return 0.0F;
}
}
/**
* Returns Pan value.
*/
public float getPan()
{
if (hasPanControl())
{
return m_panControl.getValue();
}
else
{
return 0.0F;
}
}
/**
* Sets Pan value.
* Linear scale : -1.0 <--> +1.0
*/
public void setPan(float fPan)
{
if (hasPanControl())
{
//trace(1,getClass().getName(), "Pan : "+fPan);
m_panControl.setValue(fPan);
}
}
/*----------------------------------------------*/
/*-- Seek --*/
/*----------------------------------------------*/
/**
* Sets Seek value.
* Linear scale : 0.0 <--> +1.0
*/
public void setSeek(double seek) throws IOException
{
double length = -1;
if ( (m_audioFileFormat != null) && (m_audioFileFormat.getByteLength() != AudioSystem.NOT_SPECIFIED) ) length = (double) m_audioFileFormat.getByteLength();
long newPos = (long) Math.round(seek*length);
doSeek = newPos;
}
/*----------------------------------------------*/
/*-- Audio Format --*/
/*----------------------------------------------*/
/**
* Returns source AudioFormat.
*/
public AudioFormat getAudioFormat()
{
if (m_audioFileFormat != null)
{
return m_audioFileFormat.getFormat();
}
else return null;
}
/**
* Returns source AudioFileFormat.
*/
public AudioFileFormat getAudioFileFormat()
{
if (m_audioFileFormat != null)
{
return m_audioFileFormat;
}
else return null;
}
/**
* Returns total length in seconds.
*/
public double getTotalLengthInSeconds()
{
double lenghtInSecond = 0.0;
if ( getAudioFileFormat() != null)
{
int FL = (getAudioFileFormat()).getFrameLength();
int FS = (getAudioFormat()).getFrameSize();
float SR = (getAudioFormat()).getSampleRate();
float FR = (getAudioFormat()).getFrameRate();
int TL = (getAudioFileFormat()).getByteLength();
String type = (getAudioFileFormat()).getType().toString();
String encoding = (getAudioFormat()).getEncoding().toString();
if ((FL != -1) && ( (type.startsWith("MP3")) || (type.startsWith("VORBIS")) ) )
{
// No accurate formula :-(
// Alternative dirty solution with SPI
StringTokenizer st = new StringTokenizer(type,"x");
st.nextToken();st.nextToken();
String totalMSStr = st.nextToken();
lenghtInSecond=Math.round((Integer.parseInt(totalMSStr))/1000);
}
else
{
int br = getBitRate();
if (br > 0) lenghtInSecond = TL*8/br;
else lenghtInSecond = TL/(FS*SR);
}
trace(2,getClass().getName(),"Type="+type+" Encoding="+encoding+" FL="+FL+" FS="+FS+" SR="+SR+" FR="+FR+" TL="+TL," lenghtInSecond="+lenghtInSecond);
}
if (lenghtInSecond < 0.0) lenghtInSecond = 0.0;
return lenghtInSecond;
}
/**
* Returns bit rate.
*/
public int getBitRate()
{
int bitRate = 0;
if ( getAudioFileFormat() != null)
{
int FL = (getAudioFileFormat()).getFrameLength();
int FS = (getAudioFormat()).getFrameSize();
float SR = (getAudioFormat()).getSampleRate();
float FR = (getAudioFormat()).getFrameRate();
int TL = (getAudioFileFormat()).getByteLength();
String type = (getAudioFileFormat()).getType().toString();
String encoding = (getAudioFormat()).getEncoding().toString();
// Assumes that type includes xBitRate string.
if ( (type != null) && ((type.startsWith("MP3")) || (type.startsWith("VORBIS"))) )
{
// BitRate string appended to type.
// Another solution ?
StringTokenizer st = new StringTokenizer(type,"x");
if (st.hasMoreTokens())
{
st.nextToken();
String bitRateStr = st.nextToken();
bitRate=Math.round((Integer.parseInt(bitRateStr)));
}
}
else
{
bitRate = Math.round(FS*FR*8);
}
trace(2,getClass().getName(),"Type="+type+" Encoding="+encoding+" FL="+FL+" FS="+FS+" SR="+SR+" FR="+FR+" TL="+TL," bitRate="+bitRate);
}
// N/A so computes bitRate for output.
if ((bitRate <= 0) && (m_line != null))
{
bitRate = Math.round(((m_line.getFormat()).getFrameSize())*((m_line.getFormat()).getFrameRate())*8);
}
return bitRate;
}
/**
* Gets an InputStream from File.
*/
protected InputStream openInput(File file) throws IOException
{
InputStream fileIn = new FileInputStream(file);
BufferedInputStream bufIn = new BufferedInputStream(fileIn);
return bufIn;
}
/*----------------------------------------------*/
/*-- Misc --*/
/*----------------------------------------------*/
/**
* Sends traces to Debug.
*/
private void trace(int level, String msg1, String msg2)
{
Debug dbg = Debug.getInstance();
dbg.log(level,msg1+":"+msg2);
}
private void trace(int level, String msg1, String msg2, String msg3)
{
Debug dbg = Debug.getInstance();
dbg.log(level,msg1+":"+msg2+","+msg3);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -