} catch (Exception e) { e.printStackTrace(); }
  public void run()  {    trace(1, getClass().getName(), "Thread Running");    //if (m_audioInputStream.markSupported()) m_audioInputStream.mark(m_audioFileFormat.getByteLength());    //else trace(1,getClass().getName(), "Mark not supported");    int nBytesRead = 1;    m_status = PLAYING;    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 && nBytesRead == -1)    {      m_bpl.updateMediaState("EOM");    }  }