Package javazoom.jl.player.advanced

Source Code of javazoom.jl.player.advanced.AdvancedPlayer$AmplitudeListener

/*
* 11/19/04    1.0 moved to LGPL.
*-----------------------------------------------------------------------
*   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.advanced;

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;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;

/**
* a hybrid of javazoom.jl.player.Player tweeked to include <code>play(startFrame, endFrame)</code>
* hopefully this will be included in the api
*/
public class AdvancedPlayer
{
  public interface AmplitudeListener {
    public void getAmplitude(short amplitude);
  }
  public float getVolume() {
    return volume;
  }

  public void setVolume(float volume) {
    this.volume = volume;
  }

  /** The MPEG audio bitstream.*/
  public Bitstream bitstream;
  /** The MPEG audio decoder. */
  private Decoder decoder;
  /** The AudioDevice the audio samples are written to. */
  private AudioDevice audio;
  /** Has the player been closed? */
  private boolean closed = false;
  /** Has the player played back all frames from the stream? */
  private boolean complete = false;
  private int lastPosition = 0;
  private int lastFramePosition = 0;
  private AmplitudeListener amplitudeListener;
  /** Listener for the playback process */
  private PlaybackListener listener;
  private float volume = 1;
  private boolean normalise = true;

  /**
   * Creates a new <code>Player</code> instance.
   */
  public AdvancedPlayer(InputStream stream) throws JavaLayerException
  {
    this(stream, null);
  }

  public AdvancedPlayer(InputStream stream, AudioDevice device) throws JavaLayerException
  {
    bitstream = new Bitstream(stream);
    if (device!=null) audio = device;
    else audio = FactoryRegistry.systemRegistry().createAudioDevice();
    audio.open(decoder = new 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.
   */
  public boolean play(int frames) throws JavaLayerException
  {
    boolean ret = true;

    // report to listener
    if(listener != null) listener.playbackStarted(createEvent(PlaybackEvent.STARTED));

    while (frames-- > 0 && ret)
    {
      lastFramePosition++;
      ret = decodeFrame();
    }

//    if (!ret)
    {
      // last frame, ensure all data flushed to the audio device.
      AudioDevice out = audio;
      if (out != null)
      {
       
//        System.out.println(audio.getPosition());
        out.flush();
//        System.out.println(audio.getPosition());
        synchronized (this)
        {
          complete = (!closed);
          close();
        }

        // report to listener
        if(listener != null) listener.playbackFinished(createEvent(out, PlaybackEvent.STOPPED));
      }
    }
    return ret;
  }
 
  /**
   * 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.
   */
  public int getPosition()
  {
    int position = lastPosition;
   
    AudioDevice out = audio;   
    if (out!=null)
    {
      position = out.getPosition()
    }
    return position;
  }
 
  /**
   * Retrieves the current frame position of the current audio file.
   */
  public int getFramePosition() {
    int position = lastFramePosition;
    return position;
  }

  /**
   * Closes this player. Any audio currently playing is stopped
   * immediately.
   */
  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)
      {}
    }
  }

  /**
   * Decodes a single frame.
   *
   * @return true if there are no more frames to decode, false otherwise.
   */
  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);
      short amplitude = 0;
      for(int i = 1; i < output.getBuffer().length; i++) {
          output.getBuffer()[i] = (short) (output.getBuffer()[i] * volume);
       
        if(output.getBuffer()[i] > amplitude) {
          amplitude = output.getBuffer()[i];
        }
      }
     
     
      if(amplitudeListener != null) {
        amplitudeListener.getAmplitude(amplitude);
      }
     
      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);
    }
    return true;
  }

  /**
   * skips over a single frame
   * @return false  if there are no more frames to decode, true otherwise.
   */
  protected boolean skipFrame() throws JavaLayerException
  {
    Header h = bitstream.readFrame();
    if (h == null) return false;
    bitstream.closeFrame();
    return true;
  }
 
  protected int skipFrameWithLength() throws JavaLayerException{
    Header h = bitstream.readFrame();
    if(h == null) return -1;
    int framesize = h.framesize;
    int ret = h.max_number_of_frames(framesize);
    return ret;
  }

  /**
   * Plays a range of MPEG audio frames
   * @param start  The first frame to play
   * @param end    The last frame to play
   * @return true if the last frame was played, or false if there are more frames.
   */
  public boolean play(final int start, final int end) throws JavaLayerException
  {
    boolean ret = true;
    int offset = start;
    lastFramePosition = start;
    while (offset-- > 0 && ret) ret = skipFrame();
    return play(end - start);
  }

  /**
   * Constructs a <code>PlaybackEvent</code>
   */
  private PlaybackEvent createEvent(int id)
  {
    return createEvent(audio, id);
  }

  /**
   * Constructs a <code>PlaybackEvent</code>
   */
  private PlaybackEvent createEvent(AudioDevice dev, int id)
  {
    return new PlaybackEvent(this, id, dev.getPosition());
  }

  /**
   * sets the <code>PlaybackListener</code>
   */
  public void setPlayBackListener(PlaybackListener listener)
  {
    this.listener = listener;
  }
 
  public void setAmplitudeListener(AmplitudeListener amplitudeListener) {
    this.amplitudeListener = amplitudeListener;
  }

  /**
   * gets the <code>PlaybackListener</code>
   */
  public PlaybackListener getPlayBackListener()
  {
    return listener;
  }

  /**
   * closes the player and notifies <code>PlaybackListener</code>
   */
  public void stop()
  {
    listener.playbackFinished(createEvent(PlaybackEvent.STOPPED));
    close();
  }
}
TOP

Related Classes of javazoom.jl.player.advanced.AdvancedPlayer$AmplitudeListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.