diff options
Diffstat (limited to 'songdbj/javazoom/jl/decoder/Decoder.java')
-rw-r--r-- | songdbj/javazoom/jl/decoder/Decoder.java | 357 |
1 files changed, 0 insertions, 357 deletions
diff --git a/songdbj/javazoom/jl/decoder/Decoder.java b/songdbj/javazoom/jl/decoder/Decoder.java deleted file mode 100644 index 076f9dea27..0000000000 --- a/songdbj/javazoom/jl/decoder/Decoder.java +++ /dev/null | |||
@@ -1,357 +0,0 @@ | |||
1 | /* | ||
2 | * 11/19/04 1.0 moved to LGPL. | ||
3 | * 01/12/99 Initial version. mdm@techie.com | ||
4 | *----------------------------------------------------------------------- | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU Library General Public License as published | ||
7 | * by the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Library General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Library General Public | ||
16 | * License along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | *---------------------------------------------------------------------- | ||
19 | */ | ||
20 | |||
21 | package javazoom.jl.decoder; | ||
22 | |||
23 | /** | ||
24 | * The <code>Decoder</code> class encapsulates the details of | ||
25 | * decoding an MPEG audio frame. | ||
26 | * | ||
27 | * @author MDM | ||
28 | * @version 0.0.7 12/12/99 | ||
29 | * @since 0.0.5 | ||
30 | */ | ||
31 | public class Decoder implements DecoderErrors | ||
32 | { | ||
33 | static private final Params DEFAULT_PARAMS = new Params(); | ||
34 | |||
35 | /** | ||
36 | * The Bistream from which the MPEG audio frames are read. | ||
37 | */ | ||
38 | //private Bitstream stream; | ||
39 | |||
40 | /** | ||
41 | * The Obuffer instance that will receive the decoded | ||
42 | * PCM samples. | ||
43 | */ | ||
44 | private Obuffer output; | ||
45 | |||
46 | /** | ||
47 | * Synthesis filter for the left channel. | ||
48 | */ | ||
49 | private SynthesisFilter filter1; | ||
50 | |||
51 | /** | ||
52 | * Sythesis filter for the right channel. | ||
53 | */ | ||
54 | private SynthesisFilter filter2; | ||
55 | |||
56 | /** | ||
57 | * The decoder used to decode layer III frames. | ||
58 | */ | ||
59 | private LayerIIIDecoder l3decoder; | ||
60 | private LayerIIDecoder l2decoder; | ||
61 | private LayerIDecoder l1decoder; | ||
62 | |||
63 | private int outputFrequency; | ||
64 | private int outputChannels; | ||
65 | |||
66 | private Equalizer equalizer = new Equalizer(); | ||
67 | |||
68 | private Params params; | ||
69 | |||
70 | private boolean initialized; | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Creates a new <code>Decoder</code> instance with default | ||
75 | * parameters. | ||
76 | */ | ||
77 | |||
78 | public Decoder() | ||
79 | { | ||
80 | this(null); | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * Creates a new <code>Decoder</code> instance with default | ||
85 | * parameters. | ||
86 | * | ||
87 | * @param params The <code>Params</code> instance that describes | ||
88 | * the customizable aspects of the decoder. | ||
89 | */ | ||
90 | public Decoder(Params params0) | ||
91 | { | ||
92 | if (params0==null) | ||
93 | params0 = DEFAULT_PARAMS; | ||
94 | |||
95 | params = params0; | ||
96 | |||
97 | Equalizer eq = params.getInitialEqualizerSettings(); | ||
98 | if (eq!=null) | ||
99 | { | ||
100 | equalizer.setFrom(eq); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static public Params getDefaultParams() | ||
105 | { | ||
106 | return (Params)DEFAULT_PARAMS.clone(); | ||
107 | } | ||
108 | |||
109 | public void setEqualizer(Equalizer eq) | ||
110 | { | ||
111 | if (eq==null) | ||
112 | eq = Equalizer.PASS_THRU_EQ; | ||
113 | |||
114 | equalizer.setFrom(eq); | ||
115 | |||
116 | float[] factors = equalizer.getBandFactors(); | ||
117 | |||
118 | if (filter1!=null) | ||
119 | filter1.setEQ(factors); | ||
120 | |||
121 | if (filter2!=null) | ||
122 | filter2.setEQ(factors); | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * Decodes one frame from an MPEG audio bitstream. | ||
127 | * | ||
128 | * @param header The header describing the frame to decode. | ||
129 | * @param bitstream The bistream that provides the bits for te body of the frame. | ||
130 | * | ||
131 | * @return A SampleBuffer containing the decoded samples. | ||
132 | */ | ||
133 | public Obuffer decodeFrame(Header header, Bitstream stream) | ||
134 | throws DecoderException | ||
135 | { | ||
136 | if (!initialized) | ||
137 | { | ||
138 | initialize(header); | ||
139 | } | ||
140 | |||
141 | int layer = header.layer(); | ||
142 | |||
143 | output.clear_buffer(); | ||
144 | |||
145 | FrameDecoder decoder = retrieveDecoder(header, stream, layer); | ||
146 | |||
147 | decoder.decodeFrame(); | ||
148 | |||
149 | output.write_buffer(1); | ||
150 | |||
151 | return output; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * Changes the output buffer. This will take effect the next time | ||
156 | * decodeFrame() is called. | ||
157 | */ | ||
158 | public void setOutputBuffer(Obuffer out) | ||
159 | { | ||
160 | output = out; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Retrieves the sample frequency of the PCM samples output | ||
165 | * by this decoder. This typically corresponds to the sample | ||
166 | * rate encoded in the MPEG audio stream. | ||
167 | * | ||
168 | * @param the sample rate (in Hz) of the samples written to the | ||
169 | * output buffer when decoding. | ||
170 | */ | ||
171 | public int getOutputFrequency() | ||
172 | { | ||
173 | return outputFrequency; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * Retrieves the number of channels of PCM samples output by | ||
178 | * this decoder. This usually corresponds to the number of | ||
179 | * channels in the MPEG audio stream, although it may differ. | ||
180 | * | ||
181 | * @return The number of output channels in the decoded samples: 1 | ||
182 | * for mono, or 2 for stereo. | ||
183 | * | ||
184 | */ | ||
185 | public int getOutputChannels() | ||
186 | { | ||
187 | return outputChannels; | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Retrieves the maximum number of samples that will be written to | ||
192 | * the output buffer when one frame is decoded. This can be used to | ||
193 | * help calculate the size of other buffers whose size is based upon | ||
194 | * the number of samples written to the output buffer. NB: this is | ||
195 | * an upper bound and fewer samples may actually be written, depending | ||
196 | * upon the sample rate and number of channels. | ||
197 | * | ||
198 | * @return The maximum number of samples that are written to the | ||
199 | * output buffer when decoding a single frame of MPEG audio. | ||
200 | */ | ||
201 | public int getOutputBlockSize() | ||
202 | { | ||
203 | return Obuffer.OBUFFERSIZE; | ||
204 | } | ||
205 | |||
206 | |||
207 | protected DecoderException newDecoderException(int errorcode) | ||
208 | { | ||
209 | return new DecoderException(errorcode, null); | ||
210 | } | ||
211 | |||
212 | protected DecoderException newDecoderException(int errorcode, Throwable throwable) | ||
213 | { | ||
214 | return new DecoderException(errorcode, throwable); | ||
215 | } | ||
216 | |||
217 | protected FrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer) | ||
218 | throws DecoderException | ||
219 | { | ||
220 | FrameDecoder decoder = null; | ||
221 | |||
222 | // REVIEW: allow channel output selection type | ||
223 | // (LEFT, RIGHT, BOTH, DOWNMIX) | ||
224 | switch (layer) | ||
225 | { | ||
226 | case 3: | ||
227 | if (l3decoder==null) | ||
228 | { | ||
229 | l3decoder = new LayerIIIDecoder(stream, | ||
230 | header, filter1, filter2, | ||
231 | output, OutputChannels.BOTH_CHANNELS); | ||
232 | } | ||
233 | |||
234 | decoder = l3decoder; | ||
235 | break; | ||
236 | case 2: | ||
237 | if (l2decoder==null) | ||
238 | { | ||
239 | l2decoder = new LayerIIDecoder(); | ||
240 | l2decoder.create(stream, | ||
241 | header, filter1, filter2, | ||
242 | output, OutputChannels.BOTH_CHANNELS); | ||
243 | } | ||
244 | decoder = l2decoder; | ||
245 | break; | ||
246 | case 1: | ||
247 | if (l1decoder==null) | ||
248 | { | ||
249 | l1decoder = new LayerIDecoder(); | ||
250 | l1decoder.create(stream, | ||
251 | header, filter1, filter2, | ||
252 | output, OutputChannels.BOTH_CHANNELS); | ||
253 | } | ||
254 | decoder = l1decoder; | ||
255 | break; | ||
256 | } | ||
257 | |||
258 | if (decoder==null) | ||
259 | { | ||
260 | throw newDecoderException(UNSUPPORTED_LAYER, null); | ||
261 | } | ||
262 | |||
263 | return decoder; | ||
264 | } | ||
265 | |||
266 | private void initialize(Header header) | ||
267 | throws DecoderException | ||
268 | { | ||
269 | |||
270 | // REVIEW: allow customizable scale factor | ||
271 | float scalefactor = 32700.0f; | ||
272 | |||
273 | int mode = header.mode(); | ||
274 | int layer = header.layer(); | ||
275 | int channels = mode==Header.SINGLE_CHANNEL ? 1 : 2; | ||
276 | |||
277 | |||
278 | // set up output buffer if not set up by client. | ||
279 | if (output==null) | ||
280 | output = new SampleBuffer(header.frequency(), channels); | ||
281 | |||
282 | float[] factors = equalizer.getBandFactors(); | ||
283 | filter1 = new SynthesisFilter(0, scalefactor, factors); | ||
284 | |||
285 | // REVIEW: allow mono output for stereo | ||
286 | if (channels==2) | ||
287 | filter2 = new SynthesisFilter(1, scalefactor, factors); | ||
288 | |||
289 | outputChannels = channels; | ||
290 | outputFrequency = header.frequency(); | ||
291 | |||
292 | initialized = true; | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * The <code>Params</code> class presents the customizable | ||
297 | * aspects of the decoder. | ||
298 | * <p> | ||
299 | * Instances of this class are not thread safe. | ||
300 | */ | ||
301 | public static class Params implements Cloneable | ||
302 | { | ||
303 | private OutputChannels outputChannels = OutputChannels.BOTH; | ||
304 | |||
305 | private Equalizer equalizer = new Equalizer(); | ||
306 | |||
307 | public Params() | ||
308 | { | ||
309 | } | ||
310 | |||
311 | public Object clone() | ||
312 | { | ||
313 | try | ||
314 | { | ||
315 | return super.clone(); | ||
316 | } | ||
317 | catch (CloneNotSupportedException ex) | ||
318 | { | ||
319 | throw new InternalError(this+": "+ex); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | public void setOutputChannels(OutputChannels out) | ||
324 | { | ||
325 | if (out==null) | ||
326 | throw new NullPointerException("out"); | ||
327 | |||
328 | outputChannels = out; | ||
329 | } | ||
330 | |||
331 | public OutputChannels getOutputChannels() | ||
332 | { | ||
333 | return outputChannels; | ||
334 | } | ||
335 | |||
336 | /** | ||
337 | * Retrieves the equalizer settings that the decoder's equalizer | ||
338 | * will be initialized from. | ||
339 | * <p> | ||
340 | * The <code>Equalizer</code> instance returned | ||
341 | * cannot be changed in real time to affect the | ||
342 | * decoder output as it is used only to initialize the decoders | ||
343 | * EQ settings. To affect the decoder's output in realtime, | ||
344 | * use the Equalizer returned from the getEqualizer() method on | ||
345 | * the decoder. | ||
346 | * | ||
347 | * @return The <code>Equalizer</code> used to initialize the | ||
348 | * EQ settings of the decoder. | ||
349 | */ | ||
350 | public Equalizer getInitialEqualizerSettings() | ||
351 | { | ||
352 | return equalizer; | ||
353 | } | ||
354 | |||
355 | }; | ||
356 | } | ||
357 | |||