Logo Search packages:      
Sourcecode: libjlayer-java version File versions  Download package

Player.java

/*
 * 11/19/04       1.0 moved to LGPL.
 * 29/01/00       Initial version. mdm@techie.com
 *-----------------------------------------------------------------------
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library 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 Library General Public License for more details.
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *----------------------------------------------------------------------
 */

package javazoom.jl.player;

import java.io.InputStream;

import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.decoder.SampleBuffer;
      
/**
 * The <code>Player</code> class implements a simple player for playback
 * of an MPEG audio stream. 
 * 
 * @author  Mat McGowan
 * @since   0.0.8
 */

// REVIEW: the audio device should not be opened until the
// first MPEG audio frame has been decoded. 
00042 public class Player
{           
      /**
       * The current frame number. 
       */
00047       private int frame = 0;
      
      /**
       * The MPEG audio bitstream. 
       */
      // javac blank final bug. 
00053       /*final*/ private Bitstream         bitstream;
      
      /**
       * The MPEG audio decoder. 
       */
00058       /*final*/ private Decoder           decoder; 
      
      /**
       * The AudioDevice the audio samples are written to. 
       */
00063       private AudioDevice     audio;
      
      /**
       * Has the player been closed?
       */
00068       private boolean         closed = false;
      
      /**
       * Has the player played back all frames from the stream?
       */
00073       private boolean         complete = false;

      private int             lastPosition = 0;
      
      /**
       * Creates a new <code>Player</code> instance. 
       */
00080       public Player(InputStream stream) throws JavaLayerException
      {
            this(stream, null);     
      }
      
      public Player(InputStream stream, AudioDevice device) throws JavaLayerException
      {
            bitstream = new Bitstream(stream);        
            decoder = new Decoder();
                        
            if (device!=null)
            {           
                  audio = device;
            }
            else
            {                 
                  FactoryRegistry r = FactoryRegistry.systemRegistry();
                  audio = r.createAudioDevice();
            }
            audio.open(decoder);
      }
      
      public void play() throws JavaLayerException
      {
            play(Integer.MAX_VALUE);
      }
      
      /**
       * Plays a number of MPEG audio frames. 
       * 
       * @param frames  The number of frames to play. 
       * @return  true if the last frame was played, or false if there are
       *                more frames. 
       */
00114       public boolean play(int frames) throws JavaLayerException
      {
            boolean ret = true;
                  
            while (frames-- > 0 && ret)
            {
                  ret = decodeFrame();                
            }
            
            if (!ret)
            {
                  // last frame, ensure all data flushed to the audio device. 
                  AudioDevice out = audio;
                  if (out!=null)
                  {                       
                        out.flush();
                        synchronized (this)
                        {
                              complete = (!closed);
                              close();
                        }                       
                  }
            }
            return ret;
      }
            
      /**
       * Cloases this player. Any audio currently playing is stopped
       * immediately. 
       */
00144       public synchronized void close()
      {           
            AudioDevice out = audio;
            if (out!=null)
            { 
                  closed = true;
                  audio = null;     
                  // this may fail, so ensure object state is set up before
                  // calling this method. 
                  out.close();
                  lastPosition = out.getPosition();
                  try
                  {
                        bitstream.close();
                  }
                  catch (BitstreamException ex)
                  {
                  }
            }
      }
      
      /**
       * Returns the completed status of this player.
       * 
       * @return  true if all available MPEG audio frames have been
       *                decoded, or false otherwise. 
       */
00171       public synchronized boolean isComplete()
      {
            return complete;  
      }
                        
      /**
       * Retrieves the position in milliseconds of the current audio
       * sample being played. This method delegates to the <code>
       * AudioDevice</code> that is used by this player to sound
       * the decoded audio samples. 
       */
00182       public int getPosition()
      {
            int position = lastPosition;
            
            AudioDevice out = audio;            
            if (out!=null)
            {
                  position = out.getPosition(); 
            }
            return position;
      }           
      
      /**
       * Decodes a single frame.
       * 
       * @return true if there are no more frames to decode, false otherwise.
       */
00199       protected boolean decodeFrame() throws JavaLayerException
      {           
            try
            {
                  AudioDevice out = audio;
                  if (out==null)
                        return false;

                  Header h = bitstream.readFrame();   
                  
                  if (h==null)
                        return false;
                        
                  // sample buffer set when decoder constructed
                  SampleBuffer output = (SampleBuffer)decoder.decodeFrame(h, bitstream);
                                                                                                                                                                                                                              
                  synchronized (this)
                  {
                        out = audio;
                        if (out!=null)
                        {                             
                              out.write(output.getBuffer(), 0, output.getBufferLength());
                        }                       
                  }
                                                                                                                  
                  bitstream.closeFrame();
            }           
            catch (RuntimeException ex)
            {
                  throw new JavaLayerException("Exception decoding audio frame", ex);
            }
/*
            catch (IOException ex)
            {
                  System.out.println("exception decoding audio frame: "+ex);
                  return false;     
            }
            catch (BitstreamException bitex)
            {
                  System.out.println("exception decoding audio frame: "+bitex);
                  return false;     
            }
            catch (DecoderException decex)
            {
                  System.out.println("exception decoding audio frame: "+decex);
                  return false;                       
            }
*/          
            return true;
      }

      
}

Generated by  Doxygen 1.6.0   Back to index