-public class Decoder implements DecoderErrors\r
-{\r
- static private final Params DEFAULT_PARAMS = new Params();\r
- \r
- /**\r
- * The Bistream from which the MPEG audio frames are read.\r
- */\r
- //private Bitstream stream;\r
- \r
- /**\r
- * The Obuffer instance that will receive the decoded\r
- * PCM samples.\r
- */\r
- private Obuffer output;\r
- \r
- /**\r
- * Synthesis filter for the left channel.\r
- */\r
- private SynthesisFilter filter1;\r
- \r
- /**\r
- * Sythesis filter for the right channel.\r
- */\r
- private SynthesisFilter filter2; \r
- \r
- /**\r
- * The decoder used to decode layer III frames.\r
- */\r
- private LayerIIIDecoder l3decoder;\r
- private LayerIIDecoder l2decoder;\r
- private LayerIDecoder l1decoder;\r
- \r
- private int outputFrequency;\r
- private int outputChannels;\r
- \r
- private Equalizer equalizer = new Equalizer();\r
- \r
- private Params params;\r
- \r
- private boolean initialized;\r
- \r
- \r
- /**\r
- * Creates a new <code>Decoder</code> instance with default \r
- * parameters.\r
- */\r
- \r
- public Decoder()\r
- {\r
- this(null);\r
- }\r
-\r
- /**\r
- * Creates a new <code>Decoder</code> instance with default \r
- * parameters.\r
- * \r
- * @param params The <code>Params</code> instance that describes\r
- * the customizable aspects of the decoder. \r
- */\r
- public Decoder(Params params0)\r
- {\r
- if (params0==null)\r
- params0 = DEFAULT_PARAMS;\r
- \r
- params = params0;\r
- \r
- Equalizer eq = params.getInitialEqualizerSettings();\r
- if (eq!=null)\r
- {\r
- equalizer.setFrom(eq);\r
- }\r
- }\r
- \r
- static public Params getDefaultParams()\r
- {\r
- return (Params)DEFAULT_PARAMS.clone();\r
- }\r
- \r
- public void setEqualizer(Equalizer eq)\r
- {\r
- if (eq==null)\r
- eq = Equalizer.PASS_THRU_EQ;\r
- \r
- equalizer.setFrom(eq);\r
- \r
- float[] factors = equalizer.getBandFactors();\r
-\r
- if (filter1!=null)\r
- filter1.setEQ(factors);\r
- \r
- if (filter2!=null)\r
- filter2.setEQ(factors); \r
- }\r
- \r
- /**\r
- * Decodes one frame from an MPEG audio bitstream.\r
- * \r
- * @param header The header describing the frame to decode.\r
- * @param bitstream The bistream that provides the bits for te body of the frame. \r
- * \r
- * @return A SampleBuffer containing the decoded samples.\r
- */\r
- public Obuffer decodeFrame(Header header, Bitstream stream)\r
- throws DecoderException\r
- {\r
- if (!initialized)\r
- {\r
- initialize(header);\r
- }\r
- \r
- int layer = header.layer();\r
- \r
- output.clear_buffer();\r
- \r
- FrameDecoder decoder = retrieveDecoder(header, stream, layer);\r
- \r
- decoder.decodeFrame();\r
- \r
- output.write_buffer(1);\r
- \r
- return output; \r
- }\r
- \r
- /**\r
- * Changes the output buffer. This will take effect the next time\r
- * decodeFrame() is called. \r
- */\r
- public void setOutputBuffer(Obuffer out)\r
- {\r
- output = out;\r
- }\r
- \r
- /**\r
- * Retrieves the sample frequency of the PCM samples output\r
- * by this decoder. This typically corresponds to the sample\r
- * rate encoded in the MPEG audio stream.\r
- * \r
- * @param the sample rate (in Hz) of the samples written to the\r
- * output buffer when decoding. \r
- */\r
- public int getOutputFrequency()\r
- {\r
- return outputFrequency;\r
- }\r
- \r
- /**\r
- * Retrieves the number of channels of PCM samples output by\r
- * this decoder. This usually corresponds to the number of\r
- * channels in the MPEG audio stream, although it may differ.\r
- * \r
- * @return The number of output channels in the decoded samples: 1 \r
- * for mono, or 2 for stereo.\r
- * \r
- */\r
- public int getOutputChannels()\r
- {\r
- return outputChannels; \r
- }\r
- \r
- /**\r
- * Retrieves the maximum number of samples that will be written to\r
- * the output buffer when one frame is decoded. This can be used to\r
- * help calculate the size of other buffers whose size is based upon \r
- * the number of samples written to the output buffer. NB: this is\r
- * an upper bound and fewer samples may actually be written, depending\r
- * upon the sample rate and number of channels.\r
- * \r
- * @return The maximum number of samples that are written to the \r
- * output buffer when decoding a single frame of MPEG audio.\r
- */\r
- public int getOutputBlockSize()\r
- {\r
- return Obuffer.OBUFFERSIZE;\r
- }\r
- \r
- \r
- protected DecoderException newDecoderException(int errorcode)\r
- {\r
- return new DecoderException(errorcode, null);\r
- }\r
- \r
- protected DecoderException newDecoderException(int errorcode, Throwable throwable)\r
- {\r
- return new DecoderException(errorcode, throwable);\r
- }\r
- \r
- protected FrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer)\r
- throws DecoderException\r
- {\r
- FrameDecoder decoder = null;\r
- \r
- // REVIEW: allow channel output selection type\r
- // (LEFT, RIGHT, BOTH, DOWNMIX)\r
- switch (layer)\r
- {\r
- case 3:\r
- if (l3decoder==null)\r
- {\r
- l3decoder = new LayerIIIDecoder(stream, \r
- header, filter1, filter2, \r
- output, OutputChannels.BOTH_CHANNELS);\r
- } \r
- \r
- decoder = l3decoder;\r
- break;\r
- case 2:\r
- if (l2decoder==null)\r
- {\r
- l2decoder = new LayerIIDecoder();\r
- l2decoder.create(stream, \r
- header, filter1, filter2, \r
- output, OutputChannels.BOTH_CHANNELS); \r
- }\r
- decoder = l2decoder;\r
- break;\r
- case 1:\r
- if (l1decoder==null)\r
- {\r
- l1decoder = new LayerIDecoder();\r
- l1decoder.create(stream, \r
- header, filter1, filter2, \r
- output, OutputChannels.BOTH_CHANNELS); \r
- }\r
- decoder = l1decoder;\r
- break;\r
- }\r
- \r
- if (decoder==null)\r
- {\r
- throw newDecoderException(UNSUPPORTED_LAYER, null);\r
- }\r
- \r
- return decoder;\r
- }\r
- \r
- private void initialize(Header header)\r
- throws DecoderException\r
- {\r
- \r
- // REVIEW: allow customizable scale factor\r
- float scalefactor = 32700.0f;\r
- \r
- int mode = header.mode();\r
- int layer = header.layer();\r
- int channels = mode==Header.SINGLE_CHANNEL ? 1 : 2;\r
-\r
- \r
- // set up output buffer if not set up by client.\r
- if (output==null)\r
- output = new SampleBuffer(header.frequency(), channels);\r
- \r
- float[] factors = equalizer.getBandFactors();\r
- filter1 = new SynthesisFilter(0, scalefactor, factors);\r
- \r
- // REVIEW: allow mono output for stereo\r
- if (channels==2) \r
- filter2 = new SynthesisFilter(1, scalefactor, factors);\r
-\r
- outputChannels = channels;\r
- outputFrequency = header.frequency();\r
- \r
- initialized = true;\r
- }\r
- \r
- /**\r
- * The <code>Params</code> class presents the customizable\r
- * aspects of the decoder. \r
- * <p>\r
- * Instances of this class are not thread safe. \r
- */\r
- public static class Params implements Cloneable\r
- {\r
- private OutputChannels outputChannels = OutputChannels.BOTH;\r
- \r
- private Equalizer equalizer = new Equalizer();\r
- \r
- public Params()\r
- { \r
- }\r
- \r
- public Object clone()\r
- {\r
- try\r
- {\r
- return super.clone();\r
- }\r
- catch (CloneNotSupportedException ex)\r
- { \r
- throw new InternalError(this+": "+ex);\r
- }\r
- }\r
- \r
- public void setOutputChannels(OutputChannels out)\r
- {\r
- if (out==null)\r
- throw new NullPointerException("out");\r
- \r
- outputChannels = out;\r
- }\r
- \r
- public OutputChannels getOutputChannels()\r
- {\r
- return outputChannels;\r
- }\r
- \r
- /**\r
- * Retrieves the equalizer settings that the decoder's equalizer\r
- * will be initialized from.\r
- * <p>\r
- * The <code>Equalizer</code> instance returned \r
- * cannot be changed in real time to affect the \r
- * decoder output as it is used only to initialize the decoders\r
- * EQ settings. To affect the decoder's output in realtime,\r
- * use the Equalizer returned from the getEqualizer() method on\r
- * the decoder. \r
- * \r
- * @return The <code>Equalizer</code> used to initialize the\r
- * EQ settings of the decoder. \r
- */\r
- public Equalizer getInitialEqualizerSettings()\r
- {\r
- return equalizer; \r
- }\r
- \r
- };\r
-}\r
+@LATTICE("ST,DE<OUT,DE<FIL,DE<LA,O,EQ,PA,INIT,DE*")\r
+public class Decoder implements DecoderErrors {\r
+ static private final Params DEFAULT_PARAMS = new Params();\r
+\r
+ /**\r
+ * The Bistream from which the MPEG audio frames are read.\r
+ */\r
+ @LOC("ST")\r
+ private Bitstream stream;\r
+\r
+ /**\r
+ * The Obuffer instance that will receive the decoded PCM samples.\r
+ */\r
+ @LOC("OUT")\r
+ private Obuffer output;\r
+\r
+ /**\r
+ * Synthesis filter for the left channel.\r
+ */\r
+ @LOC("FIL")\r
+ private SynthesisFilter filter1;\r
+\r
+ /**\r
+ * Sythesis filter for the right channel.\r
+ */\r
+ @LOC("FIL")\r
+ private SynthesisFilter filter2;\r
+\r
+ /**\r
+ * The decoder used to decode layer III frames.\r
+ */\r
+ @LOC("DE")\r
+ private LayerIIIDecoder l3decoder;\r
+ @LOC("DE")\r
+ private LayerIIDecoder l2decoder;\r
+ @LOC("DE")\r
+ private LayerIDecoder l1decoder;\r
+\r
+ @LOC("O")\r
+ private int outputFrequency;\r
+ @LOC("O")\r
+ private int outputChannels;\r
+\r
+ @LOC("EQ")\r
+ private Equalizer equalizer = new Equalizer();\r
+\r
+ @LOC("PA")\r
+ private Params params;\r
+\r
+ @LOC("INIT")\r
+ private boolean initialized;\r
+\r
+ /**\r
+ * Creates a new <code>Decoder</code> instance with default parameters.\r
+ */\r
+\r
+ public Decoder() {\r
+ this(null);\r
+ }\r
+\r
+ /**\r
+ * Creates a new <code>Decoder</code> instance with default parameters.\r
+ * \r
+ * @param params\r
+ * The <code>Params</code> instance that describes the customizable\r
+ * aspects of the decoder.\r
+ */\r
+ public Decoder(Params params0) {\r
+ if (params0 == null)\r
+ params0 = DEFAULT_PARAMS;\r
+\r
+ params = params0;\r
+\r
+ Equalizer eq = params.getInitialEqualizerSettings();\r
+ if (eq != null) {\r
+ equalizer.setFrom(eq);\r
+ }\r
+ }\r
+\r
+ static public Params getDefaultParams() {\r
+ return (Params) DEFAULT_PARAMS.clone();\r
+ }\r
+\r
+ public void setEqualizer(Equalizer eq) {\r
+ if (eq == null)\r
+ eq = Equalizer.PASS_THRU_EQ;\r
+\r
+ equalizer.setFrom(eq);\r
+\r
+ float[] factors = equalizer.getBandFactors();\r
+\r
+ if (filter1 != null)\r
+ filter1.setEQ(factors);\r
+\r
+ if (filter2 != null)\r
+ filter2.setEQ(factors);\r
+ }\r
+\r
+ /**\r
+ * Decodes one frame from an MPEG audio bitstream.\r
+ * \r
+ * @param header\r
+ * The header describing the frame to decode.\r
+ * @param bitstream\r
+ * The bistream that provides the bits for te body of the frame.\r
+ * \r
+ * @return A SampleBuffer containing the decoded samples.\r
+ */\r
+ @LATTICE("O<DE,DE<TH,TH<IN,THISLOC=TH")\r
+ @RETURNLOC("O")\r
+ public Obuffer decodeFrame(@LOC("IN") Header header, @LOC("IN") Bitstream stream)\r
+ throws DecoderException {\r
+\r
+ if (!initialized) {\r
+ initialize(header);\r
+ }\r
+\r
+ @LOC("TH") int layer = header.layer();\r
+\r
+ output.clear_buffer();\r
+\r
+ @LOC("DE,Decoder.DE") FrameDecoder decoder = retrieveDecoder(header, stream, layer); // return\r
+ // ceil=DELTA(TH)\r
+ decoder.decodeFrame();\r
+\r
+ // if (layer == 3) {\r
+ // if (l3decoder == null) {\r
+ // l3decoder =\r
+ // new LayerIIIDecoder(stream, header, filter1, filter2, output,\r
+ // OutputChannels.BOTH_CHANNELS);\r
+ // }\r
+ // l3decoder.decodeFrame();\r
+ // } else if (layer == 2) {\r
+ // if (l2decoder == null) {\r
+ // l2decoder = new LayerIIDecoder();\r
+ // l2decoder.create(stream, header, filter1, filter2, output,\r
+ // OutputChannels.BOTH_CHANNELS);\r
+ // }\r
+ // l2decoder.decodeFrame();\r
+ // } else {\r
+ // if (l1decoder == null) {\r
+ // l1decoder = new LayerIDecoder();\r
+ // l1decoder.create(stream, header, filter1, filter2, output,\r
+ // OutputChannels.BOTH_CHANNELS);\r
+ // }\r
+ // l1decoder.decodeFrame();\r
+ // }\r
+\r
+ output.write_buffer(1);\r