summaryrefslogtreecommitdiff
path: root/songdbj/javazoom/jl/decoder/Decoder.java
diff options
context:
space:
mode:
authorMichiel Van Der Kolk <not.valid@email.address>2005-07-11 15:42:37 +0000
committerMichiel Van Der Kolk <not.valid@email.address>2005-07-11 15:42:37 +0000
commit9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e (patch)
tree4c304cd4151020bd5494d279ee68a105ae3a5a3a /songdbj/javazoom/jl/decoder/Decoder.java
parentdfa8ecbe609ca8ea194d08560a44fb9a92e94b4b (diff)
downloadrockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.zip
rockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.tar.gz
rockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.tar.bz2
rockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.tar.xz
Songdb java version, source. only 1.5 compatible
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7101 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'songdbj/javazoom/jl/decoder/Decoder.java')
-rw-r--r--songdbj/javazoom/jl/decoder/Decoder.java357
1 files changed, 357 insertions, 0 deletions
diff --git a/songdbj/javazoom/jl/decoder/Decoder.java b/songdbj/javazoom/jl/decoder/Decoder.java
new file mode 100644
index 0000000..076f9de
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Decoder.java
@@ -0,0 +1,357 @@
+/*
+ * 11/19/04 1.0 moved to LGPL.
+ * 01/12/99 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.decoder;
+
+/**
+ * The <code>Decoder</code> class encapsulates the details of
+ * decoding an MPEG audio frame.
+ *
+ * @author MDM
+ * @version 0.0.7 12/12/99
+ * @since 0.0.5
+ */
+public class Decoder implements DecoderErrors
+{
+ static private final Params DEFAULT_PARAMS = new Params();
+
+ /**
+ * The Bistream from which the MPEG audio frames are read.
+ */
+ //private Bitstream stream;
+
+ /**
+ * The Obuffer instance that will receive the decoded
+ * PCM samples.
+ */
+ private Obuffer output;
+
+ /**
+ * Synthesis filter for the left channel.
+ */
+ private SynthesisFilter filter1;
+
+ /**
+ * Sythesis filter for the right channel.
+ */
+ private SynthesisFilter filter2;
+
+ /**
+ * The decoder used to decode layer III frames.
+ */
+ private LayerIIIDecoder l3decoder;
+ private LayerIIDecoder l2decoder;
+ private LayerIDecoder l1decoder;
+
+ private int outputFrequency;
+ private int outputChannels;
+
+ private Equalizer equalizer = new Equalizer();
+
+ private Params params;
+
+ private boolean initialized;
+
+
+ /**
+ * Creates a new <code>Decoder</code> instance with default
+ * parameters.
+ */
+
+ public Decoder()
+ {
+ this(null);
+ }
+
+ /**
+ * Creates a new <code>Decoder</code> instance with default
+ * parameters.
+ *
+ * @param params The <code>Params</code> instance that describes
+ * the customizable aspects of the decoder.
+ */
+ public Decoder(Params params0)
+ {
+ if (params0==null)
+ params0 = DEFAULT_PARAMS;
+
+ params = params0;
+
+ Equalizer eq = params.getInitialEqualizerSettings();
+ if (eq!=null)
+ {
+ equalizer.setFrom(eq);
+ }
+ }
+
+ static public Params getDefaultParams()
+ {
+ return (Params)DEFAULT_PARAMS.clone();
+ }
+
+ public void setEqualizer(Equalizer eq)
+ {
+ if (eq==null)
+ eq = Equalizer.PASS_THRU_EQ;
+
+ equalizer.setFrom(eq);
+
+ float[] factors = equalizer.getBandFactors();
+
+ if (filter1!=null)
+ filter1.setEQ(factors);
+
+ if (filter2!=null)
+ filter2.setEQ(factors);
+ }
+
+ /**
+ * Decodes one frame from an MPEG audio bitstream.
+ *
+ * @param header The header describing the frame to decode.
+ * @param bitstream The bistream that provides the bits for te body of the frame.
+ *
+ * @return A SampleBuffer containing the decoded samples.
+ */
+ public Obuffer decodeFrame(Header header, Bitstream stream)
+ throws DecoderException
+ {
+ if (!initialized)
+ {
+ initialize(header);
+ }
+
+ int layer = header.layer();
+
+ output.clear_buffer();
+
+ FrameDecoder decoder = retrieveDecoder(header, stream, layer);
+
+ decoder.decodeFrame();
+
+ output.write_buffer(1);
+
+ return output;
+ }
+
+ /**
+ * Changes the output buffer. This will take effect the next time
+ * decodeFrame() is called.
+ */
+ public void setOutputBuffer(Obuffer out)
+ {
+ output = out;
+ }
+
+ /**
+ * Retrieves the sample frequency of the PCM samples output
+ * by this decoder. This typically corresponds to the sample
+ * rate encoded in the MPEG audio stream.
+ *
+ * @param the sample rate (in Hz) of the samples written to the
+ * output buffer when decoding.
+ */
+ public int getOutputFrequency()
+ {
+ return outputFrequency;
+ }
+
+ /**
+ * Retrieves the number of channels of PCM samples output by
+ * this decoder. This usually corresponds to the number of
+ * channels in the MPEG audio stream, although it may differ.
+ *
+ * @return The number of output channels in the decoded samples: 1
+ * for mono, or 2 for stereo.
+ *
+ */
+ public int getOutputChannels()
+ {
+ return outputChannels;
+ }
+
+ /**
+ * Retrieves the maximum number of samples that will be written to
+ * the output buffer when one frame is decoded. This can be used to
+ * help calculate the size of other buffers whose size is based upon
+ * the number of samples written to the output buffer. NB: this is
+ * an upper bound and fewer samples may actually be written, depending
+ * upon the sample rate and number of channels.
+ *
+ * @return The maximum number of samples that are written to the
+ * output buffer when decoding a single frame of MPEG audio.
+ */
+ public int getOutputBlockSize()
+ {
+ return Obuffer.OBUFFERSIZE;
+ }
+
+
+ protected DecoderException newDecoderException(int errorcode)
+ {
+ return new DecoderException(errorcode, null);
+ }
+
+ protected DecoderException newDecoderException(int errorcode, Throwable throwable)
+ {
+ return new DecoderException(errorcode, throwable);
+ }
+
+ protected FrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer)
+ throws DecoderException
+ {
+ FrameDecoder decoder = null;
+
+ // REVIEW: allow channel output selection type
+ // (LEFT, RIGHT, BOTH, DOWNMIX)
+ switch (layer)
+ {
+ case 3:
+ if (l3decoder==null)
+ {
+ l3decoder = new LayerIIIDecoder(stream,
+ header, filter1, filter2,
+ output, OutputChannels.BOTH_CHANNELS);
+ }
+
+ decoder = l3decoder;
+ break;
+ case 2:
+ if (l2decoder==null)
+ {
+ l2decoder = new LayerIIDecoder();
+ l2decoder.create(stream,
+ header, filter1, filter2,
+ output, OutputChannels.BOTH_CHANNELS);
+ }
+ decoder = l2decoder;
+ break;
+ case 1:
+ if (l1decoder==null)
+ {
+ l1decoder = new LayerIDecoder();
+ l1decoder.create(stream,
+ header, filter1, filter2,
+ output, OutputChannels.BOTH_CHANNELS);
+ }
+ decoder = l1decoder;
+ break;
+ }
+
+ if (decoder==null)
+ {
+ throw newDecoderException(UNSUPPORTED_LAYER, null);
+ }
+
+ return decoder;
+ }
+
+ private void initialize(Header header)
+ throws DecoderException
+ {
+
+ // REVIEW: allow customizable scale factor
+ float scalefactor = 32700.0f;
+
+ int mode = header.mode();
+ int layer = header.layer();
+ int channels = mode==Header.SINGLE_CHANNEL ? 1 : 2;
+
+
+ // set up output buffer if not set up by client.
+ if (output==null)
+ output = new SampleBuffer(header.frequency(), channels);
+
+ float[] factors = equalizer.getBandFactors();
+ filter1 = new SynthesisFilter(0, scalefactor, factors);
+
+ // REVIEW: allow mono output for stereo
+ if (channels==2)
+ filter2 = new SynthesisFilter(1, scalefactor, factors);
+
+ outputChannels = channels;
+ outputFrequency = header.frequency();
+
+ initialized = true;
+ }
+
+ /**
+ * The <code>Params</code> class presents the customizable
+ * aspects of the decoder.
+ * <p>
+ * Instances of this class are not thread safe.
+ */
+ public static class Params implements Cloneable
+ {
+ private OutputChannels outputChannels = OutputChannels.BOTH;
+
+ private Equalizer equalizer = new Equalizer();
+
+ public Params()
+ {
+ }
+
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException ex)
+ {
+ throw new InternalError(this+": "+ex);
+ }
+ }
+
+ public void setOutputChannels(OutputChannels out)
+ {
+ if (out==null)
+ throw new NullPointerException("out");
+
+ outputChannels = out;
+ }
+
+ public OutputChannels getOutputChannels()
+ {
+ return outputChannels;
+ }
+
+ /**
+ * Retrieves the equalizer settings that the decoder's equalizer
+ * will be initialized from.
+ * <p>
+ * The <code>Equalizer</code> instance returned
+ * cannot be changed in real time to affect the
+ * decoder output as it is used only to initialize the decoders
+ * EQ settings. To affect the decoder's output in realtime,
+ * use the Equalizer returned from the getEqualizer() method on
+ * the decoder.
+ *
+ * @return The <code>Equalizer</code> used to initialize the
+ * EQ settings of the decoder.
+ */
+ public Equalizer getInitialEqualizerSettings()
+ {
+ return equalizer;
+ }
+
+ };
+}
+