From 9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e Mon Sep 17 00:00:00 2001 From: Michiel Van Der Kolk Date: Mon, 11 Jul 2005 15:42:37 +0000 Subject: Songdb java version, source. only 1.5 compatible git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7101 a1c6a512-1295-4272-9138-f99709370657 --- songdbj/javazoom/jl/player/AudioDevice.java | 103 +++++++++ songdbj/javazoom/jl/player/AudioDeviceBase.java | 177 +++++++++++++++ songdbj/javazoom/jl/player/AudioDeviceFactory.java | 87 +++++++ songdbj/javazoom/jl/player/FactoryRegistry.java | 129 +++++++++++ .../javazoom/jl/player/JavaSoundAudioDevice.java | 215 ++++++++++++++++++ .../jl/player/JavaSoundAudioDeviceFactory.java | 85 +++++++ songdbj/javazoom/jl/player/NullAudioDevice.java | 37 +++ songdbj/javazoom/jl/player/Player.java | 251 +++++++++++++++++++++ songdbj/javazoom/jl/player/PlayerApplet.java | 246 ++++++++++++++++++++ .../jl/player/advanced/AdvancedPlayer.java | 242 ++++++++++++++++++++ .../javazoom/jl/player/advanced/PlaybackEvent.java | 51 +++++ .../jl/player/advanced/PlaybackListener.java | 30 +++ songdbj/javazoom/jl/player/advanced/jlap.java | 116 ++++++++++ songdbj/javazoom/jl/player/jlp.java | 176 +++++++++++++++ 14 files changed, 1945 insertions(+) create mode 100644 songdbj/javazoom/jl/player/AudioDevice.java create mode 100644 songdbj/javazoom/jl/player/AudioDeviceBase.java create mode 100644 songdbj/javazoom/jl/player/AudioDeviceFactory.java create mode 100644 songdbj/javazoom/jl/player/FactoryRegistry.java create mode 100644 songdbj/javazoom/jl/player/JavaSoundAudioDevice.java create mode 100644 songdbj/javazoom/jl/player/JavaSoundAudioDeviceFactory.java create mode 100644 songdbj/javazoom/jl/player/NullAudioDevice.java create mode 100644 songdbj/javazoom/jl/player/Player.java create mode 100644 songdbj/javazoom/jl/player/PlayerApplet.java create mode 100644 songdbj/javazoom/jl/player/advanced/AdvancedPlayer.java create mode 100644 songdbj/javazoom/jl/player/advanced/PlaybackEvent.java create mode 100644 songdbj/javazoom/jl/player/advanced/PlaybackListener.java create mode 100644 songdbj/javazoom/jl/player/advanced/jlap.java create mode 100644 songdbj/javazoom/jl/player/jlp.java (limited to 'songdbj/javazoom/jl/player') diff --git a/songdbj/javazoom/jl/player/AudioDevice.java b/songdbj/javazoom/jl/player/AudioDevice.java new file mode 100644 index 0000000000..45c28600e6 --- /dev/null +++ b/songdbj/javazoom/jl/player/AudioDevice.java @@ -0,0 +1,103 @@ +/* + * 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 javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.JavaLayerException; + +/** + * The AudioDevice interface provides an abstraction for + * a device capable of sounding audio samples. Samples are written to + * the device wia the write() method. The device assumes + * that these samples are signed 16-bit samples taken at the output frequency + * of the decoder. If the decoder outputs more than one channel, the samples for + * each channel are assumed to appear consecutively, with the lower numbered + * channels preceeding higher-numbered channels. E.g. if there are two + * channels, the samples will appear in this order: + *

+ * 
+ *		l0, r0, l1, r1, l2, r2...
+ * 
+ * where 
+ *	lx indicates the xth sample on channel 0
+ *  rx indicates the xth sample on channel 1
+ * 
+ * + * @since 0.0.8 + * @author Mat McGowan + */ +public interface AudioDevice +{ + /** + * Prepares the AudioDevice for playback of audio samples. + * @param decoder The decoder that will be providing the audio + * samples. + * + * If the audio device is already open, this method returns silently. + * + */ + public void open(Decoder decoder) throws JavaLayerException; + + /** + * Retrieves the open state of this audio device. + * + * @return true if this audio device is open and playing + * audio samples, or false otherwise. + */ + public boolean isOpen(); + + /** + * Writes a number of samples to this AudioDevice. + * + * @param samples The array of signed 16-bit samples to write + * to the audio device. + * @param offs The offset of the first sample. + * @param len The number of samples to write. + * + * This method may return prior to the samples actually being played + * by the audio device. + */ + public void write(short[] samples, int offs, int len) throws JavaLayerException; + + + /** + * Closes this audio device. Any currently playing audio is stopped + * as soon as possible. Any previously written audio data that has not been heard + * is discarded. + * + * The implementation should ensure that any threads currently blocking + * on the device (e.g. during a write or flush + * operation should be unblocked by this method. + */ + public void close(); + + + /** + * Blocks until all audio samples previously written to this audio device have + * been heard. + */ + public void flush(); + + /** + * Retrieves the current playback position in milliseconds. + */ + public int getPosition(); +} diff --git a/songdbj/javazoom/jl/player/AudioDeviceBase.java b/songdbj/javazoom/jl/player/AudioDeviceBase.java new file mode 100644 index 0000000000..d9c84f08e7 --- /dev/null +++ b/songdbj/javazoom/jl/player/AudioDeviceBase.java @@ -0,0 +1,177 @@ +/* + * 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 javazoom.jl.decoder.Decoder; +import javazoom.jl.decoder.JavaLayerException; + +/** + * The AudioDeviceBase class provides a simple thread-safe + * implementation of the AudioDevice interface. + * Template methods are provided for subclasses to override and + * in doing so provide the implementation for the main operations + * of the AudioDevice interface. + * + * @since 0.0.8 + * @author Mat McGowan + */ +/* + * REVIEW: It is desirable to be able to use the decoder whe + * in the implementation of open(), but the decoder + * has not yet read a frame, and so much of the + * desired information (sample rate, channels etc.) + * are not available. + */ +public abstract class AudioDeviceBase implements AudioDevice +{ + private boolean open = false; + + private Decoder decoder = null; + + /** + * Opens this audio device. + * + * @param decoder The decoder that will provide audio data + * to this audio device. + */ + public synchronized void open(Decoder decoder) throws JavaLayerException + { + if (!isOpen()) + { + this.decoder = decoder; + openImpl(); + setOpen(true); + } + } + + /** + * Template method to provide the + * implementation for the opening of the audio device. + */ + protected void openImpl() throws JavaLayerException + { + } + + /** + * Sets the open state for this audio device. + */ + protected void setOpen(boolean open) + { + this.open = open; + } + + /** + * Determines if this audio device is open or not. + * + * @return true if the audio device is open, + * false if it is not. + */ + public synchronized boolean isOpen() + { + return open; + } + + /** + * Closes this audio device. If the device is currently playing + * audio, playback is stopped immediately without flushing + * any buffered audio data. + */ + public synchronized void close() + { + if (isOpen()) + { + closeImpl(); + setOpen(false); + decoder = null; + } + } + + /** + * Template method to provide the implementation for + * closing the audio device. + */ + protected void closeImpl() + { + } + + /** + * Writes audio data to this audio device. Audio data is + * assumed to be in the output format of the decoder. This + * method may return before the data has actually been sounded + * by the device if the device buffers audio samples. + * + * @param samples The samples to write to the audio device. + * @param offs The offset into the array of the first sample to write. + * @param len The number of samples from the array to write. + * @throws JavaLayerException if the audio data could not be + * written to the audio device. + * If the audio device is not open, this method does nthing. + */ + public void write(short[] samples, int offs, int len) + throws JavaLayerException + { + if (isOpen()) + { + writeImpl(samples, offs, len); + } + } + + /** + * Template method to provide the implementation for + * writing audio samples to the audio device. + */ + protected void writeImpl(short[] samples, int offs, int len) + throws JavaLayerException + { + } + + /** + * Waits for any buffered audio samples to be played by the + * audio device. This method should only be called prior + * to closing the device. + */ + public void flush() + { + if (isOpen()) + { + flushImpl(); + } + } + + /** + * Template method to provide the implementation for + * flushing any buffered audio data. + */ + protected void flushImpl() + { + } + + /** + * Retrieves the decoder that provides audio data to this + * audio device. + * + * @return The associated decoder. + */ + protected Decoder getDecoder() + { + return decoder; + } +} diff --git a/songdbj/javazoom/jl/player/AudioDeviceFactory.java b/songdbj/javazoom/jl/player/AudioDeviceFactory.java new file mode 100644 index 0000000000..2d502d2aad --- /dev/null +++ b/songdbj/javazoom/jl/player/AudioDeviceFactory.java @@ -0,0 +1,87 @@ +/* + * 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 javazoom.jl.decoder.JavaLayerException; + +/** + * An AudioDeviceFactory class is responsible for creating + * a specific AudioDevice implementation. A factory implementation + * can be as simple or complex as desired and may support just one implementation + * or may return several implementations depending upon the execution + * environment. + *

+ * When implementing a factory that provides an AudioDevice that uses + * class that may not be present, the factory should dynamically link to any + * specific implementation classes required to instantiate or test the audio + * implementation. This is so that the application as a whole + * can run without these classes being present. The audio + * device implementation, however, will usually statically link to the classes + * required. (See the JavaSound deivce and factory for an example + * of this.) + * + * @see FactoryRegistry + * + * @since 0.0.8 + * @author Mat McGowan + */ +public abstract class AudioDeviceFactory +{ + /** + * Creates a new AudioDevice. + * + * @return a new instance of a specific class of AudioDevice. + * @throws JavaLayerException if an instance of AudioDevice could not + * be created. + */ + public abstract AudioDevice createAudioDevice() throws JavaLayerException; + + /** + * Creates an instance of an AudioDevice implementation. + * @param loader The ClassLoader to use to + * load the named class, or null to use the + * system class loader. + * @param name The name of the class to load. + * @return A newly-created instance of the audio device class. + */ + protected AudioDevice instantiate(ClassLoader loader, String name) + throws ClassNotFoundException, + IllegalAccessException, + InstantiationException + { + AudioDevice dev = null; + + Class cls = null; + if (loader==null) + { + cls = Class.forName(name); + } + else + { + cls = loader.loadClass(name); + } + + Object o = cls.newInstance(); + dev = (AudioDevice)o; + + return dev; + } +} diff --git a/songdbj/javazoom/jl/player/FactoryRegistry.java b/songdbj/javazoom/jl/player/FactoryRegistry.java new file mode 100644 index 0000000000..8919995802 --- /dev/null +++ b/songdbj/javazoom/jl/player/FactoryRegistry.java @@ -0,0 +1,129 @@ +/* + * 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.util.Enumeration; +import java.util.Hashtable; + +import javazoom.jl.decoder.JavaLayerException; + +/** + * The FactoryRegistry class stores the factories + * for all the audio device implementations available in the system. + *

+ * Instances of this class are thread-safe. + * + * @since 0.0.8 + * @author Mat McGowan + */ + +public class FactoryRegistry extends AudioDeviceFactory +{ + static private FactoryRegistry instance = null; + + static synchronized public FactoryRegistry systemRegistry() + { + if (instance==null) + { + instance = new FactoryRegistry(); + instance.registerDefaultFactories(); + } + return instance; + } + + + protected Hashtable factories = new Hashtable(); + + /** + * Registers an AudioDeviceFactory instance + * with this registry. + */ + public void addFactory(AudioDeviceFactory factory) + { + factories.put(factory.getClass(), factory); + } + + public void removeFactoryType(Class cls) + { + factories.remove(cls); + } + + public void removeFactory(AudioDeviceFactory factory) + { + factories.remove(factory.getClass()); + } + + public AudioDevice createAudioDevice() throws JavaLayerException + { + AudioDevice device = null; + AudioDeviceFactory[] factories = getFactoriesPriority(); + + if (factories==null) + throw new JavaLayerException(this+": no factories registered"); + + JavaLayerException lastEx = null; + for (int i=0; (device==null) && (iJavaSoundAudioDevice implements an audio + * device by using the JavaSound API. + * + * @since 0.0.8 + * @author Mat McGowan + */ +public class JavaSoundAudioDevice extends AudioDeviceBase +{ + private SourceDataLine source = null; + + private AudioFormat fmt = null; + + private byte[] byteBuf = new byte[4096]; + + protected void setAudioFormat(AudioFormat fmt0) + { + fmt = fmt0; + } + + protected AudioFormat getAudioFormat() + { + if (fmt==null) + { + Decoder decoder = getDecoder(); + fmt = new AudioFormat(decoder.getOutputFrequency(), + 16, + decoder.getOutputChannels(), + true, + false); + } + return fmt; + } + + protected DataLine.Info getSourceLineInfo() + { + AudioFormat fmt = getAudioFormat(); + //DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt, 4000); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt); + return info; + } + + public void open(AudioFormat fmt) throws JavaLayerException + { + if (!isOpen()) + { + setAudioFormat(fmt); + openImpl(); + setOpen(true); + } + } + + protected void openImpl() + throws JavaLayerException + { + } + + + // createSource fix. + protected void createSource() throws JavaLayerException + { + Throwable t = null; + try + { + Line line = AudioSystem.getLine(getSourceLineInfo()); + if (line instanceof SourceDataLine) + { + source = (SourceDataLine)line; + //source.open(fmt, millisecondsToBytes(fmt, 2000)); + source.open(fmt); + /* + if (source.isControlSupported(FloatControl.Type.MASTER_GAIN)) + { + FloatControl c = (FloatControl)source.getControl(FloatControl.Type.MASTER_GAIN); + c.setValue(c.getMaximum()); + }*/ + source.start(); + + } + } catch (RuntimeException ex) + { + t = ex; + } + catch (LinkageError ex) + { + t = ex; + } + catch (LineUnavailableException ex) + { + t = ex; + } + if (source==null) throw new JavaLayerException("cannot obtain source audio line", t); + } + + public int millisecondsToBytes(AudioFormat fmt, int time) + { + return (int)(time*(fmt.getSampleRate()*fmt.getChannels()*fmt.getSampleSizeInBits())/8000.0); + } + + protected void closeImpl() + { + if (source!=null) + { + source.close(); + } + } + + protected void writeImpl(short[] samples, int offs, int len) + throws JavaLayerException + { + if (source==null) + createSource(); + + byte[] b = toByteArray(samples, offs, len); + source.write(b, 0, len*2); + } + + protected byte[] getByteArray(int length) + { + if (byteBuf.length < length) + { + byteBuf = new byte[length+1024]; + } + return byteBuf; + } + + protected byte[] toByteArray(short[] samples, int offs, int len) + { + byte[] b = getByteArray(len*2); + int idx = 0; + short s; + while (len-- > 0) + { + s = samples[offs++]; + b[idx++] = (byte)s; + b[idx++] = (byte)(s>>>8); + } + return b; + } + + protected void flushImpl() + { + if (source!=null) + { + source.drain(); + } + } + + public int getPosition() + { + int pos = 0; + if (source!=null) + { + pos = (int)(source.getMicrosecondPosition()/1000); + } + return pos; + } + + /** + * Runs a short test by playing a short silent sound. + */ + public void test() + throws JavaLayerException + { + try + { + open(new AudioFormat(22050, 16, 1, true, false)); + short[] data = new short[22050/10]; + write(data, 0, data.length); + flush(); + close(); + } + catch (RuntimeException ex) + { + throw new JavaLayerException("Device test failed: "+ex); + } + + } +} diff --git a/songdbj/javazoom/jl/player/JavaSoundAudioDeviceFactory.java b/songdbj/javazoom/jl/player/JavaSoundAudioDeviceFactory.java new file mode 100644 index 0000000000..92af492f65 --- /dev/null +++ b/songdbj/javazoom/jl/player/JavaSoundAudioDeviceFactory.java @@ -0,0 +1,85 @@ +/* + * 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 javazoom.jl.decoder.JavaLayerException; + +/** + * This class is responsible for creating instances of the + * JavaSoundAudioDevice. The audio device implementation is loaded + * and tested dynamically as not all systems will have support + * for JavaSound, or they may have the incorrect version. + */ +public class JavaSoundAudioDeviceFactory extends AudioDeviceFactory +{ + private boolean tested = false; + + static private final String DEVICE_CLASS_NAME = "javazoom.jl.player.JavaSoundAudioDevice"; + + public synchronized AudioDevice createAudioDevice() + throws JavaLayerException + { + if (!tested) + { + testAudioDevice(); + tested = true; + } + + try + { + return createAudioDeviceImpl(); + } + catch (Exception ex) + { + throw new JavaLayerException("unable to create JavaSound device: "+ex); + } + catch (LinkageError ex) + { + throw new JavaLayerException("unable to create JavaSound device: "+ex); + } + } + + protected JavaSoundAudioDevice createAudioDeviceImpl() + throws JavaLayerException + { + ClassLoader loader = getClass().getClassLoader(); + try + { + JavaSoundAudioDevice dev = (JavaSoundAudioDevice)instantiate(loader, DEVICE_CLASS_NAME); + return dev; + } + catch (Exception ex) + { + throw new JavaLayerException("Cannot create JavaSound device", ex); + } + catch (LinkageError ex) + { + throw new JavaLayerException("Cannot create JavaSound device", ex); + } + + } + + public void testAudioDevice() throws JavaLayerException + { + JavaSoundAudioDevice dev = createAudioDeviceImpl(); + dev.test(); + } +} diff --git a/songdbj/javazoom/jl/player/NullAudioDevice.java b/songdbj/javazoom/jl/player/NullAudioDevice.java new file mode 100644 index 0000000000..4145feecd4 --- /dev/null +++ b/songdbj/javazoom/jl/player/NullAudioDevice.java @@ -0,0 +1,37 @@ +/* + * 11/19/04 1.0 moved o 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; + +/** + * The NullAudioDevice implements a silent, no-op + * audio device. This is useful for testing purposes. + * + * @since 0.0.8 + * @author Mat McGowan + */ +public class NullAudioDevice extends AudioDeviceBase +{ + + public int getPosition() + { + return 0; + } +} diff --git a/songdbj/javazoom/jl/player/Player.java b/songdbj/javazoom/jl/player/Player.java new file mode 100644 index 0000000000..32fb1f3051 --- /dev/null +++ b/songdbj/javazoom/jl/player/Player.java @@ -0,0 +1,251 @@ +/* + * 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 Player 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. +public class Player +{ + /** + * The current frame number. + */ + private int frame = 0; + + /** + * The MPEG audio bitstream. + */ + // javac blank final bug. + /*final*/ private Bitstream bitstream; + + /** + * The MPEG audio decoder. + */ + /*final*/ 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; + + /** + * Creates a new Player instance. + */ + 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. + */ + 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. + */ + 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. + */ + public synchronized boolean isComplete() + { + return complete; + } + + /** + * Retrieves the position in milliseconds of the current audio + * sample being played. This method delegates to the + * AudioDevice 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; + } + + /** + * 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); + + 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; + } + + +} diff --git a/songdbj/javazoom/jl/player/PlayerApplet.java b/songdbj/javazoom/jl/player/PlayerApplet.java new file mode 100644 index 0000000000..d7c7dc2ffc --- /dev/null +++ b/songdbj/javazoom/jl/player/PlayerApplet.java @@ -0,0 +1,246 @@ +/* + * 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.applet.Applet; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import javazoom.jl.decoder.JavaLayerException; + +/** + * A simple applet that plays an MPEG audio file. + * The URL (relative to the document base) + * is passed as the "audioURL" parameter. + * + * @author Mat McGowan + * @since 0.0.8 + */ +public class PlayerApplet extends Applet implements Runnable +{ + static public final String AUDIO_PARAMETER = "audioURL"; + + /** + * The Player used to play the MPEG audio file. + */ + private Player player = null; + + /** + * The thread that runs the player. + */ + private Thread playerThread = null; + + private String fileName = null; + + + /** + * Retrieves the AudioDevice instance that will + * be used to sound the audio data. + * + * @return an audio device instance that will be used to + * sound the audio stream. + */ + protected AudioDevice getAudioDevice() throws JavaLayerException + { + return FactoryRegistry.systemRegistry().createAudioDevice(); + } + + /** + * Retrieves the InputStream that provides the MPEG audio + * stream data. + * + * @return an InputStream from which the MPEG audio data + * is read, or null if an error occurs. + */ + protected InputStream getAudioStream() + { + InputStream in = null; + + try + { + URL url = getAudioURL(); + if (url!=null) + in = url.openStream(); + } + catch (IOException ex) + { + System.err.println(ex); + } + return in; + } + + protected String getAudioFileName() + { + String urlString = fileName; + if (urlString==null) + { + urlString = getParameter(AUDIO_PARAMETER); + } + return urlString; + } + + protected URL getAudioURL() + { + String urlString = getAudioFileName(); + URL url = null; + if (urlString!=null) + { + try + { + url = new URL(getDocumentBase(), urlString); + } + catch (Exception ex) + { + System.err.println(ex); + } + } + return url; + } + + /** + * Sets the URL of the audio stream to play. + */ + public void setFileName(String name) + { + fileName = name; + } + + public String getFileName() + { + return fileName; + } + + /** + * Stops the audio player. If the player is already stopped + * this method is a no-op. + */ + protected void stopPlayer() throws JavaLayerException + { + if (player!=null) + { + player.close(); + player = null; + playerThread = null; + } + } + + /** + * Decompresses audio data from an InputStream and plays it + * back through an AudioDevice. The playback is run on a newly + * created thread. + * + * @param in The InputStream that provides the MPEG audio data. + * @param dev The AudioDevice to use to sound the decompressed data. + * + * @throws JavaLayerException if there was a problem decoding + * or playing the audio data. + */ + protected void play(InputStream in, AudioDevice dev) throws JavaLayerException + { + stopPlayer(); + + if (in!=null && dev!=null) + { + player = new Player(in, dev); + playerThread = createPlayerThread(); + playerThread.start(); + } + } + + /** + * Creates a new thread used to run the audio player. + * @return A new Thread that, once started, runs the audio player. + */ + protected Thread createPlayerThread() + { + return new Thread(this, "Audio player thread"); + } + + /** + * Initializes this applet. + */ + public void init() + { + } + + /** + * Starts this applet. An input stream and audio device + * are created and passed to the play() method. + */ + public void start() + { + String name = getAudioFileName(); + try + { + InputStream in = getAudioStream(); + AudioDevice dev = getAudioDevice(); + play(in, dev); + } + catch (JavaLayerException ex) + { + synchronized (System.err) + { + System.err.println("Unable to play "+name); + ex.printStackTrace(System.err); + } + } + } + + /** + * Stops this applet. If audio is currently playing, it is + * stopped. + */ + public void stop() + { + try + { + stopPlayer(); + } + catch (JavaLayerException ex) + { + System.err.println(ex); + } + } + + public void destroy() + { + } + + /** + * The run method for the audio player thread. Simply calls + * play() on the player to play the entire stream. + */ + public void run() + { + if (player!=null) + { + try + { + player.play(); + } + catch (JavaLayerException ex) + { + System.err.println("Problem playing audio: "+ex); + } + } + } +} diff --git a/songdbj/javazoom/jl/player/advanced/AdvancedPlayer.java b/songdbj/javazoom/jl/player/advanced/AdvancedPlayer.java new file mode 100644 index 0000000000..45a31e46e1 --- /dev/null +++ b/songdbj/javazoom/jl/player/advanced/AdvancedPlayer.java @@ -0,0 +1,242 @@ +/* + * 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 play(startFrame, endFrame) + * hopefully this will be included in the api + */ +public class AdvancedPlayer +{ + /** The MPEG audio bitstream.*/ + private 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; + /** Listener for the playback process */ + private PlaybackListener listener; + + /** + * Creates a new Player 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) + { + 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; + } + + /** + * Cloases 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); + + 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; + } + + /** + * 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; + while (offset-- > 0 && ret) ret = skipFrame(); + return play(end - start); + } + + /** + * Constructs a PlaybackEvent + */ + private PlaybackEvent createEvent(int id) + { + return createEvent(audio, id); + } + + /** + * Constructs a PlaybackEvent + */ + private PlaybackEvent createEvent(AudioDevice dev, int id) + { + return new PlaybackEvent(this, id, dev.getPosition()); + } + + /** + * sets the PlaybackListener + */ + public void setPlayBackListener(PlaybackListener listener) + { + this.listener = listener; + } + + /** + * gets the PlaybackListener + */ + public PlaybackListener getPlayBackListener() + { + return listener; + } + + /** + * closes the player and notifies PlaybackListener + */ + public void stop() + { + listener.playbackFinished(createEvent(PlaybackEvent.STOPPED)); + close(); + } +} \ No newline at end of file diff --git a/songdbj/javazoom/jl/player/advanced/PlaybackEvent.java b/songdbj/javazoom/jl/player/advanced/PlaybackEvent.java new file mode 100644 index 0000000000..08e3cae958 --- /dev/null +++ b/songdbj/javazoom/jl/player/advanced/PlaybackEvent.java @@ -0,0 +1,51 @@ +/* + * 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; + +/** + * An event which indicates a Player has performed an 'playback action' + * @author Paul Stanton (http://wanto.f2o.org/) + */ +public class PlaybackEvent +{ + public static int STOPPED = 1; + public static int STARTED = 2; + + private AdvancedPlayer source; + private int frame; + private int id; + + public PlaybackEvent(AdvancedPlayer source, int id, int frame) + { + this.id = id; + this.source = source; + this.frame = frame; + } + + public int getId(){return id;} + public void setId(int id){this.id = id;} + + public int getFrame(){return frame;} + public void setFrame(int frame){this.frame = frame;} + + public AdvancedPlayer getSource(){return source;} + public void setSource(AdvancedPlayer source){this.source = source;} + +} diff --git a/songdbj/javazoom/jl/player/advanced/PlaybackListener.java b/songdbj/javazoom/jl/player/advanced/PlaybackListener.java new file mode 100644 index 0000000000..9b042988b8 --- /dev/null +++ b/songdbj/javazoom/jl/player/advanced/PlaybackListener.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Listener for javalayer Player playback + * @author Paul Stanton (http://wanto.f2o.org/) + */ +public abstract class PlaybackListener +{ + public void playbackStarted(PlaybackEvent evt){} + public void playbackFinished(PlaybackEvent evt){} +} diff --git a/songdbj/javazoom/jl/player/advanced/jlap.java b/songdbj/javazoom/jl/player/advanced/jlap.java new file mode 100644 index 0000000000..beedea6716 --- /dev/null +++ b/songdbj/javazoom/jl/player/advanced/jlap.java @@ -0,0 +1,116 @@ +/* + * 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.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javazoom.jl.decoder.JavaLayerException; + +/** + * This class implements a sample player using Playback listener. + */ +public class jlap +{ + + public static void main(String[] args) + { + jlap test = new jlap(); + if (args.length != 1) + { + test.showUsage(); + System.exit(0); + } + else + { + try + { + test.play(args[0]); + } + catch (Exception ex) + { + System.err.println(ex.getMessage()); + System.exit(0); + } + } + } + + public void play(String filename) throws JavaLayerException, IOException + { + InfoListener lst = new InfoListener(); + playMp3(new File(filename), lst); + } + + public void showUsage() + { + System.out.println("Usage: jla "); + System.out.println(""); + System.out.println(" e.g. : java javazoom.jl.player.advanced.jlap localfile.mp3"); + } + + public static AdvancedPlayer playMp3(File mp3, PlaybackListener listener) throws IOException, JavaLayerException + { + return playMp3(mp3, 0, Integer.MAX_VALUE, listener); + } + + public static AdvancedPlayer playMp3(File mp3, int start, int end, PlaybackListener listener) throws IOException, JavaLayerException + { + return playMp3(new BufferedInputStream(new FileInputStream(mp3)), start, end, listener); + } + + public static AdvancedPlayer playMp3(final InputStream is, final int start, final int end, PlaybackListener listener) throws JavaLayerException + { + final AdvancedPlayer player = new AdvancedPlayer(is); + player.setPlayBackListener(listener); + // run in new thread + new Thread() + { + public void run() + { + try + { + player.play(start, end); + } + catch (Exception e) + { + throw new RuntimeException(e.getMessage()); + } + } + }.start(); + return player; + } + + public class InfoListener extends PlaybackListener + { + public void playbackStarted(PlaybackEvent evt) + { + System.out.println("Play started from frame " + evt.getFrame()); + } + + public void playbackFinished(PlaybackEvent evt) + { + System.out.println("Play completed at frame " + evt.getFrame()); + System.exit(0); + } + } +} \ No newline at end of file diff --git a/songdbj/javazoom/jl/player/jlp.java b/songdbj/javazoom/jl/player/jlp.java new file mode 100644 index 0000000000..ddb3d5ecca --- /dev/null +++ b/songdbj/javazoom/jl/player/jlp.java @@ -0,0 +1,176 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * + * 06/04/01 Streaming support added. javalayer@javazoom.net + * + * 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.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import javazoom.jl.decoder.JavaLayerException; + +/** + * The jlp class implements a simple command-line + * player for MPEG audio files. + * + * @author Mat McGowan (mdm@techie.com) + */ +public class jlp +{ + private String fFilename = null; + private boolean remote = false; + + public static void main(String[] args) + { + int retval = 0; + try + { + jlp player = createInstance(args); + if (player!=null) + player.play(); + } + catch (Exception ex) + { + System.err.println(ex); + ex.printStackTrace(System.err); + retval = 1; + } + System.exit(retval); + } + + static public jlp createInstance(String[] args) + { + jlp player = new jlp(); + if (!player.parseArgs(args)) + player = null; + return player; + } + + private jlp() + { + } + + public jlp(String filename) + { + init(filename); + } + + protected void init(String filename) + { + fFilename = filename; + } + + protected boolean parseArgs(String[] args) + { + boolean parsed = false; + if (args.length == 1) + { + init(args[0]); + parsed = true; + remote = false; + } + else if (args.length == 2) + { + if (!(args[0].equals("-url"))) + { + showUsage(); + } + else + { + init(args[1]); + parsed = true; + remote = true; + } + } + else + { + showUsage(); + } + return parsed; + } + + public void showUsage() + { + System.out.println("Usage: jlp [-url] "); + System.out.println(""); + System.out.println(" e.g. : java javazoom.jl.player.jlp localfile.mp3"); + System.out.println(" java javazoom.jl.player.jlp -url http://www.server.com/remotefile.mp3"); + System.out.println(" java javazoom.jl.player.jlp -url http://www.shoutcastserver.com:8000"); + } + + public void play() + throws JavaLayerException + { + try + { + System.out.println("playing "+fFilename+"..."); + InputStream in = null; + if (remote == true) in = getURLInputStream(); + else in = getInputStream(); + AudioDevice dev = getAudioDevice(); + Player player = new Player(in, dev); + player.play(); + } + catch (IOException ex) + { + throw new JavaLayerException("Problem playing file "+fFilename, ex); + } + catch (Exception ex) + { + throw new JavaLayerException("Problem playing file "+fFilename, ex); + } + } + + /** + * Playing file from URL (Streaming). + */ + protected InputStream getURLInputStream() + throws Exception + { + + URL url = new URL(fFilename); + InputStream fin = url.openStream(); + BufferedInputStream bin = new BufferedInputStream(fin); + return bin; + } + + /** + * Playing file from FileInputStream. + */ + protected InputStream getInputStream() + throws IOException + { + FileInputStream fin = new FileInputStream(fFilename); + BufferedInputStream bin = new BufferedInputStream(fin); + return bin; + } + + protected AudioDevice getAudioDevice() + throws JavaLayerException + { + return FactoryRegistry.systemRegistry().createAudioDevice(); + } + +} -- cgit v1.2.3