summaryrefslogtreecommitdiff
path: root/songdbj/javazoom
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/javazoom')
-rw-r--r--songdbj/javazoom/jl/converter/Converter.java411
-rw-r--r--songdbj/javazoom/jl/converter/RiffFile.java495
-rw-r--r--songdbj/javazoom/jl/converter/WaveFile.java522
-rw-r--r--songdbj/javazoom/jl/converter/WaveFileObuffer.java141
-rw-r--r--songdbj/javazoom/jl/converter/jlc.java216
-rw-r--r--songdbj/javazoom/jl/decoder/BitReserve.java223
-rw-r--r--songdbj/javazoom/jl/decoder/Bitstream.java655
-rw-r--r--songdbj/javazoom/jl/decoder/BitstreamErrors.java72
-rw-r--r--songdbj/javazoom/jl/decoder/BitstreamException.java71
-rw-r--r--songdbj/javazoom/jl/decoder/Control.java57
-rw-r--r--songdbj/javazoom/jl/decoder/Crc16.java70
-rw-r--r--songdbj/javazoom/jl/decoder/Decoder.java357
-rw-r--r--songdbj/javazoom/jl/decoder/DecoderErrors.java38
-rw-r--r--songdbj/javazoom/jl/decoder/DecoderException.java61
-rw-r--r--songdbj/javazoom/jl/decoder/Equalizer.java227
-rw-r--r--songdbj/javazoom/jl/decoder/FrameDecoder.java38
-rw-r--r--songdbj/javazoom/jl/decoder/Header.java762
-rw-r--r--songdbj/javazoom/jl/decoder/InputStreamSource.java80
-rw-r--r--songdbj/javazoom/jl/decoder/JavaLayerError.java31
-rw-r--r--songdbj/javazoom/jl/decoder/JavaLayerErrors.java40
-rw-r--r--songdbj/javazoom/jl/decoder/JavaLayerException.java80
-rw-r--r--songdbj/javazoom/jl/decoder/JavaLayerHook.java36
-rw-r--r--songdbj/javazoom/jl/decoder/JavaLayerUtils.java207
-rw-r--r--songdbj/javazoom/jl/decoder/LayerIDecoder.java444
-rw-r--r--songdbj/javazoom/jl/decoder/LayerIIDecoder.java1064
-rw-r--r--songdbj/javazoom/jl/decoder/LayerIIIDecoder.java2439
-rw-r--r--songdbj/javazoom/jl/decoder/Manager.java46
-rw-r--r--songdbj/javazoom/jl/decoder/Obuffer.java88
-rw-r--r--songdbj/javazoom/jl/decoder/OutputChannels.java143
-rw-r--r--songdbj/javazoom/jl/decoder/SampleBuffer.java132
-rw-r--r--songdbj/javazoom/jl/decoder/Source.java49
-rw-r--r--songdbj/javazoom/jl/decoder/SynthesisFilter.java1817
-rw-r--r--songdbj/javazoom/jl/decoder/au2lin.serbin0 -> 539 bytes
-rw-r--r--songdbj/javazoom/jl/decoder/huffcodetab.java600
-rw-r--r--songdbj/javazoom/jl/decoder/l3reorder.serbin0 -> 13925 bytes
-rw-r--r--songdbj/javazoom/jl/decoder/lin2au.serbin0 -> 16411 bytes
-rw-r--r--songdbj/javazoom/jl/decoder/readme.txt15
-rw-r--r--songdbj/javazoom/jl/decoder/sfd.serbin0 -> 2075 bytes
-rw-r--r--songdbj/javazoom/jl/player/AudioDevice.java103
-rw-r--r--songdbj/javazoom/jl/player/AudioDeviceBase.java177
-rw-r--r--songdbj/javazoom/jl/player/AudioDeviceFactory.java87
-rw-r--r--songdbj/javazoom/jl/player/FactoryRegistry.java129
-rw-r--r--songdbj/javazoom/jl/player/JavaSoundAudioDevice.java215
-rw-r--r--songdbj/javazoom/jl/player/JavaSoundAudioDeviceFactory.java85
-rw-r--r--songdbj/javazoom/jl/player/NullAudioDevice.java37
-rw-r--r--songdbj/javazoom/jl/player/Player.java251
-rw-r--r--songdbj/javazoom/jl/player/PlayerApplet.java246
-rw-r--r--songdbj/javazoom/jl/player/advanced/AdvancedPlayer.java242
-rw-r--r--songdbj/javazoom/jl/player/advanced/PlaybackEvent.java51
-rw-r--r--songdbj/javazoom/jl/player/advanced/PlaybackListener.java30
-rw-r--r--songdbj/javazoom/jl/player/advanced/jlap.java116
-rw-r--r--songdbj/javazoom/jl/player/jlp.java176
-rw-r--r--songdbj/javazoom/spi/PropertiesContainer.java31
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/convert/DecodedMpegAudioInputStream.java334
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/convert/MpegFormatConversionProvider.java120
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/IcyListener.java131
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileFormat.java103
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java772
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFormat.java67
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/MpegEncoding.java47
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/MpegFileFormatType.java40
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyInputStream.java412
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyTag.java42
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3MetadataParser.java50
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3Tag.java52
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3TagParseSupport.java62
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/StringableTag.java36
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseEvent.java44
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseListener.java37
-rw-r--r--songdbj/javazoom/spi/vorbis/sampled/convert/DecodedVorbisAudioInputStream.java519
-rw-r--r--songdbj/javazoom/spi/vorbis/sampled/convert/VorbisFormatConversionProvider.java244
-rw-r--r--songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileFormat.java85
-rw-r--r--songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileReader.java502
-rw-r--r--songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFormat.java66
-rw-r--r--songdbj/javazoom/spi/vorbis/sampled/file/VorbisEncoding.java41
-rw-r--r--songdbj/javazoom/spi/vorbis/sampled/file/VorbisFileFormatType.java41
76 files changed, 17550 insertions, 0 deletions
diff --git a/songdbj/javazoom/jl/converter/Converter.java b/songdbj/javazoom/jl/converter/Converter.java
new file mode 100644
index 0000000000..845082e626
--- /dev/null
+++ b/songdbj/javazoom/jl/converter/Converter.java
@@ -0,0 +1,411 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/12/99 Original verion. 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
21package javazoom.jl.converter;
22
23import java.io.BufferedInputStream;
24import java.io.File;
25import java.io.FileInputStream;
26import java.io.IOException;
27import java.io.InputStream;
28import java.io.PrintWriter;
29
30import javazoom.jl.decoder.Bitstream;
31import javazoom.jl.decoder.Decoder;
32import javazoom.jl.decoder.Header;
33import javazoom.jl.decoder.JavaLayerException;
34import javazoom.jl.decoder.Obuffer;
35
36/**
37 * The <code>Converter</code> class implements the conversion of
38 * an MPEG audio file to a .WAV file. To convert an MPEG audio stream,
39 * just create an instance of this class and call the convert()
40 * method, passing in the names of the input and output files. You can
41 * pass in optional <code>ProgressListener</code> and
42 * <code>Decoder.Params</code> objects also to customize the conversion.
43 *
44 * @author MDM 12/12/99
45 * @since 0.0.7
46 */
47public class Converter
48{
49 /**
50 * Creates a new converter instance.
51 */
52 public Converter()
53 {
54 }
55
56 public synchronized void convert(String sourceName, String destName)
57 throws JavaLayerException
58 {
59 convert(sourceName, destName, null, null);
60 }
61
62 public synchronized void convert(String sourceName, String destName,
63 ProgressListener progressListener)
64 throws JavaLayerException
65 {
66 convert(sourceName, destName, progressListener, null);
67 }
68
69
70 public void convert(String sourceName, String destName,
71 ProgressListener progressListener, Decoder.Params decoderParams)
72 throws JavaLayerException
73 {
74 if (destName.length()==0)
75 destName = null;
76 try {
77 InputStream in = openInput(sourceName);
78 convert(in, destName, progressListener, decoderParams);
79 in.close();
80 } catch(IOException ioe) {
81 throw new JavaLayerException(ioe.getLocalizedMessage(), ioe);
82 }
83 }
84
85 public synchronized void convert(InputStream sourceStream, String destName,
86 ProgressListener progressListener, Decoder.Params decoderParams)
87 throws JavaLayerException
88 {
89 if (progressListener==null)
90 progressListener = PrintWriterProgressListener.newStdOut(
91 PrintWriterProgressListener.NO_DETAIL);
92 try {
93 if (!(sourceStream instanceof BufferedInputStream))
94 sourceStream = new BufferedInputStream(sourceStream);
95 int frameCount = -1;
96 if (sourceStream.markSupported()) {
97 sourceStream.mark(-1);
98 frameCount = countFrames(sourceStream);
99 sourceStream.reset();
100 }
101 progressListener.converterUpdate(ProgressListener.UPDATE_FRAME_COUNT, frameCount, 0);
102
103
104 Obuffer output = null;
105 Decoder decoder = new Decoder(decoderParams);
106 Bitstream stream = new Bitstream(sourceStream);
107
108 if (frameCount==-1)
109 frameCount = Integer.MAX_VALUE;
110
111 int frame = 0;
112 long startTime = System.currentTimeMillis();
113
114 try
115 {
116 for (; frame<frameCount; frame++)
117 {
118 try
119 {
120 Header header = stream.readFrame();
121 if (header==null)
122 break;
123
124 progressListener.readFrame(frame, header);
125
126 if (output==null)
127 {
128 // REVIEW: Incorrect functionality.
129 // the decoder should provide decoded
130 // frequency and channels output as it may differ from
131 // the source (e.g. when downmixing stereo to mono.)
132 int channels = (header.mode()==Header.SINGLE_CHANNEL) ? 1 : 2;
133 int freq = header.frequency();
134 output = new WaveFileObuffer(channels, freq, destName);
135 decoder.setOutputBuffer(output);
136 }
137
138 Obuffer decoderOutput = decoder.decodeFrame(header, stream);
139
140 // REVIEW: the way the output buffer is set
141 // on the decoder is a bit dodgy. Even though
142 // this exception should never happen, we test to be sure.
143 if (decoderOutput!=output)
144 throw new InternalError("Output buffers are different.");
145
146
147 progressListener.decodedFrame(frame, header, output);
148
149 stream.closeFrame();
150
151 }
152 catch (Exception ex)
153 {
154 boolean stop = !progressListener.converterException(ex);
155
156 if (stop)
157 {
158 throw new JavaLayerException(ex.getLocalizedMessage(), ex);
159 }
160 }
161 }
162
163 }
164 finally
165 {
166
167 if (output!=null)
168 output.close();
169 }
170
171 int time = (int)(System.currentTimeMillis()-startTime);
172 progressListener.converterUpdate(ProgressListener.UPDATE_CONVERT_COMPLETE,
173 time, frame);
174 }
175 catch (IOException ex)
176 {
177 throw new JavaLayerException(ex.getLocalizedMessage(), ex);
178 }
179 }
180
181
182 protected int countFrames(InputStream in)
183 {
184 return -1;
185 }
186
187
188 protected InputStream openInput(String fileName)
189 throws IOException
190 {
191 // ensure name is abstract path name
192 File file = new File(fileName);
193 InputStream fileIn = new FileInputStream(file);
194 BufferedInputStream bufIn = new BufferedInputStream(fileIn);
195
196 return bufIn;
197 }
198
199
200 /**
201 * This interface is used by the Converter to provide
202 * notification of tasks being carried out by the converter,
203 * and to provide new information as it becomes available.
204 */
205
206 static public interface ProgressListener
207 {
208 public static final int UPDATE_FRAME_COUNT = 1;
209
210 /**
211 * Conversion is complete. Param1 contains the time
212 * to convert in milliseconds. Param2 contains the number
213 * of MPEG audio frames converted.
214 */
215 public static final int UPDATE_CONVERT_COMPLETE = 2;
216
217
218 /**
219 * Notifies the listener that new information is available.
220 *
221 * @param updateID Code indicating the information that has been
222 * updated.
223 *
224 * @param param1 Parameter whose value depends upon the update code.
225 * @param param2 Parameter whose value depends upon the update code.
226 *
227 * The <code>updateID</code> parameter can take these values:
228 *
229 * UPDATE_FRAME_COUNT: param1 is the frame count, or -1 if not known.
230 * UPDATE_CONVERT_COMPLETE: param1 is the conversion time, param2
231 * is the number of frames converted.
232 */
233 public void converterUpdate(int updateID, int param1, int param2);
234
235 /**
236 * If the converter wishes to make a first pass over the
237 * audio frames, this is called as each frame is parsed.
238 */
239 public void parsedFrame(int frameNo, Header header);
240
241 /**
242 * This method is called after each frame has been read,
243 * but before it has been decoded.
244 *
245 * @param frameNo The 0-based sequence number of the frame.
246 * @param header The Header rerpesenting the frame just read.
247 */
248 public void readFrame(int frameNo, Header header);
249
250 /**
251 * This method is called after a frame has been decoded.
252 *
253 * @param frameNo The 0-based sequence number of the frame.
254 * @param header The Header rerpesenting the frame just read.
255 * @param o The Obuffer the deocded data was written to.
256 */
257 public void decodedFrame(int frameNo, Header header, Obuffer o);
258
259 /**
260 * Called when an exception is thrown during while converting
261 * a frame.
262 *
263 * @param t The <code>Throwable</code> instance that
264 * was thrown.
265 *
266 * @return <code>true</code> to continue processing, or false
267 * to abort conversion.
268 *
269 * If this method returns <code>false</code>, the exception
270 * is propagated to the caller of the convert() method. If
271 * <code>true</code> is returned, the exception is silently
272 * ignored and the converter moves onto the next frame.
273 */
274 public boolean converterException(Throwable t);
275
276 }
277
278
279 /**
280 * Implementation of <code>ProgressListener</code> that writes
281 * notification text to a <code>PrintWriter</code>.
282 */
283 // REVIEW: i18n of text and order required.
284 static public class PrintWriterProgressListener implements ProgressListener
285 {
286 static public final int NO_DETAIL = 0;
287
288 /**
289 * Level of detail typically expected of expert
290 * users.
291 */
292 static public final int EXPERT_DETAIL = 1;
293
294 /**
295 * Verbose detail.
296 */
297 static public final int VERBOSE_DETAIL = 2;
298
299 /**
300 * Debug detail. All frame read notifications are shown.
301 */
302 static public final int DEBUG_DETAIL = 7;
303
304 static public final int MAX_DETAIL = 10;
305
306 private PrintWriter pw;
307
308 private int detailLevel;
309
310 static public PrintWriterProgressListener newStdOut(int detail)
311 {
312 return new PrintWriterProgressListener(
313 new PrintWriter(System.out, true), detail);
314 }
315
316 public PrintWriterProgressListener(PrintWriter writer, int detailLevel)
317 {
318 this.pw = writer;
319 this.detailLevel = detailLevel;
320 }
321
322
323 public boolean isDetail(int detail)
324 {
325 return (this.detailLevel >= detail);
326 }
327
328 public void converterUpdate(int updateID, int param1, int param2)
329 {
330 if (isDetail(VERBOSE_DETAIL))
331 {
332 switch (updateID)
333 {
334 case UPDATE_CONVERT_COMPLETE:
335 // catch divide by zero errors.
336 if (param2==0)
337 param2 = 1;
338
339 pw.println();
340 pw.println("Converted "+param2+" frames in "+param1+" ms ("+
341 (param1/param2)+" ms per frame.)");
342 }
343 }
344 }
345
346 public void parsedFrame(int frameNo, Header header)
347 {
348 if ((frameNo==0) && isDetail(VERBOSE_DETAIL))
349 {
350 String headerString = header.toString();
351 pw.println("File is a "+headerString);
352 }
353 else if (isDetail(MAX_DETAIL))
354 {
355 String headerString = header.toString();
356 pw.println("Prased frame "+frameNo+": "+headerString);
357 }
358 }
359
360 public void readFrame(int frameNo, Header header)
361 {
362 if ((frameNo==0) && isDetail(VERBOSE_DETAIL))
363 {
364 String headerString = header.toString();
365 pw.println("File is a "+headerString);
366 }
367 else if (isDetail(MAX_DETAIL))
368 {
369 String headerString = header.toString();
370 pw.println("Read frame "+frameNo+": "+headerString);
371 }
372 }
373
374 public void decodedFrame(int frameNo, Header header, Obuffer o)
375 {
376 if (isDetail(MAX_DETAIL))
377 {
378 String headerString = header.toString();
379 pw.println("Decoded frame "+frameNo+": "+headerString);
380 pw.println("Output: "+o);
381 }
382 else if (isDetail(VERBOSE_DETAIL))
383 {
384 if (frameNo==0)
385 {
386 pw.print("Converting.");
387 pw.flush();
388 }
389
390 if ((frameNo % 10)==0)
391 {
392 pw.print('.');
393 pw.flush();
394 }
395 }
396 }
397
398 public boolean converterException(Throwable t)
399 {
400 if (this.detailLevel>NO_DETAIL)
401 {
402 t.printStackTrace(pw);
403 pw.flush();
404 }
405 return false;
406 }
407
408 }
409
410
411} \ No newline at end of file
diff --git a/songdbj/javazoom/jl/converter/RiffFile.java b/songdbj/javazoom/jl/converter/RiffFile.java
new file mode 100644
index 0000000000..fb5d9e53c6
--- /dev/null
+++ b/songdbj/javazoom/jl/converter/RiffFile.java
@@ -0,0 +1,495 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 02/23/99 JavaConversion by E.B
4 * Don Cross, April 1993.
5 * RIFF file format classes.
6 * See Chapter 8 of "Multimedia Programmer's Reference" in
7 * the Microsoft Windows SDK.
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.jl.converter;
27
28import java.io.IOException;
29import java.io.RandomAccessFile;
30
31
32/**
33 * Class to manage RIFF files
34 */
35public class RiffFile
36{
37 class RiffChunkHeader
38 {
39 public int ckID = 0; // Four-character chunk ID
40 public int ckSize = 0; // Length of data in chunk
41 public RiffChunkHeader()
42 {}
43 }
44
45
46 // DDCRET
47 public static final int DDC_SUCCESS = 0; // The operation succeded
48 public static final int DDC_FAILURE = 1; // The operation failed for unspecified reasons
49 public static final int DDC_OUT_OF_MEMORY = 2; // Operation failed due to running out of memory
50 public static final int DDC_FILE_ERROR = 3; // Operation encountered file I/O error
51 public static final int DDC_INVALID_CALL = 4; // Operation was called with invalid parameters
52 public static final int DDC_USER_ABORT = 5; // Operation was aborted by the user
53 public static final int DDC_INVALID_FILE = 6; // File format does not match
54
55 // RiffFileMode
56 public static final int RFM_UNKNOWN = 0; // undefined type (can use to mean "N/A" or "not open")
57 public static final int RFM_WRITE = 1; // open for write
58 public static final int RFM_READ = 2; // open for read
59
60 private RiffChunkHeader riff_header; // header for whole file
61 protected int fmode; // current file I/O mode
62 protected RandomAccessFile file; // I/O stream to use
63
64 /**
65 * Dummy Constructor
66 */
67 public RiffFile()
68 {
69 file = null;
70 fmode = RFM_UNKNOWN;
71 riff_header = new RiffChunkHeader();
72
73 riff_header.ckID = FourCC("RIFF");
74 riff_header.ckSize = 0;
75 }
76
77 /**
78 * Return File Mode.
79 */
80 public int CurrentFileMode()
81 {return fmode;}
82
83 /**
84 * Open a RIFF file.
85 */
86 public int Open(String Filename, int NewMode)
87 {
88 int retcode = DDC_SUCCESS;
89
90 if ( fmode != RFM_UNKNOWN )
91 {
92 retcode = Close();
93 }
94
95 if ( retcode == DDC_SUCCESS )
96 {
97 switch ( NewMode )
98 {
99 case RFM_WRITE:
100 try
101 {
102 file = new RandomAccessFile(Filename,"rw");
103
104 try
105 {
106 // Write the RIFF header...
107 // We will have to come back later and patch it!
108 byte[] br = new byte[8];
109 br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF);
110 br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF);
111 br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF);
112 br[3] = (byte) (riff_header.ckID & 0x000000FF);
113
114 byte br4 = (byte) ((riff_header.ckSize >>> 24)& 0x000000FF);
115 byte br5 = (byte) ((riff_header.ckSize >>> 16)& 0x000000FF);
116 byte br6 = (byte) ((riff_header.ckSize >>> 8)& 0x000000FF);
117 byte br7 = (byte) (riff_header.ckSize & 0x000000FF);
118
119 br[4] = br7;
120 br[5] = br6;
121 br[6] = br5;
122 br[7] = br4;
123
124 file.write(br,0,8);
125 fmode = RFM_WRITE;
126 } catch (IOException ioe)
127 {
128 file.close();
129 fmode = RFM_UNKNOWN;
130 }
131 } catch (IOException ioe)
132 {
133 fmode = RFM_UNKNOWN;
134 retcode = DDC_FILE_ERROR;
135 }
136 break;
137
138 case RFM_READ:
139 try
140 {
141 file = new RandomAccessFile(Filename,"r");
142 try
143 {
144 // Try to read the RIFF header...
145 byte[] br = new byte[8];
146 file.read(br,0,8);
147 fmode = RFM_READ;
148 riff_header.ckID = ((br[0]<<24)& 0xFF000000) | ((br[1]<<16)&0x00FF0000) | ((br[2]<<8)&0x0000FF00) | (br[3]&0x000000FF);
149 riff_header.ckSize = ((br[4]<<24)& 0xFF000000) | ((br[5]<<16)&0x00FF0000) | ((br[6]<<8)&0x0000FF00) | (br[7]&0x000000FF);
150 } catch (IOException ioe)
151 {
152 file.close();
153 fmode = RFM_UNKNOWN;
154 }
155 } catch (IOException ioe)
156 {
157 fmode = RFM_UNKNOWN;
158 retcode = DDC_FILE_ERROR;
159 }
160 break;
161 default:
162 retcode = DDC_INVALID_CALL;
163 }
164 }
165 return retcode;
166 }
167
168 /**
169 * Write NumBytes data.
170 */
171 public int Write(byte[] Data, int NumBytes )
172 {
173 if ( fmode != RFM_WRITE )
174 {
175 return DDC_INVALID_CALL;
176 }
177 try
178 {
179 file.write(Data,0,NumBytes);
180 fmode = RFM_WRITE;
181 }
182 catch (IOException ioe)
183 {
184 return DDC_FILE_ERROR;
185 }
186 riff_header.ckSize += NumBytes;
187 return DDC_SUCCESS;
188 }
189
190
191
192 /**
193 * Write NumBytes data.
194 */
195 public int Write(short[] Data, int NumBytes )
196 {
197 byte[] theData = new byte[NumBytes];
198 int yc = 0;
199 for (int y = 0;y<NumBytes;y=y+2)
200 {
201 theData[y] = (byte) (Data[yc] & 0x00FF);
202 theData[y+1] =(byte) ((Data[yc++] >>> 8) & 0x00FF);
203 }
204 if ( fmode != RFM_WRITE )
205 {
206 return DDC_INVALID_CALL;
207 }
208 try
209 {
210 file.write(theData,0,NumBytes);
211 fmode = RFM_WRITE;
212 }
213 catch (IOException ioe)
214 {
215 return DDC_FILE_ERROR;
216 }
217 riff_header.ckSize += NumBytes;
218 return DDC_SUCCESS;
219 }
220
221 /**
222 * Write NumBytes data.
223 */
224 public int Write(RiffChunkHeader Triff_header, int NumBytes )
225 {
226 byte[] br = new byte[8];
227 br[0] = (byte) ((Triff_header.ckID >>> 24) & 0x000000FF);
228 br[1] = (byte) ((Triff_header.ckID >>> 16) & 0x000000FF);
229 br[2] = (byte) ((Triff_header.ckID >>> 8) & 0x000000FF);
230 br[3] = (byte) (Triff_header.ckID & 0x000000FF);
231
232 byte br4 = (byte) ((Triff_header.ckSize >>> 24)& 0x000000FF);
233 byte br5 = (byte) ((Triff_header.ckSize >>> 16)& 0x000000FF);
234 byte br6 = (byte) ((Triff_header.ckSize >>> 8)& 0x000000FF);
235 byte br7 = (byte) (Triff_header.ckSize & 0x000000FF);
236
237 br[4] = br7;
238 br[5] = br6;
239 br[6] = br5;
240 br[7] = br4;
241
242 if ( fmode != RFM_WRITE )
243 {
244 return DDC_INVALID_CALL;
245 }
246 try
247 {
248 file.write(br,0,NumBytes);
249 fmode = RFM_WRITE;
250 } catch (IOException ioe)
251 {
252 return DDC_FILE_ERROR;
253 }
254 riff_header.ckSize += NumBytes;
255 return DDC_SUCCESS;
256 }
257
258 /**
259 * Write NumBytes data.
260 */
261 public int Write(short Data, int NumBytes )
262 {
263 short theData = (short) ( ((Data>>>8)&0x00FF) | ((Data<<8)&0xFF00) );
264 if ( fmode != RFM_WRITE )
265 {
266 return DDC_INVALID_CALL;
267 }
268 try
269 {
270 file.writeShort(theData);
271 fmode = RFM_WRITE;
272 } catch (IOException ioe)
273 {
274 return DDC_FILE_ERROR;
275 }
276 riff_header.ckSize += NumBytes;
277 return DDC_SUCCESS;
278 }
279 /**
280 * Write NumBytes data.
281 */
282 public int Write(int Data, int NumBytes )
283 {
284 short theDataL = (short) ((Data>>>16)&0x0000FFFF);
285 short theDataR = (short) (Data&0x0000FFFF);
286 short theDataLI = (short) ( ((theDataL>>>8)&0x00FF) | ((theDataL<<8)&0xFF00) );
287 short theDataRI = (short) ( ((theDataR>>>8)&0x00FF) | ((theDataR<<8)&0xFF00) );
288 int theData = ((theDataRI<<16)&0xFFFF0000) | (theDataLI&0x0000FFFF);
289 if ( fmode != RFM_WRITE )
290 {
291 return DDC_INVALID_CALL;
292 }
293 try
294 {
295 file.writeInt(theData);
296 fmode = RFM_WRITE;
297 } catch (IOException ioe)
298 {
299 return DDC_FILE_ERROR;
300 }
301 riff_header.ckSize += NumBytes;
302 return DDC_SUCCESS;
303 }
304
305
306
307 /**
308 * Read NumBytes data.
309 */
310 public int Read (byte[] Data, int NumBytes)
311 {
312 int retcode = DDC_SUCCESS;
313 try
314 {
315 file.read(Data,0,NumBytes);
316 } catch (IOException ioe)
317 {
318 retcode = DDC_FILE_ERROR;
319 }
320 return retcode;
321 }
322
323 /**
324 * Expect NumBytes data.
325 */
326 public int Expect(String Data, int NumBytes )
327 {
328 byte target = 0;
329 int cnt = 0;
330 try
331 {
332 while ((NumBytes--) != 0)
333 {
334 target = file.readByte();
335 if (target != Data.charAt(cnt++)) return DDC_FILE_ERROR;
336 }
337 } catch (IOException ioe)
338 {
339 return DDC_FILE_ERROR;
340 }
341 return DDC_SUCCESS;
342 }
343
344 /**
345 * Close Riff File.
346 * Length is written too.
347 */
348 public int Close()
349 {
350 int retcode = DDC_SUCCESS;
351
352 switch ( fmode )
353 {
354 case RFM_WRITE:
355 try
356 {
357 file.seek(0);
358 try
359 {
360 byte[] br = new byte[8];
361 br[0] = (byte) ((riff_header.ckID >>> 24) & 0x000000FF);
362 br[1] = (byte) ((riff_header.ckID >>> 16) & 0x000000FF);
363 br[2] = (byte) ((riff_header.ckID >>> 8) & 0x000000FF);
364 br[3] = (byte) (riff_header.ckID & 0x000000FF);
365
366 br[7] = (byte) ((riff_header.ckSize >>> 24)& 0x000000FF);
367 br[6] = (byte) ((riff_header.ckSize >>> 16)& 0x000000FF);
368 br[5] = (byte) ((riff_header.ckSize >>> 8)& 0x000000FF);
369 br[4] = (byte) (riff_header.ckSize & 0x000000FF);
370 file.write(br,0,8);
371 file.close();
372 } catch (IOException ioe)
373 {
374 retcode = DDC_FILE_ERROR;
375 }
376 } catch (IOException ioe)
377 {
378 retcode = DDC_FILE_ERROR;
379 }
380 break;
381
382 case RFM_READ:
383 try
384 {
385 file.close();
386 } catch (IOException ioe)
387 {
388 retcode = DDC_FILE_ERROR;
389 }
390 break;
391 }
392 file = null;
393 fmode = RFM_UNKNOWN;
394 return retcode;
395 }
396
397 /**
398 * Return File Position.
399 */
400 public long CurrentFilePosition()
401 {
402 long position;
403 try
404 {
405 position = file.getFilePointer();
406 } catch (IOException ioe)
407 {
408 position = -1;
409 }
410 return position;
411 }
412
413 /**
414 * Write Data to specified offset.
415 */
416 public int Backpatch (long FileOffset, RiffChunkHeader Data, int NumBytes )
417 {
418 if (file == null)
419 {
420 return DDC_INVALID_CALL;
421 }
422 try
423 {
424 file.seek(FileOffset);
425 } catch (IOException ioe)
426 {
427 return DDC_FILE_ERROR;
428 }
429 return Write ( Data, NumBytes );
430 }
431
432 public int Backpatch (long FileOffset, byte[] Data, int NumBytes )
433 {
434 if (file == null)
435 {
436 return DDC_INVALID_CALL;
437 }
438 try
439 {
440 file.seek(FileOffset);
441 } catch (IOException ioe)
442 {
443 return DDC_FILE_ERROR;
444 }
445 return Write ( Data, NumBytes );
446 }
447
448
449 /**
450 * Seek in the File.
451 */
452 protected int Seek(long offset)
453 {
454 int rc;
455 try
456 {
457 file.seek(offset);
458 rc = DDC_SUCCESS;
459 } catch (IOException ioe)
460 {
461 rc = DDC_FILE_ERROR;
462 }
463 return rc;
464 }
465
466 /**
467 * Error Messages.
468 */
469 private String DDCRET_String(int retcode)
470 {
471 switch ( retcode )
472 {
473 case DDC_SUCCESS: return "DDC_SUCCESS";
474 case DDC_FAILURE: return "DDC_FAILURE";
475 case DDC_OUT_OF_MEMORY: return "DDC_OUT_OF_MEMORY";
476 case DDC_FILE_ERROR: return "DDC_FILE_ERROR";
477 case DDC_INVALID_CALL: return "DDC_INVALID_CALL";
478 case DDC_USER_ABORT: return "DDC_USER_ABORT";
479 case DDC_INVALID_FILE: return "DDC_INVALID_FILE";
480 }
481 return "Unknown Error";
482 }
483
484 /**
485 * Fill the header.
486 */
487 public static int FourCC(String ChunkName)
488 {
489 byte[] p = {0x20,0x20,0x20,0x20};
490 ChunkName.getBytes(0,4,p,0);
491 int ret = (((p[0] << 24)& 0xFF000000) | ((p[1] << 16)&0x00FF0000) | ((p[2] << 8)&0x0000FF00) | (p[3]&0x000000FF));
492 return ret;
493 }
494
495}
diff --git a/songdbj/javazoom/jl/converter/WaveFile.java b/songdbj/javazoom/jl/converter/WaveFile.java
new file mode 100644
index 0000000000..f158d7a39a
--- /dev/null
+++ b/songdbj/javazoom/jl/converter/WaveFile.java
@@ -0,0 +1,522 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 02/23/99 JavaConversion by E.B
4 * Don Cross, April 1993.
5 * RIFF file format classes.
6 * See Chapter 8 of "Multimedia Programmer's Reference" in
7 * the Microsoft Windows SDK.
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.jl.converter;
27
28/**
29 * Class allowing WaveFormat Access
30 */
31public class WaveFile extends RiffFile
32{
33 public static final int MAX_WAVE_CHANNELS = 2;
34
35 class WaveFormat_ChunkData
36 {
37 public short wFormatTag = 0; // Format category (PCM=1)
38 public short nChannels = 0; // Number of channels (mono=1, stereo=2)
39 public int nSamplesPerSec = 0; // Sampling rate [Hz]
40 public int nAvgBytesPerSec = 0;
41 public short nBlockAlign = 0;
42 public short nBitsPerSample = 0;
43
44 public WaveFormat_ChunkData()
45 {
46 wFormatTag = 1; // PCM
47 Config(44100,(short)16,(short)1);
48 }
49
50 public void Config (int NewSamplingRate, short NewBitsPerSample, short NewNumChannels)
51 {
52 nSamplesPerSec = NewSamplingRate;
53 nChannels = NewNumChannels;
54 nBitsPerSample = NewBitsPerSample;
55 nAvgBytesPerSec = (nChannels * nSamplesPerSec * nBitsPerSample) / 8;
56 nBlockAlign = (short) ((nChannels * nBitsPerSample) / 8);
57 }
58 }
59
60
61 class WaveFormat_Chunk
62 {
63 public RiffChunkHeader header;
64 public WaveFormat_ChunkData data;
65
66 public WaveFormat_Chunk()
67 {
68 header = new RiffChunkHeader();
69 data = new WaveFormat_ChunkData();
70 header.ckID = FourCC("fmt ");
71 header.ckSize = 16;
72 }
73
74 public int VerifyValidity()
75 {
76 boolean ret = header.ckID == FourCC("fmt ") &&
77
78 (data.nChannels == 1 || data.nChannels == 2) &&
79
80 data.nAvgBytesPerSec == ( data.nChannels *
81 data.nSamplesPerSec *
82 data.nBitsPerSample ) / 8 &&
83
84 data.nBlockAlign == ( data.nChannels *
85 data.nBitsPerSample ) / 8;
86 if (ret == true) return 1;
87 else return 0;
88 }
89 }
90
91 public class WaveFileSample
92 {
93 public short[] chan;
94
95 public WaveFileSample()
96 {chan = new short[WaveFile.MAX_WAVE_CHANNELS];}
97 }
98
99 private WaveFormat_Chunk wave_format;
100 private RiffChunkHeader pcm_data;
101 private long pcm_data_offset = 0; // offset of 'pcm_data' in output file
102 private int num_samples = 0;
103
104
105 /**
106 * Constructs a new WaveFile instance.
107 */
108 public WaveFile()
109 {
110 pcm_data = new RiffChunkHeader();
111 wave_format = new WaveFormat_Chunk();
112 pcm_data.ckID = FourCC("data");
113 pcm_data.ckSize = 0;
114 num_samples = 0;
115 }
116
117 /**
118 *
119 *
120 public int OpenForRead (String Filename)
121 {
122 // Verify filename parameter as best we can...
123 if (Filename == null)
124 {
125 return DDC_INVALID_CALL;
126 }
127 int retcode = Open ( Filename, RFM_READ );
128
129 if ( retcode == DDC_SUCCESS )
130 {
131 retcode = Expect ( "WAVE", 4 );
132
133 if ( retcode == DDC_SUCCESS )
134 {
135 retcode = Read(wave_format,24);
136
137 if ( retcode == DDC_SUCCESS && !wave_format.VerifyValidity() )
138 {
139 // This isn't standard PCM, so we don't know what it is!
140 retcode = DDC_FILE_ERROR;
141 }
142
143 if ( retcode == DDC_SUCCESS )
144 {
145 pcm_data_offset = CurrentFilePosition();
146
147 // Figure out number of samples from
148 // file size, current file position, and
149 // WAVE header.
150 retcode = Read (pcm_data, 8 );
151 num_samples = filelength(fileno(file)) - CurrentFilePosition();
152 num_samples /= NumChannels();
153 num_samples /= (BitsPerSample() / 8);
154 }
155 }
156 }
157 return retcode;
158 }*/
159
160 /**
161 *
162 */
163 public int OpenForWrite (String Filename, int SamplingRate, short BitsPerSample, short NumChannels)
164 {
165 // Verify parameters...
166 if ( (Filename==null) ||
167 (BitsPerSample != 8 && BitsPerSample != 16) ||
168 NumChannels < 1 || NumChannels > 2 )
169 {
170 return DDC_INVALID_CALL;
171 }
172
173 wave_format.data.Config ( SamplingRate, BitsPerSample, NumChannels );
174
175 int retcode = Open ( Filename, RFM_WRITE );
176
177 if ( retcode == DDC_SUCCESS )
178 {
179 byte [] theWave = {(byte)'W',(byte)'A',(byte)'V',(byte)'E'};
180 retcode = Write ( theWave, 4 );
181
182 if ( retcode == DDC_SUCCESS )
183 {
184 // Ecriture de wave_format
185 retcode = Write (wave_format.header, 8);
186 retcode = Write (wave_format.data.wFormatTag, 2);
187 retcode = Write (wave_format.data.nChannels, 2);
188 retcode = Write (wave_format.data.nSamplesPerSec, 4);
189 retcode = Write (wave_format.data.nAvgBytesPerSec, 4);
190 retcode = Write (wave_format.data.nBlockAlign, 2);
191 retcode = Write (wave_format.data.nBitsPerSample, 2);
192 /* byte[] br = new byte[16];
193 br[0] = (byte) ((wave_format.data.wFormatTag >> 8) & 0x00FF);
194 br[1] = (byte) (wave_format.data.wFormatTag & 0x00FF);
195
196 br[2] = (byte) ((wave_format.data.nChannels >> 8) & 0x00FF);
197 br[3] = (byte) (wave_format.data.nChannels & 0x00FF);
198
199 br[4] = (byte) ((wave_format.data.nSamplesPerSec >> 24)& 0x000000FF);
200 br[5] = (byte) ((wave_format.data.nSamplesPerSec >> 16)& 0x000000FF);
201 br[6] = (byte) ((wave_format.data.nSamplesPerSec >> 8)& 0x000000FF);
202 br[7] = (byte) (wave_format.data.nSamplesPerSec & 0x000000FF);
203
204 br[8] = (byte) ((wave_format.data.nAvgBytesPerSec>> 24)& 0x000000FF);
205 br[9] = (byte) ((wave_format.data.nAvgBytesPerSec >> 16)& 0x000000FF);
206 br[10] = (byte) ((wave_format.data.nAvgBytesPerSec >> 8)& 0x000000FF);
207 br[11] = (byte) (wave_format.data.nAvgBytesPerSec & 0x000000FF);
208
209 br[12] = (byte) ((wave_format.data.nBlockAlign >> 8) & 0x00FF);
210 br[13] = (byte) (wave_format.data.nBlockAlign & 0x00FF);
211
212 br[14] = (byte) ((wave_format.data.nBitsPerSample >> 8) & 0x00FF);
213 br[15] = (byte) (wave_format.data.nBitsPerSample & 0x00FF);
214 retcode = Write (br, 16); */
215
216
217 if ( retcode == DDC_SUCCESS )
218 {
219 pcm_data_offset = CurrentFilePosition();
220 retcode = Write ( pcm_data, 8 );
221 }
222 }
223 }
224
225 return retcode;
226 }
227
228 /**
229 *
230 *
231 public int ReadSample ( short[] Sample )
232 {
233
234 }*/
235
236 /**
237 *
238 *
239 public int WriteSample( short[] Sample )
240 {
241 int retcode = DDC_SUCCESS;
242 switch ( wave_format.data.nChannels )
243 {
244 case 1:
245 switch ( wave_format.data.nBitsPerSample )
246 {
247 case 8:
248 pcm_data.ckSize += 1;
249 retcode = Write ( Sample, 1 );
250 break;
251
252 case 16:
253 pcm_data.ckSize += 2;
254 retcode = Write ( Sample, 2 );
255 break;
256
257 default:
258 retcode = DDC_INVALID_CALL;
259 }
260 break;
261
262 case 2:
263 switch ( wave_format.data.nBitsPerSample )
264 {
265 case 8:
266 retcode = Write ( Sample, 1 );
267 if ( retcode == DDC_SUCCESS )
268 {
269 // &Sample[1]
270 retcode = Write (Sample, 1 );
271 if ( retcode == DDC_SUCCESS )
272 {
273 pcm_data.ckSize += 2;
274 }
275 }
276 break;
277
278 case 16:
279 retcode = Write ( Sample, 2 );
280 if ( retcode == DDC_SUCCESS )
281 {
282 // &Sample[1]
283 retcode = Write (Sample, 2 );
284 if ( retcode == DDC_SUCCESS )
285 {
286 pcm_data.ckSize += 4;
287 }
288 }
289 break;
290
291 default:
292 retcode = DDC_INVALID_CALL;
293 }
294 break;
295
296 default:
297 retcode = DDC_INVALID_CALL;
298 }
299
300 return retcode;
301 }*/
302
303 /**
304 *
305 *
306 public int SeekToSample ( long SampleIndex )
307 {
308 if ( SampleIndex >= NumSamples() )
309 {
310 return DDC_INVALID_CALL;
311 }
312 int SampleSize = (BitsPerSample() + 7) / 8;
313 int rc = Seek ( pcm_data_offset + 8 +
314 SampleSize * NumChannels() * SampleIndex );
315 return rc;
316 }*/
317
318 /**
319 * Write 16-bit audio
320 */
321 public int WriteData ( short[] data, int numData )
322 {
323 int extraBytes = numData * 2;
324 pcm_data.ckSize += extraBytes;
325 return super.Write ( data, extraBytes );
326 }
327
328 /**
329 * Read 16-bit audio.
330 *
331 public int ReadData (short[] data, int numData)
332 {return super.Read ( data, numData * 2);} */
333
334 /**
335 * Write 8-bit audio.
336 *
337 public int WriteData ( byte[] data, int numData )
338 {
339 pcm_data.ckSize += numData;
340 return super.Write ( data, numData );
341 }*/
342
343 /**
344 * Read 8-bit audio.
345 *
346 public int ReadData ( byte[] data, int numData )
347 {return super.Read ( data, numData );} */
348
349
350 /**
351 *
352 *
353 public int ReadSamples (int num, int [] WaveFileSample)
354 {
355
356 }*/
357
358 /**
359 *
360 *
361 public int WriteMonoSample ( short[] SampleData )
362 {
363 switch ( wave_format.data.nBitsPerSample )
364 {
365 case 8:
366 pcm_data.ckSize += 1;
367 return Write ( SampleData, 1 );
368
369 case 16:
370 pcm_data.ckSize += 2;
371 return Write ( SampleData, 2 );
372 }
373 return DDC_INVALID_CALL;
374 }*/
375
376 /**
377 *
378 *
379 public int WriteStereoSample ( short[] LeftSample, short[] RightSample )
380 {
381 int retcode = DDC_SUCCESS;
382 switch ( wave_format.data.nBitsPerSample )
383 {
384 case 8:
385 retcode = Write ( LeftSample, 1 );
386 if ( retcode == DDC_SUCCESS )
387 {
388 retcode = Write ( RightSample, 1 );
389 if ( retcode == DDC_SUCCESS )
390 {
391 pcm_data.ckSize += 2;
392 }
393 }
394 break;
395
396 case 16:
397 retcode = Write ( LeftSample, 2 );
398 if ( retcode == DDC_SUCCESS )
399 {
400 retcode = Write ( RightSample, 2 );
401 if ( retcode == DDC_SUCCESS )
402 {
403 pcm_data.ckSize += 4;
404 }
405 }
406 break;
407
408 default:
409 retcode = DDC_INVALID_CALL;
410 }
411 return retcode;
412 }*/
413
414 /**
415 *
416 *
417 public int ReadMonoSample ( short[] Sample )
418 {
419 int retcode = DDC_SUCCESS;
420 switch ( wave_format.data.nBitsPerSample )
421 {
422 case 8:
423 byte[] x = {0};
424 retcode = Read ( x, 1 );
425 Sample[0] = (short)(x[0]);
426 break;
427
428 case 16:
429 retcode = Read ( Sample, 2 );
430 break;
431
432 default:
433 retcode = DDC_INVALID_CALL;
434 }
435 return retcode;
436 }*/
437
438 /**
439 *
440 *
441 public int ReadStereoSample ( short[] LeftSampleData, short[] RightSampleData )
442 {
443 int retcode = DDC_SUCCESS;
444 byte[] x = new byte[2];
445 short[] y = new short[2];
446 switch ( wave_format.data.nBitsPerSample )
447 {
448 case 8:
449 retcode = Read ( x, 2 );
450 L[0] = (short) ( x[0] );
451 R[0] = (short) ( x[1] );
452 break;
453
454 case 16:
455 retcode = Read ( y, 4 );
456 L[0] = (short) ( y[0] );
457 R[0] = (short) ( y[1] );
458 break;
459
460 default:
461 retcode = DDC_INVALID_CALL;
462 }
463 return retcode;
464 }*/
465
466
467 /**
468 *
469 */
470 public int Close()
471 {
472 int rc = DDC_SUCCESS;
473
474 if ( fmode == RFM_WRITE )
475 rc = Backpatch ( pcm_data_offset, pcm_data, 8 );
476 if ( rc == DDC_SUCCESS )
477 rc = super.Close();
478 return rc;
479 }
480
481 // [Hz]
482 public int SamplingRate()
483 {return wave_format.data.nSamplesPerSec;}
484
485 public short BitsPerSample()
486 {return wave_format.data.nBitsPerSample;}
487
488 public short NumChannels()
489 {return wave_format.data.nChannels;}
490
491 public int NumSamples()
492 {return num_samples;}
493
494
495 /**
496 * Open for write using another wave file's parameters...
497 */
498 public int OpenForWrite (String Filename, WaveFile OtherWave )
499 {
500 return OpenForWrite ( Filename,
501 OtherWave.SamplingRate(),
502 OtherWave.BitsPerSample(),
503 OtherWave.NumChannels() );
504 }
505
506 /**
507 *
508 */
509 public long CurrentFilePosition()
510 {
511 return super.CurrentFilePosition();
512 }
513
514 /* public int FourCC(String ChunkName)
515 {
516 byte[] p = {0x20,0x20,0x20,0x20};
517 ChunkName.getBytes(0,4,p,0);
518 int ret = (((p[0] << 24)& 0xFF000000) | ((p[1] << 16)&0x00FF0000) | ((p[2] << 8)&0x0000FF00) | (p[3]&0x000000FF));
519 return ret;
520 }*/
521
522} \ No newline at end of file
diff --git a/songdbj/javazoom/jl/converter/WaveFileObuffer.java b/songdbj/javazoom/jl/converter/WaveFileObuffer.java
new file mode 100644
index 0000000000..eaa1dd46d4
--- /dev/null
+++ b/songdbj/javazoom/jl/converter/WaveFileObuffer.java
@@ -0,0 +1,141 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 12/12/99 0.0.7 Renamed class, additional constructor arguments
5 * and larger write buffers. mdm@techie.com.
6 *
7 * 15/02/99 Java Conversion by E.B ,javalayer@javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.jl.converter;
27
28import javazoom.jl.decoder.Obuffer;
29
30/**
31 * Implements an Obuffer by writing the data to
32 * a file in RIFF WAVE format.
33 *
34 * @since 0.0
35 */
36
37
38public class WaveFileObuffer extends Obuffer
39{
40 private short[] buffer;
41 private short[] bufferp;
42 private int channels;
43 private WaveFile outWave;
44
45 /**
46 * Creates a new WareFileObuffer instance.
47 *
48 * @param number_of_channels
49 * The number of channels of audio data
50 * this buffer will receive.
51 *
52 * @param freq The sample frequency of the samples in the buffer.
53 *
54 * @param fileName The filename to write the data to.
55 */
56 public WaveFileObuffer(int number_of_channels, int freq, String FileName)
57 {
58 if (FileName==null)
59 throw new NullPointerException("FileName");
60
61 buffer = new short[OBUFFERSIZE];
62 bufferp = new short[MAXCHANNELS];
63 channels = number_of_channels;
64
65 for (int i = 0; i < number_of_channels; ++i)
66 bufferp[i] = (short)i;
67
68 outWave = new WaveFile();
69
70 int rc = outWave.OpenForWrite (FileName,freq,(short)16,(short)channels);
71 }
72
73 /**
74 * Takes a 16 Bit PCM sample.
75 */
76 public void append(int channel, short value)
77 {
78 buffer[bufferp[channel]] = value;
79 bufferp[channel] += channels;
80 }
81
82 /**
83 * Write the samples to the file (Random Acces).
84 */
85 short[] myBuffer = new short[2];
86 public void write_buffer(int val)
87 {
88
89 int k = 0;
90 int rc = 0;
91
92 rc = outWave.WriteData(buffer, bufferp[0]);
93 // REVIEW: handle RiffFile errors.
94 /*
95 for (int j=0;j<bufferp[0];j=j+2)
96 {
97
98 //myBuffer[0] = (short)(((buffer[j]>>8)&0x000000FF) | ((buffer[j]<<8)&0x0000FF00));
99 //myBuffer[1] = (short) (((buffer[j+1]>>8)&0x000000FF) | ((buffer[j+1]<<8)&0x0000FF00));
100 myBuffer[0] = buffer[j];
101 myBuffer[1] = buffer[j+1];
102 rc = outWave.WriteData (myBuffer,2);
103 }
104 */
105 for (int i = 0; i < channels; ++i) bufferp[i] = (short)i;
106 }
107
108 public void close()
109 {
110 outWave.Close();
111 }
112
113 /**
114 *
115 */
116 public void clear_buffer()
117 {}
118
119 /**
120 *
121 */
122 public void set_stop_flag()
123 {}
124
125 /*
126 * Create STDOUT buffer
127 *
128 *
129 public static Obuffer create_stdout_obuffer(MPEG_Args maplay_args)
130 {
131 Obuffer thebuffer = null;
132 int mode = maplay_args.MPEGheader.mode();
133 int which_channels = maplay_args.which_c;
134 if (mode == Header.single_channel || which_channels != MPEG_Args.both)
135 thebuffer = new FileObuffer(1,maplay_args.output_filename);
136 else
137 thebuffer = new FileObuffer(2,maplay_args.output_filename);
138 return(thebuffer);
139 }
140 */
141}
diff --git a/songdbj/javazoom/jl/converter/jlc.java b/songdbj/javazoom/jl/converter/jlc.java
new file mode 100644
index 0000000000..57c84eba4a
--- /dev/null
+++ b/songdbj/javazoom/jl/converter/jlc.java
@@ -0,0 +1,216 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 29/01/00 Initial version. mdm@techie.com
5 *
6 * 12/12/99 JavaLayer 0.0.7 mdm@techie.com
7 *
8 * 14/02/99 MPEG_Args Based Class - E.B
9 * Adapted from javalayer and MPEG_Args.
10 * Doc'ed and integerated with JL converter. Removed
11 * Win32 specifics from original Maplay code.
12 *-----------------------------------------------------------------------
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Library General Public License as published
15 * by the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Library General Public License for more details.
22 *
23 * You should have received a copy of the GNU Library General Public
24 * License along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *----------------------------------------------------------------------
27 */
28
29package javazoom.jl.converter;
30
31import java.io.PrintWriter;
32
33import javazoom.jl.decoder.Crc16;
34import javazoom.jl.decoder.JavaLayerException;
35import javazoom.jl.decoder.OutputChannels;
36
37/**
38 * The <code>jlc</code> class presents the JavaLayer
39 * Conversion functionality as a command-line program.
40 *
41 * @since 0.0.7
42 */
43public class jlc
44{
45
46 static public void main(String args[])
47 {
48 String[] argv;
49 long start = System.currentTimeMillis();
50 int argc = args.length + 1;
51 argv = new String[argc];
52 argv[0] = "jlc";
53 for(int i=0;i<args.length;i++)
54 argv[i+1] = args[i];
55
56 jlcArgs ma = new jlcArgs();
57 if (!ma.processArgs(argv))
58 System.exit(1);
59
60 Converter conv = new Converter();
61
62 int detail = (ma.verbose_mode ?
63 ma.verbose_level :
64 Converter.PrintWriterProgressListener.NO_DETAIL);
65
66 Converter.ProgressListener listener =
67 new Converter.PrintWriterProgressListener(
68 new PrintWriter(System.out, true), detail);
69
70 try
71 {
72 conv.convert(ma.filename, ma.output_filename, listener);
73 }
74 catch (JavaLayerException ex)
75 {
76 System.err.println("Convertion failure: "+ex);
77 }
78
79 System.exit(0);
80 }
81
82
83 /**
84 * Class to contain arguments for maplay.
85 */
86 static class jlcArgs
87 {
88 // channel constants moved into OutputChannels class.
89 //public static final int both = 0;
90 //public static final int left = 1;
91 //public static final int right = 2;
92 //public static final int downmix = 3;
93
94 public int which_c;
95 public int output_mode;
96 public boolean use_own_scalefactor;
97 public float scalefactor;
98 public String output_filename;
99 public String filename;
100 //public boolean stdout_mode;
101 public boolean verbose_mode;
102 public int verbose_level = 3;
103
104 public jlcArgs()
105 {
106 which_c = OutputChannels.BOTH_CHANNELS;
107 use_own_scalefactor = false;
108 scalefactor = (float) 32768.0;
109 //stdout_mode = false;
110 verbose_mode = false;
111 }
112
113 /**
114 * Process user arguments.
115 *
116 * Returns true if successful.
117 */
118 public boolean processArgs(String[] argv)
119 {
120 filename = null;
121 Crc16[] crc;
122 crc = new Crc16[1];
123 int i;
124 int argc = argv.length;
125
126 //stdout_mode = false;
127 verbose_mode = false;
128 output_mode = OutputChannels.BOTH_CHANNELS;
129 output_filename = "";
130 if (argc < 2 || argv[1].equals("-h"))
131 return Usage();
132
133 i = 1;
134 while (i < argc)
135 {
136 /* System.out.println("Option = "+argv[i]);*/
137 if (argv[i].charAt(0) == '-')
138 {
139 if (argv[i].startsWith("-v"))
140 {
141 verbose_mode = true;
142 if (argv[i].length()>2)
143 {
144 try
145 {
146 String level = argv[i].substring(2);
147 verbose_level = Integer.parseInt(level);
148 }
149 catch (NumberFormatException ex)
150 {
151 System.err.println("Invalid verbose level. Using default.");
152 }
153 }
154 System.out.println("Verbose Activated (level "+verbose_level+")");
155 }
156 /* else if (argv[i].equals("-s"))
157 ma.stdout_mode = true; */
158 else if (argv[i].equals("-p"))
159 {
160 if (++i == argc)
161 {
162 System.out.println("Please specify an output filename after the -p option!");
163 System.exit (1);
164 }
165 //output_mode = O_WAVEFILE;
166 output_filename = argv[i];
167 }
168 /*else if (argv[i].equals("-f"))
169 {
170 if (++i == argc)
171 {
172 System.out.println("Please specify a new scalefactor after the -f option!");
173 System.exit(1);
174 }
175 ma.use_own_scalefactor = true;
176 // ma.scalefactor = argv[i];
177 }*/
178 else return Usage();
179 }
180 else
181 {
182 filename = argv[i];
183 System.out.println("FileName = "+argv[i]);
184 if (filename == null) return Usage();
185 }
186 i++;
187 }
188 if (filename == null)
189 return Usage();
190
191 return true;
192 }
193
194
195 /**
196 * Usage of JavaLayer.
197 */
198 public boolean Usage()
199 {
200 System.out.println("JavaLayer Converter :");
201 System.out.println(" -v[x] verbose mode. ");
202 System.out.println(" default = 2");
203 /* System.out.println(" -s write u-law samples at 8 kHz rate to stdout");
204 System.out.println(" -l decode only the left channel");
205 System.out.println(" -r decode only the right channel");
206 System.out.println(" -d downmix mode (layer III only)");
207 System.out.println(" -s write pcm samples to stdout");
208 System.out.println(" -d downmix mode (layer III only)");*/
209 System.out.println(" -p name output as a PCM wave file");
210 System.out.println("");
211 System.out.println(" More info on http://www.javazoom.net");
212 /* System.out.println(" -f ushort use this scalefactor instead of the default value 32768");*/
213 return false;
214 }
215 };
216}; \ No newline at end of file
diff --git a/songdbj/javazoom/jl/decoder/BitReserve.java b/songdbj/javazoom/jl/decoder/BitReserve.java
new file mode 100644
index 0000000000..a5d3056d61
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/BitReserve.java
@@ -0,0 +1,223 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 12/12/99 0.0.7 Implementation stores single bits
5 * as ints for better performance. mdm@techie.com.
6 *
7 * 02/28/99 0.0 Java Conversion by E.B, javalayer@javazoom.net
8 *
9 * Adapted from the public c code by Jeff Tsay.
10 *
11 *-----------------------------------------------------------------------
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as published
14 * by the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *----------------------------------------------------------------------
26 */
27
28package javazoom.jl.decoder;
29
30/**
31 * Implementation of Bit Reservoir for Layer III.
32 * <p>
33 * The implementation stores single bits as a word in the buffer. If
34 * a bit is set, the corresponding word in the buffer will be non-zero.
35 * If a bit is clear, the corresponding word is zero. Although this
36 * may seem waseful, this can be a factor of two quicker than
37 * packing 8 bits to a byte and extracting.
38 * <p>
39 */
40
41// REVIEW: there is no range checking, so buffer underflow or overflow
42// can silently occur.
43final class BitReserve
44{
45 /**
46 * Size of the internal buffer to store the reserved bits.
47 * Must be a power of 2. And x8, as each bit is stored as a single
48 * entry.
49 */
50 private static final int BUFSIZE = 4096*8;
51
52 /**
53 * Mask that can be used to quickly implement the
54 * modulus operation on BUFSIZE.
55 */
56 private static final int BUFSIZE_MASK = BUFSIZE-1;
57
58 private int offset, totbit, buf_byte_idx;
59 private final int[] buf = new int[BUFSIZE];
60 private int buf_bit_idx;
61
62 BitReserve()
63 {
64
65 offset = 0;
66 totbit = 0;
67 buf_byte_idx = 0;
68 }
69
70
71 /**
72 * Return totbit Field.
73 */
74 public int hsstell()
75 {
76 return(totbit);
77 }
78
79 /**
80 * Read a number bits from the bit stream.
81 * @param N the number of
82 */
83 public int hgetbits(int N)
84 {
85 totbit += N;
86
87 int val = 0;
88
89 int pos = buf_byte_idx;
90 if (pos+N < BUFSIZE)
91 {
92 while (N-- > 0)
93 {
94 val <<= 1;
95 val |= ((buf[pos++]!=0) ? 1 : 0);
96 }
97 }
98 else
99 {
100 while (N-- > 0)
101 {
102 val <<= 1;
103 val |= ((buf[pos]!=0) ? 1 : 0);
104 pos = (pos+1) & BUFSIZE_MASK;
105 }
106 }
107 buf_byte_idx = pos;
108 return val;
109 }
110
111
112
113 /**
114 * Read 1 bit from the bit stream.
115 */
116/*
117 public int hget1bit_old()
118 {
119 int val;
120 totbit++;
121 if (buf_bit_idx == 0)
122 {
123 buf_bit_idx = 8;
124 buf_byte_idx++;
125 }
126 // BUFSIZE = 4096 = 2^12, so
127 // buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff
128 val = buf[buf_byte_idx & BUFSIZE_MASK] & putmask[buf_bit_idx];
129 buf_bit_idx--;
130 val = val >>> buf_bit_idx;
131 return val;
132 }
133 */
134 /**
135 * Returns next bit from reserve.
136 * @returns 0 if next bit is reset, or 1 if next bit is set.
137 */
138 public int hget1bit()
139 {
140 totbit++;
141 int val = buf[buf_byte_idx];
142 buf_byte_idx = (buf_byte_idx+1) & BUFSIZE_MASK;
143 return val;
144 }
145
146 /**
147 * Retrieves bits from the reserve.
148 */
149/*
150 public int readBits(int[] out, int len)
151 {
152 if (buf_bit_idx == 0)
153 {
154 buf_bit_idx = 8;
155 buf_byte_idx++;
156 current = buf[buf_byte_idx & BUFSIZE_MASK];
157 }
158
159
160
161 // save total number of bits returned
162 len = buf_bit_idx;
163 buf_bit_idx = 0;
164
165 int b = current;
166 int count = len-1;
167
168 while (count >= 0)
169 {
170 out[count--] = (b & 0x1);
171 b >>>= 1;
172 }
173
174 totbit += len;
175 return len;
176 }
177 */
178
179 /**
180 * Write 8 bits into the bit stream.
181 */
182 public void hputbuf(int val)
183 {
184 int ofs = offset;
185 buf[ofs++] = val & 0x80;
186 buf[ofs++] = val & 0x40;
187 buf[ofs++] = val & 0x20;
188 buf[ofs++] = val & 0x10;
189 buf[ofs++] = val & 0x08;
190 buf[ofs++] = val & 0x04;
191 buf[ofs++] = val & 0x02;
192 buf[ofs++] = val & 0x01;
193
194 if (ofs==BUFSIZE)
195 offset = 0;
196 else
197 offset = ofs;
198
199 }
200
201 /**
202 * Rewind N bits in Stream.
203 */
204 public void rewindNbits(int N)
205 {
206 totbit -= N;
207 buf_byte_idx -= N;
208 if (buf_byte_idx<0)
209 buf_byte_idx += BUFSIZE;
210 }
211
212 /**
213 * Rewind N bytes in Stream.
214 */
215 public void rewindNbytes(int N)
216 {
217 int bits = (N << 3);
218 totbit -= bits;
219 buf_byte_idx -= bits;
220 if (buf_byte_idx<0)
221 buf_byte_idx += BUFSIZE;
222 }
223}
diff --git a/songdbj/javazoom/jl/decoder/Bitstream.java b/songdbj/javazoom/jl/decoder/Bitstream.java
new file mode 100644
index 0000000000..cebbd5b03b
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Bitstream.java
@@ -0,0 +1,655 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net
5 *
6 * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net
7 *
8 * 12/12/99 Based on Ibitstream. Exceptions thrown on errors,
9 * Temporary removed seek functionality. mdm@techie.com
10 *
11 * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net
12 *
13 * 04/14/97 : Added function prototypes for new syncing and seeking
14 * mechanisms. Also made this file portable. Changes made by Jeff Tsay
15 *
16 * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34
17 * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
18 * @(#) Berlin University of Technology
19 *-----------------------------------------------------------------------
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU Library General Public License as published
22 * by the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU Library General Public License for more details.
29 *
30 * You should have received a copy of the GNU Library General Public
31 * License along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 *----------------------------------------------------------------------
34 */
35
36package javazoom.jl.decoder;
37
38import java.io.BufferedInputStream;
39import java.io.ByteArrayInputStream;
40import java.io.IOException;
41import java.io.InputStream;
42import java.io.PushbackInputStream;
43
44
45/**
46 * The <code>Bistream</code> class is responsible for parsing
47 * an MPEG audio bitstream.
48 *
49 * <b>REVIEW:</b> much of the parsing currently occurs in the
50 * various decoders. This should be moved into this class and associated
51 * inner classes.
52 */
53public final class Bitstream implements BitstreamErrors
54{
55 /**
56 * Synchronization control constant for the initial
57 * synchronization to the start of a frame.
58 */
59 static byte INITIAL_SYNC = 0;
60
61 /**
62 * Synchronization control constant for non-initial frame
63 * synchronizations.
64 */
65 static byte STRICT_SYNC = 1;
66
67 // max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC
68 /**
69 * Maximum size of the frame buffer.
70 */
71 private static final int BUFFER_INT_SIZE = 433;
72
73 /**
74 * The frame buffer that holds the data for the current frame.
75 */
76 private final int[] framebuffer = new int[BUFFER_INT_SIZE];
77
78 /**
79 * Number of valid bytes in the frame buffer.
80 */
81 private int framesize;
82
83 /**
84 * The bytes read from the stream.
85 */
86 private byte[] frame_bytes = new byte[BUFFER_INT_SIZE*4];
87
88 /**
89 * Index into <code>framebuffer</code> where the next bits are
90 * retrieved.
91 */
92 private int wordpointer;
93
94 /**
95 * Number (0-31, from MSB to LSB) of next bit for get_bits()
96 */
97 private int bitindex;
98
99 /**
100 * The current specified syncword
101 */
102 private int syncword;
103
104 /**
105 * Audio header position in stream.
106 */
107 private int header_pos = 0;
108
109 /**
110 *
111 */
112 private boolean single_ch_mode;
113 //private int current_frame_number;
114 //private int last_frame_number;
115
116 private final int bitmask[] = {0, // dummy
117 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
118 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
119 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
120 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
121 0x0001FFFF };
122
123 private final PushbackInputStream source;
124
125 private final Header header = new Header();
126
127 private final byte syncbuf[] = new byte[4];
128
129 private Crc16[] crc = new Crc16[1];
130
131 private byte[] rawid3v2 = null;
132
133 private boolean firstframe = true;
134
135
136 /**
137 * Construct a IBitstream that reads data from a
138 * given InputStream.
139 *
140 * @param in The InputStream to read from.
141 */
142 public Bitstream(InputStream in)
143 {
144 if (in==null) throw new NullPointerException("in");
145 in = new BufferedInputStream(in);
146 loadID3v2(in);
147 firstframe = true;
148 //source = new PushbackInputStream(in, 1024);
149 source = new PushbackInputStream(in, BUFFER_INT_SIZE*4);
150
151 closeFrame();
152 //current_frame_number = -1;
153 //last_frame_number = -1;
154 }
155
156 /**
157 * Return position of the first audio header.
158 * @return size of ID3v2 tag frames.
159 */
160 public int header_pos()
161 {
162 return header_pos;
163 }
164
165 /**
166 * Load ID3v2 frames.
167 * @param in MP3 InputStream.
168 * @author JavaZOOM
169 */
170 private void loadID3v2(InputStream in)
171 {
172 int size = -1;
173 try
174 {
175 // Read ID3v2 header (10 bytes).
176 in.mark(10);
177 size = readID3v2Header(in);
178 header_pos = size;
179 }
180 catch (IOException e)
181 {}
182 finally
183 {
184 try
185 {
186 // Unread ID3v2 header (10 bytes).
187 in.reset();
188 }
189 catch (IOException e)
190 {}
191 }
192 // Load ID3v2 tags.
193 try
194 {
195 if (size > 0)
196 {
197 rawid3v2 = new byte[size];
198 in.read(rawid3v2,0,rawid3v2.length);
199 }
200 }
201 catch (IOException e)
202 {}
203 }
204
205 /**
206 * Parse ID3v2 tag header to find out size of ID3v2 frames.
207 * @param in MP3 InputStream
208 * @return size of ID3v2 frames + header
209 * @throws IOException
210 * @author JavaZOOM
211 */
212 private int readID3v2Header(InputStream in) throws IOException
213 {
214 byte[] id3header = new byte[4];
215 int size = -10;
216 in.read(id3header,0,3);
217 // Look for ID3v2
218 if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3'))
219 {
220 in.read(id3header,0,3);
221 int majorVersion = id3header[0];
222 int revision = id3header[1];
223 in.read(id3header,0,4);
224 size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]);
225 }
226 return (size+10);
227 }
228
229 /**
230 * Return raw ID3v2 frames + header.
231 * @return ID3v2 InputStream or null if ID3v2 frames are not available.
232 */
233 public InputStream getRawID3v2()
234 {
235 if (rawid3v2 == null) return null;
236 else
237 {
238 ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2);
239 return bain;
240 }
241 }
242
243 /**
244 * Close the Bitstream.
245 * @throws BitstreamException
246 */
247 public void close() throws BitstreamException
248 {
249 try
250 {
251 source.close();
252 }
253 catch (IOException ex)
254 {
255 throw newBitstreamException(STREAM_ERROR, ex);
256 }
257 }
258
259 /**
260 * Reads and parses the next frame from the input source.
261 * @return the Header describing details of the frame read,
262 * or null if the end of the stream has been reached.
263 */
264 public Header readFrame() throws BitstreamException
265 {
266 Header result = null;
267 try
268 {
269 result = readNextFrame();
270 // E.B, Parse VBR (if any) first frame.
271 if (firstframe == true)
272 {
273 result.parseVBR(frame_bytes);
274 firstframe = false;
275 }
276 }
277 catch (BitstreamException ex)
278 {
279 if ((ex.getErrorCode()==INVALIDFRAME))
280 {
281 // Try to skip this frame.
282 //System.out.println("INVALIDFRAME");
283 try
284 {
285 closeFrame();
286 result = readNextFrame();
287 }
288 catch (BitstreamException e)
289 {
290 if ((e.getErrorCode()!=STREAM_EOF))
291 {
292 // wrap original exception so stack trace is maintained.
293 throw newBitstreamException(e.getErrorCode(), e);
294 }
295 }
296 }
297 else if ((ex.getErrorCode()!=STREAM_EOF))
298 {
299 // wrap original exception so stack trace is maintained.
300 throw newBitstreamException(ex.getErrorCode(), ex);
301 }
302 }
303 return result;
304 }
305
306 /**
307 * Read next MP3 frame.
308 * @return MP3 frame header.
309 * @throws BitstreamException
310 */
311 private Header readNextFrame() throws BitstreamException
312 {
313 if (framesize == -1)
314 {
315 nextFrame();
316 }
317 return header;
318 }
319
320
321 /**
322 * Read next MP3 frame.
323 * @throws BitstreamException
324 */
325 private void nextFrame() throws BitstreamException
326 {
327 // entire frame is read by the header class.
328 header.read_header(this, crc);
329 }
330
331 /**
332 * Unreads the bytes read from the frame.
333 * @throws BitstreamException
334 */
335 // REVIEW: add new error codes for this.
336 public void unreadFrame() throws BitstreamException
337 {
338 if (wordpointer==-1 && bitindex==-1 && (framesize>0))
339 {
340 try
341 {
342 source.unread(frame_bytes, 0, framesize);
343 }
344 catch (IOException ex)
345 {
346 throw newBitstreamException(STREAM_ERROR);
347 }
348 }
349 }
350
351 /**
352 * Close MP3 frame.
353 */
354 public void closeFrame()
355 {
356 framesize = -1;
357 wordpointer = -1;
358 bitindex = -1;
359 }
360
361 /**
362 * Determines if the next 4 bytes of the stream represent a
363 * frame header.
364 */
365 public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException
366 {
367 int read = readBytes(syncbuf, 0, 4);
368 int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF);
369
370 try
371 {
372 source.unread(syncbuf, 0, read);
373 }
374 catch (IOException ex)
375 {
376 }
377
378 boolean sync = false;
379 switch (read)
380 {
381 case 0:
382 sync = true;
383 break;
384 case 4:
385 sync = isSyncMark(headerstring, syncmode, syncword);
386 break;
387 }
388
389 return sync;
390 }
391
392
393 // REVIEW: this class should provide inner classes to
394 // parse the frame contents. Eventually, readBits will
395 // be removed.
396 public int readBits(int n)
397 {
398 return get_bits(n);
399 }
400
401 public int readCheckedBits(int n)
402 {
403 // REVIEW: implement CRC check.
404 return get_bits(n);
405 }
406
407 protected BitstreamException newBitstreamException(int errorcode)
408 {
409 return new BitstreamException(errorcode, null);
410 }
411 protected BitstreamException newBitstreamException(int errorcode, Throwable throwable)
412 {
413 return new BitstreamException(errorcode, throwable);
414 }
415
416 /**
417 * Get next 32 bits from bitstream.
418 * They are stored in the headerstring.
419 * syncmod allows Synchro flag ID
420 * The returned value is False at the end of stream.
421 */
422
423 int syncHeader(byte syncmode) throws BitstreamException
424 {
425 boolean sync;
426 int headerstring;
427 // read additional 2 bytes
428 int bytesRead = readBytes(syncbuf, 0, 3);
429
430 if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null);
431
432 headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF);
433
434 do
435 {
436 headerstring <<= 8;
437
438 if (readBytes(syncbuf, 3, 1)!=1)
439 throw newBitstreamException(STREAM_EOF, null);
440
441 headerstring |= (syncbuf[3] & 0x000000FF);
442
443 sync = isSyncMark(headerstring, syncmode, syncword);
444 }
445 while (!sync);
446
447 //current_frame_number++;
448 //if (last_frame_number < current_frame_number) last_frame_number = current_frame_number;
449
450 return headerstring;
451 }
452
453 public boolean isSyncMark(int headerstring, int syncmode, int word)
454 {
455 boolean sync = false;
456
457 if (syncmode == INITIAL_SYNC)
458 {
459 //sync = ((headerstring & 0xFFF00000) == 0xFFF00000);
460 sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5
461 }
462 else
463 {
464 sync = ((headerstring & 0xFFF80C00) == word) &&
465 (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode);
466 }
467
468 // filter out invalid sample rate
469 if (sync)
470 sync = (((headerstring >>> 10) & 3)!=3);
471 // filter out invalid layer
472 if (sync)
473 sync = (((headerstring >>> 17) & 3)!=0);
474 // filter out invalid version
475 if (sync)
476 sync = (((headerstring >>> 19) & 3)!=1);
477
478 return sync;
479 }
480
481 /**
482 * Reads the data for the next frame. The frame is not parsed
483 * until parse frame is called.
484 */
485 int read_frame_data(int bytesize) throws BitstreamException
486 {
487 int numread = 0;
488 numread = readFully(frame_bytes, 0, bytesize);
489 framesize = bytesize;
490 wordpointer = -1;
491 bitindex = -1;
492 return numread;
493 }
494
495 /**
496 * Parses the data previously read with read_frame_data().
497 */
498 void parse_frame() throws BitstreamException
499 {
500 // Convert Bytes read to int
501 int b=0;
502 byte[] byteread = frame_bytes;
503 int bytesize = framesize;
504
505 // Check ID3v1 TAG (True only if last frame).
506 //for (int t=0;t<(byteread.length)-2;t++)
507 //{
508 // if ((byteread[t]=='T') && (byteread[t+1]=='A') && (byteread[t+2]=='G'))
509 // {
510 // System.out.println("ID3v1 detected at offset "+t);
511 // throw newBitstreamException(INVALIDFRAME, null);
512 // }
513 //}
514
515 for (int k=0;k<bytesize;k=k+4)
516 {
517 int convert = 0;
518 byte b0 = 0;
519 byte b1 = 0;
520 byte b2 = 0;
521 byte b3 = 0;
522 b0 = byteread[k];
523 if (k+1<bytesize) b1 = byteread[k+1];
524 if (k+2<bytesize) b2 = byteread[k+2];
525 if (k+3<bytesize) b3 = byteread[k+3];
526 framebuffer[b++] = ((b0 << 24) &0xFF000000) | ((b1 << 16) & 0x00FF0000) | ((b2 << 8) & 0x0000FF00) | (b3 & 0x000000FF);
527 }
528 wordpointer = 0;
529 bitindex = 0;
530 }
531
532 /**
533 * Read bits from buffer into the lower bits of an unsigned int.
534 * The LSB contains the latest read bit of the stream.
535 * (1 <= number_of_bits <= 16)
536 */
537 public int get_bits(int number_of_bits)
538 {
539 int returnvalue = 0;
540 int sum = bitindex + number_of_bits;
541
542 // E.B
543 // There is a problem here, wordpointer could be -1 ?!
544 if (wordpointer < 0) wordpointer = 0;
545 // E.B : End.
546
547 if (sum <= 32)
548 {
549 // all bits contained in *wordpointer
550 returnvalue = (framebuffer[wordpointer] >>> (32 - sum)) & bitmask[number_of_bits];
551 // returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits];
552 if ((bitindex += number_of_bits) == 32)
553 {
554 bitindex = 0;
555 wordpointer++; // added by me!
556 }
557 return returnvalue;
558 }
559
560 // E.B : Check that ?
561 //((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0];
562 //wordpointer++; // Added by me!
563 //((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0];
564 int Right = (framebuffer[wordpointer] & 0x0000FFFF);
565 wordpointer++;
566 int Left = (framebuffer[wordpointer] & 0xFFFF0000);
567 returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF);
568
569 returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 - bitindex))
570 returnvalue &= bitmask[number_of_bits];
571 bitindex = sum - 32;
572 return returnvalue;
573}
574
575 /**
576 * Set the word we want to sync the header to.
577 * In Big-Endian byte order
578 */
579 void set_syncword(int syncword0)
580 {
581 syncword = syncword0 & 0xFFFFFF3F;
582 single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0);
583 }
584 /**
585 * Reads the exact number of bytes from the source
586 * input stream into a byte array.
587 *
588 * @param b The byte array to read the specified number
589 * of bytes into.
590 * @param offs The index in the array where the first byte
591 * read should be stored.
592 * @param len the number of bytes to read.
593 *
594 * @exception BitstreamException is thrown if the specified
595 * number of bytes could not be read from the stream.
596 */
597 private int readFully(byte[] b, int offs, int len)
598 throws BitstreamException
599 {
600 int nRead = 0;
601 try
602 {
603 while (len > 0)
604 {
605 int bytesread = source.read(b, offs, len);
606 if (bytesread == -1)
607 {
608 while (len-->0)
609 {
610 b[offs++] = 0;
611 }
612 break;
613 //throw newBitstreamException(UNEXPECTED_EOF, new EOFException());
614 }
615 nRead = nRead + bytesread;
616 offs += bytesread;
617 len -= bytesread;
618 }
619 }
620 catch (IOException ex)
621 {
622 throw newBitstreamException(STREAM_ERROR, ex);
623 }
624 return nRead;
625 }
626
627 /**
628 * Simlar to readFully, but doesn't throw exception when
629 * EOF is reached.
630 */
631 private int readBytes(byte[] b, int offs, int len)
632 throws BitstreamException
633 {
634 int totalBytesRead = 0;
635 try
636 {
637 while (len > 0)
638 {
639 int bytesread = source.read(b, offs, len);
640 if (bytesread == -1)
641 {
642 break;
643 }
644 totalBytesRead += bytesread;
645 offs += bytesread;
646 len -= bytesread;
647 }
648 }
649 catch (IOException ex)
650 {
651 throw newBitstreamException(STREAM_ERROR, ex);
652 }
653 return totalBytesRead;
654 }
655}
diff --git a/songdbj/javazoom/jl/decoder/BitstreamErrors.java b/songdbj/javazoom/jl/decoder/BitstreamErrors.java
new file mode 100644
index 0000000000..2bdee6d797
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/BitstreamErrors.java
@@ -0,0 +1,72 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 11/17/04 INVALIDFRAME code added. javalayer@javazoom.net
4 * 12/12/99 Initial version. mdm@techie.com
5 *-----------------------------------------------------------------------
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Library General Public License as published
8 * by the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *----------------------------------------------------------------------
20 */
21
22package javazoom.jl.decoder;
23
24/**
25 * This interface describes all error codes that can be thrown
26 * in <code>BistreamException</code>s.
27 *
28 * @see BitstreamException
29 *
30 * @author MDM 12/12/99
31 * @since 0.0.6
32 */
33
34public interface BitstreamErrors extends JavaLayerErrors
35{
36
37 /**
38 * An undeterminable error occurred.
39 */
40 static public final int UNKNOWN_ERROR = BITSTREAM_ERROR + 0;
41
42 /**
43 * The header describes an unknown sample rate.
44 */
45 static public final int UNKNOWN_SAMPLE_RATE = BITSTREAM_ERROR + 1;
46
47 /**
48 * A problem occurred reading from the stream.
49 */
50 static public final int STREAM_ERROR = BITSTREAM_ERROR + 2;
51
52 /**
53 * The end of the stream was reached prematurely.
54 */
55 static public final int UNEXPECTED_EOF = BITSTREAM_ERROR + 3;
56
57 /**
58 * The end of the stream was reached.
59 */
60 static public final int STREAM_EOF = BITSTREAM_ERROR + 4;
61
62 /**
63 * Frame data are missing.
64 */
65 static public final int INVALIDFRAME = BITSTREAM_ERROR + 5;
66
67 /**
68 *
69 */
70 static public final int BITSTREAM_LAST = 0x1ff;
71
72}
diff --git a/songdbj/javazoom/jl/decoder/BitstreamException.java b/songdbj/javazoom/jl/decoder/BitstreamException.java
new file mode 100644
index 0000000000..99faa8962d
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/BitstreamException.java
@@ -0,0 +1,71 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
21package javazoom.jl.decoder;
22
23/**
24 * Instances of <code>BitstreamException</code> are thrown
25 * when operations on a <code>Bitstream</code> fail.
26 * <p>
27 * The exception provides details of the exception condition
28 * in two ways:
29 * <ol><li>
30 * as an error-code describing the nature of the error
31 * </li><br></br><li>
32 * as the <code>Throwable</code> instance, if any, that was thrown
33 * indicating that an exceptional condition has occurred.
34 * </li></ol></p>
35 *
36 * @since 0.0.6
37 * @author MDM 12/12/99
38 */
39
40public class BitstreamException extends JavaLayerException
41 implements BitstreamErrors
42{
43 private int errorcode = UNKNOWN_ERROR;
44
45 public BitstreamException(String msg, Throwable t)
46 {
47 super(msg, t);
48 }
49
50 public BitstreamException(int errorcode, Throwable t)
51 {
52 this(getErrorString(errorcode), t);
53 this.errorcode = errorcode;
54 }
55
56 public int getErrorCode()
57 {
58 return errorcode;
59 }
60
61
62 static public String getErrorString(int errorcode)
63 {
64 // REVIEW: use resource bundle to map error codes
65 // to locale-sensitive strings.
66
67 return "Bitstream errorcode "+Integer.toHexString(errorcode);
68 }
69
70
71}
diff --git a/songdbj/javazoom/jl/decoder/Control.java b/songdbj/javazoom/jl/decoder/Control.java
new file mode 100644
index 0000000000..080ed5215e
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Control.java
@@ -0,0 +1,57 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.decoder;
21
22/**
23 * Work in progress.
24 */
25
26public interface Control
27{
28
29 /**
30 * Starts playback of the media presented by this control.
31 */
32 public void start();
33
34 /**
35 * Stops playback of the media presented by this control.
36 */
37 public void stop();
38
39 public boolean isPlaying();
40
41 public void pause();
42
43
44 public boolean isRandomAccess();
45
46 /**
47 * Retrieves the current position.
48 */
49 public double getPosition();
50
51 /**
52 *
53 */
54 public void setPosition(double d);
55
56
57}
diff --git a/songdbj/javazoom/jl/decoder/Crc16.java b/songdbj/javazoom/jl/decoder/Crc16.java
new file mode 100644
index 0000000000..c35cc19341
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Crc16.java
@@ -0,0 +1,70 @@
1/*
2 * 11/19/04 : 1.0 moved to LGPL.
3 *
4 * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net
5 *
6 * @(#) crc.h 1.5, last edit: 6/15/94 16:55:32
7 * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
8 * @(#) Berlin University of Technology
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25package javazoom.jl.decoder;
26
27/**
28 * 16-Bit CRC checksum
29 */
30public final class Crc16
31{
32 private static short polynomial=(short)0x8005;
33 private short crc;
34
35 /**
36 * Dummy Constructor
37 */
38 public Crc16()
39 {
40 crc = (short) 0xFFFF;
41 }
42
43 /**
44 * Feed a bitstring to the crc calculation (0 < length <= 32).
45 */
46 public void add_bits (int bitstring, int length)
47 {
48 int bitmask = 1 << (length - 1);
49 do
50 if (((crc & 0x8000) == 0) ^ ((bitstring & bitmask) == 0 ))
51 {
52 crc <<= 1;
53 crc ^= polynomial;
54 }
55 else
56 crc <<= 1;
57 while ((bitmask >>>= 1) != 0);
58 }
59
60 /**
61 * Return the calculated checksum.
62 * Erase it for next calls to add_bits().
63 */
64 public short checksum()
65 {
66 short sum = crc;
67 crc = (short) 0xFFFF;
68 return sum;
69 }
70}
diff --git a/songdbj/javazoom/jl/decoder/Decoder.java b/songdbj/javazoom/jl/decoder/Decoder.java
new file mode 100644
index 0000000000..076f9dea27
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Decoder.java
@@ -0,0 +1,357 @@
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
21package 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 */
31public 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
diff --git a/songdbj/javazoom/jl/decoder/DecoderErrors.java b/songdbj/javazoom/jl/decoder/DecoderErrors.java
new file mode 100644
index 0000000000..66c1935051
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/DecoderErrors.java
@@ -0,0 +1,38 @@
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
21package javazoom.jl.decoder;
22
23/**
24 * This interface provides constants describing the error
25 * codes used by the Decoder to indicate errors.
26 *
27 * @author MDM
28 */
29public interface DecoderErrors extends JavaLayerErrors
30{
31
32 static public final int UNKNOWN_ERROR = DECODER_ERROR + 0;
33
34 /**
35 * Layer not supported by the decoder.
36 */
37 static public final int UNSUPPORTED_LAYER = DECODER_ERROR + 1;
38}
diff --git a/songdbj/javazoom/jl/decoder/DecoderException.java b/songdbj/javazoom/jl/decoder/DecoderException.java
new file mode 100644
index 0000000000..b75710870f
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/DecoderException.java
@@ -0,0 +1,61 @@
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
21package javazoom.jl.decoder;
22
23/**
24 * The <code>DecoderException</code> represents the class of
25 * errors that can occur when decoding MPEG audio.
26 *
27 * @author MDM
28 */
29public class DecoderException extends JavaLayerException
30 implements DecoderErrors
31{
32 private int errorcode = UNKNOWN_ERROR;
33
34 public DecoderException(String msg, Throwable t)
35 {
36 super(msg, t);
37 }
38
39 public DecoderException(int errorcode, Throwable t)
40 {
41 this(getErrorString(errorcode), t);
42 this.errorcode = errorcode;
43 }
44
45 public int getErrorCode()
46 {
47 return errorcode;
48 }
49
50
51 static public String getErrorString(int errorcode)
52 {
53 // REVIEW: use resource file to map error codes
54 // to locale-sensitive strings.
55
56 return "Decoder errorcode "+Integer.toHexString(errorcode);
57 }
58
59
60}
61
diff --git a/songdbj/javazoom/jl/decoder/Equalizer.java b/songdbj/javazoom/jl/decoder/Equalizer.java
new file mode 100644
index 0000000000..57545a939d
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Equalizer.java
@@ -0,0 +1,227 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
22package javazoom.jl.decoder;
23
24/**
25 * The <code>Equalizer</code> class can be used to specify
26 * equalization settings for the MPEG audio decoder.
27 * <p>
28 * The equalizer consists of 32 band-pass filters.
29 * Each band of the equalizer can take on a fractional value between
30 * -1.0 and +1.0.
31 * At -1.0, the input signal is attenuated by 6dB, at +1.0 the signal is
32 * amplified by 6dB.
33 *
34 * @see Decoder
35 *
36 * @author MDM
37 */
38public final class Equalizer
39{
40 /**
41 * Equalizer setting to denote that a given band will not be
42 * present in the output signal.
43 */
44 static public final float BAND_NOT_PRESENT = Float.NEGATIVE_INFINITY;
45
46 static public final Equalizer PASS_THRU_EQ = new Equalizer();
47
48 private static final int BANDS = 32;
49
50 private final float[] settings = new float[BANDS];
51
52 /**
53 * Creates a new <code>Equalizer</code> instance.
54 */
55 public Equalizer()
56 {
57 }
58
59// private Equalizer(float b1, float b2, float b3, float b4, float b5,
60// float b6, float b7, float b8, float b9, float b10, float b11,
61// float b12, float b13, float b14, float b15, float b16,
62// float b17, float b18, float b19, float b20);
63
64 public Equalizer(float[] settings)
65 {
66 setFrom(settings);
67 }
68
69 public Equalizer(EQFunction eq)
70 {
71 setFrom(eq);
72 }
73
74 public void setFrom(float[] eq)
75 {
76 reset();
77 int max = (eq.length > BANDS) ? BANDS : eq.length;
78
79 for (int i=0; i<max; i++)
80 {
81 settings[i] = limit(eq[i]);
82 }
83 }
84
85 public void setFrom(EQFunction eq)
86 {
87 reset();
88 int max = BANDS;
89
90 for (int i=0; i<max; i++)
91 {
92 settings[i] = limit(eq.getBand(i));
93 }
94 }
95
96 /**
97 * Sets the bands of this equalizer to the value the bands of
98 * another equalizer. Bands that are not present in both equalizers are ignored.
99 */
100 public void setFrom(Equalizer eq)
101 {
102 if (eq!=this)
103 {
104 setFrom(eq.settings);
105 }
106 }
107
108
109
110
111 /**
112 * Sets all bands to 0.0
113 */
114 public void reset()
115 {
116 for (int i=0; i<BANDS; i++)
117 {
118 settings[i] = 0.0f;
119 }
120 }
121
122
123 /**
124 * Retrieves the number of bands present in this equalizer.
125 */
126 public int getBandCount()
127 {
128 return settings.length;
129 }
130
131 public float setBand(int band, float neweq)
132 {
133 float eq = 0.0f;
134
135 if ((band>=0) && (band<BANDS))
136 {
137 eq = settings[band];
138 settings[band] = limit(neweq);
139 }
140
141 return eq;
142 }
143
144
145
146 /**
147 * Retrieves the eq setting for a given band.
148 */
149 public float getBand(int band)
150 {
151 float eq = 0.0f;
152
153 if ((band>=0) && (band<BANDS))
154 {
155 eq = settings[band];
156 }
157
158 return eq;
159 }
160
161 private float limit(float eq)
162 {
163 if (eq==BAND_NOT_PRESENT)
164 return eq;
165 if (eq > 1.0f)
166 return 1.0f;
167 if (eq < -1.0f)
168 return -1.0f;
169
170 return eq;
171 }
172
173 /**
174 * Retrieves an array of floats whose values represent a
175 * scaling factor that can be applied to linear samples
176 * in each band to provide the equalization represented by
177 * this instance.
178 *
179 * @return an array of factors that can be applied to the
180 * subbands.
181 */
182 float[] getBandFactors()
183 {
184 float[] factors = new float[BANDS];
185 for (int i=0, maxCount=BANDS; i<maxCount; i++)
186 {
187 factors[i] = getBandFactor(settings[i]);
188 }
189
190 return factors;
191 }
192
193 /**
194 * Converts an equalizer band setting to a sample factor.
195 * The factor is determined by the function f = 2^n where
196 * n is the equalizer band setting in the range [-1.0,1.0].
197 *
198 */
199 float getBandFactor(float eq)
200 {
201 if (eq==BAND_NOT_PRESENT)
202 return 0.0f;
203
204 float f = (float)Math.pow(2.0, eq);
205 return f;
206 }
207
208
209 static abstract public class EQFunction
210 {
211 /**
212 * Returns the setting of a band in the equalizer.
213 *
214 * @param band The index of the band to retrieve the setting
215 * for.
216 *
217 * @return the setting of the specified band. This is a value between
218 * -1 and +1.
219 */
220 public float getBand(int band)
221 {
222 return 0.0f;
223 }
224
225 }
226
227}
diff --git a/songdbj/javazoom/jl/decoder/FrameDecoder.java b/songdbj/javazoom/jl/decoder/FrameDecoder.java
new file mode 100644
index 0000000000..eec6ac6a22
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/FrameDecoder.java
@@ -0,0 +1,38 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
21package javazoom.jl.decoder;
22
23/**
24 * Implementations of FrameDecoder are responsible for decoding
25 * an MPEG audio frame.
26 *
27 */
28//REVIEW: the interface currently is too thin. There should be
29// methods to specify the output buffer, the synthesis filters and
30// possibly other objects used by the decoder.
31public interface FrameDecoder
32{
33 /**
34 * Decodes one frame of MPEG audio.
35 */
36 public void decodeFrame();
37
38}
diff --git a/songdbj/javazoom/jl/decoder/Header.java b/songdbj/javazoom/jl/decoder/Header.java
new file mode 100644
index 0000000000..e85fe19f64
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Header.java
@@ -0,0 +1,762 @@
1/*
2 * 11/19/04 : 1.0 moved to LGPL.
3 * VBRI header support added, E.B javalayer@javazoom.net
4 *
5 * 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net
6 *
7 * 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net
8 *
9 * Declarations for MPEG header class
10 * A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay.
11 * Last modified : 04/19/97
12 *
13 * @(#) header.h 1.7, last edit: 6/15/94 16:55:33
14 * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
15 * @(#) Berlin University of Technology
16 *-----------------------------------------------------------------------
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU Library General Public License as published
19 * by the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU Library General Public License for more details.
26 *
27 * You should have received a copy of the GNU Library General Public
28 * License along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 *----------------------------------------------------------------------
31 */
32package javazoom.jl.decoder;
33
34/**
35 * Class for extracting information from a frame header.
36 */
37public final class Header
38{
39 public static final int[][] frequencies =
40 {{22050, 24000, 16000, 1},
41 {44100, 48000, 32000, 1},
42 {11025, 12000, 8000, 1}}; // SZD: MPEG25
43
44 /**
45 * Constant for MPEG-2 LSF version
46 */
47 public static final int MPEG2_LSF = 0;
48 public static final int MPEG25_LSF = 2; // SZD
49
50 /**
51 * Constant for MPEG-1 version
52 */
53 public static final int MPEG1 = 1;
54
55 public static final int STEREO = 0;
56 public static final int JOINT_STEREO = 1;
57 public static final int DUAL_CHANNEL = 2;
58 public static final int SINGLE_CHANNEL = 3;
59 public static final int FOURTYFOUR_POINT_ONE = 0;
60 public static final int FOURTYEIGHT=1;
61 public static final int THIRTYTWO=2;
62
63 private int h_layer, h_protection_bit, h_bitrate_index,
64 h_padding_bit, h_mode_extension;
65 private int h_version;
66 private int h_mode;
67 private int h_sample_frequency;
68 private int h_number_of_subbands, h_intensity_stereo_bound;
69 private boolean h_copyright, h_original;
70 // VBR support added by E.B
71 private double[] h_vbr_time_per_frame = {-1, 384, 1152, 1152};
72 private boolean h_vbr;
73 private int h_vbr_frames;
74 private int h_vbr_scale;
75 private int h_vbr_bytes;
76 private byte[] h_vbr_toc;
77
78 private byte syncmode = Bitstream.INITIAL_SYNC;
79 private Crc16 crc;
80
81 public short checksum;
82 public int framesize;
83 public int nSlots;
84
85 private int _headerstring = -1; // E.B
86
87 Header()
88 {
89 }
90 public String toString()
91 {
92 StringBuffer buffer = new StringBuffer(200);
93 buffer.append("Layer ");
94 buffer.append(layer_string());
95 buffer.append(" frame ");
96 buffer.append(mode_string());
97 buffer.append(' ');
98 buffer.append(version_string());
99 if (!checksums())
100 buffer.append(" no");
101 buffer.append(" checksums");
102 buffer.append(' ');
103 buffer.append(sample_frequency_string());
104 buffer.append(',');
105 buffer.append(' ');
106 buffer.append(bitrate_string());
107
108 String s = buffer.toString();
109 return s;
110 }
111
112 /**
113 * Read a 32-bit header from the bitstream.
114 */
115 void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException
116 {
117 int headerstring;
118 int channel_bitrate;
119 boolean sync = false;
120 do
121 {
122 headerstring = stream.syncHeader(syncmode);
123 _headerstring = headerstring; // E.B
124 if (syncmode == Bitstream.INITIAL_SYNC)
125 {
126 h_version = ((headerstring >>> 19) & 1);
127 if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection
128 if (h_version == MPEG2_LSF)
129 h_version = MPEG25_LSF;
130 else
131 throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
132 if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3)
133 {
134 throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
135 }
136 }
137 h_layer = 4 - (headerstring >>> 17) & 3;
138 h_protection_bit = (headerstring >>> 16) & 1;
139 h_bitrate_index = (headerstring >>> 12) & 0xF;
140 h_padding_bit = (headerstring >>> 9) & 1;
141 h_mode = ((headerstring >>> 6) & 3);
142 h_mode_extension = (headerstring >>> 4) & 3;
143 if (h_mode == JOINT_STEREO)
144 h_intensity_stereo_bound = (h_mode_extension << 2) + 4;
145 else
146 h_intensity_stereo_bound = 0; // should never be used
147 if (((headerstring >>> 3) & 1) == 1)
148 h_copyright = true;
149 if (((headerstring >>> 2) & 1) == 1)
150 h_original = true;
151 // calculate number of subbands:
152 if (h_layer == 1)
153 h_number_of_subbands = 32;
154 else
155 {
156 channel_bitrate = h_bitrate_index;
157 // calculate bitrate per channel:
158 if (h_mode != SINGLE_CHANNEL)
159 if (channel_bitrate == 4)
160 channel_bitrate = 1;
161 else
162 channel_bitrate -= 4;
163 if ((channel_bitrate == 1) || (channel_bitrate == 2))
164 if (h_sample_frequency == THIRTYTWO)
165 h_number_of_subbands = 12;
166 else
167 h_number_of_subbands = 8;
168 else if ((h_sample_frequency == FOURTYEIGHT) || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))
169 h_number_of_subbands = 27;
170 else
171 h_number_of_subbands = 30;
172 }
173 if (h_intensity_stereo_bound > h_number_of_subbands)
174 h_intensity_stereo_bound = h_number_of_subbands;
175 // calculate framesize and nSlots
176 calculate_framesize();
177 // read framedata:
178 int framesizeloaded = stream.read_frame_data(framesize);
179 if ((framesize >=0) && (framesizeloaded != framesize))
180 {
181 // Data loaded does not match to expected framesize,
182 // it might be an ID3v1 TAG. (Fix 11/17/04).
183 throw stream.newBitstreamException(Bitstream.INVALIDFRAME);
184 }
185 if (stream.isSyncCurrentPosition(syncmode))
186 {
187 if (syncmode == Bitstream.INITIAL_SYNC)
188 {
189 syncmode = Bitstream.STRICT_SYNC;
190 stream.set_syncword(headerstring & 0xFFF80CC0);
191 }
192 sync = true;
193 }
194 else
195 {
196 stream.unreadFrame();
197 }
198 }
199 while (!sync);
200 stream.parse_frame();
201 if (h_protection_bit == 0)
202 {
203 // frame contains a crc checksum
204 checksum = (short) stream.get_bits(16);
205 if (crc == null)
206 crc = new Crc16();
207 crc.add_bits(headerstring, 16);
208 crcp[0] = crc;
209 }
210 else
211 crcp[0] = null;
212 if (h_sample_frequency == FOURTYFOUR_POINT_ONE)
213 {
214 /*
215 if (offset == null)
216 {
217 int max = max_number_of_frames(stream);
218 offset = new int[max];
219 for(int i=0; i<max; i++) offset[i] = 0;
220 }
221 // E.B : Investigate more
222 int cf = stream.current_frame();
223 int lf = stream.last_frame();
224 if ((cf > 0) && (cf == lf))
225 {
226 offset[cf] = offset[cf-1] + h_padding_bit;
227 }
228 else
229 {
230 offset[0] = h_padding_bit;
231 }
232 */
233 }
234 }
235
236 /**
237 * Parse frame to extract optionnal VBR frame.
238 * @param firstframe
239 * @author E.B (javalayer@javazoom.net)
240 */
241 void parseVBR(byte[] firstframe) throws BitstreamException
242 {
243 // Trying Xing header.
244 String xing = "Xing";
245 byte tmp[] = new byte[4];
246 int offset = 0;
247 // Compute "Xing" offset depending on MPEG version and channels.
248 if (h_version == MPEG1)
249 {
250 if (h_mode == SINGLE_CHANNEL) offset=21-4;
251 else offset=36-4;
252 }
253 else
254 {
255 if (h_mode == SINGLE_CHANNEL) offset=13-4;
256 else offset = 21-4;
257 }
258 try
259 {
260 System.arraycopy(firstframe, offset, tmp, 0, 4);
261 // Is "Xing" ?
262 if (xing.equals(new String(tmp)))
263 {
264 //Yes.
265 h_vbr = true;
266 h_vbr_frames = -1;
267 h_vbr_bytes = -1;
268 h_vbr_scale = -1;
269 h_vbr_toc = new byte[100];
270
271 int length = 4;
272 // Read flags.
273 byte flags[] = new byte[4];
274 System.arraycopy(firstframe, offset + length, flags, 0, flags.length);
275 length += flags.length;
276 // Read number of frames (if available).
277 if ((flags[3] & (byte) (1 << 0)) != 0)
278 {
279 System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
280 h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
281 length += 4;
282 }
283 // Read size (if available).
284 if ((flags[3] & (byte) (1 << 1)) != 0)
285 {
286 System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
287 h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
288 length += 4;
289 }
290 // Read TOC (if available).
291 if ((flags[3] & (byte) (1 << 2)) != 0)
292 {
293 System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);
294 length += h_vbr_toc.length;
295 }
296 // Read scale (if available).
297 if ((flags[3] & (byte) (1 << 3)) != 0)
298 {
299 System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
300 h_vbr_scale = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
301 length += 4;
302 }
303 //System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes);
304 }
305 }
306 catch (ArrayIndexOutOfBoundsException e)
307 {
308 throw new BitstreamException("XingVBRHeader Corrupted",e);
309 }
310
311 // Trying VBRI header.
312 String vbri = "VBRI";
313 offset = 36-4;
314 try
315 {
316 System.arraycopy(firstframe, offset, tmp, 0, 4);
317 // Is "VBRI" ?
318 if (vbri.equals(new String(tmp)))
319 {
320 //Yes.
321 h_vbr = true;
322 h_vbr_frames = -1;
323 h_vbr_bytes = -1;
324 h_vbr_scale = -1;
325 h_vbr_toc = new byte[100];
326 // Bytes.
327 int length = 4 + 6;
328 System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
329 h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
330 length += 4;
331 // Frames.
332 System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
333 h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
334 length += 4;
335 //System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes);
336 // TOC
337 // TODO
338 }
339 }
340 catch (ArrayIndexOutOfBoundsException e)
341 {
342 throw new BitstreamException("VBRIVBRHeader Corrupted",e);
343 }
344 }
345
346 // Functions to query header contents:
347 /**
348 * Returns version.
349 */
350 public int version() { return h_version; }
351
352 /**
353 * Returns Layer ID.
354 */
355 public int layer() { return h_layer; }
356
357 /**
358 * Returns bitrate index.
359 */
360 public int bitrate_index() { return h_bitrate_index; }
361
362 /**
363 * Returns Sample Frequency.
364 */
365 public int sample_frequency() { return h_sample_frequency; }
366
367 /**
368 * Returns Frequency.
369 */
370 public int frequency() {return frequencies[h_version][h_sample_frequency];}
371
372 /**
373 * Returns Mode.
374 */
375 public int mode() { return h_mode; }
376
377 /**
378 * Returns Protection bit.
379 */
380 public boolean checksums()
381 {
382 if (h_protection_bit == 0) return true;
383 else return false;
384 }
385
386 /**
387 * Returns Copyright.
388 */
389 public boolean copyright() { return h_copyright; }
390
391 /**
392 * Returns Original.
393 */
394 public boolean original() { return h_original; }
395
396 /**
397 * Return VBR.
398 * @return true if VBR header is found
399 */
400 public boolean vbr() { return h_vbr; }
401
402 /**
403 * Return VBR scale.
404 * @return scale of -1 if not available
405 */
406 public int vbr_scale() { return h_vbr_scale; }
407
408 /**
409 * Return VBR TOC.
410 * @return vbr toc ot null if not available
411 */
412 public byte[] vbr_toc() { return h_vbr_toc; }
413
414 /**
415 * Returns Checksum flag.
416 * Compares computed checksum with stream checksum.
417 */
418 public boolean checksum_ok () { return (checksum == crc.checksum()); }
419
420 // Seeking and layer III stuff
421 /**
422 * Returns Layer III Padding bit.
423 */
424 public boolean padding()
425 {
426 if (h_padding_bit == 0) return false;
427 else return true;
428 }
429
430 /**
431 * Returns Slots.
432 */
433 public int slots() { return nSlots; }
434
435 /**
436 * Returns Mode Extension.
437 */
438 public int mode_extension() { return h_mode_extension; }
439
440 // E.B -> private to public
441 public static final int bitrates[][][] = {
442 {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,
443 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},
444 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
445 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},
446 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
447 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},
448
449 {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000,
450 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0},
451 {0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,
452 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0},
453 {0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000,
454 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}},
455 // SZD: MPEG2.5
456 {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,
457 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},
458 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
459 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},
460 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
461 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},
462
463 };
464
465 // E.B -> private to public
466 /**
467 * Calculate Frame size.
468 * Calculates framesize in bytes excluding header size.
469 */
470 public int calculate_framesize()
471 {
472
473 if (h_layer == 1)
474 {
475 framesize = (12 * bitrates[h_version][0][h_bitrate_index]) /
476 frequencies[h_version][h_sample_frequency];
477 if (h_padding_bit != 0 ) framesize++;
478 framesize <<= 2; // one slot is 4 bytes long
479 nSlots = 0;
480 }
481 else
482 {
483 framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) /
484 frequencies[h_version][h_sample_frequency];
485 if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1; // SZD
486 if (h_padding_bit != 0) framesize++;
487 // Layer III slots
488 if (h_layer == 3)
489 {
490 if (h_version == MPEG1)
491 {
492 nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size
493 - ((h_protection_bit!=0) ? 0 : 2) // CRC size
494 - 4; // header size
495 }
496 else
497 { // MPEG-2 LSF, SZD: MPEG-2.5 LSF
498 nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side info size
499 - ((h_protection_bit!=0) ? 0 : 2) // CRC size
500 - 4; // header size
501 }
502 }
503 else
504 {
505 nSlots = 0;
506 }
507 }
508 framesize -= 4; // subtract header size
509 return framesize;
510 }
511
512 /**
513 * Returns the maximum number of frames in the stream.
514 * @param streamsize
515 * @return number of frames
516 */
517 public int max_number_of_frames(int streamsize) // E.B
518 {
519 if (h_vbr == true) return h_vbr_frames;
520 else
521 {
522 if ((framesize + 4 - h_padding_bit) == 0) return 0;
523 else return(streamsize / (framesize + 4 - h_padding_bit));
524 }
525 }
526
527 /**
528 * Returns the maximum number of frames in the stream.
529 * @param streamsize
530 * @return number of frames
531 */
532 public int min_number_of_frames(int streamsize) // E.B
533 {
534 if (h_vbr == true) return h_vbr_frames;
535 else
536 {
537 if ((framesize + 5 - h_padding_bit) == 0) return 0;
538 else return(streamsize / (framesize + 5 - h_padding_bit));
539 }
540 }
541
542
543 /**
544 * Returns ms/frame.
545 * @return milliseconds per frame
546 */
547 public float ms_per_frame() // E.B
548 {
549 if (h_vbr == true)
550 {
551 double tpf = h_vbr_time_per_frame[layer()] / frequency();
552 if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2;
553 return ((float) (tpf * 1000));
554 }
555 else
556 {
557 float ms_per_frame_array[][] = {{8.707483f, 8.0f, 12.0f},
558 {26.12245f, 24.0f, 36.0f},
559 {26.12245f, 24.0f, 36.0f}};
560 return(ms_per_frame_array[h_layer-1][h_sample_frequency]);
561 }
562 }
563
564 /**
565 * Returns total ms.
566 * @param streamsize
567 * @return total milliseconds
568 */
569 public float total_ms(int streamsize) // E.B
570 {
571 return(max_number_of_frames(streamsize) * ms_per_frame());
572 }
573
574 /**
575 * Returns synchronized header.
576 */
577 public int getSyncHeader() // E.B
578 {
579 return _headerstring;
580 }
581
582 // functions which return header informations as strings:
583 /**
584 * Return Layer version.
585 */
586 public String layer_string()
587 {
588 switch (h_layer)
589 {
590 case 1:
591 return "I";
592 case 2:
593 return "II";
594 case 3:
595 return "III";
596 }
597 return null;
598 }
599
600 // E.B -> private to public
601 public static final String bitrate_str[][][] = {
602 {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
603 "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",
604 "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",
605 "forbidden"},
606 {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
607 "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
608 "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
609 "forbidden"},
610 {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
611 "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
612 "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
613 "forbidden"}},
614
615 {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s",
616 "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s",
617 "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s",
618 "forbidden"},
619 {"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
620 "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s",
621 "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s",
622 "forbidden"},
623 {"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s",
624 "64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s",
625 "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s",
626 "forbidden"}},
627 // SZD: MPEG2.5
628 {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
629 "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",
630 "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",
631 "forbidden"},
632 {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
633 "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
634 "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
635 "forbidden"},
636 {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
637 "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
638 "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
639 "forbidden"}},
640 };
641
642 /**
643 * Return Bitrate.
644 * @return bitrate in bps
645 */
646 public String bitrate_string()
647 {
648 if (h_vbr == true)
649 {
650 return Integer.toString(bitrate()/1000)+" kb/s";
651 }
652 else return bitrate_str[h_version][h_layer - 1][h_bitrate_index];
653 }
654
655 /**
656 * Return Bitrate.
657 * @return bitrate in bps and average bitrate for VBR header
658 */
659 public int bitrate()
660 {
661 if (h_vbr == true)
662 {
663 return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames)))*1000;
664 }
665 else return bitrates[h_version][h_layer - 1][h_bitrate_index];
666 }
667
668 /**
669 * Return Instant Bitrate.
670 * Bitrate for VBR is not constant.
671 * @return bitrate in bps
672 */
673 public int bitrate_instant()
674 {
675 return bitrates[h_version][h_layer - 1][h_bitrate_index];
676 }
677
678 /**
679 * Returns Frequency
680 * @return frequency string in kHz
681 */
682 public String sample_frequency_string()
683 {
684 switch (h_sample_frequency)
685 {
686 case THIRTYTWO:
687 if (h_version == MPEG1)
688 return "32 kHz";
689 else if (h_version == MPEG2_LSF)
690 return "16 kHz";
691 else // SZD
692 return "8 kHz";
693 case FOURTYFOUR_POINT_ONE:
694 if (h_version == MPEG1)
695 return "44.1 kHz";
696 else if (h_version == MPEG2_LSF)
697 return "22.05 kHz";
698 else // SZD
699 return "11.025 kHz";
700 case FOURTYEIGHT:
701 if (h_version == MPEG1)
702 return "48 kHz";
703 else if (h_version == MPEG2_LSF)
704 return "24 kHz";
705 else // SZD
706 return "12 kHz";
707 }
708 return(null);
709 }
710
711 /**
712 * Returns Mode.
713 */
714 public String mode_string()
715 {
716 switch (h_mode)
717 {
718 case STEREO:
719 return "Stereo";
720 case JOINT_STEREO:
721 return "Joint stereo";
722 case DUAL_CHANNEL:
723 return "Dual channel";
724 case SINGLE_CHANNEL:
725 return "Single channel";
726 }
727 return null;
728 }
729
730 /**
731 * Returns Version.
732 * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF
733 */
734 public String version_string()
735 {
736 switch (h_version)
737 {
738 case MPEG1:
739 return "MPEG-1";
740 case MPEG2_LSF:
741 return "MPEG-2 LSF";
742 case MPEG25_LSF: // SZD
743 return "MPEG-2.5 LSF";
744 }
745 return(null);
746 }
747
748 /**
749 * Returns the number of subbands in the current frame.
750 * @return number of subbands
751 */
752 public int number_of_subbands() {return h_number_of_subbands;}
753
754 /**
755 * Returns Intensity Stereo.
756 * (Layer II joint stereo only).
757 * Returns the number of subbands which are in stereo mode,
758 * subbands above that limit are in intensity stereo mode.
759 * @return intensity
760 */
761 public int intensity_stereo_bound() {return h_intensity_stereo_bound;}
762}
diff --git a/songdbj/javazoom/jl/decoder/InputStreamSource.java b/songdbj/javazoom/jl/decoder/InputStreamSource.java
new file mode 100644
index 0000000000..5c62947049
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/InputStreamSource.java
@@ -0,0 +1,80 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
21package javazoom.jl.decoder;
22
23import java.io.IOException;
24import java.io.InputStream;
25
26/**
27 * <i>Work In Progress.</i>
28 *
29 * An instance of <code>InputStreamSource</code> implements a
30 * <code>Source</code> that provides data from an <code>InputStream
31 * </code>. Seeking functionality is not supported.
32 *
33 * @author MDM
34 */
35public class InputStreamSource implements Source
36{
37 private final InputStream in;
38
39 public InputStreamSource(InputStream in)
40 {
41 if (in==null)
42 throw new NullPointerException("in");
43
44 this.in = in;
45 }
46
47 public int read(byte[] b, int offs, int len)
48 throws IOException
49 {
50 int read = in.read(b, offs, len);
51 return read;
52 }
53
54 public boolean willReadBlock()
55 {
56 return true;
57 //boolean block = (in.available()==0);
58 //return block;
59 }
60
61 public boolean isSeekable()
62 {
63 return false;
64 }
65
66 public long tell()
67 {
68 return -1;
69 }
70
71 public long seek(long to)
72 {
73 return -1;
74 }
75
76 public long length()
77 {
78 return -1;
79 }
80}
diff --git a/songdbj/javazoom/jl/decoder/JavaLayerError.java b/songdbj/javazoom/jl/decoder/JavaLayerError.java
new file mode 100644
index 0000000000..d9910bcc71
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/JavaLayerError.java
@@ -0,0 +1,31 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
21package javazoom.jl.decoder;
22
23/**
24 * Work in progress.
25 *
26 * API usage errors may be handled by throwing an instance of this
27 * class, as per JMF 2.0.
28 */
29public class JavaLayerError extends Error
30{
31}
diff --git a/songdbj/javazoom/jl/decoder/JavaLayerErrors.java b/songdbj/javazoom/jl/decoder/JavaLayerErrors.java
new file mode 100644
index 0000000000..3b9c2ff9d7
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/JavaLayerErrors.java
@@ -0,0 +1,40 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
21package javazoom.jl.decoder;
22
23/**
24 * Exception erorr codes for components of the JavaLayer API.
25 */
26public interface JavaLayerErrors
27{
28 /**
29 * The first bitstream error code. See the {@link DecoderErrors DecoderErrors}
30 * interface for other bitstream error codes.
31 */
32 static public final int BITSTREAM_ERROR = 0x100;
33
34 /**
35 * The first decoder error code. See the {@link DecoderErrors DecoderErrors}
36 * interface for other decoder error codes.
37 */
38 static public final int DECODER_ERROR = 0x200;
39
40}
diff --git a/songdbj/javazoom/jl/decoder/JavaLayerException.java b/songdbj/javazoom/jl/decoder/JavaLayerException.java
new file mode 100644
index 0000000000..e7a50a8340
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/JavaLayerException.java
@@ -0,0 +1,80 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
21package javazoom.jl.decoder;
22
23import java.io.PrintStream;
24
25
26/**
27 * The JavaLayerException is the base class for all API-level
28 * exceptions thrown by JavaLayer. To facilitate conversion and
29 * common handling of exceptions from other domains, the class
30 * can delegate some functionality to a contained Throwable instance.
31 * <p>
32 *
33 * @author MDM
34 */
35public class JavaLayerException extends Exception
36{
37
38 private Throwable exception;
39
40
41 public JavaLayerException()
42 {
43 }
44
45 public JavaLayerException(String msg)
46 {
47 super(msg);
48 }
49
50 public JavaLayerException(String msg, Throwable t)
51 {
52 super(msg);
53 exception = t;
54 }
55
56 public Throwable getException()
57 {
58 return exception;
59 }
60
61
62 public void printStackTrace()
63 {
64 printStackTrace(System.err);
65 }
66
67 public void printStackTrace(PrintStream ps)
68 {
69 if (this.exception==null)
70 {
71 super.printStackTrace(ps);
72 }
73 else
74 {
75 exception.printStackTrace();
76 }
77 }
78
79
80}
diff --git a/songdbj/javazoom/jl/decoder/JavaLayerHook.java b/songdbj/javazoom/jl/decoder/JavaLayerHook.java
new file mode 100644
index 0000000000..352059433d
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/JavaLayerHook.java
@@ -0,0 +1,36 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.decoder;
21
22import java.io.InputStream;
23
24/**
25 * The <code>JavaLayerHooks</code> class allows developers to change
26 * the way the JavaLayer library uses Resources.
27 */
28
29public interface JavaLayerHook
30{
31 /**
32 * Retrieves the named resource. This allows resources to be
33 * obtained without specifying how they are retrieved.
34 */
35 public InputStream getResourceAsStream(String name);
36}
diff --git a/songdbj/javazoom/jl/decoder/JavaLayerUtils.java b/songdbj/javazoom/jl/decoder/JavaLayerUtils.java
new file mode 100644
index 0000000000..c9ce3838e5
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/JavaLayerUtils.java
@@ -0,0 +1,207 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/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
21package javazoom.jl.decoder;
22
23import java.io.IOException;
24import java.io.InputStream;
25import java.io.InvalidClassException;
26import java.io.InvalidObjectException;
27import java.io.ObjectInputStream;
28import java.io.ObjectOutputStream;
29import java.io.OutputStream;
30import java.lang.reflect.Array;
31
32/**
33 * The JavaLayerUtils class is not strictly part of the JavaLayer API.
34 * It serves to provide useful methods and system-wide hooks.
35 *
36 * @author MDM
37 */
38public class JavaLayerUtils
39{
40 static private JavaLayerHook hook = null;
41
42 /**
43 * Deserializes the object contained in the given input stream.
44 * @param in The input stream to deserialize an object from.
45 * @param cls The expected class of the deserialized object.
46 */
47 static public Object deserialize(InputStream in, Class cls)
48 throws IOException
49 {
50 if (cls==null)
51 throw new NullPointerException("cls");
52
53 Object obj = deserialize(in, cls);
54 if (!cls.isInstance(obj))
55 {
56 throw new InvalidObjectException("type of deserialized instance not of required class.");
57 }
58
59 return obj;
60 }
61
62 /**
63 * Deserializes an object from the given <code>InputStream</code>.
64 * The deserialization is delegated to an <code>
65 * ObjectInputStream</code> instance.
66 *
67 * @param in The <code>InputStream</code> to deserialize an object
68 * from.
69 *
70 * @return The object deserialized from the stream.
71 * @exception IOException is thrown if there was a problem reading
72 * the underlying stream, or an object could not be deserialized
73 * from the stream.
74 *
75 * @see java.io.ObjectInputStream
76 */
77 static public Object deserialize(InputStream in)
78 throws IOException
79 {
80 if (in==null)
81 throw new NullPointerException("in");
82
83 ObjectInputStream objIn = new ObjectInputStream(in);
84
85 Object obj;
86
87 try
88 {
89 obj = objIn.readObject();
90 }
91 catch (ClassNotFoundException ex)
92 {
93 throw new InvalidClassException(ex.toString());
94 }
95
96 return obj;
97 }
98
99 /**
100 * Deserializes an array from a given <code>InputStream</code>.
101 *
102 * @param in The <code>InputStream</code> to
103 * deserialize an object from.
104 *
105 * @param elemType The class denoting the type of the array
106 * elements.
107 * @param length The expected length of the array, or -1 if
108 * any length is expected.
109 */
110 static public Object deserializeArray(InputStream in, Class elemType, int length)
111 throws IOException
112 {
113 if (elemType==null)
114 throw new NullPointerException("elemType");
115
116 if (length<-1)
117 throw new IllegalArgumentException("length");
118
119 Object obj = deserialize(in);
120
121 Class cls = obj.getClass();
122
123
124 if (!cls.isArray())
125 throw new InvalidObjectException("object is not an array");
126
127 Class arrayElemType = cls.getComponentType();
128 if (arrayElemType!=elemType)
129 throw new InvalidObjectException("unexpected array component type");
130
131 if (length != -1)
132 {
133 int arrayLength = Array.getLength(obj);
134 if (arrayLength!=length)
135 throw new InvalidObjectException("array length mismatch");
136 }
137
138 return obj;
139 }
140
141 static public Object deserializeArrayResource(String name, Class elemType, int length)
142 throws IOException
143 {
144 InputStream str = getResourceAsStream(name);
145 if (str==null)
146 throw new IOException("unable to load resource '"+name+"'");
147
148 Object obj = deserializeArray(str, elemType, length);
149
150 return obj;
151 }
152
153 static public void serialize(OutputStream out, Object obj)
154 throws IOException
155 {
156 if (out==null)
157 throw new NullPointerException("out");
158
159 if (obj==null)
160 throw new NullPointerException("obj");
161
162 ObjectOutputStream objOut = new ObjectOutputStream(out);
163 objOut.writeObject(obj);
164
165 }
166
167 /**
168 * Sets the system-wide JavaLayer hook.
169 */
170 static synchronized public void setHook(JavaLayerHook hook0)
171 {
172 hook = hook0;
173 }
174
175 static synchronized public JavaLayerHook getHook()
176 {
177 return hook;
178 }
179
180 /**
181 * Retrieves an InputStream for a named resource.
182 *
183 * @param name The name of the resource. This must be a simple
184 * name, and not a qualified package name.
185 *
186 * @return The InputStream for the named resource, or null if
187 * the resource has not been found. If a hook has been
188 * provided, its getResourceAsStream() method is called
189 * to retrieve the resource.
190 */
191 static synchronized public InputStream getResourceAsStream(String name)
192 {
193 InputStream is = null;
194
195 if (hook!=null)
196 {
197 is = hook.getResourceAsStream(name);
198 }
199 else
200 {
201 Class cls = JavaLayerUtils.class;
202 is = cls.getResourceAsStream(name);
203 }
204
205 return is;
206 }
207}
diff --git a/songdbj/javazoom/jl/decoder/LayerIDecoder.java b/songdbj/javazoom/jl/decoder/LayerIDecoder.java
new file mode 100644
index 0000000000..b633dd2403
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/LayerIDecoder.java
@@ -0,0 +1,444 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 12/12/99 Initial version. Adapted from javalayer.java
5 * and Subband*.java. mdm@techie.com
6 *
7 * 02/28/99 Initial version : javalayer.java by E.B
8 *-----------------------------------------------------------------------
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *----------------------------------------------------------------------
23 */
24
25package javazoom.jl.decoder;
26
27/**
28 * Implements decoding of MPEG Audio Layer I frames.
29 */
30class LayerIDecoder implements FrameDecoder
31{
32 protected Bitstream stream;
33 protected Header header;
34 protected SynthesisFilter filter1, filter2;
35 protected Obuffer buffer;
36 protected int which_channels;
37 protected int mode;
38
39 protected int num_subbands;
40 protected Subband[] subbands;
41 protected Crc16 crc = null; // new Crc16[1] to enable CRC checking.
42
43 public LayerIDecoder()
44 {
45 crc = new Crc16();
46 }
47
48 public void create(Bitstream stream0, Header header0,
49 SynthesisFilter filtera, SynthesisFilter filterb,
50 Obuffer buffer0, int which_ch0)
51 {
52 stream = stream0;
53 header = header0;
54 filter1 = filtera;
55 filter2 = filterb;
56 buffer = buffer0;
57 which_channels = which_ch0;
58
59 }
60
61
62
63 public void decodeFrame()
64 {
65
66 num_subbands = header.number_of_subbands();
67 subbands = new Subband[32];
68 mode = header.mode();
69
70 createSubbands();
71
72 readAllocation();
73 readScaleFactorSelection();
74
75 if ((crc != null) || header.checksum_ok())
76 {
77 readScaleFactors();
78
79 readSampleData();
80 }
81
82 }
83
84 protected void createSubbands()
85 {
86 int i;
87 if (mode == Header.SINGLE_CHANNEL)
88 for (i = 0; i < num_subbands; ++i)
89 subbands[i] = new SubbandLayer1(i);
90 else if (mode == Header.JOINT_STEREO)
91 {
92 for (i = 0; i < header.intensity_stereo_bound(); ++i)
93 subbands[i] = new SubbandLayer1Stereo(i);
94 for (; i < num_subbands; ++i)
95 subbands[i] = new SubbandLayer1IntensityStereo(i);
96 }
97 else
98 {
99 for (i = 0; i < num_subbands; ++i)
100 subbands[i] = new SubbandLayer1Stereo(i);
101 }
102 }
103
104 protected void readAllocation()
105 {
106 // start to read audio data:
107 for (int i = 0; i < num_subbands; ++i)
108 subbands[i].read_allocation(stream, header, crc);
109
110 }
111
112 protected void readScaleFactorSelection()
113 {
114 // scale factor selection not present for layer I.
115 }
116
117 protected void readScaleFactors()
118 {
119 for (int i = 0; i < num_subbands; ++i)
120 subbands[i].read_scalefactor(stream, header);
121 }
122
123 protected void readSampleData()
124 {
125 boolean read_ready = false;
126 boolean write_ready = false;
127 int mode = header.mode();
128 int i;
129 do
130 {
131 for (i = 0; i < num_subbands; ++i)
132 read_ready = subbands[i].read_sampledata(stream);
133 do
134 {
135 for (i = 0; i < num_subbands; ++i)
136 write_ready = subbands[i].put_next_sample(which_channels,filter1, filter2);
137
138 filter1.calculate_pcm_samples(buffer);
139 if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL))
140 filter2.calculate_pcm_samples(buffer);
141 } while (!write_ready);
142 } while (!read_ready);
143
144 }
145
146 /**
147 * Abstract base class for subband classes of layer I and II
148 */
149 static abstract class Subband
150 {
151 /*
152 * Changes from version 1.1 to 1.2:
153 * - array size increased by one, although a scalefactor with index 63
154 * is illegal (to prevent segmentation faults)
155 */
156 // Scalefactors for layer I and II, Annex 3-B.1 in ISO/IEC DIS 11172:
157 public static final float scalefactors[] =
158 {
159 2.00000000000000f, 1.58740105196820f, 1.25992104989487f, 1.00000000000000f,
160 0.79370052598410f, 0.62996052494744f, 0.50000000000000f, 0.39685026299205f,
161 0.31498026247372f, 0.25000000000000f, 0.19842513149602f, 0.15749013123686f,
162 0.12500000000000f, 0.09921256574801f, 0.07874506561843f, 0.06250000000000f,
163 0.04960628287401f, 0.03937253280921f, 0.03125000000000f, 0.02480314143700f,
164 0.01968626640461f, 0.01562500000000f, 0.01240157071850f, 0.00984313320230f,
165 0.00781250000000f, 0.00620078535925f, 0.00492156660115f, 0.00390625000000f,
166 0.00310039267963f, 0.00246078330058f, 0.00195312500000f, 0.00155019633981f,
167 0.00123039165029f, 0.00097656250000f, 0.00077509816991f, 0.00061519582514f,
168 0.00048828125000f, 0.00038754908495f, 0.00030759791257f, 0.00024414062500f,
169 0.00019377454248f, 0.00015379895629f, 0.00012207031250f, 0.00009688727124f,
170 0.00007689947814f, 0.00006103515625f, 0.00004844363562f, 0.00003844973907f,
171 0.00003051757813f, 0.00002422181781f, 0.00001922486954f, 0.00001525878906f,
172 0.00001211090890f, 0.00000961243477f, 0.00000762939453f, 0.00000605545445f,
173 0.00000480621738f, 0.00000381469727f, 0.00000302772723f, 0.00000240310869f,
174 0.00000190734863f, 0.00000151386361f, 0.00000120155435f, 0.00000000000000f /* illegal scalefactor */
175 };
176
177 public abstract void read_allocation (Bitstream stream, Header header, Crc16 crc);
178 public abstract void read_scalefactor (Bitstream stream, Header header);
179 public abstract boolean read_sampledata (Bitstream stream);
180 public abstract boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2);
181 };
182
183 /**
184 * Class for layer I subbands in single channel mode.
185 * Used for single channel mode
186 * and in derived class for intensity stereo mode
187 */
188 static class SubbandLayer1 extends Subband
189 {
190
191 // Factors and offsets for sample requantization
192 public static final float table_factor[] = {
193 0.0f, (1.0f/2.0f) * (4.0f/3.0f), (1.0f/4.0f) * (8.0f/7.0f), (1.0f/8.0f) * (16.0f/15.0f),
194 (1.0f/16.0f) * (32.0f/31.0f), (1.0f/32.0f) * (64.0f/63.0f), (1.0f/64.0f) * (128.0f/127.0f),
195 (1.0f/128.0f) * (256.0f/255.0f), (1.0f/256.0f) * (512.0f/511.0f),
196 (1.0f/512.0f) * (1024.0f/1023.0f), (1.0f/1024.0f) * (2048.0f/2047.0f),
197 (1.0f/2048.0f) * (4096.0f/4095.0f), (1.0f/4096.0f) * (8192.0f/8191.0f),
198 (1.0f/8192.0f) * (16384.0f/16383.0f), (1.0f/16384.0f) * (32768.0f/32767.0f)
199 };
200
201 public static final float table_offset[] = {
202 0.0f, ((1.0f/2.0f)-1.0f) * (4.0f/3.0f), ((1.0f/4.0f)-1.0f) * (8.0f/7.0f), ((1.0f/8.0f)-1.0f) * (16.0f/15.0f),
203 ((1.0f/16.0f)-1.0f) * (32.0f/31.0f), ((1.0f/32.0f)-1.0f) * (64.0f/63.0f), ((1.0f/64.0f)-1.0f) * (128.0f/127.0f),
204 ((1.0f/128.0f)-1.0f) * (256.0f/255.0f), ((1.0f/256.0f)-1.0f) * (512.0f/511.0f),
205 ((1.0f/512.0f)-1.0f) * (1024.0f/1023.0f), ((1.0f/1024.0f)-1.0f) * (2048.0f/2047.0f),
206 ((1.0f/2048.0f)-1.0f) * (4096.0f/4095.0f), ((1.0f/4096.0f)-1.0f) * (8192.0f/8191.0f),
207 ((1.0f/8192.0f)-1.0f) * (16384.0f/16383.0f), ((1.0f/16384.0f)-1.0f) * (32768.0f/32767.0f)
208 };
209
210 protected int subbandnumber;
211 protected int samplenumber;
212 protected int allocation;
213 protected float scalefactor;
214 protected int samplelength;
215 protected float sample;
216 protected float factor, offset;
217
218 /**
219 * Construtor.
220 */
221 public SubbandLayer1(int subbandnumber)
222 {
223 this.subbandnumber = subbandnumber;
224 samplenumber = 0;
225 }
226
227 /**
228 *
229 */
230 public void read_allocation(Bitstream stream, Header header, Crc16 crc)
231 {
232 if ((allocation = stream.get_bits (4)) == 15) ;
233 // cerr << "WARNING: stream contains an illegal allocation!\n";
234 // MPEG-stream is corrupted!
235 if (crc != null)
236 crc.add_bits (allocation, 4);
237 if (allocation != 0)
238 {
239 samplelength = allocation + 1;
240 factor = table_factor[allocation];
241 offset = table_offset[allocation];
242 }
243 }
244
245 /**
246 *
247 */
248 public void read_scalefactor(Bitstream stream, Header header)
249 {
250 if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)];
251 }
252
253 /**
254 *
255 */
256 public boolean read_sampledata(Bitstream stream)
257 {
258 if (allocation != 0)
259 {
260 sample = (float) (stream.get_bits(samplelength));
261 }
262 if (++samplenumber == 12)
263 {
264 samplenumber = 0;
265 return true;
266 }
267 return false;
268 }
269
270 /**
271 *
272 */
273 public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
274 {
275 if ((allocation !=0) && (channels != OutputChannels.RIGHT_CHANNEL))
276 {
277 float scaled_sample = (sample * factor + offset) * scalefactor;
278 filter1.input_sample (scaled_sample, subbandnumber);
279 }
280 return true;
281 }
282 };
283
284 /**
285 * Class for layer I subbands in joint stereo mode.
286 */
287 static class SubbandLayer1IntensityStereo extends SubbandLayer1
288 {
289 protected float channel2_scalefactor;
290
291 /**
292 * Constructor
293 */
294 public SubbandLayer1IntensityStereo(int subbandnumber)
295 {
296 super(subbandnumber);
297 }
298
299 /**
300 *
301 */
302 public void read_allocation(Bitstream stream, Header header, Crc16 crc)
303 {
304 super.read_allocation (stream, header, crc);
305 }
306
307 /**
308 *
309 */
310 public void read_scalefactor (Bitstream stream, Header header)
311 {
312 if (allocation != 0)
313 {
314 scalefactor = scalefactors[stream.get_bits(6)];
315 channel2_scalefactor = scalefactors[stream.get_bits(6)];
316 }
317 }
318
319 /**
320 *
321 */
322 public boolean read_sampledata(Bitstream stream)
323 {
324 return super.read_sampledata (stream);
325 }
326
327 /**
328 *
329 */
330 public boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2)
331 {
332 if (allocation !=0 )
333 {
334 sample = sample * factor + offset; // requantization
335 if (channels == OutputChannels.BOTH_CHANNELS)
336 {
337 float sample1 = sample * scalefactor,
338 sample2 = sample * channel2_scalefactor;
339 filter1.input_sample(sample1, subbandnumber);
340 filter2.input_sample(sample2, subbandnumber);
341 }
342 else if (channels == OutputChannels.LEFT_CHANNEL)
343 {
344 float sample1 = sample * scalefactor;
345 filter1.input_sample(sample1, subbandnumber);
346 }
347 else
348 {
349 float sample2 = sample * channel2_scalefactor;
350 filter1.input_sample(sample2, subbandnumber);
351 }
352 }
353 return true;
354 }
355 };
356
357 /**
358 * Class for layer I subbands in stereo mode.
359 */
360 static class SubbandLayer1Stereo extends SubbandLayer1
361 {
362 protected int channel2_allocation;
363 protected float channel2_scalefactor;
364 protected int channel2_samplelength;
365 protected float channel2_sample;
366 protected float channel2_factor, channel2_offset;
367
368
369 /**
370 * Constructor
371 */
372 public SubbandLayer1Stereo(int subbandnumber)
373 {
374 super(subbandnumber);
375 }
376
377 /**
378 *
379 */
380 public void read_allocation (Bitstream stream, Header header, Crc16 crc)
381 {
382 allocation = stream.get_bits(4);
383 channel2_allocation = stream.get_bits(4);
384 if (crc != null)
385 {
386 crc.add_bits (allocation, 4);
387 crc.add_bits (channel2_allocation, 4);
388 }
389 if (allocation != 0)
390 {
391 samplelength = allocation + 1;
392 factor = table_factor[allocation];
393 offset = table_offset[allocation];
394 }
395 if (channel2_allocation != 0)
396 {
397 channel2_samplelength = channel2_allocation + 1;
398 channel2_factor = table_factor[channel2_allocation];
399 channel2_offset = table_offset[channel2_allocation];
400 }
401 }
402
403 /**
404 *
405 */
406 public void read_scalefactor(Bitstream stream, Header header)
407 {
408 if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)];
409 if (channel2_allocation != 0) channel2_scalefactor = scalefactors[stream.get_bits(6)];
410 }
411
412 /**
413 *
414 */
415 public boolean read_sampledata (Bitstream stream)
416 {
417 boolean returnvalue = super.read_sampledata(stream);
418 if (channel2_allocation != 0)
419 {
420 channel2_sample = (float) (stream.get_bits(channel2_samplelength));
421 }
422 return(returnvalue);
423 }
424
425 /**
426 *
427 */
428 public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
429 {
430 super.put_next_sample (channels, filter1, filter2);
431 if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL))
432 {
433 float sample2 = (channel2_sample * channel2_factor + channel2_offset) *
434 channel2_scalefactor;
435 if (channels == OutputChannels.BOTH_CHANNELS)
436 filter2.input_sample (sample2, subbandnumber);
437 else
438 filter1.input_sample (sample2, subbandnumber);
439 }
440 return true;
441 }
442 };
443
444}
diff --git a/songdbj/javazoom/jl/decoder/LayerIIDecoder.java b/songdbj/javazoom/jl/decoder/LayerIIDecoder.java
new file mode 100644
index 0000000000..7265b1f8fa
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/LayerIIDecoder.java
@@ -0,0 +1,1064 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 29/05/01 Michael Scheerer, Fixed some C++ to Java porting bugs.
5 *
6 * 16/07/01 Michael Scheerer, Catched a bug in method
7 * read_sampledata, which causes an outOfIndexException.
8 *
9 * 12/12/99 Initial version. Adapted from javalayer.java
10 * and Subband*.java. mdm@techie.com
11 *
12 * 02/28/99 Initial version : javalayer.java by E.B
13 *-----------------------------------------------------------------------
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as published
16 * by the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *----------------------------------------------------------------------
28 */
29
30package javazoom.jl.decoder;
31
32/**
33 * Implements decoding of MPEG Audio Layer II frames.
34 */
35class LayerIIDecoder extends LayerIDecoder implements FrameDecoder
36{
37
38 public LayerIIDecoder()
39 {
40 }
41
42
43 protected void createSubbands()
44 {
45 int i;
46 if (mode == Header.SINGLE_CHANNEL)
47 for (i = 0; i < num_subbands; ++i)
48 subbands[i] = new SubbandLayer2(i);
49 else if (mode == Header.JOINT_STEREO)
50 {
51 for (i = 0; i < header.intensity_stereo_bound(); ++i)
52 subbands[i] = new SubbandLayer2Stereo(i);
53 for (; i < num_subbands; ++i)
54 subbands[i] = new SubbandLayer2IntensityStereo(i);
55 }
56 else
57 {
58 for (i = 0; i < num_subbands; ++i)
59 subbands[i] = new SubbandLayer2Stereo(i);
60 }
61
62 }
63
64 protected void readScaleFactorSelection()
65 {
66 for (int i = 0; i < num_subbands; ++i)
67 ((SubbandLayer2)subbands[i]).read_scalefactor_selection(stream, crc);
68 }
69
70
71
72 /**
73 * Class for layer II subbands in single channel mode.
74 */
75 static class SubbandLayer2 extends Subband
76 {
77 // this table contains 3 requantized samples for each legal codeword
78 // when grouped in 5 bits, i.e. 3 quantizationsteps per sample
79 public static final float grouping_5bits[] = new float[]
80 {
81 -2.0f/3.0f, -2.0f/3.0f, -2.0f/3.0f,
82 0.0f, -2.0f/3.0f, -2.0f/3.0f,
83 2.0f/3.0f, -2.0f/3.0f, -2.0f/3.0f,
84 -2.0f/3.0f, 0.0f, -2.0f/3.0f,
85 0.0f, 0.0f, -2.0f/3.0f,
86 2.0f/3.0f, 0.0f, -2.0f/3.0f,
87 -2.0f/3.0f, 2.0f/3.0f, -2.0f/3.0f,
88 0.0f, 2.0f/3.0f, -2.0f/3.0f,
89 2.0f/3.0f, 2.0f/3.0f, -2.0f/3.0f,
90 -2.0f/3.0f, -2.0f/3.0f, 0.0f,
91 0.0f, -2.0f/3.0f, 0.0f,
92 2.0f/3.0f, -2.0f/3.0f, 0.0f,
93 -2.0f/3.0f, 0.0f, 0.0f,
94 0.0f, 0.0f, 0.0f,
95 2.0f/3.0f, 0.0f, 0.0f,
96 -2.0f/3.0f, 2.0f/3.0f, 0.0f,
97 0.0f, 2.0f/3.0f, 0.0f,
98 2.0f/3.0f, 2.0f/3.0f, 0.0f,
99 -2.0f/3.0f, -2.0f/3.0f, 2.0f/3.0f,
100 0.0f, -2.0f/3.0f, 2.0f/3.0f,
101 2.0f/3.0f, -2.0f/3.0f, 2.0f/3.0f,
102 -2.0f/3.0f, 0.0f, 2.0f/3.0f,
103 0.0f, 0.0f, 2.0f/3.0f,
104 2.0f/3.0f, 0.0f, 2.0f/3.0f,
105 -2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f,
106 0.0f, 2.0f/3.0f, 2.0f/3.0f,
107 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f
108 };
109
110 // this table contains 3 requantized samples for each legal codeword
111 // when grouped in 7 bits, i.e. 5 quantizationsteps per sample
112 public static final float grouping_7bits[] = new float[]
113 {
114 -0.8f, -0.8f, -0.8f, -0.4f, -0.8f, -0.8f, 0.0f, -0.8f, -0.8f, 0.4f, -0.8f, -0.8f, 0.8f, -0.8f, -0.8f,
115 -0.8f, -0.4f, -0.8f, -0.4f, -0.4f, -0.8f, 0.0f, -0.4f, -0.8f, 0.4f, -0.4f, -0.8f, 0.8f, -0.4f, -0.8f,
116 -0.8f, 0.0f, -0.8f, -0.4f, 0.0f, -0.8f, 0.0f, 0.0f, -0.8f, 0.4f, 0.0f, -0.8f, 0.8f, 0.0f, -0.8f,
117 -0.8f, 0.4f, -0.8f, -0.4f, 0.4f, -0.8f, 0.0f, 0.4f, -0.8f, 0.4f, 0.4f, -0.8f, 0.8f, 0.4f, -0.8f,
118 -0.8f, 0.8f, -0.8f, -0.4f, 0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.4f, 0.8f, -0.8f, 0.8f, 0.8f, -0.8f,
119 -0.8f, -0.8f, -0.4f, -0.4f, -0.8f, -0.4f, 0.0f, -0.8f, -0.4f, 0.4f, -0.8f, -0.4f, 0.8f, -0.8f, -0.4f,
120 -0.8f, -0.4f, -0.4f, -0.4f, -0.4f, -0.4f, 0.0f, -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.8f, -0.4f, -0.4f,
121 -0.8f, 0.0f, -0.4f, -0.4f, 0.0f, -0.4f, 0.0f, 0.0f, -0.4f, 0.4f, 0.0f, -0.4f, 0.8f, 0.0f, -0.4f,
122 -0.8f, 0.4f, -0.4f, -0.4f, 0.4f, -0.4f, 0.0f, 0.4f, -0.4f, 0.4f, 0.4f, -0.4f, 0.8f, 0.4f, -0.4f,
123 -0.8f, 0.8f, -0.4f, -0.4f, 0.8f, -0.4f, 0.0f, 0.8f, -0.4f, 0.4f, 0.8f, -0.4f, 0.8f, 0.8f, -0.4f,
124 -0.8f, -0.8f, 0.0f, -0.4f, -0.8f, 0.0f, 0.0f, -0.8f, 0.0f, 0.4f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f,
125 -0.8f, -0.4f, 0.0f, -0.4f, -0.4f, 0.0f, 0.0f, -0.4f, 0.0f, 0.4f, -0.4f, 0.0f, 0.8f, -0.4f, 0.0f,
126 -0.8f, 0.0f, 0.0f, -0.4f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.4f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f,
127 -0.8f, 0.4f, 0.0f, -0.4f, 0.4f, 0.0f, 0.0f, 0.4f, 0.0f, 0.4f, 0.4f, 0.0f, 0.8f, 0.4f, 0.0f,
128 -0.8f, 0.8f, 0.0f, -0.4f, 0.8f, 0.0f, 0.0f, 0.8f, 0.0f, 0.4f, 0.8f, 0.0f, 0.8f, 0.8f, 0.0f,
129 -0.8f, -0.8f, 0.4f, -0.4f, -0.8f, 0.4f, 0.0f, -0.8f, 0.4f, 0.4f, -0.8f, 0.4f, 0.8f, -0.8f, 0.4f,
130 -0.8f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.0f, -0.4f, 0.4f, 0.4f, -0.4f, 0.4f, 0.8f, -0.4f, 0.4f,
131 -0.8f, 0.0f, 0.4f, -0.4f, 0.0f, 0.4f, 0.0f, 0.0f, 0.4f, 0.4f, 0.0f, 0.4f, 0.8f, 0.0f, 0.4f,
132 -0.8f, 0.4f, 0.4f, -0.4f, 0.4f, 0.4f, 0.0f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.4f, 0.4f,
133 -0.8f, 0.8f, 0.4f, -0.4f, 0.8f, 0.4f, 0.0f, 0.8f, 0.4f, 0.4f, 0.8f, 0.4f, 0.8f, 0.8f, 0.4f,
134 -0.8f, -0.8f, 0.8f, -0.4f, -0.8f, 0.8f, 0.0f, -0.8f, 0.8f, 0.4f, -0.8f, 0.8f, 0.8f, -0.8f, 0.8f,
135 -0.8f, -0.4f, 0.8f, -0.4f, -0.4f, 0.8f, 0.0f, -0.4f, 0.8f, 0.4f, -0.4f, 0.8f, 0.8f, -0.4f, 0.8f,
136 -0.8f, 0.0f, 0.8f, -0.4f, 0.0f, 0.8f, 0.0f, 0.0f, 0.8f, 0.4f, 0.0f, 0.8f, 0.8f, 0.0f, 0.8f,
137 -0.8f, 0.4f, 0.8f, -0.4f, 0.4f, 0.8f, 0.0f, 0.4f, 0.8f, 0.4f, 0.4f, 0.8f, 0.8f, 0.4f, 0.8f,
138 -0.8f, 0.8f, 0.8f, -0.4f, 0.8f, 0.8f, 0.0f, 0.8f, 0.8f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f
139 };
140
141 // this table contains 3 requantized samples for each legal codeword
142 // when grouped in 10 bits, i.e. 9 quantizationsteps per sample
143 public static final float grouping_10bits[] =
144 {
145 -8.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f,
146 -2.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 0.0f, -8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f,
147 4.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -8.0f/9.0f,
148 -8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f,
149 -2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 0.0f, -6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f,
150 4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f,
151 -8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f,
152 -2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 0.0f, -4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f,
153 4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f,
154 -8.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f,
155 -2.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 0.0f, -2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f,
156 4.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -8.0f/9.0f,
157 -8.0f/9.0f, 0.0f, -8.0f/9.0f, -6.0f/9.0f, 0.0f, -8.0f/9.0f, -4.0f/9.0f, 0.0f, -8.0f/9.0f,
158 -2.0f/9.0f, 0.0f, -8.0f/9.0f, 0.0f, 0.0f, -8.0f/9.0f, 2.0f/9.0f, 0.0f, -8.0f/9.0f,
159 4.0f/9.0f, 0.0f, -8.0f/9.0f, 6.0f/9.0f, 0.0f, -8.0f/9.0f, 8.0f/9.0f, 0.0f, -8.0f/9.0f,
160 -8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f,
161 -2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 0.0f, 2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f,
162 4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f,
163 -8.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f,
164 -2.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 0.0f, 4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f,
165 4.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -8.0f/9.0f,
166 -8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f,
167 -2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 0.0f, 6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f,
168 4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f,
169 -8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f,
170 -2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 0.0f, 8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f,
171 4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f,
172 -8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f,
173 -2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 0.0f, -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f,
174 4.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -6.0f/9.0f,
175 -8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f,
176 -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f,
177 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f,
178 -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f,
179 -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f,
180 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f,
181 -8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f,
182 -2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 0.0f, -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f,
183 4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f,
184 -8.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f,
185 -2.0f/9.0f, 0.0f, -6.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f,
186 4.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f,
187 -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f,
188 -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f,
189 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f,
190 -8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f,
191 -2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 0.0f, 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f,
192 4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f,
193 -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f,
194 -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f,
195 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f,
196 -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f,
197 -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f,
198 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f,
199 -8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f,
200 -2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 0.0f, -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f,
201 4.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -4.0f/9.0f,
202 -8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f,
203 -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f,
204 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f,
205 -8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f,
206 -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f,
207 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f,
208 -8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f,
209 -2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 0.0f, -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f,
210 4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f,
211 -8.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f,
212 -2.0f/9.0f, 0.0f, -4.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f,
213 4.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f,
214 -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f,
215 -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f,
216 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f,
217 -8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f,
218 -2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 0.0f, 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f,
219 4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f,
220 -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f,
221 -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f,
222 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f,
223 -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f,
224 -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f,
225 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f,
226 -8.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f,
227 -2.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 0.0f, -8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f,
228 4.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, -2.0f/9.0f,
229 -8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f,
230 -2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 0.0f, -6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f,
231 4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f,
232 -8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f,
233 -2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 0.0f, -4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f,
234 4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f,
235 -8.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f,
236 -2.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 0.0f, -2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f,
237 4.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -2.0f/9.0f,
238 -8.0f/9.0f, 0.0f, -2.0f/9.0f, -6.0f/9.0f, 0.0f, -2.0f/9.0f, -4.0f/9.0f, 0.0f, -2.0f/9.0f,
239 -2.0f/9.0f, 0.0f, -2.0f/9.0f, 0.0f, 0.0f, -2.0f/9.0f, 2.0f/9.0f, 0.0f, -2.0f/9.0f,
240 4.0f/9.0f, 0.0f, -2.0f/9.0f, 6.0f/9.0f, 0.0f, -2.0f/9.0f, 8.0f/9.0f, 0.0f, -2.0f/9.0f,
241 -8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f,
242 -2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 0.0f, 2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f,
243 4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f,
244 -8.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f,
245 -2.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 0.0f, 4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f,
246 4.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -2.0f/9.0f,
247 -8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f,
248 -2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 0.0f, 6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f,
249 4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f,
250 -8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f,
251 -2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 0.0f, 8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f,
252 4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f,
253 -8.0f/9.0f, -8.0f/9.0f, 0.0f, -6.0f/9.0f, -8.0f/9.0f, 0.0f, -4.0f/9.0f, -8.0f/9.0f, 0.0f,
254 -2.0f/9.0f, -8.0f/9.0f, 0.0f, 0.0f, -8.0f/9.0f, 0.0f, 2.0f/9.0f, -8.0f/9.0f, 0.0f,
255 4.0f/9.0f, -8.0f/9.0f, 0.0f, 6.0f/9.0f, -8.0f/9.0f, 0.0f, 8.0f/9.0f, -8.0f/9.0f, 0.0f,
256 -8.0f/9.0f, -6.0f/9.0f, 0.0f, -6.0f/9.0f, -6.0f/9.0f, 0.0f, -4.0f/9.0f, -6.0f/9.0f, 0.0f,
257 -2.0f/9.0f, -6.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f,
258 4.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f,
259 -8.0f/9.0f, -4.0f/9.0f, 0.0f, -6.0f/9.0f, -4.0f/9.0f, 0.0f, -4.0f/9.0f, -4.0f/9.0f, 0.0f,
260 -2.0f/9.0f, -4.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f,
261 4.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f,
262 -8.0f/9.0f, -2.0f/9.0f, 0.0f, -6.0f/9.0f, -2.0f/9.0f, 0.0f, -4.0f/9.0f, -2.0f/9.0f, 0.0f,
263 -2.0f/9.0f, -2.0f/9.0f, 0.0f, 0.0f, -2.0f/9.0f, 0.0f, 2.0f/9.0f, -2.0f/9.0f, 0.0f,
264 4.0f/9.0f, -2.0f/9.0f, 0.0f, 6.0f/9.0f, -2.0f/9.0f, 0.0f, 8.0f/9.0f, -2.0f/9.0f, 0.0f,
265 -8.0f/9.0f, 0.0f, 0.0f, -6.0f/9.0f, 0.0f, 0.0f, -4.0f/9.0f, 0.0f, 0.0f,
266 -2.0f/9.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f/9.0f, 0.0f, 0.0f,
267 4.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 0.0f, 0.0f,
268 -8.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f,
269 -2.0f/9.0f, 2.0f/9.0f, 0.0f, 0.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f,
270 4.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f,
271 -8.0f/9.0f, 4.0f/9.0f, 0.0f, -6.0f/9.0f, 4.0f/9.0f, 0.0f, -4.0f/9.0f, 4.0f/9.0f, 0.0f,
272 -2.0f/9.0f, 4.0f/9.0f, 0.0f, 0.0f, 4.0f/9.0f, 0.0f, 2.0f/9.0f, 4.0f/9.0f, 0.0f,
273 4.0f/9.0f, 4.0f/9.0f, 0.0f, 6.0f/9.0f, 4.0f/9.0f, 0.0f, 8.0f/9.0f, 4.0f/9.0f, 0.0f,
274 -8.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f,
275 -2.0f/9.0f, 6.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f,
276 4.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f,
277 -8.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f,
278 -2.0f/9.0f, 8.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f,
279 4.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f,
280 -8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f,
281 -2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 0.0f, -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f,
282 4.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 2.0f/9.0f,
283 -8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f,
284 -2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 0.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f,
285 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f,
286 -8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f,
287 -2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 0.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f,
288 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f,
289 -8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f,
290 -2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 0.0f, -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f,
291 4.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 2.0f/9.0f,
292 -8.0f/9.0f, 0.0f, 2.0f/9.0f, -6.0f/9.0f, 0.0f, 2.0f/9.0f, -4.0f/9.0f, 0.0f, 2.0f/9.0f,
293 -2.0f/9.0f, 0.0f, 2.0f/9.0f, 0.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f,
294 4.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f,
295 -8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f,
296 -2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 0.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f,
297 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f,
298 -8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f,
299 -2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 0.0f, 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f,
300 4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f,
301 -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f,
302 -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f,
303 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f,
304 -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f,
305 -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f,
306 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f,
307 -8.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f,
308 -2.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 0.0f, -8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f,
309 4.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 4.0f/9.0f,
310 -8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f,
311 -2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 0.0f, -6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f,
312 4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f,
313 -8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f,
314 -2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 0.0f, -4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f,
315 4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f,
316 -8.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f,
317 -2.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 0.0f, -2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f,
318 4.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 4.0f/9.0f,
319 -8.0f/9.0f, 0.0f, 4.0f/9.0f, -6.0f/9.0f, 0.0f, 4.0f/9.0f, -4.0f/9.0f, 0.0f, 4.0f/9.0f,
320 -2.0f/9.0f, 0.0f, 4.0f/9.0f, 0.0f, 0.0f, 4.0f/9.0f, 2.0f/9.0f, 0.0f, 4.0f/9.0f,
321 4.0f/9.0f, 0.0f, 4.0f/9.0f, 6.0f/9.0f, 0.0f, 4.0f/9.0f, 8.0f/9.0f, 0.0f, 4.0f/9.0f,
322 -8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f,
323 -2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 0.0f, 2.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f,
324 4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f,
325 -8.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f,
326 -2.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 0.0f, 4.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f,
327 4.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 4.0f/9.0f,
328 -8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f,
329 -2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 0.0f, 6.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f,
330 4.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f,
331 -8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f,
332 -2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 0.0f, 8.0f/9.0f, 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f,
333 4.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f,
334 -8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f,
335 -2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 0.0f, -8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f,
336 4.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 6.0f/9.0f,
337 -8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f,
338 -2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 0.0f, -6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f,
339 4.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f,
340 -8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f,
341 -2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 0.0f, -4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f,
342 4.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f,
343 -8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f,
344 -2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 0.0f, -2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f,
345 4.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 6.0f/9.0f,
346 -8.0f/9.0f, 0.0f, 6.0f/9.0f, -6.0f/9.0f, 0.0f, 6.0f/9.0f, -4.0f/9.0f, 0.0f, 6.0f/9.0f,
347 -2.0f/9.0f, 0.0f, 6.0f/9.0f, 0.0f, 0.0f, 6.0f/9.0f, 2.0f/9.0f, 0.0f, 6.0f/9.0f,
348 4.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f,
349 -8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f,
350 -2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 0.0f, 2.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f,
351 4.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f,
352 -8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f,
353 -2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 0.0f, 4.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f,
354 4.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 6.0f/9.0f,
355 -8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f,
356 -2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 0.0f, 6.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f,
357 4.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f,
358 -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f,
359 -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f,
360 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f,
361 -8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f,
362 -2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 0.0f, -8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f,
363 4.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -8.0f/9.0f, 8.0f/9.0f,
364 -8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f,
365 -2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 0.0f, -6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f,
366 4.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f,
367 -8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f,
368 -2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 0.0f, -4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f,
369 4.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f,
370 -8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f,
371 -2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 0.0f, -2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f,
372 4.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -2.0f/9.0f, 8.0f/9.0f,
373 -8.0f/9.0f, 0.0f, 8.0f/9.0f, -6.0f/9.0f, 0.0f, 8.0f/9.0f, -4.0f/9.0f, 0.0f, 8.0f/9.0f,
374 -2.0f/9.0f, 0.0f, 8.0f/9.0f, 0.0f, 0.0f, 8.0f/9.0f, 2.0f/9.0f, 0.0f, 8.0f/9.0f,
375 4.0f/9.0f, 0.0f, 8.0f/9.0f, 6.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f,
376 -8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f,
377 -2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 0.0f, 2.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f,
378 4.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f,
379 -8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f,
380 -2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 0.0f, 4.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f,
381 4.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 4.0f/9.0f, 8.0f/9.0f,
382 -8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f,
383 -2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 0.0f, 6.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f,
384 4.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f,
385 -8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, -4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f,
386 -2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 0.0f, 8.0f/9.0f, 8.0f/9.0f, 2.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f,
387 4.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 6.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f, 8.0f/9.0f
388 };
389
390 // data taken from ISO/IEC DIS 11172, Annexes 3-B.2[abcd] and 3-B.4:
391
392 // subbands 0-2 in tables 3-B.2a and 2b: (index is allocation)
393 public static final int table_ab1_codelength[] =
394 // bits per codeword
395 { 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
396
397 public static final float table_ab1_groupingtables[][] =
398 // pointer to sample grouping table, or NULL-pointer if ungrouped
399 { null, grouping_5bits, null, null, null, null, null, null, null, null, null, null, null, null, null, null };
400
401 public static final float table_ab1_factor[] =
402 // factor for requantization: (real)sample * factor - 1.0 gives requantized sample
403 { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32.0f, 1.0f/64.0f,
404 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, 1.0f/1024.0f, 1.0f/2048.0f,
405 1.0f/4096.0f, 1.0f/8192.0f, 1.0f/16384.0f, 1.0f/32768.0f };
406
407 public static final float table_ab1_c[] =
408 // factor c for requantization from table 3-B.4
409 { 0.0f, 1.33333333333f, 1.14285714286f, 1.06666666666f, 1.03225806452f,
410 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, 1.00097751711f,
411 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f, 1.00003051851f,
412 1.00001525902f };
413
414 public static final float table_ab1_d[] =
415 // addend d for requantization from table 3-B.4
416 { 0.0f, 0.50000000000f, 0.25000000000f, 0.12500000000f, 0.06250000000f,
417 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, 0.00195312500f,
418 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f, 0.00006103516f,
419 0.00003051758f };
420
421 // subbands 3-... tables 3-B.2a and 2b:
422 public static final float[] table_ab234_groupingtables[] =
423 { null, grouping_5bits, grouping_7bits, null, grouping_10bits, null, null, null, null, null, null, null, null, null, null, null };
424
425 // subbands 3-10 in tables 3-B.2a and 2b:
426 public static final int table_ab2_codelength[] =
427 { 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 };
428 public static final float table_ab2_factor[] =
429 { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f,
430 1.0f/32.0f, 1.0f/64.0f, 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f,
431 1.0f/1024.0f, 1.0f/2048.0f, 1.0f/4096.0f, 1.0f/32768.0f };
432 public static final float table_ab2_c[] =
433 { 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f,
434 1.06666666666f, 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f,
435 1.00195694716f, 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f,
436 1.00001525902f };
437 public static final float table_ab2_d[] =
438 { 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f,
439 0.12500000000f, 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f,
440 0.00390625000f, 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f,
441 0.00003051758f };
442
443 // subbands 11-22 in tables 3-B.2a and 2b:
444 public static final int table_ab3_codelength[] = { 0, 5, 7, 3, 10, 4, 5, 16 };
445 public static final float table_ab3_factor[] =
446 { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32768.0f };
447 public static final float table_ab3_c[] =
448 { 0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f,
449 1.06666666666f, 1.03225806452f, 1.00001525902f };
450 public static final float table_ab3_d[] =
451 { 0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f,
452 0.12500000000f, 0.06250000000f, 0.00003051758f };
453
454 // subbands 23-... in tables 3-B.2a and 2b:
455 public static final int table_ab4_codelength[] = { 0, 5, 7, 16 };
456 public static final float table_ab4_factor[] = { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/32768.0f };
457 public static final float table_ab4_c[] = { 0.0f, 1.33333333333f, 1.60000000000f, 1.00001525902f };
458 public static final float table_ab4_d[] = { 0.0f, 0.50000000000f, 0.50000000000f, 0.00003051758f };
459
460 // subbands in tables 3-B.2c and 2d:
461 public static final int table_cd_codelength[] =
462 { 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
463 public static final float table_cd_groupingtables[][] =
464 { null, grouping_5bits, grouping_7bits, grouping_10bits, null, null, null, null, null, null, null, null, null, null, null, null };
465 public static final float table_cd_factor[] =
466 { 0.0f, 1.0f/2.0f, 1.0f/4.0f, 1.0f/8.0f, 1.0f/8.0f, 1.0f/16.0f, 1.0f/32.0f, 1.0f/64.0f,
467 1.0f/128.0f, 1.0f/256.0f, 1.0f/512.0f, 1.0f/1024.0f, 1.0f/2048.0f, 1.0f/4096.0f,
468 1.0f/8192.0f, 1.0f/16384.0f };
469 public static final float table_cd_c[] =
470 { 0.0f, 1.33333333333f, 1.60000000000f, 1.77777777777f, 1.06666666666f,
471 1.03225806452f, 1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f,
472 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f, 1.00006103888f,
473 1.00003051851f };
474 public static final float table_cd_d[] =
475 { 0.0f, 0.50000000000f, 0.50000000000f, 0.50000000000f, 0.12500000000f,
476 0.06250000000f, 0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f,
477 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f, 0.00012207031f,
478 0.00006103516f };
479
480
481
482 protected int subbandnumber;
483 protected int allocation;
484 protected int scfsi;
485 protected float scalefactor1, scalefactor2, scalefactor3;
486 protected int[] codelength = {0};
487 protected float groupingtable[][] = new float[2][];
488 //protected float[][] groupingtable = {{0},{0}} ;
489 protected float[] factor = {0.0f};
490 protected int groupnumber;
491 protected int samplenumber;
492 protected float[] samples = new float[3];
493 protected float[] c = {0};
494 protected float[] d = {0};
495 /**
496 * Constructor
497 */
498 public SubbandLayer2(int subbandnumber)
499 {
500 this.subbandnumber = subbandnumber;
501 groupnumber = samplenumber = 0;
502 }
503
504
505 /**
506 *
507 */
508 protected int get_allocationlength (Header header)
509 {
510 if (header.version() == Header.MPEG1)
511 {
512 int channel_bitrate = header.bitrate_index();
513
514 // calculate bitrate per channel:
515 if (header.mode() != Header.SINGLE_CHANNEL)
516 if (channel_bitrate == 4)
517 channel_bitrate = 1;
518 else
519 channel_bitrate -= 4;
520
521 if (channel_bitrate == 1 || channel_bitrate == 2)
522 // table 3-B.2c or 3-B.2d
523 if (subbandnumber <= 1)
524 return 4;
525 else
526 return 3;
527 else
528 // tables 3-B.2a or 3-B.2b
529 if (subbandnumber <= 10)
530 return 4;
531 else if (subbandnumber <= 22)
532 return 3;
533 else
534 return 2;
535 }
536 else
537 { // MPEG-2 LSF -- Jeff
538
539 // table B.1 of ISO/IEC 13818-3
540 if (subbandnumber <= 3)
541 return 4;
542 else if (subbandnumber <= 10)
543 return 3;
544 else
545 return 2;
546 }
547 }
548
549 /**
550 *
551 */
552 protected void prepare_sample_reading(Header header, int allocation,
553 //float[][] groupingtable,
554 int channel,
555 float[] factor, int[] codelength,
556 float[] c, float[] d)
557 {
558 int channel_bitrate = header.bitrate_index();
559 // calculate bitrate per channel:
560 if (header.mode() != Header.SINGLE_CHANNEL)
561 if (channel_bitrate == 4)
562 channel_bitrate = 1;
563 else
564 channel_bitrate -= 4;
565
566 if (channel_bitrate == 1 || channel_bitrate == 2)
567 {
568 // table 3-B.2c or 3-B.2d
569 groupingtable[channel] = table_cd_groupingtables[allocation];
570 factor[0] = table_cd_factor[allocation];
571 codelength[0] = table_cd_codelength[allocation];
572 c[0] = table_cd_c[allocation];
573 d[0] = table_cd_d[allocation];
574 }
575 else
576 {
577 // tables 3-B.2a or 3-B.2b
578 if (subbandnumber <= 2)
579 {
580 groupingtable[channel] = table_ab1_groupingtables[allocation];
581 factor[0] = table_ab1_factor[allocation];
582 codelength[0] = table_ab1_codelength[allocation];
583 c[0] = table_ab1_c[allocation];
584 d[0] = table_ab1_d[allocation];
585 }
586 else
587 {
588 groupingtable[channel] = table_ab234_groupingtables[allocation];
589 if (subbandnumber <= 10)
590 {
591 factor[0] = table_ab2_factor[allocation];
592 codelength[0] = table_ab2_codelength[allocation];
593 c[0] = table_ab2_c[allocation];
594 d[0] = table_ab2_d[allocation];
595 }
596 else if (subbandnumber <= 22)
597 {
598 factor[0] = table_ab3_factor[allocation];
599 codelength[0] = table_ab3_codelength[allocation];
600 c[0] = table_ab3_c[allocation];
601 d[0] = table_ab3_d[allocation];
602 }
603 else
604 {
605 factor[0] = table_ab4_factor[allocation];
606 codelength[0] = table_ab4_codelength[allocation];
607 c[0] = table_ab4_c[allocation];
608 d[0] = table_ab4_d[allocation];
609 }
610 }
611 }
612 }
613
614
615 /**
616 *
617 */
618 public void read_allocation(Bitstream stream, Header header, Crc16 crc)
619 {
620 int length = get_allocationlength(header);
621 allocation = stream.get_bits(length);
622 if (crc != null)
623 crc.add_bits(allocation, length);
624 }
625
626 /**
627 *
628 */
629 public void read_scalefactor_selection (Bitstream stream, Crc16 crc)
630 {
631 if (allocation != 0)
632 {
633 scfsi = stream.get_bits(2);
634 if (crc != null) crc.add_bits(scfsi, 2);
635 }
636 }
637
638 /**
639 *
640 */
641 public void read_scalefactor (Bitstream stream, Header header)
642 {
643 if (allocation != 0)
644 {
645 switch (scfsi)
646 {
647 case 0:
648 scalefactor1 = scalefactors[stream.get_bits(6)];
649 scalefactor2 = scalefactors[stream.get_bits(6)];
650 scalefactor3 = scalefactors[stream.get_bits(6)];
651 break;
652 case 1:
653 scalefactor1 = scalefactor2 = scalefactors[stream.get_bits(6)];
654 scalefactor3 = scalefactors[stream.get_bits(6)];
655 break;
656 case 2:
657 scalefactor1 = scalefactor2 = scalefactor3 = scalefactors[stream.get_bits(6)];
658 break;
659 case 3:
660 scalefactor1 = scalefactors[stream.get_bits(6)];
661 scalefactor2 = scalefactor3 = scalefactors[stream.get_bits(6)];
662 break;
663 }
664 prepare_sample_reading(header, allocation, 0,
665 factor, codelength, c, d);
666 }
667 }
668
669 /**
670 *
671 */
672 public boolean read_sampledata (Bitstream stream)
673 {
674 if (allocation != 0)
675 if (groupingtable[0] != null)
676 {
677 int samplecode = stream.get_bits(codelength[0]);
678 // create requantized samples:
679 samplecode += samplecode << 1;
680 float[] target = samples;
681 float[] source = groupingtable[0];
682 /*
683 int tmp = 0;
684 int temp = 0;
685 target[tmp++] = source[samplecode + temp];
686 temp++;
687 target[tmp++] = source[samplecode + temp];
688 temp++;
689 target[tmp] = source[samplecode + temp];
690 */
691 //Bugfix:
692 int tmp = 0;
693 int temp = samplecode;
694
695 if(temp > source.length - 3) temp = source.length - 3;
696
697 target[tmp] = source[temp];
698 temp++;tmp++;
699 target[tmp] = source[temp];
700 temp++;tmp++;
701 target[tmp] = source[temp];
702
703 // memcpy (samples, groupingtable + samplecode, 3 * sizeof (real));
704 }
705 else
706 {
707 samples[0] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0);
708 samples[1] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0);
709 samples[2] = (float) ((stream.get_bits(codelength[0])) * factor[0] - 1.0);
710 }
711
712 samplenumber = 0;
713 if (++groupnumber == 12)
714 return true;
715 else
716 return false;
717 }
718
719 /**
720 *
721 */
722 public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
723 {
724 if ((allocation != 0) && (channels != OutputChannels.RIGHT_CHANNEL))
725 {
726 float sample = samples[samplenumber];
727
728 if (groupingtable[0] == null)
729 sample = (sample + d[0]) * c[0];
730 if (groupnumber <= 4)
731 sample *= scalefactor1;
732 else if (groupnumber <= 8)
733 sample *= scalefactor2;
734 else
735 sample *= scalefactor3;
736 filter1.input_sample(sample, subbandnumber);
737 }
738
739 if (++samplenumber == 3)
740 return true;
741 else
742 return false;
743 }
744 };
745
746 /**
747 * Class for layer II subbands in joint stereo mode.
748 */
749 static class SubbandLayer2IntensityStereo extends SubbandLayer2
750 {
751 protected int channel2_scfsi;
752 protected float channel2_scalefactor1, channel2_scalefactor2, channel2_scalefactor3;
753
754 /**
755 * Constructor
756 */
757 public SubbandLayer2IntensityStereo (int subbandnumber)
758 {
759 super(subbandnumber);
760 }
761
762 /**
763 *
764 */
765 public void read_allocation(Bitstream stream, Header header, Crc16 crc)
766 {
767 super.read_allocation (stream, header, crc);
768 }
769
770 /**
771 *
772 */
773 public void read_scalefactor_selection(Bitstream stream, Crc16 crc)
774 {
775 if (allocation != 0)
776 {
777 scfsi = stream.get_bits(2);
778 channel2_scfsi = stream.get_bits(2);
779 if (crc != null)
780 {
781 crc.add_bits(scfsi, 2);
782 crc.add_bits(channel2_scfsi, 2);
783 }
784 }
785 }
786
787 /**
788 *
789 */
790 public void read_scalefactor(Bitstream stream, Header header)
791 {
792 if (allocation != 0)
793 {
794 super.read_scalefactor(stream, header);
795 switch (channel2_scfsi)
796 {
797 case 0:
798 channel2_scalefactor1 = scalefactors[stream.get_bits(6)];
799 channel2_scalefactor2 = scalefactors[stream.get_bits(6)];
800 channel2_scalefactor3 = scalefactors[stream.get_bits(6)];
801 break;
802
803 case 1:
804 channel2_scalefactor1 = channel2_scalefactor2 = scalefactors[stream.get_bits (6)];
805 channel2_scalefactor3 = scalefactors[stream.get_bits(6)];
806 break;
807
808 case 2:
809 channel2_scalefactor1 = channel2_scalefactor2 =
810 channel2_scalefactor3 = scalefactors[stream.get_bits(6)];
811 break;
812
813 case 3:
814 channel2_scalefactor1 = scalefactors[stream.get_bits(6)];
815 channel2_scalefactor2 = channel2_scalefactor3 = scalefactors[stream.get_bits (6)];
816 break;
817 }
818 }
819
820 }
821
822 /**
823 *
824 */
825 public boolean read_sampledata(Bitstream stream)
826 {
827 return super.read_sampledata (stream);
828 }
829
830 /**
831 *
832 */
833 public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
834 {
835 if (allocation != 0)
836 {
837 float sample = samples[samplenumber];
838
839 if (groupingtable[0] == null)
840 sample = (sample + d[0]) * c[0];
841 if (channels == OutputChannels.BOTH_CHANNELS)
842 {
843 float sample2 = sample;
844 if (groupnumber <= 4)
845 {
846 sample *= scalefactor1;
847 sample2 *= channel2_scalefactor1;
848 }
849 else if (groupnumber <= 8)
850 {
851 sample *= scalefactor2;
852 sample2 *= channel2_scalefactor2;
853 }
854 else
855 {
856 sample *= scalefactor3;
857 sample2 *= channel2_scalefactor3;
858 }
859 filter1.input_sample(sample, subbandnumber);
860 filter2.input_sample(sample2, subbandnumber);
861 }
862 else if (channels == OutputChannels.LEFT_CHANNEL)
863 {
864 if (groupnumber <= 4)
865 sample *= scalefactor1;
866 else if (groupnumber <= 8)
867 sample *= scalefactor2;
868 else
869 sample *= scalefactor3;
870 filter1.input_sample(sample, subbandnumber);
871 }
872 else
873 {
874 if (groupnumber <= 4)
875 sample *= channel2_scalefactor1;
876 else if (groupnumber <= 8)
877 sample *= channel2_scalefactor2;
878 else
879 sample *= channel2_scalefactor3;
880 filter1.input_sample(sample, subbandnumber);
881 }
882 }
883
884 if (++samplenumber == 3)
885 return true;
886 else
887 return false;
888 }
889 };
890
891 /**
892 * Class for layer II subbands in stereo mode.
893 */
894 static class SubbandLayer2Stereo extends SubbandLayer2
895 {
896 protected int channel2_allocation;
897 protected int channel2_scfsi;
898 protected float channel2_scalefactor1, channel2_scalefactor2, channel2_scalefactor3;
899 //protected boolean channel2_grouping; ???? Never used!
900 protected int[] channel2_codelength = {0};
901 //protected float[][] channel2_groupingtable = {{0},{0}};
902 protected float[] channel2_factor = {0};
903 protected float[] channel2_samples;
904 protected float[] channel2_c = {0};
905 protected float[] channel2_d = {0};
906
907 /**
908 * Constructor
909 */
910 public SubbandLayer2Stereo(int subbandnumber)
911 {
912 super(subbandnumber);
913 channel2_samples = new float[3];
914 }
915
916 /**
917 *
918 */
919 public void read_allocation (Bitstream stream, Header header, Crc16 crc)
920 {
921 int length = get_allocationlength(header);
922 allocation = stream.get_bits(length);
923 channel2_allocation = stream.get_bits(length);
924 if (crc != null)
925 {
926 crc.add_bits(allocation, length);
927 crc.add_bits(channel2_allocation, length);
928 }
929 }
930
931 /**
932 *
933 */
934 public void read_scalefactor_selection(Bitstream stream, Crc16 crc)
935 {
936 if (allocation != 0)
937 {
938 scfsi = stream.get_bits(2);
939 if (crc != null)
940 crc.add_bits(scfsi, 2);
941 }
942 if (channel2_allocation != 0)
943 {
944 channel2_scfsi = stream.get_bits(2);
945 if (crc != null)
946 crc.add_bits(channel2_scfsi, 2);
947 }
948 }
949
950 /**
951 *
952 */
953 public void read_scalefactor(Bitstream stream, Header header)
954 {
955 super.read_scalefactor(stream, header);
956 if (channel2_allocation != 0)
957 {
958 switch (channel2_scfsi)
959 {
960 case 0:
961 channel2_scalefactor1 = scalefactors[stream.get_bits(6)];
962 channel2_scalefactor2 = scalefactors[stream.get_bits(6)];
963 channel2_scalefactor3 = scalefactors[stream.get_bits(6)];
964 break;
965
966 case 1:
967 channel2_scalefactor1 = channel2_scalefactor2 =
968 scalefactors[stream.get_bits(6)];
969 channel2_scalefactor3 = scalefactors[stream.get_bits(6)];
970 break;
971
972 case 2:
973 channel2_scalefactor1 = channel2_scalefactor2 =
974 channel2_scalefactor3 = scalefactors[stream.get_bits(6)];
975 break;
976
977 case 3:
978 channel2_scalefactor1 = scalefactors[stream.get_bits(6)];
979 channel2_scalefactor2 = channel2_scalefactor3 =
980 scalefactors[stream.get_bits(6)];
981 break;
982 }
983 prepare_sample_reading(header, channel2_allocation, 1,
984 channel2_factor, channel2_codelength, channel2_c,
985 channel2_d);
986 }
987 }
988
989 /**
990 *
991 */
992 public boolean read_sampledata (Bitstream stream)
993 {
994 boolean returnvalue = super.read_sampledata(stream);
995
996 if (channel2_allocation != 0)
997 if (groupingtable[1] != null)
998 {
999 int samplecode = stream.get_bits(channel2_codelength[0]);
1000 // create requantized samples:
1001 samplecode += samplecode << 1;
1002 /*
1003 float[] target = channel2_samples;
1004 float[] source = channel2_groupingtable[0];
1005 int tmp = 0;
1006 int temp = 0;
1007 target[tmp++] = source[samplecode + temp];
1008 temp++;
1009 target[tmp++] = source[samplecode + temp];
1010 temp++;
1011 target[tmp] = source[samplecode + temp];
1012 // memcpy (channel2_samples, channel2_groupingtable + samplecode, 3 * sizeof (real));
1013 */
1014 float[] target = channel2_samples;
1015 float[] source = groupingtable[1];
1016 int tmp = 0;
1017 int temp = samplecode;
1018 target[tmp] = source[temp];
1019 temp++;tmp++;
1020 target[tmp] = source[temp];
1021 temp++;tmp++;
1022 target[tmp] = source[temp];
1023
1024 }
1025 else
1026 {
1027 channel2_samples[0] = (float) ((stream.get_bits(channel2_codelength[0])) *
1028 channel2_factor[0] - 1.0);
1029 channel2_samples[1] = (float) ((stream.get_bits(channel2_codelength[0])) *
1030 channel2_factor[0] - 1.0);
1031 channel2_samples[2] = (float) ((stream.get_bits(channel2_codelength[0])) *
1032 channel2_factor[0] - 1.0);
1033 }
1034 return returnvalue;
1035 }
1036
1037 /**
1038 *
1039 */
1040 public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
1041 {
1042 boolean returnvalue = super.put_next_sample(channels, filter1, filter2);
1043 if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL))
1044 {
1045 float sample = channel2_samples[samplenumber - 1];
1046
1047 if (groupingtable[1] == null)
1048 sample = (sample + channel2_d[0]) * channel2_c[0];
1049
1050 if (groupnumber <= 4)
1051 sample *= channel2_scalefactor1;
1052 else if (groupnumber <= 8)
1053 sample *= channel2_scalefactor2;
1054 else
1055 sample *= channel2_scalefactor3;
1056 if (channels == OutputChannels.BOTH_CHANNELS)
1057 filter2.input_sample(sample, subbandnumber);
1058 else
1059 filter1.input_sample(sample, subbandnumber);
1060 }
1061 return returnvalue;
1062 }
1063 }
1064}
diff --git a/songdbj/javazoom/jl/decoder/LayerIIIDecoder.java b/songdbj/javazoom/jl/decoder/LayerIIIDecoder.java
new file mode 100644
index 0000000000..602badf0f2
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/LayerIIIDecoder.java
@@ -0,0 +1,2439 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 18/06/01 Michael Scheerer, Fixed bugs which causes
5 * negative indexes in method huffmann_decode and in method
6 * dequanisize_sample.
7 *
8 * 16/07/01 Michael Scheerer, Catched a bug in method
9 * huffmann_decode, which causes an outOfIndexException.
10 * Cause : Indexnumber of 24 at SfBandIndex,
11 * which has only a length of 22. I have simply and dirty
12 * fixed the index to <= 22, because I'm not really be able
13 * to fix the bug. The Indexnumber is taken from the MP3
14 * file and the origin Ma-Player with the same code works
15 * well.
16 *
17 * 02/19/99 Java Conversion by E.B, javalayer@javazoom.net
18 *-----------------------------------------------------------------------
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU Library General Public License as published
21 * by the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU Library General Public License for more details.
28 *
29 * You should have received a copy of the GNU Library General Public
30 * License along with this program; if not, write to the Free Software
31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 *----------------------------------------------------------------------
33 */
34
35package javazoom.jl.decoder;
36
37/**
38 * Class Implementing Layer 3 Decoder.
39 *
40 * @since 0.0
41 */
42final class LayerIIIDecoder implements FrameDecoder
43{
44 final double d43 = (4.0/3.0);
45
46 public int[] scalefac_buffer;
47
48 // MDM: removed, as this wasn't being used.
49 //private float CheckSumOut1d = 0.0f;
50 private int CheckSumHuff = 0;
51 private int[] is_1d;
52 private float[][][] ro;
53 private float[][][] lr;
54 private float[] out_1d;
55 private float[][] prevblck;
56 private float[][] k;
57 private int[] nonzero;
58 private Bitstream stream;
59 private Header header;
60 private SynthesisFilter filter1, filter2;
61 private Obuffer buffer;
62 private int which_channels;
63 private BitReserve br;
64 private III_side_info_t si;
65
66 private temporaire2[] III_scalefac_t;
67 private temporaire2[] scalefac;
68 // private III_scalefac_t scalefac;
69
70 private int max_gr;
71 private int frame_start;
72 private int part2_start;
73 private int channels;
74 private int first_channel;
75 private int last_channel;
76 private int sfreq;
77
78
79 /**
80 * Constructor.
81 */
82 // REVIEW: these constructor arguments should be moved to the
83 // decodeFrame() method, where possible, so that one
84 public LayerIIIDecoder(Bitstream stream0, Header header0,
85 SynthesisFilter filtera, SynthesisFilter filterb,
86 Obuffer buffer0, int which_ch0)
87 {
88 huffcodetab.inithuff();
89 is_1d = new int[SBLIMIT*SSLIMIT+4];
90 ro = new float[2][SBLIMIT][SSLIMIT];
91 lr = new float[2][SBLIMIT][SSLIMIT];
92 out_1d = new float[SBLIMIT*SSLIMIT];
93 prevblck = new float[2][SBLIMIT*SSLIMIT];
94 k = new float[2][SBLIMIT*SSLIMIT];
95 nonzero = new int[2];
96
97 //III_scalefact_t
98 III_scalefac_t = new temporaire2[2];
99 III_scalefac_t[0] = new temporaire2();
100 III_scalefac_t[1] = new temporaire2();
101 scalefac = III_scalefac_t;
102 // L3TABLE INIT
103
104 sfBandIndex = new SBI[9]; // SZD: MPEG2.5 +3 indices
105 int[] l0 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
106 int[] s0 = {0,4,8,12,18,24,32,42,56,74,100,132,174,192};
107 int[] l1 = {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576};
108 int[] s1 = {0,4,8,12,18,26,36,48,62,80,104,136,180,192};
109 int[] l2 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
110 int[] s2 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
111
112 int[] l3 = {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576};
113 int[] s3 = {0,4,8,12,16,22,30,40,52,66,84,106,136,192};
114 int[] l4 = {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576};
115 int[] s4 = {0,4,8,12,16,22,28,38,50,64,80,100,126,192};
116 int[] l5 = {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576};
117 int[] s5 = {0,4,8,12,16,22,30,42,58,78,104,138,180,192};
118 // SZD: MPEG2.5
119 int[] l6 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
120 int[] s6 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
121 int[] l7 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
122 int[] s7 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
123 int[] l8 = {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576};
124 int[] s8 = {0,8,16,24,36,52,72,96,124,160,162,164,166,192};
125
126 sfBandIndex[0]= new SBI(l0,s0);
127 sfBandIndex[1]= new SBI(l1,s1);
128 sfBandIndex[2]= new SBI(l2,s2);
129
130 sfBandIndex[3]= new SBI(l3,s3);
131 sfBandIndex[4]= new SBI(l4,s4);
132 sfBandIndex[5]= new SBI(l5,s5);
133 //SZD: MPEG2.5
134 sfBandIndex[6]= new SBI(l6,s6);
135 sfBandIndex[7]= new SBI(l7,s7);
136 sfBandIndex[8]= new SBI(l8,s8);
137 // END OF L3TABLE INIT
138
139 if(reorder_table == null) { // SZD: generate LUT
140 reorder_table = new int[9][];
141 for(int i = 0; i < 9; i++)
142 reorder_table[i] = reorder(sfBandIndex[i].s);
143 }
144
145 // Sftable
146 int[] ll0 = {0, 6, 11, 16, 21};
147 int[] ss0 = {0, 6, 12};
148 sftable = new Sftable(ll0,ss0);
149 // END OF Sftable
150
151 // scalefac_buffer
152 scalefac_buffer = new int[54];
153 // END OF scalefac_buffer
154
155 stream = stream0;
156 header = header0;
157 filter1 = filtera;
158 filter2 = filterb;
159 buffer = buffer0;
160 which_channels = which_ch0;
161
162 frame_start = 0;
163 channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2;
164 max_gr = (header.version() == Header.MPEG1) ? 2 : 1;
165
166 sfreq = header.sample_frequency() +
167 ((header.version() == Header.MPEG1) ? 3 :
168 (header.version() == Header.MPEG25_LSF) ? 6 : 0); // SZD
169
170 if (channels == 2)
171 {
172 switch (which_channels)
173 {
174 case OutputChannels.LEFT_CHANNEL:
175 case OutputChannels.DOWNMIX_CHANNELS:
176 first_channel = last_channel = 0;
177 break;
178
179 case OutputChannels.RIGHT_CHANNEL:
180 first_channel = last_channel = 1;
181 break;
182
183 case OutputChannels.BOTH_CHANNELS:
184 default:
185 first_channel = 0;
186 last_channel = 1;
187 break;
188 }
189 }
190 else
191 {
192 first_channel = last_channel = 0;
193 }
194
195 for(int ch=0;ch<2;ch++)
196 for (int j=0; j<576; j++)
197 prevblck[ch][j] = 0.0f;
198
199 nonzero[0] = nonzero[1] = 576;
200
201 br = new BitReserve();
202 si = new III_side_info_t();
203 }
204
205 /**
206 * Notify decoder that a seek is being made.
207 */
208 public void seek_notify()
209 {
210 frame_start = 0;
211 for(int ch=0;ch<2;ch++)
212 for (int j=0; j<576; j++)
213 prevblck[ch][j] = 0.0f;
214 br = new BitReserve();
215 }
216
217 public void decodeFrame()
218 {
219 decode();
220 }
221
222 /**
223 * Decode one frame, filling the buffer with the output samples.
224 */
225
226 // subband samples are buffered and passed to the
227 // SynthesisFilter in one go.
228 private float[] samples1 = new float[32];
229 private float[] samples2 = new float[32];
230
231 public void decode()
232 {
233 int nSlots = header.slots();
234 int flush_main;
235 int gr, ch, ss, sb, sb18;
236 int main_data_end;
237 int bytes_to_discard;
238 int i;
239
240 get_side_info();
241
242 for (i=0; i<nSlots; i++)
243 br.hputbuf(stream.get_bits(8));
244
245 main_data_end = br.hsstell() >>> 3; // of previous frame
246
247 if ((flush_main = (br.hsstell() & 7)) != 0) {
248 br.hgetbits(8 - flush_main);
249 main_data_end++;
250 }
251
252 bytes_to_discard = frame_start - main_data_end
253 - si.main_data_begin;
254
255 frame_start += nSlots;
256
257 if (bytes_to_discard < 0)
258 return;
259
260 if (main_data_end > 4096) {
261 frame_start -= 4096;
262 br.rewindNbytes(4096);
263 }
264
265 for (; bytes_to_discard > 0; bytes_to_discard--)
266 br.hgetbits(8);
267
268 for (gr=0;gr<max_gr;gr++) {
269
270 for (ch=0; ch<channels; ch++) {
271 part2_start = br.hsstell();
272
273 if (header.version() == Header.MPEG1)
274 get_scale_factors(ch, gr);
275 else // MPEG-2 LSF, SZD: MPEG-2.5 LSF
276 get_LSF_scale_factors(ch, gr);
277
278 huffman_decode(ch, gr);
279 // System.out.println("CheckSum HuffMan = " + CheckSumHuff);
280 dequantize_sample(ro[ch], ch, gr);
281 }
282
283 stereo(gr);
284
285 if ((which_channels == OutputChannels.DOWNMIX_CHANNELS) && (channels > 1))
286 do_downmix();
287
288 for (ch=first_channel; ch<=last_channel; ch++) {
289
290 reorder(lr[ch], ch, gr);
291 antialias(ch, gr);
292 //for (int hb = 0;hb<576;hb++) CheckSumOut1d = CheckSumOut1d + out_1d[hb];
293 //System.out.println("CheckSumOut1d = "+CheckSumOut1d);
294
295 hybrid(ch, gr);
296
297 //for (int hb = 0;hb<576;hb++) CheckSumOut1d = CheckSumOut1d + out_1d[hb];
298 //System.out.println("CheckSumOut1d = "+CheckSumOut1d);
299
300 for (sb18=18;sb18<576;sb18+=36) // Frequency inversion
301 for (ss=1;ss<SSLIMIT;ss+=2)
302 out_1d[sb18 + ss] = -out_1d[sb18 + ss];
303
304 if ((ch == 0) || (which_channels == OutputChannels.RIGHT_CHANNEL)) {
305 for (ss=0;ss<SSLIMIT;ss++) { // Polyphase synthesis
306 sb = 0;
307 for (sb18=0; sb18<576; sb18+=18) {
308 samples1[sb] = out_1d[sb18+ss];
309 //filter1.input_sample(out_1d[sb18+ss], sb);
310 sb++;
311 }
312 filter1.input_samples(samples1);
313 filter1.calculate_pcm_samples(buffer);
314 }
315 } else {
316 for (ss=0;ss<SSLIMIT;ss++) { // Polyphase synthesis
317 sb = 0;
318 for (sb18=0; sb18<576; sb18+=18) {
319 samples2[sb] = out_1d[sb18+ss];
320 //filter2.input_sample(out_1d[sb18+ss], sb);
321 sb++;
322 }
323 filter2.input_samples(samples2);
324 filter2.calculate_pcm_samples(buffer);
325 }
326
327 }
328 } // channels
329 } // granule
330
331
332 // System.out.println("Counter = ................................."+counter);
333 //if (counter < 609)
334 //{
335 counter++;
336 buffer.write_buffer(1);
337 //}
338 //else if (counter == 609)
339 //{
340 // buffer.close();
341 // counter++;
342 //}
343 //else
344 //{
345 //}
346
347 }
348
349 /**
350 * Reads the side info from the stream, assuming the entire.
351 * frame has been read already.
352 * Mono : 136 bits (= 17 bytes)
353 * Stereo : 256 bits (= 32 bytes)
354 */
355 private boolean get_side_info()
356 {
357 int ch, gr;
358 if (header.version() == Header.MPEG1)
359 {
360
361 si.main_data_begin = stream.get_bits(9);
362 if (channels == 1)
363 si.private_bits = stream.get_bits(5);
364 else si.private_bits = stream.get_bits(3);
365
366 for (ch=0; ch<channels; ch++) {
367 si.ch[ch].scfsi[0] = stream.get_bits(1);
368 si.ch[ch].scfsi[1] = stream.get_bits(1);
369 si.ch[ch].scfsi[2] = stream.get_bits(1);
370 si.ch[ch].scfsi[3] = stream.get_bits(1);
371 }
372
373 for (gr=0; gr<2; gr++) {
374 for (ch=0; ch<channels; ch++) {
375 si.ch[ch].gr[gr].part2_3_length = stream.get_bits(12);
376 si.ch[ch].gr[gr].big_values = stream.get_bits(9);
377 si.ch[ch].gr[gr].global_gain = stream.get_bits(8);
378 si.ch[ch].gr[gr].scalefac_compress = stream.get_bits(4);
379 si.ch[ch].gr[gr].window_switching_flag = stream.get_bits(1);
380 if ((si.ch[ch].gr[gr].window_switching_flag) != 0) {
381 si.ch[ch].gr[gr].block_type = stream.get_bits(2);
382 si.ch[ch].gr[gr].mixed_block_flag = stream.get_bits(1);
383
384 si.ch[ch].gr[gr].table_select[0] = stream.get_bits(5);
385 si.ch[ch].gr[gr].table_select[1] = stream.get_bits(5);
386
387 si.ch[ch].gr[gr].subblock_gain[0] = stream.get_bits(3);
388 si.ch[ch].gr[gr].subblock_gain[1] = stream.get_bits(3);
389 si.ch[ch].gr[gr].subblock_gain[2] = stream.get_bits(3);
390
391 // Set region_count parameters since they are implicit in this case.
392
393 if (si.ch[ch].gr[gr].block_type == 0) {
394 // Side info bad: block_type == 0 in split block
395 return false;
396 } else if (si.ch[ch].gr[gr].block_type == 2
397 && si.ch[ch].gr[gr].mixed_block_flag == 0) {
398 si.ch[ch].gr[gr].region0_count = 8;
399 } else {
400 si.ch[ch].gr[gr].region0_count = 7;
401 }
402 si.ch[ch].gr[gr].region1_count = 20 -
403 si.ch[ch].gr[gr].region0_count;
404 } else {
405 si.ch[ch].gr[gr].table_select[0] = stream.get_bits(5);
406 si.ch[ch].gr[gr].table_select[1] = stream.get_bits(5);
407 si.ch[ch].gr[gr].table_select[2] = stream.get_bits(5);
408 si.ch[ch].gr[gr].region0_count = stream.get_bits(4);
409 si.ch[ch].gr[gr].region1_count = stream.get_bits(3);
410 si.ch[ch].gr[gr].block_type = 0;
411 }
412 si.ch[ch].gr[gr].preflag = stream.get_bits(1);
413 si.ch[ch].gr[gr].scalefac_scale = stream.get_bits(1);
414 si.ch[ch].gr[gr].count1table_select = stream.get_bits(1);
415 }
416 }
417
418 } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF
419
420 si.main_data_begin = stream.get_bits(8);
421 if (channels == 1)
422 si.private_bits = stream.get_bits(1);
423 else si.private_bits = stream.get_bits(2);
424
425 for (ch=0; ch<channels; ch++) {
426
427 si.ch[ch].gr[0].part2_3_length = stream.get_bits(12);
428 si.ch[ch].gr[0].big_values = stream.get_bits(9);
429 si.ch[ch].gr[0].global_gain = stream.get_bits(8);
430 si.ch[ch].gr[0].scalefac_compress = stream.get_bits(9);
431 si.ch[ch].gr[0].window_switching_flag = stream.get_bits(1);
432
433 if ((si.ch[ch].gr[0].window_switching_flag) != 0) {
434
435 si.ch[ch].gr[0].block_type = stream.get_bits(2);
436 si.ch[ch].gr[0].mixed_block_flag = stream.get_bits(1);
437 si.ch[ch].gr[0].table_select[0] = stream.get_bits(5);
438 si.ch[ch].gr[0].table_select[1] = stream.get_bits(5);
439
440 si.ch[ch].gr[0].subblock_gain[0] = stream.get_bits(3);
441 si.ch[ch].gr[0].subblock_gain[1] = stream.get_bits(3);
442 si.ch[ch].gr[0].subblock_gain[2] = stream.get_bits(3);
443
444 // Set region_count parameters since they are implicit in this case.
445
446 if (si.ch[ch].gr[0].block_type == 0) {
447 // Side info bad: block_type == 0 in split block
448 return false;
449 } else if (si.ch[ch].gr[0].block_type == 2
450 && si.ch[ch].gr[0].mixed_block_flag == 0) {
451 si.ch[ch].gr[0].region0_count = 8;
452 } else {
453 si.ch[ch].gr[0].region0_count = 7;
454 si.ch[ch].gr[0].region1_count = 20 -
455 si.ch[ch].gr[0].region0_count;
456 }
457
458 } else {
459 si.ch[ch].gr[0].table_select[0] = stream.get_bits(5);
460 si.ch[ch].gr[0].table_select[1] = stream.get_bits(5);
461 si.ch[ch].gr[0].table_select[2] = stream.get_bits(5);
462 si.ch[ch].gr[0].region0_count = stream.get_bits(4);
463 si.ch[ch].gr[0].region1_count = stream.get_bits(3);
464 si.ch[ch].gr[0].block_type = 0;
465 }
466
467 si.ch[ch].gr[0].scalefac_scale = stream.get_bits(1);
468 si.ch[ch].gr[0].count1table_select = stream.get_bits(1);
469 } // for(ch=0; ch<channels; ch++)
470 } // if (header.version() == MPEG1)
471 return true;
472 }
473
474 /**
475 *
476 */
477 private void get_scale_factors(int ch, int gr)
478 {
479 int sfb, window;
480 gr_info_s gr_info = (si.ch[ch].gr[gr]);
481 int scale_comp = gr_info.scalefac_compress;
482 int length0 = slen[0][scale_comp];
483 int length1 = slen[1][scale_comp];
484
485 if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
486 if ((gr_info.mixed_block_flag) != 0) { // MIXED
487 for (sfb = 0; sfb < 8; sfb++)
488 scalefac[ch].l[sfb] = br.hgetbits(
489 slen[0][gr_info.scalefac_compress]);
490 for (sfb = 3; sfb < 6; sfb++)
491 for (window=0; window<3; window++)
492 scalefac[ch].s[window][sfb] = br.hgetbits(
493 slen[0][gr_info.scalefac_compress]);
494 for (sfb = 6; sfb < 12; sfb++)
495 for (window=0; window<3; window++)
496 scalefac[ch].s[window][sfb] = br.hgetbits(
497 slen[1][gr_info.scalefac_compress]);
498 for (sfb=12,window=0; window<3; window++)
499 scalefac[ch].s[window][sfb] = 0;
500
501 } else { // SHORT
502
503 scalefac[ch].s[0][0] = br.hgetbits(length0);
504 scalefac[ch].s[1][0] = br.hgetbits(length0);
505 scalefac[ch].s[2][0] = br.hgetbits(length0);
506 scalefac[ch].s[0][1] = br.hgetbits(length0);
507 scalefac[ch].s[1][1] = br.hgetbits(length0);
508 scalefac[ch].s[2][1] = br.hgetbits(length0);
509 scalefac[ch].s[0][2] = br.hgetbits(length0);
510 scalefac[ch].s[1][2] = br.hgetbits(length0);
511 scalefac[ch].s[2][2] = br.hgetbits(length0);
512 scalefac[ch].s[0][3] = br.hgetbits(length0);
513 scalefac[ch].s[1][3] = br.hgetbits(length0);
514 scalefac[ch].s[2][3] = br.hgetbits(length0);
515 scalefac[ch].s[0][4] = br.hgetbits(length0);
516 scalefac[ch].s[1][4] = br.hgetbits(length0);
517 scalefac[ch].s[2][4] = br.hgetbits(length0);
518 scalefac[ch].s[0][5] = br.hgetbits(length0);
519 scalefac[ch].s[1][5] = br.hgetbits(length0);
520 scalefac[ch].s[2][5] = br.hgetbits(length0);
521 scalefac[ch].s[0][6] = br.hgetbits(length1);
522 scalefac[ch].s[1][6] = br.hgetbits(length1);
523 scalefac[ch].s[2][6] = br.hgetbits(length1);
524 scalefac[ch].s[0][7] = br.hgetbits(length1);
525 scalefac[ch].s[1][7] = br.hgetbits(length1);
526 scalefac[ch].s[2][7] = br.hgetbits(length1);
527 scalefac[ch].s[0][8] = br.hgetbits(length1);
528 scalefac[ch].s[1][8] = br.hgetbits(length1);
529 scalefac[ch].s[2][8] = br.hgetbits(length1);
530 scalefac[ch].s[0][9] = br.hgetbits(length1);
531 scalefac[ch].s[1][9] = br.hgetbits(length1);
532 scalefac[ch].s[2][9] = br.hgetbits(length1);
533 scalefac[ch].s[0][10] = br.hgetbits(length1);
534 scalefac[ch].s[1][10] = br.hgetbits(length1);
535 scalefac[ch].s[2][10] = br.hgetbits(length1);
536 scalefac[ch].s[0][11] = br.hgetbits(length1);
537 scalefac[ch].s[1][11] = br.hgetbits(length1);
538 scalefac[ch].s[2][11] = br.hgetbits(length1);
539 scalefac[ch].s[0][12] = 0;
540 scalefac[ch].s[1][12] = 0;
541 scalefac[ch].s[2][12] = 0;
542 } // SHORT
543
544 } else { // LONG types 0,1,3
545
546 if ((si.ch[ch].scfsi[0] == 0) || (gr == 0)) {
547 scalefac[ch].l[0] = br.hgetbits(length0);
548 scalefac[ch].l[1] = br.hgetbits(length0);
549 scalefac[ch].l[2] = br.hgetbits(length0);
550 scalefac[ch].l[3] = br.hgetbits(length0);
551 scalefac[ch].l[4] = br.hgetbits(length0);
552 scalefac[ch].l[5] = br.hgetbits(length0);
553 }
554 if ((si.ch[ch].scfsi[1] == 0) || (gr == 0)) {
555 scalefac[ch].l[6] = br.hgetbits(length0);
556 scalefac[ch].l[7] = br.hgetbits(length0);
557 scalefac[ch].l[8] = br.hgetbits(length0);
558 scalefac[ch].l[9] = br.hgetbits(length0);
559 scalefac[ch].l[10] = br.hgetbits(length0);
560 }
561 if ((si.ch[ch].scfsi[2] == 0) || (gr == 0)) {
562 scalefac[ch].l[11] = br.hgetbits(length1);
563 scalefac[ch].l[12] = br.hgetbits(length1);
564 scalefac[ch].l[13] = br.hgetbits(length1);
565 scalefac[ch].l[14] = br.hgetbits(length1);
566 scalefac[ch].l[15] = br.hgetbits(length1);
567 }
568 if ((si.ch[ch].scfsi[3] == 0) || (gr == 0)) {
569 scalefac[ch].l[16] = br.hgetbits(length1);
570 scalefac[ch].l[17] = br.hgetbits(length1);
571 scalefac[ch].l[18] = br.hgetbits(length1);
572 scalefac[ch].l[19] = br.hgetbits(length1);
573 scalefac[ch].l[20] = br.hgetbits(length1);
574 }
575
576 scalefac[ch].l[21] = 0;
577 scalefac[ch].l[22] = 0;
578 }
579 }
580
581 /**
582 *
583 */
584 // MDM: new_slen is fully initialized before use, no need
585 // to reallocate array.
586 private final int[] new_slen = new int[4];
587
588 private void get_LSF_scale_data(int ch, int gr)
589 {
590
591 int scalefac_comp, int_scalefac_comp;
592 int mode_ext = header.mode_extension();
593 int m;
594 int blocktypenumber;
595 int blocknumber = 0;
596
597 gr_info_s gr_info = (si.ch[ch].gr[gr]);
598
599 scalefac_comp = gr_info.scalefac_compress;
600
601 if (gr_info.block_type == 2) {
602 if (gr_info.mixed_block_flag == 0)
603 blocktypenumber = 1;
604 else if (gr_info.mixed_block_flag == 1)
605 blocktypenumber = 2;
606 else
607 blocktypenumber = 0;
608 } else {
609 blocktypenumber = 0;
610 }
611
612 if(!(((mode_ext == 1) || (mode_ext == 3)) && (ch == 1))) {
613
614 if(scalefac_comp < 400) {
615
616 new_slen[0] = (scalefac_comp >>> 4) / 5 ;
617 new_slen[1] = (scalefac_comp >>> 4) % 5 ;
618 new_slen[2] = (scalefac_comp & 0xF) >>> 2 ;
619 new_slen[3] = (scalefac_comp & 3);
620 si.ch[ch].gr[gr].preflag = 0;
621 blocknumber = 0;
622
623 } else if (scalefac_comp < 500) {
624
625 new_slen[0] = ((scalefac_comp - 400) >>> 2) / 5 ;
626 new_slen[1] = ((scalefac_comp - 400) >>> 2) % 5 ;
627 new_slen[2] = (scalefac_comp - 400 ) & 3 ;
628 new_slen[3] = 0;
629 si.ch[ch].gr[gr].preflag = 0;
630 blocknumber = 1;
631
632 } else if (scalefac_comp < 512) {
633
634 new_slen[0] = (scalefac_comp - 500 ) / 3 ;
635 new_slen[1] = (scalefac_comp - 500) % 3 ;
636 new_slen[2] = 0;
637 new_slen[3] = 0;
638 si.ch[ch].gr[gr].preflag = 1;
639 blocknumber = 2;
640 }
641 }
642
643 if((((mode_ext == 1) || (mode_ext == 3)) && (ch == 1)))
644 {
645 int_scalefac_comp = scalefac_comp >>> 1;
646
647 if (int_scalefac_comp < 180)
648 {
649 new_slen[0] = int_scalefac_comp / 36 ;
650 new_slen[1] = (int_scalefac_comp % 36 ) / 6 ;
651 new_slen[2] = (int_scalefac_comp % 36) % 6;
652 new_slen[3] = 0;
653 si.ch[ch].gr[gr].preflag = 0;
654 blocknumber = 3;
655 } else if (int_scalefac_comp < 244) {
656 new_slen[0] = ((int_scalefac_comp - 180 ) & 0x3F) >>> 4 ;
657 new_slen[1] = ((int_scalefac_comp - 180) & 0xF) >>> 2 ;
658 new_slen[2] = (int_scalefac_comp - 180 ) & 3 ;
659 new_slen[3] = 0;
660 si.ch[ch].gr[gr].preflag = 0;
661 blocknumber = 4;
662 } else if (int_scalefac_comp < 255) {
663 new_slen[0] = (int_scalefac_comp - 244 ) / 3 ;
664 new_slen[1] = (int_scalefac_comp - 244 ) % 3 ;
665 new_slen[2] = 0 ;
666 new_slen[3] = 0;
667 si.ch[ch].gr[gr].preflag = 0;
668 blocknumber = 5;
669 }
670 }
671
672 for (int x=0; x<45; x++) // why 45, not 54?
673 scalefac_buffer[x] = 0;
674
675 m = 0;
676 for (int i=0; i<4;i++) {
677 for (int j = 0; j < nr_of_sfb_block[blocknumber][blocktypenumber][i];
678 j++)
679 {
680 scalefac_buffer[m] = (new_slen[i] == 0) ? 0 :
681 br.hgetbits(new_slen[i]);
682 m++;
683
684 } // for (unint32 j ...
685 } // for (uint32 i ...
686 }
687
688 /**
689 *
690 */
691 private void get_LSF_scale_factors(int ch, int gr)
692 {
693 int m = 0;
694 int sfb, window;
695 gr_info_s gr_info = (si.ch[ch].gr[gr]);
696
697 get_LSF_scale_data(ch, gr);
698
699 if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
700 if (gr_info.mixed_block_flag != 0) { // MIXED
701 for (sfb = 0; sfb < 8; sfb++)
702 {
703 scalefac[ch].l[sfb] = scalefac_buffer[m];
704 m++;
705 }
706 for (sfb = 3; sfb < 12; sfb++) {
707 for (window=0; window<3; window++)
708 {
709 scalefac[ch].s[window][sfb] = scalefac_buffer[m];
710 m++;
711 }
712 }
713 for (window=0; window<3; window++)
714 scalefac[ch].s[window][12] = 0;
715
716 } else { // SHORT
717
718 for (sfb = 0; sfb < 12; sfb++) {
719 for (window=0; window<3; window++)
720 {
721 scalefac[ch].s[window][sfb] = scalefac_buffer[m];
722 m++;
723 }
724 }
725
726 for (window=0; window<3; window++)
727 scalefac[ch].s[window][12] = 0;
728 }
729 } else { // LONG types 0,1,3
730
731 for (sfb = 0; sfb < 21; sfb++) {
732 scalefac[ch].l[sfb] = scalefac_buffer[m];
733 m++;
734 }
735 scalefac[ch].l[21] = 0; // Jeff
736 scalefac[ch].l[22] = 0;
737 }
738 }
739
740 /**
741 *
742 */
743 int[] x = {0};
744 int[] y = {0};
745 int[] v = {0};
746 int[] w = {0};
747 private void huffman_decode(int ch, int gr)
748 {
749 x[0] = 0;
750 y[0] = 0;
751 v[0] = 0;
752 w[0] = 0;
753
754 int part2_3_end = part2_start + si.ch[ch].gr[gr].part2_3_length;
755 int num_bits;
756 int region1Start;
757 int region2Start;
758 int index;
759
760 int buf, buf1;
761
762 huffcodetab h;
763
764 // Find region boundary for short block case
765
766 if ( ((si.ch[ch].gr[gr].window_switching_flag) != 0) &&
767 (si.ch[ch].gr[gr].block_type == 2) ) {
768
769 // Region2.
770 //MS: Extrahandling for 8KHZ
771 region1Start = (sfreq == 8) ? 72 : 36; // sfb[9/3]*3=36 or in case 8KHZ = 72
772 region2Start = 576; // No Region2 for short block case
773
774 } else { // Find region boundary for long block case
775
776 buf = si.ch[ch].gr[gr].region0_count + 1;
777 buf1 = buf + si.ch[ch].gr[gr].region1_count + 1;
778
779 if(buf1 > sfBandIndex[sfreq].l.length - 1) buf1 = sfBandIndex[sfreq].l.length - 1;
780
781 region1Start = sfBandIndex[sfreq].l[buf];
782 region2Start = sfBandIndex[sfreq].l[buf1]; /* MI */
783 }
784
785 index = 0;
786 // Read bigvalues area
787 for (int i=0; i<(si.ch[ch].gr[gr].big_values<<1); i+=2) {
788 if (i<region1Start) h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[0]];
789 else if (i<region2Start) h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[1]];
790 else h = huffcodetab.ht[si.ch[ch].gr[gr].table_select[2]];
791
792 huffcodetab.huffman_decoder(h, x, y, v, w, br);
793 //if (index >= is_1d.length) System.out.println("i0="+i+"/"+(si.ch[ch].gr[gr].big_values<<1)+" Index="+index+" is_1d="+is_1d.length);
794
795 is_1d[index++] = x[0];
796 is_1d[index++] = y[0];
797
798 CheckSumHuff = CheckSumHuff + x[0] + y[0];
799 // System.out.println("x = "+x[0]+" y = "+y[0]);
800 }
801
802 // Read count1 area
803 h = huffcodetab.ht[si.ch[ch].gr[gr].count1table_select+32];
804 num_bits = br.hsstell();
805
806 while ((num_bits < part2_3_end) && (index < 576)) {
807
808 huffcodetab.huffman_decoder(h, x, y, v, w, br);
809
810 is_1d[index++] = v[0];
811 is_1d[index++] = w[0];
812 is_1d[index++] = x[0];
813 is_1d[index++] = y[0];
814 CheckSumHuff = CheckSumHuff + v[0] + w[0] + x[0] + y[0];
815 // System.out.println("v = "+v[0]+" w = "+w[0]);
816 // System.out.println("x = "+x[0]+" y = "+y[0]);
817 num_bits = br.hsstell();
818 }
819
820 if (num_bits > part2_3_end) {
821 br.rewindNbits(num_bits - part2_3_end);
822 index-=4;
823 }
824
825 num_bits = br.hsstell();
826
827 // Dismiss stuffing bits
828 if (num_bits < part2_3_end)
829 br.hgetbits(part2_3_end - num_bits);
830
831 // Zero out rest
832
833 if (index < 576)
834 nonzero[ch] = index;
835 else
836 nonzero[ch] = 576;
837
838 if (index < 0) index = 0;
839
840 // may not be necessary
841 for (; index<576; index++)
842 is_1d[index] = 0;
843 }
844
845 /**
846 *
847 */
848 private void i_stereo_k_values(int is_pos, int io_type, int i)
849 {
850 if (is_pos == 0) {
851 k[0][i] = 1.0f;
852 k[1][i] = 1.0f;
853 } else if ((is_pos & 1) != 0) {
854 k[0][i] = io[io_type][(is_pos + 1) >>> 1];
855 k[1][i] = 1.0f;
856 } else {
857 k[0][i] = 1.0f;
858 k[1][i] = io[io_type][is_pos >>> 1];
859 }
860 }
861
862 /**
863 *
864 */
865 private void dequantize_sample(float xr[][], int ch, int gr)
866 {
867 gr_info_s gr_info = (si.ch[ch].gr[gr]);
868 int cb=0;
869 int next_cb_boundary;
870 int cb_begin = 0;
871 int cb_width = 0;
872 int index=0, t_index, j;
873 float g_gain;
874 float[][] xr_1d = xr;
875
876 // choose correct scalefactor band per block type, initalize boundary
877
878 if ((gr_info.window_switching_flag !=0 ) && (gr_info.block_type == 2) ) {
879 if (gr_info.mixed_block_flag != 0)
880 next_cb_boundary=sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3
881 else {
882 cb_width = sfBandIndex[sfreq].s[1];
883 next_cb_boundary = (cb_width << 2) - cb_width;
884 cb_begin = 0;
885 }
886 } else {
887 next_cb_boundary=sfBandIndex[sfreq].l[1]; // LONG blocks: 0,1,3
888 }
889
890 // Compute overall (global) scaling.
891
892 g_gain = (float) Math.pow(2.0 , (0.25 * (gr_info.global_gain - 210.0)));
893
894 for (j=0; j<nonzero[ch]; j++)
895 {
896 // Modif E.B 02/22/99
897 int reste = j % SSLIMIT;
898 int quotien = (int) ((j-reste)/SSLIMIT);
899 if (is_1d[j] == 0) xr_1d[quotien][reste] = 0.0f;
900 else
901 {
902 int abv = is_1d[j];
903 // Pow Array fix (11/17/04)
904 if (abv < t_43.length)
905 {
906 if (is_1d[j] > 0) xr_1d[quotien][reste] = g_gain * t_43[abv];
907 else
908 {
909 if (-abv < t_43.length) xr_1d[quotien][reste] = -g_gain * t_43[-abv];
910 else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43);
911 }
912 }
913 else
914 {
915 if (is_1d[j] > 0) xr_1d[quotien][reste] = g_gain * (float)Math.pow(abv, d43);
916 else xr_1d[quotien][reste] = -g_gain * (float)Math.pow(-abv, d43);
917 }
918 }
919 }
920
921 // apply formula per block type
922 for (j=0; j<nonzero[ch]; j++)
923 {
924 // Modif E.B 02/22/99
925 int reste = j % SSLIMIT;
926 int quotien = (int) ((j-reste)/SSLIMIT);
927
928 if (index == next_cb_boundary) { /* Adjust critical band boundary */
929 if ((gr_info.window_switching_flag != 0) && (gr_info.block_type == 2)) {
930 if (gr_info.mixed_block_flag != 0) {
931
932 if (index == sfBandIndex[sfreq].l[8]) {
933 next_cb_boundary = sfBandIndex[sfreq].s[4];
934 next_cb_boundary = (next_cb_boundary << 2) -
935 next_cb_boundary;
936 cb = 3;
937 cb_width = sfBandIndex[sfreq].s[4] -
938 sfBandIndex[sfreq].s[3];
939
940 cb_begin = sfBandIndex[sfreq].s[3];
941 cb_begin = (cb_begin << 2) - cb_begin;
942
943 } else if (index < sfBandIndex[sfreq].l[8]) {
944
945 next_cb_boundary = sfBandIndex[sfreq].l[(++cb)+1];
946
947 } else {
948
949 next_cb_boundary = sfBandIndex[sfreq].s[(++cb)+1];
950 next_cb_boundary = (next_cb_boundary << 2) -
951 next_cb_boundary;
952
953 cb_begin = sfBandIndex[sfreq].s[cb];
954 cb_width = sfBandIndex[sfreq].s[cb+1] -
955 cb_begin;
956 cb_begin = (cb_begin << 2) - cb_begin;
957 }
958
959 } else {
960
961 next_cb_boundary = sfBandIndex[sfreq].s[(++cb)+1];
962 next_cb_boundary = (next_cb_boundary << 2) -
963 next_cb_boundary;
964
965 cb_begin = sfBandIndex[sfreq].s[cb];
966 cb_width = sfBandIndex[sfreq].s[cb+1] -
967 cb_begin;
968 cb_begin = (cb_begin << 2) - cb_begin;
969 }
970
971 } else { // long blocks
972
973 next_cb_boundary = sfBandIndex[sfreq].l[(++cb)+1];
974
975 }
976 }
977
978 // Do long/short dependent scaling operations
979
980 if ((gr_info.window_switching_flag !=0)&&
981 (((gr_info.block_type == 2) && (gr_info.mixed_block_flag == 0)) ||
982 ((gr_info.block_type == 2) && (gr_info.mixed_block_flag!=0) && (j >= 36)) ))
983 {
984
985 t_index = (index - cb_begin) / cb_width;
986 /* xr[sb][ss] *= pow(2.0, ((-2.0 * gr_info.subblock_gain[t_index])
987 -(0.5 * (1.0 + gr_info.scalefac_scale)
988 * scalefac[ch].s[t_index][cb]))); */
989 int idx = scalefac[ch].s[t_index][cb]
990 << gr_info.scalefac_scale;
991 idx += (gr_info.subblock_gain[t_index] << 2);
992
993 xr_1d[quotien][reste] *= two_to_negative_half_pow[idx];
994
995 } else { // LONG block types 0,1,3 & 1st 2 subbands of switched blocks
996 /* xr[sb][ss] *= pow(2.0, -0.5 * (1.0+gr_info.scalefac_scale)
997 * (scalefac[ch].l[cb]
998 + gr_info.preflag * pretab[cb])); */
999 int idx = scalefac[ch].l[cb];
1000
1001 if (gr_info.preflag != 0)
1002 idx += pretab[cb];
1003
1004 idx = idx << gr_info.scalefac_scale;
1005 xr_1d[quotien][reste] *= two_to_negative_half_pow[idx];
1006 }
1007 index++;
1008 }
1009
1010 for (j=nonzero[ch]; j<576; j++)
1011 {
1012 // Modif E.B 02/22/99
1013 int reste = j % SSLIMIT;
1014 int quotien = (int) ((j-reste)/SSLIMIT);
1015 if(reste < 0) reste = 0;
1016 if(quotien < 0) quotien = 0;
1017 xr_1d[quotien][reste] = 0.0f;
1018 }
1019
1020 return;
1021 }
1022
1023 /**
1024 *
1025 */
1026 private void reorder(float xr[][], int ch, int gr)
1027 {
1028 gr_info_s gr_info = (si.ch[ch].gr[gr]);
1029 int freq, freq3;
1030 int index;
1031 int sfb, sfb_start, sfb_lines;
1032 int src_line, des_line;
1033 float[][] xr_1d = xr;
1034
1035 if ((gr_info.window_switching_flag !=0) && (gr_info.block_type == 2)) {
1036
1037 for(index=0; index<576; index++)
1038 out_1d[index] = 0.0f;
1039
1040 if (gr_info.mixed_block_flag !=0 ) {
1041 // NO REORDER FOR LOW 2 SUBBANDS
1042 for (index = 0; index < 36; index++)
1043 {
1044 // Modif E.B 02/22/99
1045 int reste = index % SSLIMIT;
1046 int quotien = (int) ((index-reste)/SSLIMIT);
1047 out_1d[index] = xr_1d[quotien][reste];
1048 }
1049 // REORDERING FOR REST SWITCHED SHORT
1050 /*for( sfb=3,sfb_start=sfBandIndex[sfreq].s[3],
1051 sfb_lines=sfBandIndex[sfreq].s[4] - sfb_start;
1052 sfb < 13; sfb++,sfb_start = sfBandIndex[sfreq].s[sfb],
1053 sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start )
1054 {*/
1055 for( sfb=3; sfb < 13; sfb++)
1056 {
1057 //System.out.println("sfreq="+sfreq+" sfb="+sfb+" sfBandIndex="+sfBandIndex.length+" sfBandIndex[sfreq].s="+sfBandIndex[sfreq].s.length);
1058 sfb_start = sfBandIndex[sfreq].s[sfb];
1059 sfb_lines = sfBandIndex[sfreq].s[sfb+1] - sfb_start;
1060
1061 int sfb_start3 = (sfb_start << 2) - sfb_start;
1062
1063 for(freq=0, freq3=0; freq<sfb_lines;
1064 freq++, freq3+=3) {
1065
1066 src_line = sfb_start3 + freq;
1067 des_line = sfb_start3 + freq3;
1068 // Modif E.B 02/22/99
1069 int reste = src_line % SSLIMIT;
1070 int quotien = (int) ((src_line-reste)/SSLIMIT);
1071
1072 out_1d[des_line] = xr_1d[quotien][reste];
1073 src_line += sfb_lines;
1074 des_line++;
1075
1076 reste = src_line % SSLIMIT;
1077 quotien = (int) ((src_line-reste)/SSLIMIT);
1078
1079 out_1d[des_line] = xr_1d[quotien][reste];
1080 src_line += sfb_lines;
1081 des_line++;
1082
1083 reste = src_line % SSLIMIT;
1084 quotien = (int) ((src_line-reste)/SSLIMIT);
1085
1086 out_1d[des_line] = xr_1d[quotien][reste];
1087 }
1088 }
1089
1090 } else { // pure short
1091 for(index=0;index<576;index++)
1092 {
1093 int j = reorder_table[sfreq][index];
1094 int reste = j % SSLIMIT;
1095 int quotien = (int) ((j-reste)/SSLIMIT);
1096 out_1d[index] = xr_1d[quotien][reste];
1097 }
1098 }
1099 }
1100 else { // long blocks
1101 for(index=0; index<576; index++)
1102 {
1103 // Modif E.B 02/22/99
1104 int reste = index % SSLIMIT;
1105 int quotien = (int) ((index-reste)/SSLIMIT);
1106 out_1d[index] = xr_1d[quotien][reste];
1107 }
1108 }
1109 }
1110
1111 /**
1112 *
1113 */
1114
1115 int[] is_pos = new int[576];
1116 float[] is_ratio = new float[576];
1117
1118 private void stereo(int gr)
1119 {
1120 int sb, ss;
1121
1122 if (channels == 1) { // mono , bypass xr[0][][] to lr[0][][]
1123
1124 for(sb=0;sb<SBLIMIT;sb++)
1125 for(ss=0;ss<SSLIMIT;ss+=3) {
1126 lr[0][sb][ss] = ro[0][sb][ss];
1127 lr[0][sb][ss+1] = ro[0][sb][ss+1];
1128 lr[0][sb][ss+2] = ro[0][sb][ss+2];
1129 }
1130
1131 } else {
1132
1133 gr_info_s gr_info = (si.ch[0].gr[gr]);
1134 int mode_ext = header.mode_extension();
1135 int sfb;
1136 int i;
1137 int lines, temp, temp2;
1138
1139 boolean ms_stereo = ((header.mode() == Header.JOINT_STEREO) && ((mode_ext & 0x2)!=0));
1140 boolean i_stereo = ((header.mode() == Header.JOINT_STEREO) && ((mode_ext & 0x1)!=0));
1141 boolean lsf = ((header.version() == Header.MPEG2_LSF || header.version() == Header.MPEG25_LSF )); // SZD
1142
1143 int io_type = (gr_info.scalefac_compress & 1);
1144
1145 // initialization
1146
1147 for (i=0; i<576; i++)
1148 {
1149 is_pos[i] = 7;
1150
1151 is_ratio[i] = 0.0f;
1152 }
1153
1154 if (i_stereo) {
1155 if ((gr_info.window_switching_flag !=0 )&& (gr_info.block_type == 2)) {
1156 if (gr_info.mixed_block_flag != 0) {
1157
1158 int max_sfb = 0;
1159
1160 for (int j=0; j<3; j++) {
1161 int sfbcnt;
1162 sfbcnt = 2;
1163 for( sfb=12; sfb >=3; sfb-- ) {
1164 i = sfBandIndex[sfreq].s[sfb];
1165 lines = sfBandIndex[sfreq].s[sfb+1] - i;
1166 i = (i << 2) - i + (j+1) * lines - 1;
1167
1168 while (lines > 0) {
1169 if (ro[1][i/18][i%18] != 0.0f) {
1170 // MDM: in java, array access is very slow.
1171 // Is quicker to compute div and mod values.
1172 //if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) {
1173 sfbcnt = sfb;
1174 sfb = -10;
1175 lines = -10;
1176 }
1177
1178 lines--;
1179 i--;
1180
1181 } // while (lines > 0)
1182
1183 } // for (sfb=12 ...
1184 sfb = sfbcnt + 1;
1185
1186 if (sfb > max_sfb)
1187 max_sfb = sfb;
1188
1189 while(sfb < 12) {
1190 temp = sfBandIndex[sfreq].s[sfb];
1191 sb = sfBandIndex[sfreq].s[sfb+1] - temp;
1192 i = (temp << 2) - temp + j * sb;
1193
1194 for ( ; sb > 0; sb--) {
1195 is_pos[i] = scalefac[1].s[j][sfb];
1196 if (is_pos[i] != 7)
1197 if (lsf)
1198 i_stereo_k_values(is_pos[i], io_type, i);
1199 else
1200 is_ratio[i] = TAN12[is_pos[i]];
1201
1202 i++;
1203 } // for (; sb>0...
1204 sfb++;
1205 } // while (sfb < 12)
1206 sfb = sfBandIndex[sfreq].s[10];
1207 sb = sfBandIndex[sfreq].s[11] - sfb;
1208 sfb = (sfb << 2) - sfb + j * sb;
1209 temp = sfBandIndex[sfreq].s[11];
1210 sb = sfBandIndex[sfreq].s[12] - temp;
1211 i = (temp << 2) - temp + j * sb;
1212
1213 for (; sb > 0; sb--) {
1214 is_pos[i] = is_pos[sfb];
1215
1216 if (lsf) {
1217 k[0][i] = k[0][sfb];
1218 k[1][i] = k[1][sfb];
1219 } else {
1220 is_ratio[i] = is_ratio[sfb];
1221 }
1222 i++;
1223 } // for (; sb > 0 ...
1224 }
1225 if (max_sfb <= 3) {
1226 i = 2;
1227 ss = 17;
1228 sb = -1;
1229 while (i >= 0) {
1230 if (ro[1][i][ss] != 0.0f) {
1231 sb = (i<<4) + (i<<1) + ss;
1232 i = -1;
1233 } else {
1234 ss--;
1235 if (ss < 0) {
1236 i--;
1237 ss = 17;
1238 }
1239 } // if (ro ...
1240 } // while (i>=0)
1241 i = 0;
1242 while (sfBandIndex[sfreq].l[i] <= sb)
1243 i++;
1244 sfb = i;
1245 i = sfBandIndex[sfreq].l[i];
1246 for (; sfb<8; sfb++) {
1247 sb = sfBandIndex[sfreq].l[sfb+1]-sfBandIndex[sfreq].l[sfb];
1248 for (; sb>0; sb--) {
1249 is_pos[i] = scalefac[1].l[sfb];
1250 if (is_pos[i] != 7)
1251 if (lsf)
1252 i_stereo_k_values(is_pos[i], io_type, i);
1253 else
1254 is_ratio[i] = TAN12[is_pos[i]];
1255 i++;
1256 } // for (; sb>0 ...
1257 } // for (; sfb<8 ...
1258 } // for (j=0 ...
1259 } else { // if (gr_info.mixed_block_flag)
1260 for (int j=0; j<3; j++) {
1261 int sfbcnt;
1262 sfbcnt = -1;
1263 for( sfb=12; sfb >=0; sfb-- )
1264 {
1265 temp = sfBandIndex[sfreq].s[sfb];
1266 lines = sfBandIndex[sfreq].s[sfb+1] - temp;
1267 i = (temp << 2) - temp + (j+1) * lines - 1;
1268
1269 while (lines > 0) {
1270 if (ro[1][i/18][i%18] != 0.0f) {
1271 // MDM: in java, array access is very slow.
1272 // Is quicker to compute div and mod values.
1273 //if (ro[1][ss_div[i]][ss_mod[i]] != 0.0f) {
1274 sfbcnt = sfb;
1275 sfb = -10;
1276 lines = -10;
1277 }
1278 lines--;
1279 i--;
1280 } // while (lines > 0) */
1281
1282 } // for (sfb=12 ...
1283 sfb = sfbcnt + 1;
1284 while(sfb<12) {
1285 temp = sfBandIndex[sfreq].s[sfb];
1286 sb = sfBandIndex[sfreq].s[sfb+1] - temp;
1287 i = (temp << 2) - temp + j * sb;
1288 for ( ; sb > 0; sb--) {
1289 is_pos[i] = scalefac[1].s[j][sfb];
1290 if (is_pos[i] != 7)
1291 if (lsf)
1292 i_stereo_k_values(is_pos[i], io_type, i);
1293 else
1294 is_ratio[i] = TAN12[is_pos[i]];
1295 i++;
1296 } // for (; sb>0 ...
1297 sfb++;
1298 } // while (sfb<12)
1299
1300 temp = sfBandIndex[sfreq].s[10];
1301 temp2= sfBandIndex[sfreq].s[11];
1302 sb = temp2 - temp;
1303 sfb = (temp << 2) - temp + j * sb;
1304 sb = sfBandIndex[sfreq].s[12] - temp2;
1305 i = (temp2 << 2) - temp2 + j * sb;
1306
1307 for (; sb>0; sb--) {
1308 is_pos[i] = is_pos[sfb];
1309
1310 if (lsf) {
1311 k[0][i] = k[0][sfb];
1312 k[1][i] = k[1][sfb];
1313 } else {
1314 is_ratio[i] = is_ratio[sfb];
1315 }
1316 i++;
1317 } // for (; sb>0 ...
1318 } // for (sfb=12
1319 } // for (j=0 ...
1320 } else { // if (gr_info.window_switching_flag ...
1321 i = 31;
1322 ss = 17;
1323 sb = 0;
1324 while (i >= 0) {
1325 if (ro[1][i][ss] != 0.0f) {
1326 sb = (i<<4) + (i<<1) + ss;
1327 i = -1;
1328 } else {
1329 ss--;
1330 if (ss < 0) {
1331 i--;
1332 ss = 17;
1333 }
1334 }
1335 }
1336 i = 0;
1337 while (sfBandIndex[sfreq].l[i] <= sb)
1338 i++;
1339
1340 sfb = i;
1341 i = sfBandIndex[sfreq].l[i];
1342 for (; sfb<21; sfb++) {
1343 sb = sfBandIndex[sfreq].l[sfb+1] - sfBandIndex[sfreq].l[sfb];
1344 for (; sb > 0; sb--) {
1345 is_pos[i] = scalefac[1].l[sfb];
1346 if (is_pos[i] != 7)
1347 if (lsf)
1348 i_stereo_k_values(is_pos[i], io_type, i);
1349 else
1350 is_ratio[i] = TAN12[is_pos[i]];
1351 i++;
1352 }
1353 }
1354 sfb = sfBandIndex[sfreq].l[20];
1355 for (sb = 576 - sfBandIndex[sfreq].l[21]; (sb > 0) && (i<576); sb--)
1356 {
1357 is_pos[i] = is_pos[sfb]; // error here : i >=576
1358
1359 if (lsf) {
1360 k[0][i] = k[0][sfb];
1361 k[1][i] = k[1][sfb];
1362 } else {
1363 is_ratio[i] = is_ratio[sfb];
1364 }
1365 i++;
1366 } // if (gr_info.mixed_block_flag)
1367 } // if (gr_info.window_switching_flag ...
1368 } // if (i_stereo)
1369
1370 i = 0;
1371 for(sb=0;sb<SBLIMIT;sb++)
1372 for(ss=0;ss<SSLIMIT;ss++) {
1373 if (is_pos[i] == 7) {
1374 if (ms_stereo) {
1375 lr[0][sb][ss] = (ro[0][sb][ss]+ro[1][sb][ss]) * 0.707106781f;
1376 lr[1][sb][ss] = (ro[0][sb][ss]-ro[1][sb][ss]) * 0.707106781f;
1377 } else {
1378 lr[0][sb][ss] = ro[0][sb][ss];
1379 lr[1][sb][ss] = ro[1][sb][ss];
1380 }
1381 }
1382 else if (i_stereo) {
1383
1384 if (lsf) {
1385 lr[0][sb][ss] = ro[0][sb][ss] * k[0][i];
1386 lr[1][sb][ss] = ro[0][sb][ss] * k[1][i];
1387 } else {
1388 lr[1][sb][ss] = ro[0][sb][ss] / (float) (1 + is_ratio[i]);
1389 lr[0][sb][ss] = lr[1][sb][ss] * is_ratio[i];
1390 }
1391 }
1392 /* else {
1393 System.out.println("Error in stereo processing\n");
1394 } */
1395 i++;
1396 }
1397
1398 } // channels == 2
1399
1400 }
1401
1402 /**
1403 *
1404 */
1405 private void antialias(int ch, int gr)
1406 {
1407 int sb18, ss, sb18lim;
1408 gr_info_s gr_info = (si.ch[ch].gr[gr]);
1409 // 31 alias-reduction operations between each pair of sub-bands
1410 // with 8 butterflies between each pair
1411
1412 if ((gr_info.window_switching_flag !=0) && (gr_info.block_type == 2) &&
1413 !(gr_info.mixed_block_flag != 0) )
1414 return;
1415
1416 if ((gr_info.window_switching_flag !=0) && (gr_info.mixed_block_flag != 0)&&
1417 (gr_info.block_type == 2)) {
1418 sb18lim = 18;
1419 } else {
1420 sb18lim = 558;
1421 }
1422
1423 for (sb18=0; sb18 < sb18lim; sb18+=18) {
1424 for (ss=0;ss<8;ss++) {
1425 int src_idx1 = sb18 + 17 - ss;
1426 int src_idx2 = sb18 + 18 + ss;
1427 float bu = out_1d[src_idx1];
1428 float bd = out_1d[src_idx2];
1429 out_1d[src_idx1] = (bu * cs[ss]) - (bd * ca[ss]);
1430 out_1d[src_idx2] = (bd * cs[ss]) + (bu * ca[ss]);
1431 }
1432 }
1433 }
1434
1435 /**
1436 *
1437 */
1438
1439 // MDM: tsOutCopy and rawout do not need initializing, so the arrays
1440 // can be reused.
1441 float[] tsOutCopy = new float[18];
1442 float[] rawout = new float[36];
1443
1444 private void hybrid(int ch, int gr)
1445 {
1446 int bt;
1447 int sb18;
1448 gr_info_s gr_info = (si.ch[ch].gr[gr]);
1449 float[] tsOut;
1450
1451 float[][] prvblk;
1452
1453 for(sb18=0;sb18<576;sb18+=18)
1454 {
1455 bt = ((gr_info.window_switching_flag !=0 ) && (gr_info.mixed_block_flag !=0) &&
1456 (sb18 < 36)) ? 0 : gr_info.block_type;
1457
1458 tsOut = out_1d;
1459 // Modif E.B 02/22/99
1460 for (int cc = 0;cc<18;cc++)
1461 tsOutCopy[cc] = tsOut[cc+sb18];
1462
1463 inv_mdct(tsOutCopy, rawout, bt);
1464
1465
1466 for (int cc = 0;cc<18;cc++)
1467 tsOut[cc+sb18] = tsOutCopy[cc];
1468 // Fin Modif
1469
1470 // overlap addition
1471 prvblk = prevblck;
1472
1473 tsOut[0 + sb18] = rawout[0] + prvblk[ch][sb18 + 0];
1474 prvblk[ch][sb18 + 0] = rawout[18];
1475 tsOut[1 + sb18] = rawout[1] + prvblk[ch][sb18 + 1];
1476 prvblk[ch][sb18 + 1] = rawout[19];
1477 tsOut[2 + sb18] = rawout[2] + prvblk[ch][sb18 + 2];
1478 prvblk[ch][sb18 + 2] = rawout[20];
1479 tsOut[3 + sb18] = rawout[3] + prvblk[ch][sb18 + 3];
1480 prvblk[ch][sb18 + 3] = rawout[21];
1481 tsOut[4 + sb18] = rawout[4] + prvblk[ch][sb18 + 4];
1482 prvblk[ch][sb18 + 4] = rawout[22];
1483 tsOut[5 + sb18] = rawout[5] + prvblk[ch][sb18 + 5];
1484 prvblk[ch][sb18 + 5] = rawout[23];
1485 tsOut[6 + sb18] = rawout[6] + prvblk[ch][sb18 + 6];
1486 prvblk[ch][sb18 + 6] = rawout[24];
1487 tsOut[7 + sb18] = rawout[7] + prvblk[ch][sb18 + 7];
1488 prvblk[ch][sb18 + 7] = rawout[25];
1489 tsOut[8 + sb18] = rawout[8] + prvblk[ch][sb18 + 8];
1490 prvblk[ch][sb18 + 8] = rawout[26];
1491 tsOut[9 + sb18] = rawout[9] + prvblk[ch][sb18 + 9];
1492 prvblk[ch][sb18 + 9] = rawout[27];
1493 tsOut[10 + sb18] = rawout[10] + prvblk[ch][sb18 + 10];
1494 prvblk[ch][sb18 + 10] = rawout[28];
1495 tsOut[11 + sb18] = rawout[11] + prvblk[ch][sb18 + 11];
1496 prvblk[ch][sb18 + 11] = rawout[29];
1497 tsOut[12 + sb18] = rawout[12] + prvblk[ch][sb18 + 12];
1498 prvblk[ch][sb18 + 12] = rawout[30];
1499 tsOut[13 + sb18] = rawout[13] + prvblk[ch][sb18 + 13];
1500 prvblk[ch][sb18 + 13] = rawout[31];
1501 tsOut[14 + sb18] = rawout[14] + prvblk[ch][sb18 + 14];
1502 prvblk[ch][sb18 + 14] = rawout[32];
1503 tsOut[15 + sb18] = rawout[15] + prvblk[ch][sb18 + 15];
1504 prvblk[ch][sb18 + 15] = rawout[33];
1505 tsOut[16 + sb18] = rawout[16] + prvblk[ch][sb18 + 16];
1506 prvblk[ch][sb18 + 16] = rawout[34];
1507 tsOut[17 + sb18] = rawout[17] + prvblk[ch][sb18 + 17];
1508 prvblk[ch][sb18 + 17] = rawout[35];
1509 }
1510 }
1511
1512 /**
1513 *
1514 */
1515 private void do_downmix()
1516 {
1517 for (int sb=0; sb<SSLIMIT; sb++) {
1518 for (int ss=0; ss<SSLIMIT; ss+=3) {
1519 lr[0][sb][ss] = (lr[0][sb][ss] + lr[1][sb][ss]) * 0.5f;
1520 lr[0][sb][ss+1] = (lr[0][sb][ss+1] + lr[1][sb][ss+1]) * 0.5f;
1521 lr[0][sb][ss+2] = (lr[0][sb][ss+2] + lr[1][sb][ss+2]) * 0.5f;
1522 }
1523 }
1524 }
1525
1526 /**
1527 * Fast INV_MDCT.
1528 */
1529
1530 public void inv_mdct(float[] in, float[] out, int block_type)
1531 {
1532 float[] win_bt;
1533 int i;
1534
1535 float tmpf_0, tmpf_1, tmpf_2, tmpf_3, tmpf_4, tmpf_5, tmpf_6, tmpf_7, tmpf_8, tmpf_9;
1536 float tmpf_10, tmpf_11, tmpf_12, tmpf_13, tmpf_14, tmpf_15, tmpf_16, tmpf_17;
1537
1538 tmpf_0 = tmpf_1 = tmpf_2 = tmpf_3 = tmpf_4 = tmpf_5 = tmpf_6 = tmpf_7 = tmpf_8 = tmpf_9 =
1539 tmpf_10 = tmpf_11 = tmpf_12 = tmpf_13 = tmpf_14 = tmpf_15 = tmpf_16 = tmpf_17 = 0.0f;
1540
1541
1542
1543 if(block_type == 2)
1544 {
1545
1546 /*
1547 *
1548 * Under MicrosoftVM 2922, This causes a GPF, or
1549 * At best, an ArrayIndexOutOfBoundsExceptin.
1550 for(int p=0;p<36;p+=9)
1551 {
1552 out[p] = out[p+1] = out[p+2] = out[p+3] =
1553 out[p+4] = out[p+5] = out[p+6] = out[p+7] =
1554 out[p+8] = 0.0f;
1555 }
1556 */
1557 out[0] = 0.0f;
1558 out[1] = 0.0f;
1559 out[2] = 0.0f;
1560 out[3] = 0.0f;
1561 out[4] = 0.0f;
1562 out[5] = 0.0f;
1563 out[6] = 0.0f;
1564 out[7] = 0.0f;
1565 out[8] = 0.0f;
1566 out[9] = 0.0f;
1567 out[10] = 0.0f;
1568 out[11] = 0.0f;
1569 out[12] = 0.0f;
1570 out[13] = 0.0f;
1571 out[14] = 0.0f;
1572 out[15] = 0.0f;
1573 out[16] = 0.0f;
1574 out[17] = 0.0f;
1575 out[18] = 0.0f;
1576 out[19] = 0.0f;
1577 out[20] = 0.0f;
1578 out[21] = 0.0f;
1579 out[22] = 0.0f;
1580 out[23] = 0.0f;
1581 out[24] = 0.0f;
1582 out[25] = 0.0f;
1583 out[26] = 0.0f;
1584 out[27] = 0.0f;
1585 out[28] = 0.0f;
1586 out[29] = 0.0f;
1587 out[30] = 0.0f;
1588 out[31] = 0.0f;
1589 out[32] = 0.0f;
1590 out[33] = 0.0f;
1591 out[34] = 0.0f;
1592 out[35] = 0.0f;
1593
1594 int six_i = 0;
1595
1596 for(i=0;i<3;i++)
1597 {
1598 // 12 point IMDCT
1599 // Begin 12 point IDCT
1600 // Input aliasing for 12 pt IDCT
1601 in[15+i] += in[12+i]; in[12+i] += in[9+i]; in[9+i] += in[6+i];
1602 in[6+i] += in[3+i]; in[3+i] += in[0+i];
1603
1604 // Input aliasing on odd indices (for 6 point IDCT)
1605 in[15+i] += in[9+i]; in[9+i] += in[3+i];
1606
1607 // 3 point IDCT on even indices
1608 float pp1, pp2, sum;
1609 pp2 = in[12+i] * 0.500000000f;
1610 pp1 = in[ 6+i] * 0.866025403f;
1611 sum = in[0+i] + pp2;
1612 tmpf_1 = in[0+i] - in[12+i];
1613 tmpf_0 = sum + pp1;
1614 tmpf_2 = sum - pp1;
1615
1616 // End 3 point IDCT on even indices
1617 // 3 point IDCT on odd indices (for 6 point IDCT)
1618 pp2 = in[15+i] * 0.500000000f;
1619 pp1 = in[ 9+i] * 0.866025403f;
1620 sum = in[ 3+i] + pp2;
1621 tmpf_4 = in[3+i] - in[15+i];
1622 tmpf_5 = sum + pp1;
1623 tmpf_3 = sum - pp1;
1624 // End 3 point IDCT on odd indices
1625 // Twiddle factors on odd indices (for 6 point IDCT)
1626
1627 tmpf_3 *= 1.931851653f;
1628 tmpf_4 *= 0.707106781f;
1629 tmpf_5 *= 0.517638090f;
1630
1631 // Output butterflies on 2 3 point IDCT's (for 6 point IDCT)
1632 float save = tmpf_0;
1633 tmpf_0 += tmpf_5;
1634 tmpf_5 = save - tmpf_5;
1635 save = tmpf_1;
1636 tmpf_1 += tmpf_4;
1637 tmpf_4 = save - tmpf_4;
1638 save = tmpf_2;
1639 tmpf_2 += tmpf_3;
1640 tmpf_3 = save - tmpf_3;
1641
1642 // End 6 point IDCT
1643 // Twiddle factors on indices (for 12 point IDCT)
1644
1645 tmpf_0 *= 0.504314480f;
1646 tmpf_1 *= 0.541196100f;
1647 tmpf_2 *= 0.630236207f;
1648 tmpf_3 *= 0.821339815f;
1649 tmpf_4 *= 1.306562965f;
1650 tmpf_5 *= 3.830648788f;
1651
1652 // End 12 point IDCT
1653
1654 // Shift to 12 point modified IDCT, multiply by window type 2
1655 tmpf_8 = -tmpf_0 * 0.793353340f;
1656 tmpf_9 = -tmpf_0 * 0.608761429f;
1657 tmpf_7 = -tmpf_1 * 0.923879532f;
1658 tmpf_10 = -tmpf_1 * 0.382683432f;
1659 tmpf_6 = -tmpf_2 * 0.991444861f;
1660 tmpf_11 = -tmpf_2 * 0.130526192f;
1661
1662 tmpf_0 = tmpf_3;
1663 tmpf_1 = tmpf_4 * 0.382683432f;
1664 tmpf_2 = tmpf_5 * 0.608761429f;
1665
1666 tmpf_3 = -tmpf_5 * 0.793353340f;
1667 tmpf_4 = -tmpf_4 * 0.923879532f;
1668 tmpf_5 = -tmpf_0 * 0.991444861f;
1669
1670 tmpf_0 *= 0.130526192f;
1671
1672 out[six_i + 6] += tmpf_0;
1673 out[six_i + 7] += tmpf_1;
1674 out[six_i + 8] += tmpf_2;
1675 out[six_i + 9] += tmpf_3;
1676 out[six_i + 10] += tmpf_4;
1677 out[six_i + 11] += tmpf_5;
1678 out[six_i + 12] += tmpf_6;
1679 out[six_i + 13] += tmpf_7;
1680 out[six_i + 14] += tmpf_8;
1681 out[six_i + 15] += tmpf_9;
1682 out[six_i + 16] += tmpf_10;
1683 out[six_i + 17] += tmpf_11;
1684
1685 six_i += 6;
1686 }
1687 }
1688 else
1689 {
1690 // 36 point IDCT
1691 // input aliasing for 36 point IDCT
1692 in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14]; in[14]+=in[13];
1693 in[13]+=in[12]; in[12]+=in[11]; in[11]+=in[10]; in[10]+=in[9];
1694 in[9] +=in[8]; in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5];
1695 in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2]; in[2] +=in[1];
1696 in[1] +=in[0];
1697
1698 // 18 point IDCT for odd indices
1699 // input aliasing for 18 point IDCT
1700 in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
1701 in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1];
1702
1703 float tmp0,tmp1,tmp2,tmp3,tmp4,tmp0_,tmp1_,tmp2_,tmp3_;
1704 float tmp0o,tmp1o,tmp2o,tmp3o,tmp4o,tmp0_o,tmp1_o,tmp2_o,tmp3_o;
1705
1706 // Fast 9 Point Inverse Discrete Cosine Transform
1707 //
1708 // By Francois-Raymond Boyer
1709 // mailto:boyerf@iro.umontreal.ca
1710 // http://www.iro.umontreal.ca/~boyerf
1711 //
1712 // The code has been optimized for Intel processors
1713 // (takes a lot of time to convert float to and from iternal FPU representation)
1714 //
1715 // It is a simple "factorization" of the IDCT matrix.
1716
1717 // 9 point IDCT on even indices
1718
1719 // 5 points on odd indices (not realy an IDCT)
1720 float i00 = in[0]+in[0];
1721 float iip12 = i00 + in[12];
1722
1723 tmp0 = iip12 + in[4]*1.8793852415718f + in[8]*1.532088886238f + in[16]*0.34729635533386f;
1724 tmp1 = i00 + in[4] - in[8] - in[12] - in[12] - in[16];
1725 tmp2 = iip12 - in[4]*0.34729635533386f - in[8]*1.8793852415718f + in[16]*1.532088886238f;
1726 tmp3 = iip12 - in[4]*1.532088886238f + in[8]*0.34729635533386f - in[16]*1.8793852415718f;
1727 tmp4 = in[0] - in[4] + in[8] - in[12] + in[16];
1728
1729 // 4 points on even indices
1730 float i66_ = in[6]*1.732050808f; // Sqrt[3]
1731
1732 tmp0_ = in[2]*1.9696155060244f + i66_ + in[10]*1.2855752193731f + in[14]*0.68404028665134f;
1733 tmp1_ = (in[2] - in[10] - in[14])*1.732050808f;
1734 tmp2_ = in[2]*1.2855752193731f - i66_ - in[10]*0.68404028665134f + in[14]*1.9696155060244f;
1735 tmp3_ = in[2]*0.68404028665134f - i66_ + in[10]*1.9696155060244f - in[14]*1.2855752193731f;
1736
1737 // 9 point IDCT on odd indices
1738 // 5 points on odd indices (not realy an IDCT)
1739 float i0 = in[0+1]+in[0+1];
1740 float i0p12 = i0 + in[12+1];
1741
1742 tmp0o = i0p12 + in[4+1]*1.8793852415718f + in[8+1]*1.532088886238f + in[16+1]*0.34729635533386f;
1743 tmp1o = i0 + in[4+1] - in[8+1] - in[12+1] - in[12+1] - in[16+1];
1744 tmp2o = i0p12 - in[4+1]*0.34729635533386f - in[8+1]*1.8793852415718f + in[16+1]*1.532088886238f;
1745 tmp3o = i0p12 - in[4+1]*1.532088886238f + in[8+1]*0.34729635533386f - in[16+1]*1.8793852415718f;
1746 tmp4o = (in[0+1] - in[4+1] + in[8+1] - in[12+1] + in[16+1])*0.707106781f; // Twiddled
1747
1748 // 4 points on even indices
1749 float i6_ = in[6+1]*1.732050808f; // Sqrt[3]
1750
1751 tmp0_o = in[2+1]*1.9696155060244f + i6_ + in[10+1]*1.2855752193731f + in[14+1]*0.68404028665134f;
1752 tmp1_o = (in[2+1] - in[10+1] - in[14+1])*1.732050808f;
1753 tmp2_o = in[2+1]*1.2855752193731f - i6_ - in[10+1]*0.68404028665134f + in[14+1]*1.9696155060244f;
1754 tmp3_o = in[2+1]*0.68404028665134f - i6_ + in[10+1]*1.9696155060244f - in[14+1]*1.2855752193731f;
1755
1756 // Twiddle factors on odd indices
1757 // and
1758 // Butterflies on 9 point IDCT's
1759 // and
1760 // twiddle factors for 36 point IDCT
1761
1762 float e, o;
1763 e = tmp0 + tmp0_; o = (tmp0o + tmp0_o)*0.501909918f; tmpf_0 = e + o; tmpf_17 = e - o;
1764 e = tmp1 + tmp1_; o = (tmp1o + tmp1_o)*0.517638090f; tmpf_1 = e + o; tmpf_16 = e - o;
1765 e = tmp2 + tmp2_; o = (tmp2o + tmp2_o)*0.551688959f; tmpf_2 = e + o; tmpf_15 = e - o;
1766 e = tmp3 + tmp3_; o = (tmp3o + tmp3_o)*0.610387294f; tmpf_3 = e + o; tmpf_14 = e - o;
1767 tmpf_4 = tmp4 + tmp4o; tmpf_13 = tmp4 - tmp4o;
1768 e = tmp3 - tmp3_; o = (tmp3o - tmp3_o)*0.871723397f; tmpf_5 = e + o; tmpf_12 = e - o;
1769 e = tmp2 - tmp2_; o = (tmp2o - tmp2_o)*1.183100792f; tmpf_6 = e + o; tmpf_11 = e - o;
1770 e = tmp1 - tmp1_; o = (tmp1o - tmp1_o)*1.931851653f; tmpf_7 = e + o; tmpf_10 = e - o;
1771 e = tmp0 - tmp0_; o = (tmp0o - tmp0_o)*5.736856623f; tmpf_8 = e + o; tmpf_9 = e - o;
1772
1773 // end 36 point IDCT */
1774 // shift to modified IDCT
1775 win_bt = win[block_type];
1776
1777 out[0] =-tmpf_9 * win_bt[0];
1778 out[1] =-tmpf_10 * win_bt[1];
1779 out[2] =-tmpf_11 * win_bt[2];
1780 out[3] =-tmpf_12 * win_bt[3];
1781 out[4] =-tmpf_13 * win_bt[4];
1782 out[5] =-tmpf_14 * win_bt[5];
1783 out[6] =-tmpf_15 * win_bt[6];
1784 out[7] =-tmpf_16 * win_bt[7];
1785 out[8] =-tmpf_17 * win_bt[8];
1786 out[9] = tmpf_17 * win_bt[9];
1787 out[10]= tmpf_16 * win_bt[10];
1788 out[11]= tmpf_15 * win_bt[11];
1789 out[12]= tmpf_14 * win_bt[12];
1790 out[13]= tmpf_13 * win_bt[13];
1791 out[14]= tmpf_12 * win_bt[14];
1792 out[15]= tmpf_11 * win_bt[15];
1793 out[16]= tmpf_10 * win_bt[16];
1794 out[17]= tmpf_9 * win_bt[17];
1795 out[18]= tmpf_8 * win_bt[18];
1796 out[19]= tmpf_7 * win_bt[19];
1797 out[20]= tmpf_6 * win_bt[20];
1798 out[21]= tmpf_5 * win_bt[21];
1799 out[22]= tmpf_4 * win_bt[22];
1800 out[23]= tmpf_3 * win_bt[23];
1801 out[24]= tmpf_2 * win_bt[24];
1802 out[25]= tmpf_1 * win_bt[25];
1803 out[26]= tmpf_0 * win_bt[26];
1804 out[27]= tmpf_0 * win_bt[27];
1805 out[28]= tmpf_1 * win_bt[28];
1806 out[29]= tmpf_2 * win_bt[29];
1807 out[30]= tmpf_3 * win_bt[30];
1808 out[31]= tmpf_4 * win_bt[31];
1809 out[32]= tmpf_5 * win_bt[32];
1810 out[33]= tmpf_6 * win_bt[33];
1811 out[34]= tmpf_7 * win_bt[34];
1812 out[35]= tmpf_8 * win_bt[35];
1813 }
1814 }
1815
1816 private int counter = 0;
1817 private static final int SSLIMIT=18;
1818 private static final int SBLIMIT=32;
1819 // Size of the table of whole numbers raised to 4/3 power.
1820 // This may be adjusted for performance without any problems.
1821 //public static final int POW_TABLE_LIMIT=512;
1822
1823 /************************************************************/
1824 /* L3TABLE */
1825 /************************************************************/
1826
1827 static class SBI
1828 {
1829 public int[] l;
1830 public int[] s;
1831
1832 public SBI()
1833 {
1834 l = new int[23];
1835 s = new int[14];
1836 }
1837 public SBI(int[] thel, int[] thes)
1838 {
1839 l = thel;
1840 s = thes;
1841 }
1842 }
1843
1844 static class gr_info_s
1845 {
1846 public int part2_3_length = 0;
1847 public int big_values = 0;
1848 public int global_gain = 0;
1849 public int scalefac_compress = 0;
1850 public int window_switching_flag = 0;
1851 public int block_type = 0;
1852 public int mixed_block_flag = 0;
1853 public int[] table_select;
1854 public int[] subblock_gain;
1855 public int region0_count = 0;
1856 public int region1_count = 0;
1857 public int preflag = 0;
1858 public int scalefac_scale = 0;
1859 public int count1table_select = 0;
1860
1861 /**
1862 * Dummy Constructor
1863 */
1864 public gr_info_s()
1865 {
1866 table_select = new int[3];
1867 subblock_gain = new int[3];
1868 }
1869 }
1870
1871 static class temporaire
1872 {
1873 public int[] scfsi;
1874 public gr_info_s[] gr;
1875
1876 /**
1877 * Dummy Constructor
1878 */
1879 public temporaire()
1880 {
1881 scfsi = new int[4];
1882 gr = new gr_info_s[2];
1883 gr[0] = new gr_info_s();
1884 gr[1] = new gr_info_s();
1885 }
1886 }
1887
1888 static class III_side_info_t
1889 {
1890
1891 public int main_data_begin = 0;
1892 public int private_bits = 0;
1893 public temporaire[] ch;
1894 /**
1895 * Dummy Constructor
1896 */
1897 public III_side_info_t()
1898 {
1899 ch = new temporaire[2];
1900 ch[0] = new temporaire();
1901 ch[1] = new temporaire();
1902 }
1903 }
1904
1905 static class temporaire2
1906 {
1907 public int[] l; /* [cb] */
1908 public int[][] s; /* [window][cb] */
1909
1910 /**
1911 * Dummy Constructor
1912 */
1913 public temporaire2()
1914 {
1915 l = new int[23];
1916 s = new int[3][13];
1917 }
1918 }
1919 //class III_scalefac_t
1920 //{
1921 // public temporaire2[] tab;
1922 // /**
1923 // * Dummy Constructor
1924 // */
1925 // public III_scalefac_t()
1926 // {
1927 // tab = new temporaire2[2];
1928 // }
1929 //}
1930
1931 private static final int slen[][] =
1932 {
1933 {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},
1934 {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}
1935 };
1936
1937 public static final int pretab[] =
1938 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0};
1939
1940 private SBI[] sfBandIndex; // Init in the constructor.
1941
1942 public static final float two_to_negative_half_pow[] =
1943 { 1.0000000000E+00f, 7.0710678119E-01f, 5.0000000000E-01f, 3.5355339059E-01f,
1944 2.5000000000E-01f, 1.7677669530E-01f, 1.2500000000E-01f, 8.8388347648E-02f,
1945 6.2500000000E-02f, 4.4194173824E-02f, 3.1250000000E-02f, 2.2097086912E-02f,
1946 1.5625000000E-02f, 1.1048543456E-02f, 7.8125000000E-03f, 5.5242717280E-03f,
1947 3.9062500000E-03f, 2.7621358640E-03f, 1.9531250000E-03f, 1.3810679320E-03f,
1948 9.7656250000E-04f, 6.9053396600E-04f, 4.8828125000E-04f, 3.4526698300E-04f,
1949 2.4414062500E-04f, 1.7263349150E-04f, 1.2207031250E-04f, 8.6316745750E-05f,
1950 6.1035156250E-05f, 4.3158372875E-05f, 3.0517578125E-05f, 2.1579186438E-05f,
1951 1.5258789062E-05f, 1.0789593219E-05f, 7.6293945312E-06f, 5.3947966094E-06f,
1952 3.8146972656E-06f, 2.6973983047E-06f, 1.9073486328E-06f, 1.3486991523E-06f,
1953 9.5367431641E-07f, 6.7434957617E-07f, 4.7683715820E-07f, 3.3717478809E-07f,
1954 2.3841857910E-07f, 1.6858739404E-07f, 1.1920928955E-07f, 8.4293697022E-08f,
1955 5.9604644775E-08f, 4.2146848511E-08f, 2.9802322388E-08f, 2.1073424255E-08f,
1956 1.4901161194E-08f, 1.0536712128E-08f, 7.4505805969E-09f, 5.2683560639E-09f,
1957 3.7252902985E-09f, 2.6341780319E-09f, 1.8626451492E-09f, 1.3170890160E-09f,
1958 9.3132257462E-10f, 6.5854450798E-10f, 4.6566128731E-10f, 3.2927225399E-10f
1959 };
1960
1961
1962 public static final float t_43[] = create_t_43();
1963
1964 static private float[] create_t_43()
1965 {
1966 float[] t43 = new float[8192];
1967 final double d43 = (4.0/3.0);
1968
1969 for (int i=0; i<8192; i++)
1970 {
1971 t43[i] = (float)Math.pow(i, d43);
1972 }
1973 return t43;
1974 }
1975
1976 public static final float io[][] =
1977 {
1978 { 1.0000000000E+00f, 8.4089641526E-01f, 7.0710678119E-01f, 5.9460355751E-01f,
1979 5.0000000001E-01f, 4.2044820763E-01f, 3.5355339060E-01f, 2.9730177876E-01f,
1980 2.5000000001E-01f, 2.1022410382E-01f, 1.7677669530E-01f, 1.4865088938E-01f,
1981 1.2500000000E-01f, 1.0511205191E-01f, 8.8388347652E-02f, 7.4325444691E-02f,
1982 6.2500000003E-02f, 5.2556025956E-02f, 4.4194173826E-02f, 3.7162722346E-02f,
1983 3.1250000002E-02f, 2.6278012978E-02f, 2.2097086913E-02f, 1.8581361173E-02f,
1984 1.5625000001E-02f, 1.3139006489E-02f, 1.1048543457E-02f, 9.2906805866E-03f,
1985 7.8125000006E-03f, 6.5695032447E-03f, 5.5242717285E-03f, 4.6453402934E-03f },
1986 { 1.0000000000E+00f, 7.0710678119E-01f, 5.0000000000E-01f, 3.5355339060E-01f,
1987 2.5000000000E-01f, 1.7677669530E-01f, 1.2500000000E-01f, 8.8388347650E-02f,
1988 6.2500000001E-02f, 4.4194173825E-02f, 3.1250000001E-02f, 2.2097086913E-02f,
1989 1.5625000000E-02f, 1.1048543456E-02f, 7.8125000002E-03f, 5.5242717282E-03f,
1990 3.9062500001E-03f, 2.7621358641E-03f, 1.9531250001E-03f, 1.3810679321E-03f,
1991 9.7656250004E-04f, 6.9053396603E-04f, 4.8828125002E-04f, 3.4526698302E-04f,
1992 2.4414062501E-04f, 1.7263349151E-04f, 1.2207031251E-04f, 8.6316745755E-05f,
1993 6.1035156254E-05f, 4.3158372878E-05f, 3.0517578127E-05f, 2.1579186439E-05f }
1994 };
1995
1996
1997
1998 public static final float TAN12[] =
1999 {
2000 0.0f, 0.26794919f, 0.57735027f, 1.0f,
2001 1.73205081f, 3.73205081f, 9.9999999e10f, -3.73205081f,
2002 -1.73205081f, -1.0f, -0.57735027f, -0.26794919f,
2003 0.0f, 0.26794919f, 0.57735027f, 1.0f
2004 };
2005
2006 // REVIEW: in java, the array lookup may well be slower than
2007 // the actual calculation
2008 // 576 / 18
2009/*
2010 private static final int ss_div[] =
2011 {
2012 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2013 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2014 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2015 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2016 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2017 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2018 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
2019 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2020 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
2021 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
2022 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
2023 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
2024 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2025 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2026 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2027 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
2028 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2029 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2030 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
2031 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
2032 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2033 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
2034 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
2035 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
2036 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
2037 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
2038 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
2039 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
2040 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
2041 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
2042 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
2043 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
2044 };
2045
2046 // 576 % 18
2047 private static final int ss_mod[] =
2048 {
2049 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2050 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2051 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2052 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2053 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2054 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2055 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2056 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2057 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2058 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2059 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2060 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2061 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2062 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2063 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2064 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2065 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2066 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2067 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2068 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2069 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2070 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2071 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2072 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2073 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2074 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2075 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2076 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2077 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2078 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2079 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
2080 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
2081 };
2082*/
2083 private static /*final*/ int reorder_table[][]/* = loadReorderTable()*/; // SZD: will be generated on demand
2084
2085 /**
2086 * Loads the data for the reorder
2087 */
2088 /*private static int[][] loadReorderTable() // SZD: table will be generated
2089 {
2090 try
2091 {
2092 Class elemType = int[][].class.getComponentType();
2093 Object o = JavaLayerUtils.deserializeArrayResource("l3reorder.ser", elemType, 6);
2094 return (int[][])o;
2095 }
2096 catch (IOException ex)
2097 {
2098 throw new ExceptionInInitializerError(ex);
2099 }
2100 }*/
2101
2102 static int[] reorder(int scalefac_band[]) { // SZD: converted from LAME
2103 int j = 0;
2104 int ix[] = new int[576];
2105 for(int sfb = 0; sfb < 13; sfb++) {
2106 int start = scalefac_band[sfb];
2107 int end = scalefac_band[sfb + 1];
2108 for(int window = 0; window < 3; window++)
2109 for(int i = start; i < end; i++)
2110 ix[3 * i + window] = j++;
2111 }
2112 return ix;
2113 }
2114
2115 /*static final int reorder_table_data[][]; =
2116 {
2117 { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
2118 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
2119 34, 27, 31, 35, 36, 42, 48, 37, 43, 49, 38, 44, 50, 39, 45, 51,
2120 40, 46, 52, 41, 47, 53, 54, 60, 66, 55, 61, 67, 56, 62, 68, 57,
2121 63, 69, 58, 64, 70, 59, 65, 71, 72, 80, 88, 73, 81, 89, 74, 82,
2122 90, 75, 83, 91, 76, 84, 92, 77, 85, 93, 78, 86, 94, 79, 87, 95,
2123 96,106,116, 97,107,117, 98,108,118, 99,109,119,100,110,120,101,
2124 111,121,102,112,122,103,113,123,104,114,124,105,115,125,126,140,
2125 154,127,141,155,128,142,156,129,143,157,130,144,158,131,145,159,
2126 132,146,160,133,147,161,134,148,162,135,149,163,136,150,164,137,
2127 151,165,138,152,166,139,153,167,168,186,204,169,187,205,170,188,
2128 206,171,189,207,172,190,208,173,191,209,174,192,210,175,193,211,
2129 176,194,212,177,195,213,178,196,214,179,197,215,180,198,216,181,
2130 199,217,182,200,218,183,201,219,184,202,220,185,203,221,222,248,
2131 274,223,249,275,224,250,276,225,251,277,226,252,278,227,253,279,
2132 228,254,280,229,255,281,230,256,282,231,257,283,232,258,284,233,
2133 259,285,234,260,286,235,261,287,236,262,288,237,263,289,238,264,
2134 290,239,265,291,240,266,292,241,267,293,242,268,294,243,269,295,
2135 244,270,296,245,271,297,246,272,298,247,273,299,300,332,364,301,
2136 333,365,302,334,366,303,335,367,304,336,368,305,337,369,306,338,
2137 370,307,339,371,308,340,372,309,341,373,310,342,374,311,343,375,
2138 312,344,376,313,345,377,314,346,378,315,347,379,316,348,380,317,
2139 349,381,318,350,382,319,351,383,320,352,384,321,353,385,322,354,
2140 386,323,355,387,324,356,388,325,357,389,326,358,390,327,359,391,
2141 328,360,392,329,361,393,330,362,394,331,363,395,396,438,480,397,
2142 439,481,398,440,482,399,441,483,400,442,484,401,443,485,402,444,
2143 486,403,445,487,404,446,488,405,447,489,406,448,490,407,449,491,
2144 408,450,492,409,451,493,410,452,494,411,453,495,412,454,496,413,
2145 455,497,414,456,498,415,457,499,416,458,500,417,459,501,418,460,
2146 502,419,461,503,420,462,504,421,463,505,422,464,506,423,465,507,
2147 424,466,508,425,467,509,426,468,510,427,469,511,428,470,512,429,
2148 471,513,430,472,514,431,473,515,432,474,516,433,475,517,434,476,
2149 518,435,477,519,436,478,520,437,479,521,522,540,558,523,541,559,
2150 524,542,560,525,543,561,526,544,562,527,545,563,528,546,564,529,
2151 547,565,530,548,566,531,549,567,532,550,568,533,551,569,534,552,
2152 570,535,553,571,536,554,572,537,555,573,538,556,574,539,557,575},
2153 { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
2154 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
2155 34, 27, 31, 35, 36, 42, 48, 37, 43, 49, 38, 44, 50, 39, 45, 51,
2156 40, 46, 52, 41, 47, 53, 54, 62, 70, 55, 63, 71, 56, 64, 72, 57,
2157 65, 73, 58, 66, 74, 59, 67, 75, 60, 68, 76, 61, 69, 77, 78, 88,
2158 98, 79, 89, 99, 80, 90,100, 81, 91,101, 82, 92,102, 83, 93,103,
2159 84, 94,104, 85, 95,105, 86, 96,106, 87, 97,107,108,120,132,109,
2160 121,133,110,122,134,111,123,135,112,124,136,113,125,137,114,126,
2161 138,115,127,139,116,128,140,117,129,141,118,130,142,119,131,143,
2162 144,158,172,145,159,173,146,160,174,147,161,175,148,162,176,149,
2163 163,177,150,164,178,151,165,179,152,166,180,153,167,181,154,168,
2164 182,155,169,183,156,170,184,157,171,185,186,204,222,187,205,223,
2165 188,206,224,189,207,225,190,208,226,191,209,227,192,210,228,193,
2166 211,229,194,212,230,195,213,231,196,214,232,197,215,233,198,216,
2167 234,199,217,235,200,218,236,201,219,237,202,220,238,203,221,239,
2168 240,264,288,241,265,289,242,266,290,243,267,291,244,268,292,245,
2169 269,293,246,270,294,247,271,295,248,272,296,249,273,297,250,274,
2170 298,251,275,299,252,276,300,253,277,301,254,278,302,255,279,303,
2171 256,280,304,257,281,305,258,282,306,259,283,307,260,284,308,261,
2172 285,309,262,286,310,263,287,311,312,344,376,313,345,377,314,346,
2173 378,315,347,379,316,348,380,317,349,381,318,350,382,319,351,383,
2174 320,352,384,321,353,385,322,354,386,323,355,387,324,356,388,325,
2175 357,389,326,358,390,327,359,391,328,360,392,329,361,393,330,362,
2176 394,331,363,395,332,364,396,333,365,397,334,366,398,335,367,399,
2177 336,368,400,337,369,401,338,370,402,339,371,403,340,372,404,341,
2178 373,405,342,374,406,343,375,407,408,452,496,409,453,497,410,454,
2179 498,411,455,499,412,456,500,413,457,501,414,458,502,415,459,503,
2180 416,460,504,417,461,505,418,462,506,419,463,507,420,464,508,421,
2181 465,509,422,466,510,423,467,511,424,468,512,425,469,513,426,470,
2182 514,427,471,515,428,472,516,429,473,517,430,474,518,431,475,519,
2183 432,476,520,433,477,521,434,478,522,435,479,523,436,480,524,437,
2184 481,525,438,482,526,439,483,527,440,484,528,441,485,529,442,486,
2185 530,443,487,531,444,488,532,445,489,533,446,490,534,447,491,535,
2186 448,492,536,449,493,537,450,494,538,451,495,539,540,552,564,541,
2187 553,565,542,554,566,543,555,567,544,556,568,545,557,569,546,558,
2188 570,547,559,571,548,560,572,549,561,573,550,562,574,551,563,575},
2189 { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
2190 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
2191 34, 27, 31, 35, 36, 42, 48, 37, 43, 49, 38, 44, 50, 39, 45, 51,
2192 40, 46, 52, 41, 47, 53, 54, 62, 70, 55, 63, 71, 56, 64, 72, 57,
2193 65, 73, 58, 66, 74, 59, 67, 75, 60, 68, 76, 61, 69, 77, 78, 88,
2194 98, 79, 89, 99, 80, 90,100, 81, 91,101, 82, 92,102, 83, 93,103,
2195 84, 94,104, 85, 95,105, 86, 96,106, 87, 97,107,108,120,132,109,
2196 121,133,110,122,134,111,123,135,112,124,136,113,125,137,114,126,
2197 138,115,127,139,116,128,140,117,129,141,118,130,142,119,131,143,
2198 144,158,172,145,159,173,146,160,174,147,161,175,148,162,176,149,
2199 163,177,150,164,178,151,165,179,152,166,180,153,167,181,154,168,
2200 182,155,169,183,156,170,184,157,171,185,186,204,222,187,205,223,
2201 188,206,224,189,207,225,190,208,226,191,209,227,192,210,228,193,
2202 211,229,194,212,230,195,213,231,196,214,232,197,215,233,198,216,
2203 234,199,217,235,200,218,236,201,219,237,202,220,238,203,221,239,
2204 240,264,288,241,265,289,242,266,290,243,267,291,244,268,292,245,
2205 269,293,246,270,294,247,271,295,248,272,296,249,273,297,250,274,
2206 298,251,275,299,252,276,300,253,277,301,254,278,302,255,279,303,
2207 256,280,304,257,281,305,258,282,306,259,283,307,260,284,308,261,
2208 285,309,262,286,310,263,287,311,312,342,372,313,343,373,314,344,
2209 374,315,345,375,316,346,376,317,347,377,318,348,378,319,349,379,
2210 320,350,380,321,351,381,322,352,382,323,353,383,324,354,384,325,
2211 355,385,326,356,386,327,357,387,328,358,388,329,359,389,330,360,
2212 390,331,361,391,332,362,392,333,363,393,334,364,394,335,365,395,
2213 336,366,396,337,367,397,338,368,398,339,369,399,340,370,400,341,
2214 371,401,402,442,482,403,443,483,404,444,484,405,445,485,406,446,
2215 486,407,447,487,408,448,488,409,449,489,410,450,490,411,451,491,
2216 412,452,492,413,453,493,414,454,494,415,455,495,416,456,496,417,
2217 457,497,418,458,498,419,459,499,420,460,500,421,461,501,422,462,
2218 502,423,463,503,424,464,504,425,465,505,426,466,506,427,467,507,
2219 428,468,508,429,469,509,430,470,510,431,471,511,432,472,512,433,
2220 473,513,434,474,514,435,475,515,436,476,516,437,477,517,438,478,
2221 518,439,479,519,440,480,520,441,481,521,522,540,558,523,541,559,
2222 524,542,560,525,543,561,526,544,562,527,545,563,528,546,564,529,
2223 547,565,530,548,566,531,549,567,532,550,568,533,551,569,534,552,
2224 570,535,553,571,536,554,572,537,555,573,538,556,574,539,557,575},
2225 { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
2226 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
2227 34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39, 43, 47,
2228 48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52, 58, 64, 53,
2229 59, 65, 66, 74, 82, 67, 75, 83, 68, 76, 84, 69, 77, 85, 70, 78,
2230 86, 71, 79, 87, 72, 80, 88, 73, 81, 89, 90,100,110, 91,101,111,
2231 92,102,112, 93,103,113, 94,104,114, 95,105,115, 96,106,116, 97,
2232 107,117, 98,108,118, 99,109,119,120,132,144,121,133,145,122,134,
2233 146,123,135,147,124,136,148,125,137,149,126,138,150,127,139,151,
2234 128,140,152,129,141,153,130,142,154,131,143,155,156,170,184,157,
2235 171,185,158,172,186,159,173,187,160,174,188,161,175,189,162,176,
2236 190,163,177,191,164,178,192,165,179,193,166,180,194,167,181,195,
2237 168,182,196,169,183,197,198,216,234,199,217,235,200,218,236,201,
2238 219,237,202,220,238,203,221,239,204,222,240,205,223,241,206,224,
2239 242,207,225,243,208,226,244,209,227,245,210,228,246,211,229,247,
2240 212,230,248,213,231,249,214,232,250,215,233,251,252,274,296,253,
2241 275,297,254,276,298,255,277,299,256,278,300,257,279,301,258,280,
2242 302,259,281,303,260,282,304,261,283,305,262,284,306,263,285,307,
2243 264,286,308,265,287,309,266,288,310,267,289,311,268,290,312,269,
2244 291,313,270,292,314,271,293,315,272,294,316,273,295,317,318,348,
2245 378,319,349,379,320,350,380,321,351,381,322,352,382,323,353,383,
2246 324,354,384,325,355,385,326,356,386,327,357,387,328,358,388,329,
2247 359,389,330,360,390,331,361,391,332,362,392,333,363,393,334,364,
2248 394,335,365,395,336,366,396,337,367,397,338,368,398,339,369,399,
2249 340,370,400,341,371,401,342,372,402,343,373,403,344,374,404,345,
2250 375,405,346,376,406,347,377,407,408,464,520,409,465,521,410,466,
2251 522,411,467,523,412,468,524,413,469,525,414,470,526,415,471,527,
2252 416,472,528,417,473,529,418,474,530,419,475,531,420,476,532,421,
2253 477,533,422,478,534,423,479,535,424,480,536,425,481,537,426,482,
2254 538,427,483,539,428,484,540,429,485,541,430,486,542,431,487,543,
2255 432,488,544,433,489,545,434,490,546,435,491,547,436,492,548,437,
2256 493,549,438,494,550,439,495,551,440,496,552,441,497,553,442,498,
2257 554,443,499,555,444,500,556,445,501,557,446,502,558,447,503,559,
2258 448,504,560,449,505,561,450,506,562,451,507,563,452,508,564,453,
2259 509,565,454,510,566,455,511,567,456,512,568,457,513,569,458,514,
2260 570,459,515,571,460,516,572,461,517,573,462,518,574,463,519,575},
2261 { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
2262 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
2263 34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39, 43, 47,
2264 48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52, 58, 64, 53,
2265 59, 65, 66, 72, 78, 67, 73, 79, 68, 74, 80, 69, 75, 81, 70, 76,
2266 82, 71, 77, 83, 84, 94,104, 85, 95,105, 86, 96,106, 87, 97,107,
2267 88, 98,108, 89, 99,109, 90,100,110, 91,101,111, 92,102,112, 93,
2268 103,113,114,126,138,115,127,139,116,128,140,117,129,141,118,130,
2269 142,119,131,143,120,132,144,121,133,145,122,134,146,123,135,147,
2270 124,136,148,125,137,149,150,164,178,151,165,179,152,166,180,153,
2271 167,181,154,168,182,155,169,183,156,170,184,157,171,185,158,172,
2272 186,159,173,187,160,174,188,161,175,189,162,176,190,163,177,191,
2273 192,208,224,193,209,225,194,210,226,195,211,227,196,212,228,197,
2274 213,229,198,214,230,199,215,231,200,216,232,201,217,233,202,218,
2275 234,203,219,235,204,220,236,205,221,237,206,222,238,207,223,239,
2276 240,260,280,241,261,281,242,262,282,243,263,283,244,264,284,245,
2277 265,285,246,266,286,247,267,287,248,268,288,249,269,289,250,270,
2278 290,251,271,291,252,272,292,253,273,293,254,274,294,255,275,295,
2279 256,276,296,257,277,297,258,278,298,259,279,299,300,326,352,301,
2280 327,353,302,328,354,303,329,355,304,330,356,305,331,357,306,332,
2281 358,307,333,359,308,334,360,309,335,361,310,336,362,311,337,363,
2282 312,338,364,313,339,365,314,340,366,315,341,367,316,342,368,317,
2283 343,369,318,344,370,319,345,371,320,346,372,321,347,373,322,348,
2284 374,323,349,375,324,350,376,325,351,377,378,444,510,379,445,511,
2285 380,446,512,381,447,513,382,448,514,383,449,515,384,450,516,385,
2286 451,517,386,452,518,387,453,519,388,454,520,389,455,521,390,456,
2287 522,391,457,523,392,458,524,393,459,525,394,460,526,395,461,527,
2288 396,462,528,397,463,529,398,464,530,399,465,531,400,466,532,401,
2289 467,533,402,468,534,403,469,535,404,470,536,405,471,537,406,472,
2290 538,407,473,539,408,474,540,409,475,541,410,476,542,411,477,543,
2291 412,478,544,413,479,545,414,480,546,415,481,547,416,482,548,417,
2292 483,549,418,484,550,419,485,551,420,486,552,421,487,553,422,488,
2293 554,423,489,555,424,490,556,425,491,557,426,492,558,427,493,559,
2294 428,494,560,429,495,561,430,496,562,431,497,563,432,498,564,433,
2295 499,565,434,500,566,435,501,567,436,502,568,437,503,569,438,504,
2296 570,439,505,571,440,506,572,441,507,573,442,508,574,443,509,575},
2297 { 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11, 12, 16, 20, 13,
2298 17, 21, 14, 18, 22, 15, 19, 23, 24, 28, 32, 25, 29, 33, 26, 30,
2299 34, 27, 31, 35, 36, 40, 44, 37, 41, 45, 38, 42, 46, 39, 43, 47,
2300 48, 54, 60, 49, 55, 61, 50, 56, 62, 51, 57, 63, 52, 58, 64, 53,
2301 59, 65, 66, 74, 82, 67, 75, 83, 68, 76, 84, 69, 77, 85, 70, 78,
2302 86, 71, 79, 87, 72, 80, 88, 73, 81, 89, 90,102,114, 91,103,115,
2303 92,104,116, 93,105,117, 94,106,118, 95,107,119, 96,108,120, 97,
2304 109,121, 98,110,122, 99,111,123,100,112,124,101,113,125,126,142,
2305 158,127,143,159,128,144,160,129,145,161,130,146,162,131,147,163,
2306 132,148,164,133,149,165,134,150,166,135,151,167,136,152,168,137,
2307 153,169,138,154,170,139,155,171,140,156,172,141,157,173,174,194,
2308 214,175,195,215,176,196,216,177,197,217,178,198,218,179,199,219,
2309 180,200,220,181,201,221,182,202,222,183,203,223,184,204,224,185,
2310 205,225,186,206,226,187,207,227,188,208,228,189,209,229,190,210,
2311 230,191,211,231,192,212,232,193,213,233,234,260,286,235,261,287,
2312 236,262,288,237,263,289,238,264,290,239,265,291,240,266,292,241,
2313 267,293,242,268,294,243,269,295,244,270,296,245,271,297,246,272,
2314 298,247,273,299,248,274,300,249,275,301,250,276,302,251,277,303,
2315 252,278,304,253,279,305,254,280,306,255,281,307,256,282,308,257,
2316 283,309,258,284,310,259,285,311,312,346,380,313,347,381,314,348,
2317 382,315,349,383,316,350,384,317,351,385,318,352,386,319,353,387,
2318 320,354,388,321,355,389,322,356,390,323,357,391,324,358,392,325,
2319 359,393,326,360,394,327,361,395,328,362,396,329,363,397,330,364,
2320 398,331,365,399,332,366,400,333,367,401,334,368,402,335,369,403,
2321 336,370,404,337,371,405,338,372,406,339,373,407,340,374,408,341,
2322 375,409,342,376,410,343,377,411,344,378,412,345,379,413,414,456,
2323 498,415,457,499,416,458,500,417,459,501,418,460,502,419,461,503,
2324 420,462,504,421,463,505,422,464,506,423,465,507,424,466,508,425,
2325 467,509,426,468,510,427,469,511,428,470,512,429,471,513,430,472,
2326 514,431,473,515,432,474,516,433,475,517,434,476,518,435,477,519,
2327 436,478,520,437,479,521,438,480,522,439,481,523,440,482,524,441,
2328 483,525,442,484,526,443,485,527,444,486,528,445,487,529,446,488,
2329 530,447,489,531,448,490,532,449,491,533,450,492,534,451,493,535,
2330 452,494,536,453,495,537,454,496,538,455,497,539,540,552,564,541,
2331 553,565,542,554,566,543,555,567,544,556,568,545,557,569,546,558,
2332 570,547,559,571,548,560,572,549,561,573,550,562,574,551,563,575}
2333 };
2334*/
2335
2336 private static final float cs[] =
2337 {
2338 0.857492925712f, 0.881741997318f, 0.949628649103f, 0.983314592492f,
2339 0.995517816065f, 0.999160558175f, 0.999899195243f, 0.999993155067f
2340 };
2341
2342 private static final float ca[] =
2343 {
2344 -0.5144957554270f, -0.4717319685650f, -0.3133774542040f, -0.1819131996110f,
2345 -0.0945741925262f, -0.0409655828852f, -0.0141985685725f, -0.00369997467375f
2346 };
2347
2348 /************************************************************/
2349 /* END OF L3TABLE */
2350 /************************************************************/
2351
2352 /************************************************************/
2353 /* L3TYPE */
2354 /************************************************************/
2355
2356
2357 /***************************************************************/
2358 /* END OF L3TYPE */
2359 /***************************************************************/
2360
2361 /***************************************************************/
2362 /* INV_MDCT */
2363 /***************************************************************/
2364 public static final float win[][] =
2365 {
2366 { -1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f,
2367 -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f,
2368 -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f,
2369 -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f,
2370 -4.0715656898E-01f, -3.6969460527E-01f, -3.3876269197E-01f, -3.1242222492E-01f,
2371 -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f,
2372 -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f,
2373 -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f,
2374 -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f },
2375
2376 { -1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f,
2377 -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f,
2378 -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f,
2379 -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f,
2380 -4.0715656898E-01f, -3.6969460527E-01f, -3.3908542600E-01f, -3.1511810350E-01f,
2381 -2.9642226150E-01f, -2.8184548650E-01f, -5.4119610000E-01f, -2.6213228100E-01f,
2382 -2.5387916537E-01f, -2.3296291359E-01f, -1.9852728987E-01f, -1.5233534808E-01f,
2383 -9.6496400054E-02f, -3.3423828516E-02f, 0.0000000000E+00f, 0.0000000000E+00f,
2384 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f },
2385
2386 { -4.8300800645E-02f, -1.5715656932E-01f, -2.8325045177E-01f, -4.2953747763E-01f,
2387 -1.2071067795E+00f, -8.2426483178E-01f, -1.1451749106E+00f, -1.7695290101E+00f,
2388 -4.5470225061E+00f, -3.4890531002E+00f, -7.3296292804E-01f, -1.5076514758E-01f,
2389 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
2390 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
2391 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
2392 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
2393 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
2394 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f },
2395
2396 { 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
2397 0.0000000000E+00f, 0.0000000000E+00f, -1.5076513660E-01f, -7.3296291107E-01f,
2398 -3.4890530566E+00f, -4.5470224727E+00f, -1.7695290031E+00f, -1.1451749092E+00f,
2399 -8.3137738100E-01f, -1.3065629650E+00f, -5.4142014250E-01f, -4.6528974900E-01f,
2400 -4.1066990750E-01f, -3.7004680800E-01f, -3.3876269197E-01f, -3.1242222492E-01f,
2401 -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f,
2402 -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f,
2403 -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f,
2404 -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f }
2405 };
2406 /***************************************************************/
2407 /* END OF INV_MDCT */
2408 /***************************************************************/
2409
2410 class Sftable
2411 {
2412 public int[] l;
2413 public int[] s;
2414
2415 public Sftable()
2416 {
2417 l = new int[5];
2418 s = new int[3];
2419 }
2420
2421 public Sftable(int[] thel, int[] thes)
2422 {
2423 l = thel;
2424 s = thes;
2425 }
2426 }
2427
2428 public Sftable sftable;
2429
2430 public static final int nr_of_sfb_block[][][] =
2431 {{{ 6, 5, 5, 5} , { 9, 9, 9, 9} , { 6, 9, 9, 9}},
2432 {{ 6, 5, 7, 3} , { 9, 9,12, 6} , { 6, 9,12, 6}},
2433 {{11,10, 0, 0} , {18,18, 0, 0} , {15,18, 0, 0}},
2434 {{ 7, 7, 7, 0} , {12,12,12, 0} , { 6,15,12, 0}},
2435 {{ 6, 6, 6, 3} , {12, 9, 9, 6} , { 6,12, 9, 6}},
2436 {{ 8, 8, 5, 0} , {15,12, 9, 0} , { 6,18, 9, 0}}};
2437
2438
2439}
diff --git a/songdbj/javazoom/jl/decoder/Manager.java b/songdbj/javazoom/jl/decoder/Manager.java
new file mode 100644
index 0000000000..f566a232e7
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Manager.java
@@ -0,0 +1,46 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.decoder;
21
22/**
23 * Work in progress.
24 *
25 * Manages a number of controls.
26 */
27public class Manager //implements Control
28{
29 public void addControl(Control c)
30 {
31
32 }
33
34 public void removeControl(Control c)
35 {
36
37 }
38
39 public void removeAll()
40 {
41
42 }
43
44 // control interface delegates to a managed control
45
46}
diff --git a/songdbj/javazoom/jl/decoder/Obuffer.java b/songdbj/javazoom/jl/decoder/Obuffer.java
new file mode 100644
index 0000000000..45a71a9baf
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Obuffer.java
@@ -0,0 +1,88 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/12/99 Added appendSamples() method for efficiency. MDM.
4 * 15/02/99 ,Java Conversion by E.B ,ebsp@iname.com, JavaLayer
5 *
6 * Declarations for output buffer, includes operating system
7 * implementation of the virtual Obuffer. Optional routines
8 * enabling seeks and stops added by Jeff Tsay.
9 *
10 * @(#) obuffer.h 1.8, last edit: 6/15/94 16:51:56
11 * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
12 * @(#) Berlin University of Technology
13 *
14 * Idea and first implementation for u-law output with fast downsampling by
15 * Jim Boucher (jboucher@flash.bu.edu)
16 *
17 * LinuxObuffer class written by
18 * Louis P. Kruger (lpkruger@phoenix.princeton.edu)
19 *-----------------------------------------------------------------------
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU Library General Public License as published
22 * by the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU Library General Public License for more details.
29 *
30 * You should have received a copy of the GNU Library General Public
31 * License along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 *----------------------------------------------------------------------
34 */
35package javazoom.jl.decoder;
36
37/**
38 * Base Class for audio output.
39 */
40public abstract class Obuffer
41{
42 public static final int OBUFFERSIZE = 2 * 1152; // max. 2 * 1152 samples per frame
43 public static final int MAXCHANNELS = 2; // max. number of channels
44
45 /**
46 * Takes a 16 Bit PCM sample.
47 */
48 public abstract void append(int channel, short value);
49
50 /**
51 * Accepts 32 new PCM samples.
52 */
53 public void appendSamples(int channel, float[] f)
54 {
55 short s;
56 for (int i=0; i<32;)
57 {
58 s = clip(f[i++]);
59 append(channel, s);
60 }
61 }
62
63 /**
64 * Clip Sample to 16 Bits
65 */
66 private final short clip(float sample)
67 {
68 return ((sample > 32767.0f) ? 32767 :
69 ((sample < -32768.0f) ? -32768 :
70 (short) sample));
71 }
72
73 /**
74 * Write the samples to the file or directly to the audio hardware.
75 */
76 public abstract void write_buffer(int val);
77 public abstract void close();
78
79 /**
80 * Clears all data in the buffer (for seeking).
81 */
82 public abstract void clear_buffer();
83
84 /**
85 * Notify the buffer that the user has stopped the stream.
86 */
87 public abstract void set_stop_flag();
88}
diff --git a/songdbj/javazoom/jl/decoder/OutputChannels.java b/songdbj/javazoom/jl/decoder/OutputChannels.java
new file mode 100644
index 0000000000..58c8310de7
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/OutputChannels.java
@@ -0,0 +1,143 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 12/12/99 Initial implementation. 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
21package javazoom.jl.decoder;
22
23
24/**
25 * A Type-safe representation of the the supported output channel
26 * constants.
27 *
28 * This class is immutable and, hence, is thread safe.
29 *
30 * @author Mat McGowan 12/12/99
31 * @since 0.0.7
32 */
33public class OutputChannels
34{
35 /**
36 * Flag to indicate output should include both channels.
37 */
38 public static final int BOTH_CHANNELS = 0;
39
40 /**
41 * Flag to indicate output should include the left channel only.
42 */
43 public static final int LEFT_CHANNEL = 1;
44
45 /**
46 * Flag to indicate output should include the right channel only.
47 */
48 public static final int RIGHT_CHANNEL = 2;
49
50 /**
51 * Flag to indicate output is mono.
52 */
53 public static final int DOWNMIX_CHANNELS = 3;
54
55
56 public static final OutputChannels LEFT = new OutputChannels(LEFT_CHANNEL);
57 public static final OutputChannels RIGHT = new OutputChannels(RIGHT_CHANNEL);
58 public static final OutputChannels BOTH = new OutputChannels(BOTH_CHANNELS);
59 public static final OutputChannels DOWNMIX = new OutputChannels(DOWNMIX_CHANNELS);
60
61
62 private /*final*/ int outputChannels;
63
64 /**
65 * Creates an <code>OutputChannels</code> instance
66 * corresponding to the given channel code.
67 *
68 * @param code one of the OutputChannels channel code constants.
69 *
70 * @throws IllegalArgumentException if code is not a valid
71 * channel code.
72 */
73 static public OutputChannels fromInt(int code)
74 {
75 switch (code)
76 {
77 case LEFT_CHANNEL:
78 return LEFT;
79 case RIGHT_CHANNEL:
80 return RIGHT;
81 case BOTH_CHANNELS:
82 return BOTH;
83 case DOWNMIX_CHANNELS:
84 return DOWNMIX;
85 default:
86 throw new IllegalArgumentException("Invalid channel code: "+code);
87 }
88 }
89
90 private OutputChannels(int channels)
91 {
92 outputChannels = channels;
93
94 if (channels<0 || channels>3)
95 throw new IllegalArgumentException("channels");
96 }
97
98 /**
99 * Retrieves the code representing the desired output channels.
100 * Will be one of LEFT_CHANNEL, RIGHT_CHANNEL, BOTH_CHANNELS
101 * or DOWNMIX_CHANNELS.
102 *
103 * @return the channel code represented by this instance.
104 */
105 public int getChannelsOutputCode()
106 {
107 return outputChannels;
108 }
109
110 /**
111 * Retrieves the number of output channels represented
112 * by this channel output type.
113 *
114 * @return The number of output channels for this channel output
115 * type. This will be 2 for BOTH_CHANNELS only, and 1
116 * for all other types.
117 */
118 public int getChannelCount()
119 {
120 int count = (outputChannels==BOTH_CHANNELS) ? 2 : 1;
121 return count;
122 }
123
124
125 public boolean equals(Object o)
126 {
127 boolean equals = false;
128
129 if (o instanceof OutputChannels)
130 {
131 OutputChannels oc = (OutputChannels)o;
132 equals = (oc.outputChannels == outputChannels);
133 }
134
135 return equals;
136 }
137
138 public int hashCode()
139 {
140 return outputChannels;
141 }
142
143}
diff --git a/songdbj/javazoom/jl/decoder/SampleBuffer.java b/songdbj/javazoom/jl/decoder/SampleBuffer.java
new file mode 100644
index 0000000000..ba4bfa060f
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/SampleBuffer.java
@@ -0,0 +1,132 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 12/12/99 Initial Version based on FileObuffer. mdm@techie.com.
5 *
6 * FileObuffer:
7 * 15/02/99 Java Conversion by E.B ,javalayer@javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.jl.decoder;
27
28/**
29 * The <code>SampleBuffer</code> class implements an output buffer
30 * that provides storage for a fixed size block of samples.
31 */
32public class SampleBuffer extends Obuffer
33{
34 private short[] buffer;
35 private int[] bufferp;
36 private int channels;
37 private int frequency;
38
39 /**
40 * Constructor
41 */
42 public SampleBuffer(int sample_frequency, int number_of_channels)
43 {
44 buffer = new short[OBUFFERSIZE];
45 bufferp = new int[MAXCHANNELS];
46 channels = number_of_channels;
47 frequency = sample_frequency;
48
49 for (int i = 0; i < number_of_channels; ++i)
50 bufferp[i] = (short)i;
51
52 }
53
54 public int getChannelCount()
55 {
56 return this.channels;
57 }
58
59 public int getSampleFrequency()
60 {
61 return this.frequency;
62 }
63
64 public short[] getBuffer()
65 {
66 return this.buffer;
67 }
68
69 public int getBufferLength()
70 {
71 return bufferp[0];
72 }
73
74 /**
75 * Takes a 16 Bit PCM sample.
76 */
77 public void append(int channel, short value)
78 {
79 buffer[bufferp[channel]] = value;
80 bufferp[channel] += channels;
81 }
82
83 public void appendSamples(int channel, float[] f)
84 {
85 int pos = bufferp[channel];
86
87 short s;
88 float fs;
89 for (int i=0; i<32;)
90 {
91 fs = f[i++];
92 fs = (fs>32767.0f ? 32767.0f
93 : (fs < -32767.0f ? -32767.0f : fs));
94
95 s = (short)fs;
96 buffer[pos] = s;
97 pos += channels;
98 }
99
100 bufferp[channel] = pos;
101 }
102
103
104 /**
105 * Write the samples to the file (Random Acces).
106 */
107 public void write_buffer(int val)
108 {
109
110 //for (int i = 0; i < channels; ++i)
111 // bufferp[i] = (short)i;
112
113 }
114
115 public void close()
116 {}
117
118 /**
119 *
120 */
121 public void clear_buffer()
122 {
123 for (int i = 0; i < channels; ++i)
124 bufferp[i] = (short)i;
125 }
126
127 /**
128 *
129 */
130 public void set_stop_flag()
131 {}
132}
diff --git a/songdbj/javazoom/jl/decoder/Source.java b/songdbj/javazoom/jl/decoder/Source.java
new file mode 100644
index 0000000000..9d6a5d732e
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/Source.java
@@ -0,0 +1,49 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.decoder;
21
22import java.io.IOException;
23
24/**
25 * Work in progress.
26 *
27 * Class to describe a seekable data source.
28 *
29 */
30public interface Source
31{
32
33 public static final long LENGTH_UNKNOWN = -1;
34
35 public int read(byte[] b, int offs, int len)
36 throws IOException;
37
38
39 public boolean willReadBlock();
40
41 public boolean isSeekable();
42
43 public long length();
44
45 public long tell();
46
47 public long seek(long pos);
48
49}
diff --git a/songdbj/javazoom/jl/decoder/SynthesisFilter.java b/songdbj/javazoom/jl/decoder/SynthesisFilter.java
new file mode 100644
index 0000000000..581ab03cc2
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/SynthesisFilter.java
@@ -0,0 +1,1817 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 04/01/00 Fixes for running under build 23xx Microsoft JVM. mdm.
5 *
6 * 19/12/99 Performance improvements to compute_pcm_samples().
7 * Mat McGowan. mdm@techie.com.
8 *
9 * 16/02/99 Java Conversion by E.B , javalayer@javazoom.net
10 *
11 * @(#) synthesis_filter.h 1.8, last edit: 6/15/94 16:52:00
12 * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
13 * @(#) Berlin University of Technology
14 *
15 *-----------------------------------------------------------------------
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU Library General Public License as published
18 * by the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU Library General Public License for more details.
25 *
26 * You should have received a copy of the GNU Library General Public
27 * License along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *----------------------------------------------------------------------
30 */
31package javazoom.jl.decoder;
32
33import java.io.IOException;
34
35/**
36 * A class for the synthesis filter bank.
37 * This class does a fast downsampling from 32, 44.1 or 48 kHz to 8 kHz, if ULAW is defined.
38 * Frequencies above 4 kHz are removed by ignoring higher subbands.
39 */
40final class SynthesisFilter
41{
42 private float[] v1;
43 private float[] v2;
44 private float[] actual_v; // v1 or v2
45 private int actual_write_pos; // 0-15
46 private float[] samples; // 32 new subband samples
47 private int channel;
48 private float scalefactor;
49 private float[] eq;
50
51 /**
52 * Quality value for controlling CPU usage/quality tradeoff.
53 */
54 /*
55 private int quality;
56
57 private int v_inc;
58
59
60
61 public static final int HIGH_QUALITY = 1;
62 public static final int MEDIUM_QUALITY = 2;
63 public static final int LOW_QUALITY = 4;
64 */
65
66 /**
67 * Contructor.
68 * The scalefactor scales the calculated float pcm samples to short values
69 * (raw pcm samples are in [-1.0, 1.0], if no violations occur).
70 */
71 public SynthesisFilter(int channelnumber, float factor, float[] eq0)
72 {
73 if (d==null)
74 {
75 d = load_d();
76 d16 = splitArray(d, 16);
77 }
78
79 v1 = new float[512];
80 v2 = new float[512];
81 samples = new float[32];
82 channel = channelnumber;
83 scalefactor = factor;
84 setEQ(eq);
85 //setQuality(HIGH_QUALITY);
86
87 reset();
88 }
89
90 public void setEQ(float[] eq0)
91 {
92 this.eq = eq0;
93 if (eq==null)
94 {
95 eq = new float[32];
96 for (int i=0; i<32; i++)
97 eq[i] = 1.0f;
98 }
99 if (eq.length<32)
100 {
101 throw new IllegalArgumentException("eq0");
102 }
103
104 }
105
106 /*
107 private void setQuality(int quality0)
108 {
109 switch (quality0)
110 {
111 case HIGH_QUALITY:
112 case MEDIUM_QUALITY:
113 case LOW_QUALITY:
114 v_inc = 16 * quality0;
115 quality = quality0;
116 break;
117 default :
118 throw new IllegalArgumentException("Unknown quality value");
119 }
120 }
121
122 public int getQuality()
123 {
124 return quality;
125 }
126 */
127
128 /**
129 * Reset the synthesis filter.
130 */
131 public void reset()
132 {
133 //float[] floatp;
134 // float[] floatp2;
135
136 // initialize v1[] and v2[]:
137 //for (floatp = v1 + 512, floatp2 = v2 + 512; floatp > v1; )
138 // *--floatp = *--floatp2 = 0.0;
139 for (int p=0;p<512;p++)
140 v1[p] = v2[p] = 0.0f;
141
142 // initialize samples[]:
143 //for (floatp = samples + 32; floatp > samples; )
144 // *--floatp = 0.0;
145 for (int p2=0;p2<32;p2++)
146 samples[p2] = 0.0f;
147
148 actual_v = v1;
149 actual_write_pos = 15;
150 }
151
152
153 /**
154 * Inject Sample.
155 */
156 public void input_sample(float sample, int subbandnumber)
157 {
158 samples[subbandnumber] = eq[subbandnumber]*sample;
159 }
160
161 public void input_samples(float[] s)
162 {
163 for (int i=31; i>=0; i--)
164 {
165 samples[i] = s[i]*eq[i];
166 }
167 }
168
169 /**
170 * Compute new values via a fast cosine transform.
171 */
172 private void compute_new_v()
173 {
174 // p is fully initialized from x1
175 //float[] p = _p;
176 // pp is fully initialized from p
177 //float[] pp = _pp;
178
179 //float[] new_v = _new_v;
180
181 //float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3
182 //float[] p = new float[16];
183 //float[] pp = new float[16];
184
185 /*
186 for (int i=31; i>=0; i--)
187 {
188 new_v[i] = 0.0f;
189 }
190 */
191
192 float new_v0, new_v1, new_v2, new_v3, new_v4, new_v5, new_v6, new_v7, new_v8, new_v9;
193 float new_v10, new_v11, new_v12, new_v13, new_v14, new_v15, new_v16, new_v17, new_v18, new_v19;
194 float new_v20, new_v21, new_v22, new_v23, new_v24, new_v25, new_v26, new_v27, new_v28, new_v29;
195 float new_v30, new_v31;
196
197 new_v0 = new_v1 = new_v2 = new_v3 = new_v4 = new_v5 = new_v6 = new_v7 = new_v8 = new_v9 =
198 new_v10 = new_v11 = new_v12 = new_v13 = new_v14 = new_v15 = new_v16 = new_v17 = new_v18 = new_v19 =
199 new_v20 = new_v21 = new_v22 = new_v23 = new_v24 = new_v25 = new_v26 = new_v27 = new_v28 = new_v29 =
200 new_v30 = new_v31 = 0.0f;
201
202
203// float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3
204// float[] p = new float[16];
205// float[] pp = new float[16];
206
207 float[] s = samples;
208
209 float s0 = s[0];
210 float s1 = s[1];
211 float s2 = s[2];
212 float s3 = s[3];
213 float s4 = s[4];
214 float s5 = s[5];
215 float s6 = s[6];
216 float s7 = s[7];
217 float s8 = s[8];
218 float s9 = s[9];
219 float s10 = s[10];
220 float s11 = s[11];
221 float s12 = s[12];
222 float s13 = s[13];
223 float s14 = s[14];
224 float s15 = s[15];
225 float s16 = s[16];
226 float s17 = s[17];
227 float s18 = s[18];
228 float s19 = s[19];
229 float s20 = s[20];
230 float s21 = s[21];
231 float s22 = s[22];
232 float s23 = s[23];
233 float s24 = s[24];
234 float s25 = s[25];
235 float s26 = s[26];
236 float s27 = s[27];
237 float s28 = s[28];
238 float s29 = s[29];
239 float s30 = s[30];
240 float s31 = s[31];
241
242 float p0 = s0 + s31;
243 float p1 = s1 + s30;
244 float p2 = s2 + s29;
245 float p3 = s3 + s28;
246 float p4 = s4 + s27;
247 float p5 = s5 + s26;
248 float p6 = s6 + s25;
249 float p7 = s7 + s24;
250 float p8 = s8 + s23;
251 float p9 = s9 + s22;
252 float p10 = s10 + s21;
253 float p11 = s11 + s20;
254 float p12 = s12 + s19;
255 float p13 = s13 + s18;
256 float p14 = s14 + s17;
257 float p15 = s15 + s16;
258
259 float pp0 = p0 + p15;
260 float pp1 = p1 + p14;
261 float pp2 = p2 + p13;
262 float pp3 = p3 + p12;
263 float pp4 = p4 + p11;
264 float pp5 = p5 + p10;
265 float pp6 = p6 + p9;
266 float pp7 = p7 + p8;
267 float pp8 = (p0 - p15) * cos1_32;
268 float pp9 = (p1 - p14) * cos3_32;
269 float pp10 = (p2 - p13) * cos5_32;
270 float pp11 = (p3 - p12) * cos7_32;
271 float pp12 = (p4 - p11) * cos9_32;
272 float pp13 = (p5 - p10) * cos11_32;
273 float pp14 = (p6 - p9) * cos13_32;
274 float pp15 = (p7 - p8) * cos15_32;
275
276 p0 = pp0 + pp7;
277 p1 = pp1 + pp6;
278 p2 = pp2 + pp5;
279 p3 = pp3 + pp4;
280 p4 = (pp0 - pp7) * cos1_16;
281 p5 = (pp1 - pp6) * cos3_16;
282 p6 = (pp2 - pp5) * cos5_16;
283 p7 = (pp3 - pp4) * cos7_16;
284 p8 = pp8 + pp15;
285 p9 = pp9 + pp14;
286 p10 = pp10 + pp13;
287 p11 = pp11 + pp12;
288 p12 = (pp8 - pp15) * cos1_16;
289 p13 = (pp9 - pp14) * cos3_16;
290 p14 = (pp10 - pp13) * cos5_16;
291 p15 = (pp11 - pp12) * cos7_16;
292
293
294 pp0 = p0 + p3;
295 pp1 = p1 + p2;
296 pp2 = (p0 - p3) * cos1_8;
297 pp3 = (p1 - p2) * cos3_8;
298 pp4 = p4 + p7;
299 pp5 = p5 + p6;
300 pp6 = (p4 - p7) * cos1_8;
301 pp7 = (p5 - p6) * cos3_8;
302 pp8 = p8 + p11;
303 pp9 = p9 + p10;
304 pp10 = (p8 - p11) * cos1_8;
305 pp11 = (p9 - p10) * cos3_8;
306 pp12 = p12 + p15;
307 pp13 = p13 + p14;
308 pp14 = (p12 - p15) * cos1_8;
309 pp15 = (p13 - p14) * cos3_8;
310
311 p0 = pp0 + pp1;
312 p1 = (pp0 - pp1) * cos1_4;
313 p2 = pp2 + pp3;
314 p3 = (pp2 - pp3) * cos1_4;
315 p4 = pp4 + pp5;
316 p5 = (pp4 - pp5) * cos1_4;
317 p6 = pp6 + pp7;
318 p7 = (pp6 - pp7) * cos1_4;
319 p8 = pp8 + pp9;
320 p9 = (pp8 - pp9) * cos1_4;
321 p10 = pp10 + pp11;
322 p11 = (pp10 - pp11) * cos1_4;
323 p12 = pp12 + pp13;
324 p13 = (pp12 - pp13) * cos1_4;
325 p14 = pp14 + pp15;
326 p15 = (pp14 - pp15) * cos1_4;
327
328 // this is pretty insane coding
329 float tmp1;
330 new_v19/*36-17*/ = -(new_v4 = (new_v12 = p7) + p5) - p6;
331 new_v27/*44-17*/ = -p6 - p7 - p4;
332 new_v6 = (new_v10 = (new_v14 = p15) + p11) + p13;
333 new_v17/*34-17*/ = -(new_v2 = p15 + p13 + p9) - p14;
334 new_v21/*38-17*/ = (tmp1 = -p14 - p15 - p10 - p11) - p13;
335 new_v29/*46-17*/ = -p14 - p15 - p12 - p8;
336 new_v25/*42-17*/ = tmp1 - p12;
337 new_v31/*48-17*/ = -p0;
338 new_v0 = p1;
339 new_v23/*40-17*/ = -(new_v8 = p3) - p2;
340
341 p0 = (s0 - s31) * cos1_64;
342 p1 = (s1 - s30) * cos3_64;
343 p2 = (s2 - s29) * cos5_64;
344 p3 = (s3 - s28) * cos7_64;
345 p4 = (s4 - s27) * cos9_64;
346 p5 = (s5 - s26) * cos11_64;
347 p6 = (s6 - s25) * cos13_64;
348 p7 = (s7 - s24) * cos15_64;
349 p8 = (s8 - s23) * cos17_64;
350 p9 = (s9 - s22) * cos19_64;
351 p10 = (s10 - s21) * cos21_64;
352 p11 = (s11 - s20) * cos23_64;
353 p12 = (s12 - s19) * cos25_64;
354 p13 = (s13 - s18) * cos27_64;
355 p14 = (s14 - s17) * cos29_64;
356 p15 = (s15 - s16) * cos31_64;
357
358
359 pp0 = p0 + p15;
360 pp1 = p1 + p14;
361 pp2 = p2 + p13;
362 pp3 = p3 + p12;
363 pp4 = p4 + p11;
364 pp5 = p5 + p10;
365 pp6 = p6 + p9;
366 pp7 = p7 + p8;
367 pp8 = (p0 - p15) * cos1_32;
368 pp9 = (p1 - p14) * cos3_32;
369 pp10 = (p2 - p13) * cos5_32;
370 pp11 = (p3 - p12) * cos7_32;
371 pp12 = (p4 - p11) * cos9_32;
372 pp13 = (p5 - p10) * cos11_32;
373 pp14 = (p6 - p9) * cos13_32;
374 pp15 = (p7 - p8) * cos15_32;
375
376
377 p0 = pp0 + pp7;
378 p1 = pp1 + pp6;
379 p2 = pp2 + pp5;
380 p3 = pp3 + pp4;
381 p4 = (pp0 - pp7) * cos1_16;
382 p5 = (pp1 - pp6) * cos3_16;
383 p6 = (pp2 - pp5) * cos5_16;
384 p7 = (pp3 - pp4) * cos7_16;
385 p8 = pp8 + pp15;
386 p9 = pp9 + pp14;
387 p10 = pp10 + pp13;
388 p11 = pp11 + pp12;
389 p12 = (pp8 - pp15) * cos1_16;
390 p13 = (pp9 - pp14) * cos3_16;
391 p14 = (pp10 - pp13) * cos5_16;
392 p15 = (pp11 - pp12) * cos7_16;
393
394
395 pp0 = p0 + p3;
396 pp1 = p1 + p2;
397 pp2 = (p0 - p3) * cos1_8;
398 pp3 = (p1 - p2) * cos3_8;
399 pp4 = p4 + p7;
400 pp5 = p5 + p6;
401 pp6 = (p4 - p7) * cos1_8;
402 pp7 = (p5 - p6) * cos3_8;
403 pp8 = p8 + p11;
404 pp9 = p9 + p10;
405 pp10 = (p8 - p11) * cos1_8;
406 pp11 = (p9 - p10) * cos3_8;
407 pp12 = p12 + p15;
408 pp13 = p13 + p14;
409 pp14 = (p12 - p15) * cos1_8;
410 pp15 = (p13 - p14) * cos3_8;
411
412
413 p0 = pp0 + pp1;
414 p1 = (pp0 - pp1) * cos1_4;
415 p2 = pp2 + pp3;
416 p3 = (pp2 - pp3) * cos1_4;
417 p4 = pp4 + pp5;
418 p5 = (pp4 - pp5) * cos1_4;
419 p6 = pp6 + pp7;
420 p7 = (pp6 - pp7) * cos1_4;
421 p8 = pp8 + pp9;
422 p9 = (pp8 - pp9) * cos1_4;
423 p10 = pp10 + pp11;
424 p11 = (pp10 - pp11) * cos1_4;
425 p12 = pp12 + pp13;
426 p13 = (pp12 - pp13) * cos1_4;
427 p14 = pp14 + pp15;
428 p15 = (pp14 - pp15) * cos1_4;
429
430
431 // manually doing something that a compiler should handle sucks
432 // coding like this is hard to read
433 float tmp2;
434 new_v5 = (new_v11 = (new_v13 = (new_v15 = p15) + p7) + p11)
435 + p5 + p13;
436 new_v7 = (new_v9 = p15 + p11 + p3) + p13;
437 new_v16/*33-17*/ = -(new_v1 = (tmp1 = p13 + p15 + p9) + p1) - p14;
438 new_v18/*35-17*/ = -(new_v3 = tmp1 + p5 + p7) - p6 - p14;
439
440 new_v22/*39-17*/ = (tmp1 = -p10 - p11 - p14 - p15)
441 - p13 - p2 - p3;
442 new_v20/*37-17*/ = tmp1 - p13 - p5 - p6 - p7;
443 new_v24/*41-17*/ = tmp1 - p12 - p2 - p3;
444 new_v26/*43-17*/ = tmp1 - p12 - (tmp2 = p4 + p6 + p7);
445 new_v30/*47-17*/ = (tmp1 = -p8 - p12 - p14 - p15) - p0;
446 new_v28/*45-17*/ = tmp1 - tmp2;
447
448 // insert V[0-15] (== new_v[0-15]) into actual v:
449 // float[] x2 = actual_v + actual_write_pos;
450 float dest[] = actual_v;
451
452 int pos = actual_write_pos;
453
454 dest[0 + pos] = new_v0;
455 dest[16 + pos] = new_v1;
456 dest[32 + pos] = new_v2;
457 dest[48 + pos] = new_v3;
458 dest[64 + pos] = new_v4;
459 dest[80 + pos] = new_v5;
460 dest[96 + pos] = new_v6;
461 dest[112 + pos] = new_v7;
462 dest[128 + pos] = new_v8;
463 dest[144 + pos] = new_v9;
464 dest[160 + pos] = new_v10;
465 dest[176 + pos] = new_v11;
466 dest[192 + pos] = new_v12;
467 dest[208 + pos] = new_v13;
468 dest[224 + pos] = new_v14;
469 dest[240 + pos] = new_v15;
470
471 // V[16] is always 0.0:
472 dest[256 + pos] = 0.0f;
473
474 // insert V[17-31] (== -new_v[15-1]) into actual v:
475 dest[272 + pos] = -new_v15;
476 dest[288 + pos] = -new_v14;
477 dest[304 + pos] = -new_v13;
478 dest[320 + pos] = -new_v12;
479 dest[336 + pos] = -new_v11;
480 dest[352 + pos] = -new_v10;
481 dest[368 + pos] = -new_v9;
482 dest[384 + pos] = -new_v8;
483 dest[400 + pos] = -new_v7;
484 dest[416 + pos] = -new_v6;
485 dest[432 + pos] = -new_v5;
486 dest[448 + pos] = -new_v4;
487 dest[464 + pos] = -new_v3;
488 dest[480 + pos] = -new_v2;
489 dest[496 + pos] = -new_v1;
490
491 // insert V[32] (== -new_v[0]) into other v:
492 dest = (actual_v==v1) ? v2 : v1;
493
494 dest[0 + pos] = -new_v0;
495 // insert V[33-48] (== new_v[16-31]) into other v:
496 dest[16 + pos] = new_v16;
497 dest[32 + pos] = new_v17;
498 dest[48 + pos] = new_v18;
499 dest[64 + pos] = new_v19;
500 dest[80 + pos] = new_v20;
501 dest[96 + pos] = new_v21;
502 dest[112 + pos] = new_v22;
503 dest[128 + pos] = new_v23;
504 dest[144 + pos] = new_v24;
505 dest[160 + pos] = new_v25;
506 dest[176 + pos] = new_v26;
507 dest[192 + pos] = new_v27;
508 dest[208 + pos] = new_v28;
509 dest[224 + pos] = new_v29;
510 dest[240 + pos] = new_v30;
511 dest[256 + pos] = new_v31;
512
513 // insert V[49-63] (== new_v[30-16]) into other v:
514 dest[272 + pos] = new_v30;
515 dest[288 + pos] = new_v29;
516 dest[304 + pos] = new_v28;
517 dest[320 + pos] = new_v27;
518 dest[336 + pos] = new_v26;
519 dest[352 + pos] = new_v25;
520 dest[368 + pos] = new_v24;
521 dest[384 + pos] = new_v23;
522 dest[400 + pos] = new_v22;
523 dest[416 + pos] = new_v21;
524 dest[432 + pos] = new_v20;
525 dest[448 + pos] = new_v19;
526 dest[464 + pos] = new_v18;
527 dest[480 + pos] = new_v17;
528 dest[496 + pos] = new_v16;
529/*
530 }
531 else
532 {
533 v1[0 + actual_write_pos] = -new_v0;
534 // insert V[33-48] (== new_v[16-31]) into other v:
535 v1[16 + actual_write_pos] = new_v16;
536 v1[32 + actual_write_pos] = new_v17;
537 v1[48 + actual_write_pos] = new_v18;
538 v1[64 + actual_write_pos] = new_v19;
539 v1[80 + actual_write_pos] = new_v20;
540 v1[96 + actual_write_pos] = new_v21;
541 v1[112 + actual_write_pos] = new_v22;
542 v1[128 + actual_write_pos] = new_v23;
543 v1[144 + actual_write_pos] = new_v24;
544 v1[160 + actual_write_pos] = new_v25;
545 v1[176 + actual_write_pos] = new_v26;
546 v1[192 + actual_write_pos] = new_v27;
547 v1[208 + actual_write_pos] = new_v28;
548 v1[224 + actual_write_pos] = new_v29;
549 v1[240 + actual_write_pos] = new_v30;
550 v1[256 + actual_write_pos] = new_v31;
551
552 // insert V[49-63] (== new_v[30-16]) into other v:
553 v1[272 + actual_write_pos] = new_v30;
554 v1[288 + actual_write_pos] = new_v29;
555 v1[304 + actual_write_pos] = new_v28;
556 v1[320 + actual_write_pos] = new_v27;
557 v1[336 + actual_write_pos] = new_v26;
558 v1[352 + actual_write_pos] = new_v25;
559 v1[368 + actual_write_pos] = new_v24;
560 v1[384 + actual_write_pos] = new_v23;
561 v1[400 + actual_write_pos] = new_v22;
562 v1[416 + actual_write_pos] = new_v21;
563 v1[432 + actual_write_pos] = new_v20;
564 v1[448 + actual_write_pos] = new_v19;
565 v1[464 + actual_write_pos] = new_v18;
566 v1[480 + actual_write_pos] = new_v17;
567 v1[496 + actual_write_pos] = new_v16;
568 }
569*/
570 }
571
572 /**
573 * Compute new values via a fast cosine transform.
574 */
575 private void compute_new_v_old()
576 {
577 // p is fully initialized from x1
578 //float[] p = _p;
579 // pp is fully initialized from p
580 //float[] pp = _pp;
581
582 //float[] new_v = _new_v;
583
584 float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3
585 float[] p = new float[16];
586 float[] pp = new float[16];
587
588
589 for (int i=31; i>=0; i--)
590 {
591 new_v[i] = 0.0f;
592 }
593
594// float[] new_v = new float[32]; // new V[0-15] and V[33-48] of Figure 3-A.2 in ISO DIS 11172-3
595// float[] p = new float[16];
596// float[] pp = new float[16];
597
598 float[] x1 = samples;
599
600 p[0] = x1[0] + x1[31];
601 p[1] = x1[1] + x1[30];
602 p[2] = x1[2] + x1[29];
603 p[3] = x1[3] + x1[28];
604 p[4] = x1[4] + x1[27];
605 p[5] = x1[5] + x1[26];
606 p[6] = x1[6] + x1[25];
607 p[7] = x1[7] + x1[24];
608 p[8] = x1[8] + x1[23];
609 p[9] = x1[9] + x1[22];
610 p[10] = x1[10] + x1[21];
611 p[11] = x1[11] + x1[20];
612 p[12] = x1[12] + x1[19];
613 p[13] = x1[13] + x1[18];
614 p[14] = x1[14] + x1[17];
615 p[15] = x1[15] + x1[16];
616
617 pp[0] = p[0] + p[15];
618 pp[1] = p[1] + p[14];
619 pp[2] = p[2] + p[13];
620 pp[3] = p[3] + p[12];
621 pp[4] = p[4] + p[11];
622 pp[5] = p[5] + p[10];
623 pp[6] = p[6] + p[9];
624 pp[7] = p[7] + p[8];
625 pp[8] = (p[0] - p[15]) * cos1_32;
626 pp[9] = (p[1] - p[14]) * cos3_32;
627 pp[10] = (p[2] - p[13]) * cos5_32;
628 pp[11] = (p[3] - p[12]) * cos7_32;
629 pp[12] = (p[4] - p[11]) * cos9_32;
630 pp[13] = (p[5] - p[10]) * cos11_32;
631 pp[14] = (p[6] - p[9]) * cos13_32;
632 pp[15] = (p[7] - p[8]) * cos15_32;
633
634 p[0] = pp[0] + pp[7];
635 p[1] = pp[1] + pp[6];
636 p[2] = pp[2] + pp[5];
637 p[3] = pp[3] + pp[4];
638 p[4] = (pp[0] - pp[7]) * cos1_16;
639 p[5] = (pp[1] - pp[6]) * cos3_16;
640 p[6] = (pp[2] - pp[5]) * cos5_16;
641 p[7] = (pp[3] - pp[4]) * cos7_16;
642 p[8] = pp[8] + pp[15];
643 p[9] = pp[9] + pp[14];
644 p[10] = pp[10] + pp[13];
645 p[11] = pp[11] + pp[12];
646 p[12] = (pp[8] - pp[15]) * cos1_16;
647 p[13] = (pp[9] - pp[14]) * cos3_16;
648 p[14] = (pp[10] - pp[13]) * cos5_16;
649 p[15] = (pp[11] - pp[12]) * cos7_16;
650
651
652 pp[0] = p[0] + p[3];
653 pp[1] = p[1] + p[2];
654 pp[2] = (p[0] - p[3]) * cos1_8;
655 pp[3] = (p[1] - p[2]) * cos3_8;
656 pp[4] = p[4] + p[7];
657 pp[5] = p[5] + p[6];
658 pp[6] = (p[4] - p[7]) * cos1_8;
659 pp[7] = (p[5] - p[6]) * cos3_8;
660 pp[8] = p[8] + p[11];
661 pp[9] = p[9] + p[10];
662 pp[10] = (p[8] - p[11]) * cos1_8;
663 pp[11] = (p[9] - p[10]) * cos3_8;
664 pp[12] = p[12] + p[15];
665 pp[13] = p[13] + p[14];
666 pp[14] = (p[12] - p[15]) * cos1_8;
667 pp[15] = (p[13] - p[14]) * cos3_8;
668
669 p[0] = pp[0] + pp[1];
670 p[1] = (pp[0] - pp[1]) * cos1_4;
671 p[2] = pp[2] + pp[3];
672 p[3] = (pp[2] - pp[3]) * cos1_4;
673 p[4] = pp[4] + pp[5];
674 p[5] = (pp[4] - pp[5]) * cos1_4;
675 p[6] = pp[6] + pp[7];
676 p[7] = (pp[6] - pp[7]) * cos1_4;
677 p[8] = pp[8] + pp[9];
678 p[9] = (pp[8] - pp[9]) * cos1_4;
679 p[10] = pp[10] + pp[11];
680 p[11] = (pp[10] - pp[11]) * cos1_4;
681 p[12] = pp[12] + pp[13];
682 p[13] = (pp[12] - pp[13]) * cos1_4;
683 p[14] = pp[14] + pp[15];
684 p[15] = (pp[14] - pp[15]) * cos1_4;
685
686 // this is pretty insane coding
687 float tmp1;
688 new_v[36-17] = -(new_v[4] = (new_v[12] = p[7]) + p[5]) - p[6];
689 new_v[44-17] = -p[6] - p[7] - p[4];
690 new_v[6] = (new_v[10] = (new_v[14] = p[15]) + p[11]) + p[13];
691 new_v[34-17] = -(new_v[2] = p[15] + p[13] + p[9]) - p[14];
692 new_v[38-17] = (tmp1 = -p[14] - p[15] - p[10] - p[11]) - p[13];
693 new_v[46-17] = -p[14] - p[15] - p[12] - p[8];
694 new_v[42-17] = tmp1 - p[12];
695 new_v[48-17] = -p[0];
696 new_v[0] = p[1];
697 new_v[40-17] = -(new_v[8] = p[3]) - p[2];
698
699 p[0] = (x1[0] - x1[31]) * cos1_64;
700 p[1] = (x1[1] - x1[30]) * cos3_64;
701 p[2] = (x1[2] - x1[29]) * cos5_64;
702 p[3] = (x1[3] - x1[28]) * cos7_64;
703 p[4] = (x1[4] - x1[27]) * cos9_64;
704 p[5] = (x1[5] - x1[26]) * cos11_64;
705 p[6] = (x1[6] - x1[25]) * cos13_64;
706 p[7] = (x1[7] - x1[24]) * cos15_64;
707 p[8] = (x1[8] - x1[23]) * cos17_64;
708 p[9] = (x1[9] - x1[22]) * cos19_64;
709 p[10] = (x1[10] - x1[21]) * cos21_64;
710 p[11] = (x1[11] - x1[20]) * cos23_64;
711 p[12] = (x1[12] - x1[19]) * cos25_64;
712 p[13] = (x1[13] - x1[18]) * cos27_64;
713 p[14] = (x1[14] - x1[17]) * cos29_64;
714 p[15] = (x1[15] - x1[16]) * cos31_64;
715
716
717 pp[0] = p[0] + p[15];
718 pp[1] = p[1] + p[14];
719 pp[2] = p[2] + p[13];
720 pp[3] = p[3] + p[12];
721 pp[4] = p[4] + p[11];
722 pp[5] = p[5] + p[10];
723 pp[6] = p[6] + p[9];
724 pp[7] = p[7] + p[8];
725 pp[8] = (p[0] - p[15]) * cos1_32;
726 pp[9] = (p[1] - p[14]) * cos3_32;
727 pp[10] = (p[2] - p[13]) * cos5_32;
728 pp[11] = (p[3] - p[12]) * cos7_32;
729 pp[12] = (p[4] - p[11]) * cos9_32;
730 pp[13] = (p[5] - p[10]) * cos11_32;
731 pp[14] = (p[6] - p[9]) * cos13_32;
732 pp[15] = (p[7] - p[8]) * cos15_32;
733
734
735 p[0] = pp[0] + pp[7];
736 p[1] = pp[1] + pp[6];
737 p[2] = pp[2] + pp[5];
738 p[3] = pp[3] + pp[4];
739 p[4] = (pp[0] - pp[7]) * cos1_16;
740 p[5] = (pp[1] - pp[6]) * cos3_16;
741 p[6] = (pp[2] - pp[5]) * cos5_16;
742 p[7] = (pp[3] - pp[4]) * cos7_16;
743 p[8] = pp[8] + pp[15];
744 p[9] = pp[9] + pp[14];
745 p[10] = pp[10] + pp[13];
746 p[11] = pp[11] + pp[12];
747 p[12] = (pp[8] - pp[15]) * cos1_16;
748 p[13] = (pp[9] - pp[14]) * cos3_16;
749 p[14] = (pp[10] - pp[13]) * cos5_16;
750 p[15] = (pp[11] - pp[12]) * cos7_16;
751
752
753 pp[0] = p[0] + p[3];
754 pp[1] = p[1] + p[2];
755 pp[2] = (p[0] - p[3]) * cos1_8;
756 pp[3] = (p[1] - p[2]) * cos3_8;
757 pp[4] = p[4] + p[7];
758 pp[5] = p[5] + p[6];
759 pp[6] = (p[4] - p[7]) * cos1_8;
760 pp[7] = (p[5] - p[6]) * cos3_8;
761 pp[8] = p[8] + p[11];
762 pp[9] = p[9] + p[10];
763 pp[10] = (p[8] - p[11]) * cos1_8;
764 pp[11] = (p[9] - p[10]) * cos3_8;
765 pp[12] = p[12] + p[15];
766 pp[13] = p[13] + p[14];
767 pp[14] = (p[12] - p[15]) * cos1_8;
768 pp[15] = (p[13] - p[14]) * cos3_8;
769
770
771 p[0] = pp[0] + pp[1];
772 p[1] = (pp[0] - pp[1]) * cos1_4;
773 p[2] = pp[2] + pp[3];
774 p[3] = (pp[2] - pp[3]) * cos1_4;
775 p[4] = pp[4] + pp[5];
776 p[5] = (pp[4] - pp[5]) * cos1_4;
777 p[6] = pp[6] + pp[7];
778 p[7] = (pp[6] - pp[7]) * cos1_4;
779 p[8] = pp[8] + pp[9];
780 p[9] = (pp[8] - pp[9]) * cos1_4;
781 p[10] = pp[10] + pp[11];
782 p[11] = (pp[10] - pp[11]) * cos1_4;
783 p[12] = pp[12] + pp[13];
784 p[13] = (pp[12] - pp[13]) * cos1_4;
785 p[14] = pp[14] + pp[15];
786 p[15] = (pp[14] - pp[15]) * cos1_4;
787
788
789 // manually doing something that a compiler should handle sucks
790 // coding like this is hard to read
791 float tmp2;
792 new_v[5] = (new_v[11] = (new_v[13] = (new_v[15] = p[15]) + p[7]) + p[11])
793 + p[5] + p[13];
794 new_v[7] = (new_v[9] = p[15] + p[11] + p[3]) + p[13];
795 new_v[33-17] = -(new_v[1] = (tmp1 = p[13] + p[15] + p[9]) + p[1]) - p[14];
796 new_v[35-17] = -(new_v[3] = tmp1 + p[5] + p[7]) - p[6] - p[14];
797
798 new_v[39-17] = (tmp1 = -p[10] - p[11] - p[14] - p[15])
799 - p[13] - p[2] - p[3];
800 new_v[37-17] = tmp1 - p[13] - p[5] - p[6] - p[7];
801 new_v[41-17] = tmp1 - p[12] - p[2] - p[3];
802 new_v[43-17] = tmp1 - p[12] - (tmp2 = p[4] + p[6] + p[7]);
803 new_v[47-17] = (tmp1 = -p[8] - p[12] - p[14] - p[15]) - p[0];
804 new_v[45-17] = tmp1 - tmp2;
805
806 // insert V[0-15] (== new_v[0-15]) into actual v:
807 x1 = new_v;
808 // float[] x2 = actual_v + actual_write_pos;
809 float[] dest = actual_v;
810
811 dest[0 + actual_write_pos] = x1[0];
812 dest[16 + actual_write_pos] = x1[1];
813 dest[32 + actual_write_pos] = x1[2];
814 dest[48 + actual_write_pos] = x1[3];
815 dest[64 + actual_write_pos] = x1[4];
816 dest[80 + actual_write_pos] = x1[5];
817 dest[96 + actual_write_pos] = x1[6];
818 dest[112 + actual_write_pos] = x1[7];
819 dest[128 + actual_write_pos] = x1[8];
820 dest[144 + actual_write_pos] = x1[9];
821 dest[160 + actual_write_pos] = x1[10];
822 dest[176 + actual_write_pos] = x1[11];
823 dest[192 + actual_write_pos] = x1[12];
824 dest[208 + actual_write_pos] = x1[13];
825 dest[224 + actual_write_pos] = x1[14];
826 dest[240 + actual_write_pos] = x1[15];
827
828 // V[16] is always 0.0:
829 dest[256 + actual_write_pos] = 0.0f;
830
831 // insert V[17-31] (== -new_v[15-1]) into actual v:
832 dest[272 + actual_write_pos] = -x1[15];
833 dest[288 + actual_write_pos] = -x1[14];
834 dest[304 + actual_write_pos] = -x1[13];
835 dest[320 + actual_write_pos] = -x1[12];
836 dest[336 + actual_write_pos] = -x1[11];
837 dest[352 + actual_write_pos] = -x1[10];
838 dest[368 + actual_write_pos] = -x1[9];
839 dest[384 + actual_write_pos] = -x1[8];
840 dest[400 + actual_write_pos] = -x1[7];
841 dest[416 + actual_write_pos] = -x1[6];
842 dest[432 + actual_write_pos] = -x1[5];
843 dest[448 + actual_write_pos] = -x1[4];
844 dest[464 + actual_write_pos] = -x1[3];
845 dest[480 + actual_write_pos] = -x1[2];
846 dest[496 + actual_write_pos] = -x1[1];
847
848 // insert V[32] (== -new_v[0]) into other v:
849
850 }
851
852 /**
853 * Compute PCM Samples.
854 */
855
856 private float[] _tmpOut = new float[32];
857
858
859 private void compute_pcm_samples0(Obuffer buffer)
860 {
861 final float[] vp = actual_v;
862 //int inc = v_inc;
863 final float[] tmpOut = _tmpOut;
864 int dvp =0;
865
866 // fat chance of having this loop unroll
867 for( int i=0; i<32; i++)
868 {
869 float pcm_sample;
870 final float[] dp = d16[i];
871 pcm_sample = (float)(((vp[0 + dvp] * dp[0]) +
872 (vp[15 + dvp] * dp[1]) +
873 (vp[14 + dvp] * dp[2]) +
874 (vp[13 + dvp] * dp[3]) +
875 (vp[12 + dvp] * dp[4]) +
876 (vp[11 + dvp] * dp[5]) +
877 (vp[10 + dvp] * dp[6]) +
878 (vp[9 + dvp] * dp[7]) +
879 (vp[8 + dvp] * dp[8]) +
880 (vp[7 + dvp] * dp[9]) +
881 (vp[6 + dvp] * dp[10]) +
882 (vp[5 + dvp] * dp[11]) +
883 (vp[4 + dvp] * dp[12]) +
884 (vp[3 + dvp] * dp[13]) +
885 (vp[2 + dvp] * dp[14]) +
886 (vp[1 + dvp] * dp[15])
887 ) * scalefactor);
888
889 tmpOut[i] = pcm_sample;
890
891 dvp += 16;
892 } // for
893 }
894
895 private void compute_pcm_samples1(Obuffer buffer)
896 {
897 final float[] vp = actual_v;
898 //int inc = v_inc;
899 final float[] tmpOut = _tmpOut;
900 int dvp =0;
901
902 // fat chance of having this loop unroll
903 for( int i=0; i<32; i++)
904 {
905 final float[] dp = d16[i];
906 float pcm_sample;
907
908 pcm_sample = (float)(((vp[1 + dvp] * dp[0]) +
909 (vp[0 + dvp] * dp[1]) +
910 (vp[15 + dvp] * dp[2]) +
911 (vp[14 + dvp] * dp[3]) +
912 (vp[13 + dvp] * dp[4]) +
913 (vp[12 + dvp] * dp[5]) +
914 (vp[11 + dvp] * dp[6]) +
915 (vp[10 + dvp] * dp[7]) +
916 (vp[9 + dvp] * dp[8]) +
917 (vp[8 + dvp] * dp[9]) +
918 (vp[7 + dvp] * dp[10]) +
919 (vp[6 + dvp] * dp[11]) +
920 (vp[5 + dvp] * dp[12]) +
921 (vp[4 + dvp] * dp[13]) +
922 (vp[3 + dvp] * dp[14]) +
923 (vp[2 + dvp] * dp[15])
924 ) * scalefactor);
925
926 tmpOut[i] = pcm_sample;
927
928 dvp += 16;
929 } // for
930 }
931 private void compute_pcm_samples2(Obuffer buffer)
932 {
933 final float[] vp = actual_v;
934
935 //int inc = v_inc;
936 final float[] tmpOut = _tmpOut;
937 int dvp =0;
938
939 // fat chance of having this loop unroll
940 for( int i=0; i<32; i++)
941 {
942 final float[] dp = d16[i];
943 float pcm_sample;
944
945 pcm_sample = (float)(((vp[2 + dvp] * dp[0]) +
946 (vp[1 + dvp] * dp[1]) +
947 (vp[0 + dvp] * dp[2]) +
948 (vp[15 + dvp] * dp[3]) +
949 (vp[14 + dvp] * dp[4]) +
950 (vp[13 + dvp] * dp[5]) +
951 (vp[12 + dvp] * dp[6]) +
952 (vp[11 + dvp] * dp[7]) +
953 (vp[10 + dvp] * dp[8]) +
954 (vp[9 + dvp] * dp[9]) +
955 (vp[8 + dvp] * dp[10]) +
956 (vp[7 + dvp] * dp[11]) +
957 (vp[6 + dvp] * dp[12]) +
958 (vp[5 + dvp] * dp[13]) +
959 (vp[4 + dvp] * dp[14]) +
960 (vp[3 + dvp] * dp[15])
961 ) * scalefactor);
962
963 tmpOut[i] = pcm_sample;
964
965 dvp += 16;
966 } // for
967 }
968
969 private void compute_pcm_samples3(Obuffer buffer)
970 {
971 final float[] vp = actual_v;
972
973 int idx = 0;
974 //int inc = v_inc;
975 final float[] tmpOut = _tmpOut;
976 int dvp =0;
977
978 // fat chance of having this loop unroll
979 for( int i=0; i<32; i++)
980 {
981 final float[] dp = d16[i];
982 float pcm_sample;
983
984 pcm_sample = (float)(((vp[3 + dvp] * dp[0]) +
985 (vp[2 + dvp] * dp[1]) +
986 (vp[1 + dvp] * dp[2]) +
987 (vp[0 + dvp] * dp[3]) +
988 (vp[15 + dvp] * dp[4]) +
989 (vp[14 + dvp] * dp[5]) +
990 (vp[13 + dvp] * dp[6]) +
991 (vp[12 + dvp] * dp[7]) +
992 (vp[11 + dvp] * dp[8]) +
993 (vp[10 + dvp] * dp[9]) +
994 (vp[9 + dvp] * dp[10]) +
995 (vp[8 + dvp] * dp[11]) +
996 (vp[7 + dvp] * dp[12]) +
997 (vp[6 + dvp] * dp[13]) +
998 (vp[5 + dvp] * dp[14]) +
999 (vp[4 + dvp] * dp[15])
1000 ) * scalefactor);
1001
1002 tmpOut[i] = pcm_sample;
1003
1004 dvp += 16;
1005 } // for
1006 }
1007
1008 private void compute_pcm_samples4(Obuffer buffer)
1009 {
1010 final float[] vp = actual_v;
1011
1012 //int inc = v_inc;
1013 final float[] tmpOut = _tmpOut;
1014 int dvp =0;
1015
1016 // fat chance of having this loop unroll
1017 for( int i=0; i<32; i++)
1018 {
1019 final float[] dp = d16[i];
1020 float pcm_sample;
1021
1022 pcm_sample = (float)(((vp[4 + dvp] * dp[0]) +
1023 (vp[3 + dvp] * dp[1]) +
1024 (vp[2 + dvp] * dp[2]) +
1025 (vp[1 + dvp] * dp[3]) +
1026 (vp[0 + dvp] * dp[4]) +
1027 (vp[15 + dvp] * dp[5]) +
1028 (vp[14 + dvp] * dp[6]) +
1029 (vp[13 + dvp] * dp[7]) +
1030 (vp[12 + dvp] * dp[8]) +
1031 (vp[11 + dvp] * dp[9]) +
1032 (vp[10 + dvp] * dp[10]) +
1033 (vp[9 + dvp] * dp[11]) +
1034 (vp[8 + dvp] * dp[12]) +
1035 (vp[7 + dvp] * dp[13]) +
1036 (vp[6 + dvp] * dp[14]) +
1037 (vp[5 + dvp] * dp[15])
1038 ) * scalefactor);
1039
1040 tmpOut[i] = pcm_sample;
1041
1042 dvp += 16;
1043 } // for
1044 }
1045
1046 private void compute_pcm_samples5(Obuffer buffer)
1047 {
1048 final float[] vp = actual_v;
1049
1050 //int inc = v_inc;
1051 final float[] tmpOut = _tmpOut;
1052 int dvp =0;
1053
1054 // fat chance of having this loop unroll
1055 for( int i=0; i<32; i++)
1056 {
1057 final float[] dp = d16[i];
1058 float pcm_sample;
1059
1060 pcm_sample = (float)(((vp[5 + dvp] * dp[0]) +
1061 (vp[4 + dvp] * dp[1]) +
1062 (vp[3 + dvp] * dp[2]) +
1063 (vp[2 + dvp] * dp[3]) +
1064 (vp[1 + dvp] * dp[4]) +
1065 (vp[0 + dvp] * dp[5]) +
1066 (vp[15 + dvp] * dp[6]) +
1067 (vp[14 + dvp] * dp[7]) +
1068 (vp[13 + dvp] * dp[8]) +
1069 (vp[12 + dvp] * dp[9]) +
1070 (vp[11 + dvp] * dp[10]) +
1071 (vp[10 + dvp] * dp[11]) +
1072 (vp[9 + dvp] * dp[12]) +
1073 (vp[8 + dvp] * dp[13]) +
1074 (vp[7 + dvp] * dp[14]) +
1075 (vp[6 + dvp] * dp[15])
1076 ) * scalefactor);
1077
1078 tmpOut[i] = pcm_sample;
1079
1080 dvp += 16;
1081 } // for
1082 }
1083
1084 private void compute_pcm_samples6(Obuffer buffer)
1085 {
1086 final float[] vp = actual_v;
1087 //int inc = v_inc;
1088 final float[] tmpOut = _tmpOut;
1089 int dvp =0;
1090
1091 // fat chance of having this loop unroll
1092 for( int i=0; i<32; i++)
1093 {
1094 final float[] dp = d16[i];
1095 float pcm_sample;
1096
1097 pcm_sample = (float)(((vp[6 + dvp] * dp[0]) +
1098 (vp[5 + dvp] * dp[1]) +
1099 (vp[4 + dvp] * dp[2]) +
1100 (vp[3 + dvp] * dp[3]) +
1101 (vp[2 + dvp] * dp[4]) +
1102 (vp[1 + dvp] * dp[5]) +
1103 (vp[0 + dvp] * dp[6]) +
1104 (vp[15 + dvp] * dp[7]) +
1105 (vp[14 + dvp] * dp[8]) +
1106 (vp[13 + dvp] * dp[9]) +
1107 (vp[12 + dvp] * dp[10]) +
1108 (vp[11 + dvp] * dp[11]) +
1109 (vp[10 + dvp] * dp[12]) +
1110 (vp[9 + dvp] * dp[13]) +
1111 (vp[8 + dvp] * dp[14]) +
1112 (vp[7 + dvp] * dp[15])
1113 ) * scalefactor);
1114
1115 tmpOut[i] = pcm_sample;
1116
1117 dvp += 16;
1118 } // for
1119 }
1120
1121 private void compute_pcm_samples7(Obuffer buffer)
1122 {
1123 final float[] vp = actual_v;
1124
1125 //int inc = v_inc;
1126 final float[] tmpOut = _tmpOut;
1127 int dvp =0;
1128
1129 // fat chance of having this loop unroll
1130 for( int i=0; i<32; i++)
1131 {
1132 final float[] dp = d16[i];
1133 float pcm_sample;
1134
1135 pcm_sample = (float)(((vp[7 + dvp] * dp[0]) +
1136 (vp[6 + dvp] * dp[1]) +
1137 (vp[5 + dvp] * dp[2]) +
1138 (vp[4 + dvp] * dp[3]) +
1139 (vp[3 + dvp] * dp[4]) +
1140 (vp[2 + dvp] * dp[5]) +
1141 (vp[1 + dvp] * dp[6]) +
1142 (vp[0 + dvp] * dp[7]) +
1143 (vp[15 + dvp] * dp[8]) +
1144 (vp[14 + dvp] * dp[9]) +
1145 (vp[13 + dvp] * dp[10]) +
1146 (vp[12 + dvp] * dp[11]) +
1147 (vp[11 + dvp] * dp[12]) +
1148 (vp[10 + dvp] * dp[13]) +
1149 (vp[9 + dvp] * dp[14]) +
1150 (vp[8 + dvp] * dp[15])
1151 ) * scalefactor);
1152
1153 tmpOut[i] = pcm_sample;
1154
1155 dvp += 16;
1156 } // for
1157 }
1158 private void compute_pcm_samples8(Obuffer buffer)
1159 {
1160 final float[] vp = actual_v;
1161
1162 //int inc = v_inc;
1163 final float[] tmpOut = _tmpOut;
1164 int dvp =0;
1165
1166 // fat chance of having this loop unroll
1167 for( int i=0; i<32; i++)
1168 {
1169 final float[] dp = d16[i];
1170 float pcm_sample;
1171
1172 pcm_sample = (float)(((vp[8 + dvp] * dp[0]) +
1173 (vp[7 + dvp] * dp[1]) +
1174 (vp[6 + dvp] * dp[2]) +
1175 (vp[5 + dvp] * dp[3]) +
1176 (vp[4 + dvp] * dp[4]) +
1177 (vp[3 + dvp] * dp[5]) +
1178 (vp[2 + dvp] * dp[6]) +
1179 (vp[1 + dvp] * dp[7]) +
1180 (vp[0 + dvp] * dp[8]) +
1181 (vp[15 + dvp] * dp[9]) +
1182 (vp[14 + dvp] * dp[10]) +
1183 (vp[13 + dvp] * dp[11]) +
1184 (vp[12 + dvp] * dp[12]) +
1185 (vp[11 + dvp] * dp[13]) +
1186 (vp[10 + dvp] * dp[14]) +
1187 (vp[9 + dvp] * dp[15])
1188 ) * scalefactor);
1189
1190 tmpOut[i] = pcm_sample;
1191
1192 dvp += 16;
1193 } // for
1194 }
1195
1196 private void compute_pcm_samples9(Obuffer buffer)
1197 {
1198 final float[] vp = actual_v;
1199
1200 //int inc = v_inc;
1201 final float[] tmpOut = _tmpOut;
1202 int dvp =0;
1203
1204 // fat chance of having this loop unroll
1205 for( int i=0; i<32; i++)
1206 {
1207 final float[] dp = d16[i];
1208 float pcm_sample;
1209
1210 pcm_sample = (float)(((vp[9 + dvp] * dp[0]) +
1211 (vp[8 + dvp] * dp[1]) +
1212 (vp[7 + dvp] * dp[2]) +
1213 (vp[6 + dvp] * dp[3]) +
1214 (vp[5 + dvp] * dp[4]) +
1215 (vp[4 + dvp] * dp[5]) +
1216 (vp[3 + dvp] * dp[6]) +
1217 (vp[2 + dvp] * dp[7]) +
1218 (vp[1 + dvp] * dp[8]) +
1219 (vp[0 + dvp] * dp[9]) +
1220 (vp[15 + dvp] * dp[10]) +
1221 (vp[14 + dvp] * dp[11]) +
1222 (vp[13 + dvp] * dp[12]) +
1223 (vp[12 + dvp] * dp[13]) +
1224 (vp[11 + dvp] * dp[14]) +
1225 (vp[10 + dvp] * dp[15])
1226 ) * scalefactor);
1227
1228 tmpOut[i] = pcm_sample;
1229
1230 dvp += 16;
1231 } // for
1232 }
1233
1234 private void compute_pcm_samples10(Obuffer buffer)
1235 {
1236 final float[] vp = actual_v;
1237 //int inc = v_inc;
1238 final float[] tmpOut = _tmpOut;
1239 int dvp =0;
1240
1241 // fat chance of having this loop unroll
1242 for( int i=0; i<32; i++)
1243 {
1244 final float[] dp = d16[i];
1245 float pcm_sample;
1246
1247 pcm_sample = (float)(((vp[10 + dvp] * dp[0]) +
1248 (vp[9 + dvp] * dp[1]) +
1249 (vp[8 + dvp] * dp[2]) +
1250 (vp[7 + dvp] * dp[3]) +
1251 (vp[6 + dvp] * dp[4]) +
1252 (vp[5 + dvp] * dp[5]) +
1253 (vp[4 + dvp] * dp[6]) +
1254 (vp[3 + dvp] * dp[7]) +
1255 (vp[2 + dvp] * dp[8]) +
1256 (vp[1 + dvp] * dp[9]) +
1257 (vp[0 + dvp] * dp[10]) +
1258 (vp[15 + dvp] * dp[11]) +
1259 (vp[14 + dvp] * dp[12]) +
1260 (vp[13 + dvp] * dp[13]) +
1261 (vp[12 + dvp] * dp[14]) +
1262 (vp[11 + dvp] * dp[15])
1263 ) * scalefactor);
1264
1265 tmpOut[i] = pcm_sample;
1266
1267 dvp += 16;
1268 } // for
1269 }
1270 private void compute_pcm_samples11(Obuffer buffer)
1271 {
1272 final float[] vp = actual_v;
1273
1274 //int inc = v_inc;
1275 final float[] tmpOut = _tmpOut;
1276 int dvp =0;
1277
1278 // fat chance of having this loop unroll
1279 for( int i=0; i<32; i++)
1280 {
1281 final float[] dp = d16[i];
1282 float pcm_sample;
1283
1284 pcm_sample = (float)(((vp[11 + dvp] * dp[0]) +
1285 (vp[10 + dvp] * dp[1]) +
1286 (vp[9 + dvp] * dp[2]) +
1287 (vp[8 + dvp] * dp[3]) +
1288 (vp[7 + dvp] * dp[4]) +
1289 (vp[6 + dvp] * dp[5]) +
1290 (vp[5 + dvp] * dp[6]) +
1291 (vp[4 + dvp] * dp[7]) +
1292 (vp[3 + dvp] * dp[8]) +
1293 (vp[2 + dvp] * dp[9]) +
1294 (vp[1 + dvp] * dp[10]) +
1295 (vp[0 + dvp] * dp[11]) +
1296 (vp[15 + dvp] * dp[12]) +
1297 (vp[14 + dvp] * dp[13]) +
1298 (vp[13 + dvp] * dp[14]) +
1299 (vp[12 + dvp] * dp[15])
1300 ) * scalefactor);
1301
1302 tmpOut[i] = pcm_sample;
1303
1304 dvp += 16;
1305 } // for
1306 }
1307 private void compute_pcm_samples12(Obuffer buffer)
1308 {
1309 final float[] vp = actual_v;
1310 //int inc = v_inc;
1311 final float[] tmpOut = _tmpOut;
1312 int dvp =0;
1313
1314 // fat chance of having this loop unroll
1315 for( int i=0; i<32; i++)
1316 {
1317 final float[] dp = d16[i];
1318 float pcm_sample;
1319
1320 pcm_sample = (float)(((vp[12 + dvp] * dp[0]) +
1321 (vp[11 + dvp] * dp[1]) +
1322 (vp[10 + dvp] * dp[2]) +
1323 (vp[9 + dvp] * dp[3]) +
1324 (vp[8 + dvp] * dp[4]) +
1325 (vp[7 + dvp] * dp[5]) +
1326 (vp[6 + dvp] * dp[6]) +
1327 (vp[5 + dvp] * dp[7]) +
1328 (vp[4 + dvp] * dp[8]) +
1329 (vp[3 + dvp] * dp[9]) +
1330 (vp[2 + dvp] * dp[10]) +
1331 (vp[1 + dvp] * dp[11]) +
1332 (vp[0 + dvp] * dp[12]) +
1333 (vp[15 + dvp] * dp[13]) +
1334 (vp[14 + dvp] * dp[14]) +
1335 (vp[13 + dvp] * dp[15])
1336 ) * scalefactor);
1337
1338 tmpOut[i] = pcm_sample;
1339
1340 dvp += 16;
1341 } // for
1342 }
1343 private void compute_pcm_samples13(Obuffer buffer)
1344 {
1345 final float[] vp = actual_v;
1346
1347 //int inc = v_inc;
1348 final float[] tmpOut = _tmpOut;
1349 int dvp =0;
1350
1351 // fat chance of having this loop unroll
1352 for( int i=0; i<32; i++)
1353 {
1354 final float[] dp = d16[i];
1355 float pcm_sample;
1356
1357 pcm_sample = (float)(((vp[13 + dvp] * dp[0]) +
1358 (vp[12 + dvp] * dp[1]) +
1359 (vp[11 + dvp] * dp[2]) +
1360 (vp[10 + dvp] * dp[3]) +
1361 (vp[9 + dvp] * dp[4]) +
1362 (vp[8 + dvp] * dp[5]) +
1363 (vp[7 + dvp] * dp[6]) +
1364 (vp[6 + dvp] * dp[7]) +
1365 (vp[5 + dvp] * dp[8]) +
1366 (vp[4 + dvp] * dp[9]) +
1367 (vp[3 + dvp] * dp[10]) +
1368 (vp[2 + dvp] * dp[11]) +
1369 (vp[1 + dvp] * dp[12]) +
1370 (vp[0 + dvp] * dp[13]) +
1371 (vp[15 + dvp] * dp[14]) +
1372 (vp[14 + dvp] * dp[15])
1373 ) * scalefactor);
1374
1375 tmpOut[i] = pcm_sample;
1376
1377 dvp += 16;
1378 } // for
1379 }
1380 private void compute_pcm_samples14(Obuffer buffer)
1381 {
1382 final float[] vp = actual_v;
1383
1384 //int inc = v_inc;
1385 final float[] tmpOut = _tmpOut;
1386 int dvp =0;
1387
1388 // fat chance of having this loop unroll
1389 for( int i=0; i<32; i++)
1390 {
1391 final float[] dp = d16[i];
1392 float pcm_sample;
1393
1394 pcm_sample = (float)(((vp[14 + dvp] * dp[0]) +
1395 (vp[13 + dvp] * dp[1]) +
1396 (vp[12 + dvp] * dp[2]) +
1397 (vp[11 + dvp] * dp[3]) +
1398 (vp[10 + dvp] * dp[4]) +
1399 (vp[9 + dvp] * dp[5]) +
1400 (vp[8 + dvp] * dp[6]) +
1401 (vp[7 + dvp] * dp[7]) +
1402 (vp[6 + dvp] * dp[8]) +
1403 (vp[5 + dvp] * dp[9]) +
1404 (vp[4 + dvp] * dp[10]) +
1405 (vp[3 + dvp] * dp[11]) +
1406 (vp[2 + dvp] * dp[12]) +
1407 (vp[1 + dvp] * dp[13]) +
1408 (vp[0 + dvp] * dp[14]) +
1409 (vp[15 + dvp] * dp[15])
1410 ) * scalefactor);
1411
1412 tmpOut[i] = pcm_sample;
1413
1414 dvp += 16;
1415 } // for
1416 }
1417 private void compute_pcm_samples15(Obuffer buffer)
1418 {
1419 final float[] vp = actual_v;
1420
1421 //int inc = v_inc;
1422 final float[] tmpOut = _tmpOut;
1423 int dvp =0;
1424
1425 // fat chance of having this loop unroll
1426 for( int i=0; i<32; i++)
1427 {
1428 float pcm_sample;
1429 final float dp[] = d16[i];
1430 pcm_sample = (float)(((vp[15 + dvp] * dp[0]) +
1431 (vp[14 + dvp] * dp[1]) +
1432 (vp[13 + dvp] * dp[2]) +
1433 (vp[12 + dvp] * dp[3]) +
1434 (vp[11 + dvp] * dp[4]) +
1435 (vp[10 + dvp] * dp[5]) +
1436 (vp[9 + dvp] * dp[6]) +
1437 (vp[8 + dvp] * dp[7]) +
1438 (vp[7 + dvp] * dp[8]) +
1439 (vp[6 + dvp] * dp[9]) +
1440 (vp[5 + dvp] * dp[10]) +
1441 (vp[4 + dvp] * dp[11]) +
1442 (vp[3 + dvp] * dp[12]) +
1443 (vp[2 + dvp] * dp[13]) +
1444 (vp[1 + dvp] * dp[14]) +
1445 (vp[0 + dvp] * dp[15])
1446 ) * scalefactor);
1447
1448 tmpOut[i] = pcm_sample;
1449 dvp += 16;
1450 } // for
1451 }
1452
1453private void compute_pcm_samples(Obuffer buffer)
1454{
1455
1456 switch (actual_write_pos)
1457 {
1458 case 0:
1459 compute_pcm_samples0(buffer);
1460 break;
1461 case 1:
1462 compute_pcm_samples1(buffer);
1463 break;
1464 case 2:
1465 compute_pcm_samples2(buffer);
1466 break;
1467 case 3:
1468 compute_pcm_samples3(buffer);
1469 break;
1470 case 4:
1471 compute_pcm_samples4(buffer);
1472 break;
1473 case 5:
1474 compute_pcm_samples5(buffer);
1475 break;
1476 case 6:
1477 compute_pcm_samples6(buffer);
1478 break;
1479 case 7:
1480 compute_pcm_samples7(buffer);
1481 break;
1482 case 8:
1483 compute_pcm_samples8(buffer);
1484 break;
1485 case 9:
1486 compute_pcm_samples9(buffer);
1487 break;
1488 case 10:
1489 compute_pcm_samples10(buffer);
1490 break;
1491 case 11:
1492 compute_pcm_samples11(buffer);
1493 break;
1494 case 12:
1495 compute_pcm_samples12(buffer);
1496 break;
1497 case 13:
1498 compute_pcm_samples13(buffer);
1499 break;
1500 case 14:
1501 compute_pcm_samples14(buffer);
1502 break;
1503 case 15:
1504 compute_pcm_samples15(buffer);
1505 break;
1506 }
1507
1508 if (buffer!=null)
1509 {
1510 buffer.appendSamples(channel, _tmpOut);
1511 }
1512
1513/*
1514 // MDM: I was considering putting in quality control for
1515 // low-spec CPUs, but the performance gain (about 10-15%)
1516 // did not justify the considerable drop in audio quality.
1517 switch (inc)
1518 {
1519 case 16:
1520 buffer.appendSamples(channel, tmpOut);
1521 break;
1522 case 32:
1523 for (int i=0; i<16; i++)
1524 {
1525 buffer.append(channel, (short)tmpOut[i]);
1526 buffer.append(channel, (short)tmpOut[i]);
1527 }
1528 break;
1529 case 64:
1530 for (int i=0; i<8; i++)
1531 {
1532 buffer.append(channel, (short)tmpOut[i]);
1533 buffer.append(channel, (short)tmpOut[i]);
1534 buffer.append(channel, (short)tmpOut[i]);
1535 buffer.append(channel, (short)tmpOut[i]);
1536 }
1537 break;
1538
1539 }
1540*/
1541 }
1542
1543 /**
1544 * Calculate 32 PCM samples and put the into the Obuffer-object.
1545 */
1546
1547 public void calculate_pcm_samples(Obuffer buffer)
1548 {
1549 compute_new_v();
1550 compute_pcm_samples(buffer);
1551
1552 actual_write_pos = (actual_write_pos + 1) & 0xf;
1553 actual_v = (actual_v == v1) ? v2 : v1;
1554
1555 // initialize samples[]:
1556 //for (register float *floatp = samples + 32; floatp > samples; )
1557 // *--floatp = 0.0f;
1558
1559 // MDM: this may not be necessary. The Layer III decoder always
1560 // outputs 32 subband samples, but I haven't checked layer I & II.
1561 for (int p=0;p<32;p++)
1562 samples[p] = 0.0f;
1563 }
1564
1565
1566 private static final double MY_PI = 3.14159265358979323846;
1567 private static final float cos1_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 64.0)));
1568 private static final float cos3_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 64.0)));
1569 private static final float cos5_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 64.0)));
1570 private static final float cos7_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 64.0)));
1571 private static final float cos9_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 64.0)));
1572 private static final float cos11_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 64.0)));
1573 private static final float cos13_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 64.0)));
1574 private static final float cos15_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 64.0)));
1575 private static final float cos17_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 17.0 / 64.0)));
1576 private static final float cos19_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 19.0 / 64.0)));
1577 private static final float cos21_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 21.0 / 64.0)));
1578 private static final float cos23_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 23.0 / 64.0)));
1579 private static final float cos25_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 25.0 / 64.0)));
1580 private static final float cos27_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 27.0 / 64.0)));
1581 private static final float cos29_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 29.0 / 64.0)));
1582 private static final float cos31_64 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 31.0 / 64.0)));
1583 private static final float cos1_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 32.0)));
1584 private static final float cos3_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 32.0)));
1585 private static final float cos5_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 32.0)));
1586 private static final float cos7_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 32.0)));
1587 private static final float cos9_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 9.0 / 32.0)));
1588 private static final float cos11_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 11.0 / 32.0)));
1589 private static final float cos13_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 13.0 / 32.0)));
1590 private static final float cos15_32 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 15.0 / 32.0)));
1591 private static final float cos1_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 16.0)));
1592 private static final float cos3_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 16.0)));
1593 private static final float cos5_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 5.0 / 16.0)));
1594 private static final float cos7_16 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 7.0 / 16.0)));
1595 private static final float cos1_8 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 8.0)));
1596 private static final float cos3_8 =(float) (1.0 / (2.0 * Math.cos(MY_PI * 3.0 / 8.0)));
1597 private static final float cos1_4 =(float) (1.0 / (2.0 * Math.cos(MY_PI / 4.0)));
1598
1599 // Note: These values are not in the same order
1600 // as in Annex 3-B.3 of the ISO/IEC DIS 11172-3
1601 // private float d[] = {0.000000000, -4.000442505};
1602
1603 private static float d[] = null;
1604
1605 /**
1606 * d[] split into subarrays of length 16. This provides for
1607 * more faster access by allowing a block of 16 to be addressed
1608 * with constant offset.
1609 **/
1610 private static float d16[][] = null;
1611
1612 /**
1613 * Loads the data for the d[] from the resource SFd.ser.
1614 * @return the loaded values for d[].
1615 */
1616 static private float[] load_d()
1617 {
1618 try
1619 {
1620 Class elemType = Float.TYPE;
1621 Object o = JavaLayerUtils.deserializeArrayResource("sfd.ser", elemType, 512);
1622 return (float[])o;
1623 }
1624 catch (IOException ex)
1625 {
1626 throw new ExceptionInInitializerError(ex);
1627 }
1628 }
1629
1630 /**
1631 * Converts a 1D array into a number of smaller arrays. This is used
1632 * to achieve offset + constant indexing into an array. Each sub-array
1633 * represents a block of values of the original array.
1634 * @param array The array to split up into blocks.
1635 * @param blockSize The size of the blocks to split the array
1636 * into. This must be an exact divisor of
1637 * the length of the array, or some data
1638 * will be lost from the main array.
1639 *
1640 * @return An array of arrays in which each element in the returned
1641 * array will be of length <code>blockSize</code>.
1642 */
1643 static private float[][] splitArray(final float[] array, final int blockSize)
1644 {
1645 int size = array.length / blockSize;
1646 float[][] split = new float[size][];
1647 for (int i=0; i<size; i++)
1648 {
1649 split[i] = subArray(array, i*blockSize, blockSize);
1650 }
1651 return split;
1652 }
1653
1654 /**
1655 * Returns a subarray of an existing array.
1656 *
1657 * @param array The array to retrieve a subarra from.
1658 * @param offs The offset in the array that corresponds to
1659 * the first index of the subarray.
1660 * @param len The number of indeces in the subarray.
1661 * @return The subarray, which may be of length 0.
1662 */
1663 static private float[] subArray(final float[] array, final int offs, int len)
1664 {
1665 if (offs+len > array.length)
1666 {
1667 len = array.length-offs;
1668 }
1669
1670 if (len < 0)
1671 len = 0;
1672
1673 float[] subarray = new float[len];
1674 for (int i=0; i<len; i++)
1675 {
1676 subarray[i] = array[offs+i];
1677 }
1678
1679 return subarray;
1680 }
1681
1682 // The original data for d[]. This data is loaded from a file
1683 // to reduce the overall package size and to improve performance.
1684/*
1685 static final float d_data[] = {
1686 0.000000000f, -0.000442505f, 0.003250122f, -0.007003784f,
1687 0.031082153f, -0.078628540f, 0.100311279f, -0.572036743f,
1688 1.144989014f, 0.572036743f, 0.100311279f, 0.078628540f,
1689 0.031082153f, 0.007003784f, 0.003250122f, 0.000442505f,
1690 -0.000015259f, -0.000473022f, 0.003326416f, -0.007919312f,
1691 0.030517578f, -0.084182739f, 0.090927124f, -0.600219727f,
1692 1.144287109f, 0.543823242f, 0.108856201f, 0.073059082f,
1693 0.031478882f, 0.006118774f, 0.003173828f, 0.000396729f,
1694 -0.000015259f, -0.000534058f, 0.003387451f, -0.008865356f,
1695 0.029785156f, -0.089706421f, 0.080688477f, -0.628295898f,
1696 1.142211914f, 0.515609741f, 0.116577148f, 0.067520142f,
1697 0.031738281f, 0.005294800f, 0.003082275f, 0.000366211f,
1698 -0.000015259f, -0.000579834f, 0.003433228f, -0.009841919f,
1699 0.028884888f, -0.095169067f, 0.069595337f, -0.656219482f,
1700 1.138763428f, 0.487472534f, 0.123474121f, 0.061996460f,
1701 0.031845093f, 0.004486084f, 0.002990723f, 0.000320435f,
1702 -0.000015259f, -0.000625610f, 0.003463745f, -0.010848999f,
1703 0.027801514f, -0.100540161f, 0.057617188f, -0.683914185f,
1704 1.133926392f, 0.459472656f, 0.129577637f, 0.056533813f,
1705 0.031814575f, 0.003723145f, 0.002899170f, 0.000289917f,
1706 -0.000015259f, -0.000686646f, 0.003479004f, -0.011886597f,
1707 0.026535034f, -0.105819702f, 0.044784546f, -0.711318970f,
1708 1.127746582f, 0.431655884f, 0.134887695f, 0.051132202f,
1709 0.031661987f, 0.003005981f, 0.002792358f, 0.000259399f,
1710 -0.000015259f, -0.000747681f, 0.003479004f, -0.012939453f,
1711 0.025085449f, -0.110946655f, 0.031082153f, -0.738372803f,
1712 1.120223999f, 0.404083252f, 0.139450073f, 0.045837402f,
1713 0.031387329f, 0.002334595f, 0.002685547f, 0.000244141f,
1714 -0.000030518f, -0.000808716f, 0.003463745f, -0.014022827f,
1715 0.023422241f, -0.115921021f, 0.016510010f, -0.765029907f,
1716 1.111373901f, 0.376800537f, 0.143264771f, 0.040634155f,
1717 0.031005859f, 0.001693726f, 0.002578735f, 0.000213623f,
1718 -0.000030518f, -0.000885010f, 0.003417969f, -0.015121460f,
1719 0.021575928f, -0.120697021f, 0.001068115f, -0.791213989f,
1720 1.101211548f, 0.349868774f, 0.146362305f, 0.035552979f,
1721 0.030532837f, 0.001098633f, 0.002456665f, 0.000198364f,
1722 -0.000030518f, -0.000961304f, 0.003372192f, -0.016235352f,
1723 0.019531250f, -0.125259399f, -0.015228271f, -0.816864014f,
1724 1.089782715f, 0.323318481f, 0.148773193f, 0.030609131f,
1725 0.029937744f, 0.000549316f, 0.002349854f, 0.000167847f,
1726 -0.000030518f, -0.001037598f, 0.003280640f, -0.017349243f,
1727 0.017257690f, -0.129562378f, -0.032379150f, -0.841949463f,
1728 1.077117920f, 0.297210693f, 0.150497437f, 0.025817871f,
1729 0.029281616f, 0.000030518f, 0.002243042f, 0.000152588f,
1730 -0.000045776f, -0.001113892f, 0.003173828f, -0.018463135f,
1731 0.014801025f, -0.133590698f, -0.050354004f, -0.866363525f,
1732 1.063217163f, 0.271591187f, 0.151596069f, 0.021179199f,
1733 0.028533936f, -0.000442505f, 0.002120972f, 0.000137329f,
1734 -0.000045776f, -0.001205444f, 0.003051758f, -0.019577026f,
1735 0.012115479f, -0.137298584f, -0.069168091f, -0.890090942f,
1736 1.048156738f, 0.246505737f, 0.152069092f, 0.016708374f,
1737 0.027725220f, -0.000869751f, 0.002014160f, 0.000122070f,
1738 -0.000061035f, -0.001296997f, 0.002883911f, -0.020690918f,
1739 0.009231567f, -0.140670776f, -0.088775635f, -0.913055420f,
1740 1.031936646f, 0.221984863f, 0.151962280f, 0.012420654f,
1741 0.026840210f, -0.001266479f, 0.001907349f, 0.000106812f,
1742 -0.000061035f, -0.001388550f, 0.002700806f, -0.021789551f,
1743 0.006134033f, -0.143676758f, -0.109161377f, -0.935195923f,
1744 1.014617920f, 0.198059082f, 0.151306152f, 0.008316040f,
1745 0.025909424f, -0.001617432f, 0.001785278f, 0.000106812f,
1746 -0.000076294f, -0.001480103f, 0.002487183f, -0.022857666f,
1747 0.002822876f, -0.146255493f, -0.130310059f, -0.956481934f,
1748 0.996246338f, 0.174789429f, 0.150115967f, 0.004394531f,
1749 0.024932861f, -0.001937866f, 0.001693726f, 0.000091553f,
1750 -0.000076294f, -0.001586914f, 0.002227783f, -0.023910522f,
1751 -0.000686646f, -0.148422241f, -0.152206421f, -0.976852417f,
1752 0.976852417f, 0.152206421f, 0.148422241f, 0.000686646f,
1753 0.023910522f, -0.002227783f, 0.001586914f, 0.000076294f,
1754 -0.000091553f, -0.001693726f, 0.001937866f, -0.024932861f,
1755 -0.004394531f, -0.150115967f, -0.174789429f, -0.996246338f,
1756 0.956481934f, 0.130310059f, 0.146255493f, -0.002822876f,
1757 0.022857666f, -0.002487183f, 0.001480103f, 0.000076294f,
1758 -0.000106812f, -0.001785278f, 0.001617432f, -0.025909424f,
1759 -0.008316040f, -0.151306152f, -0.198059082f, -1.014617920f,
1760 0.935195923f, 0.109161377f, 0.143676758f, -0.006134033f,
1761 0.021789551f, -0.002700806f, 0.001388550f, 0.000061035f,
1762 -0.000106812f, -0.001907349f, 0.001266479f, -0.026840210f,
1763 -0.012420654f, -0.151962280f, -0.221984863f, -1.031936646f,
1764 0.913055420f, 0.088775635f, 0.140670776f, -0.009231567f,
1765 0.020690918f, -0.002883911f, 0.001296997f, 0.000061035f,
1766 -0.000122070f, -0.002014160f, 0.000869751f, -0.027725220f,
1767 -0.016708374f, -0.152069092f, -0.246505737f, -1.048156738f,
1768 0.890090942f, 0.069168091f, 0.137298584f, -0.012115479f,
1769 0.019577026f, -0.003051758f, 0.001205444f, 0.000045776f,
1770 -0.000137329f, -0.002120972f, 0.000442505f, -0.028533936f,
1771 -0.021179199f, -0.151596069f, -0.271591187f, -1.063217163f,
1772 0.866363525f, 0.050354004f, 0.133590698f, -0.014801025f,
1773 0.018463135f, -0.003173828f, 0.001113892f, 0.000045776f,
1774 -0.000152588f, -0.002243042f, -0.000030518f, -0.029281616f,
1775 -0.025817871f, -0.150497437f, -0.297210693f, -1.077117920f,
1776 0.841949463f, 0.032379150f, 0.129562378f, -0.017257690f,
1777 0.017349243f, -0.003280640f, 0.001037598f, 0.000030518f,
1778 -0.000167847f, -0.002349854f, -0.000549316f, -0.029937744f,
1779 -0.030609131f, -0.148773193f, -0.323318481f, -1.089782715f,
1780 0.816864014f, 0.015228271f, 0.125259399f, -0.019531250f,
1781 0.016235352f, -0.003372192f, 0.000961304f, 0.000030518f,
1782 -0.000198364f, -0.002456665f, -0.001098633f, -0.030532837f,
1783 -0.035552979f, -0.146362305f, -0.349868774f, -1.101211548f,
1784 0.791213989f, -0.001068115f, 0.120697021f, -0.021575928f,
1785 0.015121460f, -0.003417969f, 0.000885010f, 0.000030518f,
1786 -0.000213623f, -0.002578735f, -0.001693726f, -0.031005859f,
1787 -0.040634155f, -0.143264771f, -0.376800537f, -1.111373901f,
1788 0.765029907f, -0.016510010f, 0.115921021f, -0.023422241f,
1789 0.014022827f, -0.003463745f, 0.000808716f, 0.000030518f,
1790 -0.000244141f, -0.002685547f, -0.002334595f, -0.031387329f,
1791 -0.045837402f, -0.139450073f, -0.404083252f, -1.120223999f,
1792 0.738372803f, -0.031082153f, 0.110946655f, -0.025085449f,
1793 0.012939453f, -0.003479004f, 0.000747681f, 0.000015259f,
1794 -0.000259399f, -0.002792358f, -0.003005981f, -0.031661987f,
1795 -0.051132202f, -0.134887695f, -0.431655884f, -1.127746582f,
1796 0.711318970f, -0.044784546f, 0.105819702f, -0.026535034f,
1797 0.011886597f, -0.003479004f, 0.000686646f, 0.000015259f,
1798 -0.000289917f, -0.002899170f, -0.003723145f, -0.031814575f,
1799 -0.056533813f, -0.129577637f, -0.459472656f, -1.133926392f,
1800 0.683914185f, -0.057617188f, 0.100540161f, -0.027801514f,
1801 0.010848999f, -0.003463745f, 0.000625610f, 0.000015259f,
1802 -0.000320435f, -0.002990723f, -0.004486084f, -0.031845093f,
1803 -0.061996460f, -0.123474121f, -0.487472534f, -1.138763428f,
1804 0.656219482f, -0.069595337f, 0.095169067f, -0.028884888f,
1805 0.009841919f, -0.003433228f, 0.000579834f, 0.000015259f,
1806 -0.000366211f, -0.003082275f, -0.005294800f, -0.031738281f,
1807 -0.067520142f, -0.116577148f, -0.515609741f, -1.142211914f,
1808 0.628295898f, -0.080688477f, 0.089706421f, -0.029785156f,
1809 0.008865356f, -0.003387451f, 0.000534058f, 0.000015259f,
1810 -0.000396729f, -0.003173828f, -0.006118774f, -0.031478882f,
1811 -0.073059082f, -0.108856201f, -0.543823242f, -1.144287109f,
1812 0.600219727f, -0.090927124f, 0.084182739f, -0.030517578f,
1813 0.007919312f, -0.003326416f, 0.000473022f, 0.000015259f
1814 };
1815 */
1816
1817}
diff --git a/songdbj/javazoom/jl/decoder/au2lin.ser b/songdbj/javazoom/jl/decoder/au2lin.ser
new file mode 100644
index 0000000000..de0d1f62d9
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/au2lin.ser
Binary files differ
diff --git a/songdbj/javazoom/jl/decoder/huffcodetab.java b/songdbj/javazoom/jl/decoder/huffcodetab.java
new file mode 100644
index 0000000000..86975646f0
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/huffcodetab.java
@@ -0,0 +1,600 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 16/11/99 Renamed class, added javadoc, and changed table
4 * name from String to 3 chars. mdm@techie.com
5 * 02/15/99 Java Conversion by E.B, javalayer@javazoom.net
6 *
7 * 04/19/97 : Adapted from the ISO MPEG Audio Subgroup Software Simulation
8 * Group's public c source for its MPEG audio decoder. Miscellaneous
9 * changes by Jeff Tsay (ctsay@pasteur.eecs.berkeley.edu).
10 *-----------------------------------------------------------------------
11 * Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved
12 * MPEG/audio coding/decoding software, work in progress
13 * NOT for public distribution until verified and approved by the
14 * MPEG/audio committee. For further information, please contact
15 * Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com
16 *
17 * VERSION 4.1
18 * changes made since last update:
19 * date programmers comment
20 * 27.2.92 F.O.Witte (ITT Intermetall)
21 * 8/24/93 M. Iwadare Changed for 1 pass decoding.
22 * 7/14/94 J. Koller useless 'typedef' before huffcodetab removed
23 *-----------------------------------------------------------------------
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU Library General Public License as published
26 * by the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU Library General Public License for more details.
33 *
34 * You should have received a copy of the GNU Library General Public
35 * License along with this program; if not, write to the Free Software
36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 *----------------------------------------------------------------------
38 */
39
40package javazoom.jl.decoder;
41
42/**
43 * Class to implements Huffman decoder.
44 */
45final class huffcodetab
46{
47 private static final int MXOFF=250;
48 private static final int HTN=34;
49
50 private char tablename0 = ' '; /* string, containing table_description */
51 private char tablename1 = ' '; /* string, containing table_description */
52 private char tablename2 = ' '; /* string, containing table_description */
53
54 private int xlen; /* max. x-index+ */
55 private int ylen; /* max. y-index+ */
56 private int linbits; /* number of linbits */
57 private int linmax; /* max number to be stored in linbits */
58 private int ref; /* a positive value indicates a reference */
59 private int[] table=null; /* pointer to array[xlen][ylen] */
60 private int[] hlen=null; /* pointer to array[xlen][ylen] */
61 private int[][] val=null; /* decoder tree */
62 private int treelen; /* length of decoder tree */
63
64 private static int ValTab0[][] = {
65 {0,0} // dummy
66 };
67
68 private static int ValTab1[][] = {
69 {2,1},{0,0},{2,1},{0,16},{2,1},{0,1},{0,17},
70 };
71
72 private static int ValTab2[][] = {
73 {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1},
74 {0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},
75 };
76
77 private static int ValTab3[][] = {
78 {4,1},{2,1},{0,0},{0,1},{2,1},{0,17},{2,1},{0,16},{4,1},{2,1},
79 {0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},
80 };
81
82 private static int ValTab4[][] = {{0,0}}; // dummy
83
84 private static int ValTab5[][] = {
85 {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{8,1},{4,1},
86 {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1},{0,34},
87 {0,48},{2,1},{0,3},{0,19},{2,1},{0,49},{2,1},{0,50},{2,1},{0,35},
88 {0,51},
89 };
90
91 private static int ValTab6[][] = {
92 {6,1},{4,1},{2,1},{0,0},{0,16},{0,17},{6,1},{2,1},{0,1},{2,1},
93 {0,32},{0,33},{6,1},{2,1},{0,18},{2,1},{0,2},{0,34},{4,1},{2,1},
94 {0,49},{0,19},{4,1},{2,1},{0,48},{0,50},{2,1},{0,35},{2,1},{0,3},
95 {0,51},
96 };
97
98 private static int ValTab7[][] = {
99 {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1},
100 {2,1},{0,32},{0,2},{0,33},{18,1},{6,1},{2,1},{0,18},{2,1},{0,34},
101 {0,48},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,3},{0,50},{2,1},
102 {0,35},{0,4},{10,1},{4,1},{2,1},{0,64},{0,65},{2,1},{0,20},{2,1},
103 {0,66},{0,36},{12,1},{6,1},{4,1},{2,1},{0,51},{0,67},{0,80},{4,1},
104 {2,1},{0,52},{0,5},{0,81},{6,1},{2,1},{0,21},{2,1},{0,82},{0,37},
105 {4,1},{2,1},{0,68},{0,53},{4,1},{2,1},{0,83},{0,84},{2,1},{0,69},
106 {0,85},
107 };
108
109 private static int ValTab8[][] = {
110 {6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1},
111 {0,33},{0,18},{14,1},{4,1},{2,1},{0,32},{0,2},{2,1},{0,34},{4,1},
112 {2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{14,1},{8,1},{4,1},{2,1},
113 {0,50},{0,35},{2,1},{0,64},{0,4},{2,1},{0,65},{2,1},{0,20},{0,66},
114 {12,1},{6,1},{2,1},{0,36},{2,1},{0,51},{0,80},{4,1},{2,1},{0,67},
115 {0,52},{0,81},{6,1},{2,1},{0,21},{2,1},{0,5},{0,82},{6,1},{2,1},
116 {0,37},{2,1},{0,68},{0,53},{2,1},{0,83},{2,1},{0,69},{2,1},{0,84},
117 {0,85},
118 };
119
120 private static int ValTab9[][] = {
121 {8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{10,1},{4,1},
122 {2,1},{0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},{12,1},{6,1},
123 {4,1},{2,1},{0,48},{0,3},{0,49},{2,1},{0,19},{2,1},{0,50},{0,35},
124 {12,1},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,64},{0,51},{2,1},
125 {0,66},{0,36},{10,1},{6,1},{4,1},{2,1},{0,4},{0,80},{0,67},{2,1},
126 {0,52},{0,81},{8,1},{4,1},{2,1},{0,21},{0,82},{2,1},{0,37},{0,68},
127 {6,1},{4,1},{2,1},{0,5},{0,84},{0,83},{2,1},{0,53},{2,1},{0,69},
128 {0,85},
129 };
130
131 private static int ValTab10[][] = {
132 {2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{10,1},{2,1},{0,17},{4,1},
133 {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{28,1},{8,1},{4,1},{2,1},
134 {0,34},{0,48},{2,1},{0,49},{0,19},{8,1},{4,1},{2,1},{0,3},{0,50},
135 {2,1},{0,35},{0,64},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,4},
136 {0,51},{2,1},{0,66},{0,36},{28,1},{10,1},{6,1},{4,1},{2,1},{0,80},
137 {0,5},{0,96},{2,1},{0,97},{0,22},{12,1},{6,1},{4,1},{2,1},{0,67},
138 {0,52},{0,81},{2,1},{0,21},{2,1},{0,82},{0,37},{4,1},{2,1},{0,38},
139 {0,54},{0,113},{20,1},{8,1},{2,1},{0,23},{4,1},{2,1},{0,68},{0,83},
140 {0,6},{6,1},{4,1},{2,1},{0,53},{0,69},{0,98},{2,1},{0,112},{2,1},
141 {0,7},{0,100},{14,1},{4,1},{2,1},{0,114},{0,39},{6,1},{2,1},{0,99},
142 {2,1},{0,84},{0,85},{2,1},{0,70},{0,115},{8,1},{4,1},{2,1},{0,55},
143 {0,101},{2,1},{0,86},{0,116},{6,1},{2,1},{0,71},{2,1},{0,102},{0,117},
144 {4,1},{2,1},{0,87},{0,118},{2,1},{0,103},{0,119},
145 };
146
147 private static int ValTab11[][] = {
148 {6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1},
149 {2,1},{0,32},{0,2},{0,18},{24,1},{8,1},{2,1},{0,33},{2,1},{0,34},
150 {2,1},{0,48},{0,3},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,50},
151 {0,35},{4,1},{2,1},{0,64},{0,4},{2,1},{0,65},{0,20},{30,1},{16,1},
152 {10,1},{4,1},{2,1},{0,66},{0,36},{4,1},{2,1},{0,51},{0,67},{0,80},
153 {4,1},{2,1},{0,52},{0,81},{0,97},{6,1},{2,1},{0,22},{2,1},{0,6},
154 {0,38},{2,1},{0,98},{2,1},{0,21},{2,1},{0,5},{0,82},{16,1},{10,1},
155 {6,1},{4,1},{2,1},{0,37},{0,68},{0,96},{2,1},{0,99},{0,54},{4,1},
156 {2,1},{0,112},{0,23},{0,113},{16,1},{6,1},{4,1},{2,1},{0,7},{0,100},
157 {0,114},{2,1},{0,39},{4,1},{2,1},{0,83},{0,53},{2,1},{0,84},{0,69},
158 {10,1},{4,1},{2,1},{0,70},{0,115},{2,1},{0,55},{2,1},{0,101},{0,86},
159 {10,1},{6,1},{4,1},{2,1},{0,85},{0,87},{0,116},{2,1},{0,71},{0,102},
160 {4,1},{2,1},{0,117},{0,118},{2,1},{0,103},{0,119},
161 };
162
163 private static int ValTab12[][] = {
164 {12,1},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{2,1},{0,0},{2,1},
165 {0,32},{0,2},{16,1},{4,1},{2,1},{0,33},{0,18},{4,1},{2,1},{0,34},
166 {0,49},{2,1},{0,19},{2,1},{0,48},{2,1},{0,3},{0,64},{26,1},{8,1},
167 {4,1},{2,1},{0,50},{0,35},{2,1},{0,65},{0,51},{10,1},{4,1},{2,1},
168 {0,20},{0,66},{2,1},{0,36},{2,1},{0,4},{0,80},{4,1},{2,1},{0,67},
169 {0,52},{2,1},{0,81},{0,21},{28,1},{14,1},{8,1},{4,1},{2,1},{0,82},
170 {0,37},{2,1},{0,83},{0,53},{4,1},{2,1},{0,96},{0,22},{0,97},{4,1},
171 {2,1},{0,98},{0,38},{6,1},{4,1},{2,1},{0,5},{0,6},{0,68},{2,1},
172 {0,84},{0,69},{18,1},{10,1},{4,1},{2,1},{0,99},{0,54},{4,1},{2,1},
173 {0,112},{0,7},{0,113},{4,1},{2,1},{0,23},{0,100},{2,1},{0,70},{0,114},
174 {10,1},{6,1},{2,1},{0,39},{2,1},{0,85},{0,115},{2,1},{0,55},{0,86},
175 {8,1},{4,1},{2,1},{0,101},{0,116},{2,1},{0,71},{0,102},{4,1},{2,1},
176 {0,117},{0,87},{2,1},{0,118},{2,1},{0,103},{0,119},
177 };
178
179 private static int ValTab13[][] = {
180 {2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{28,1},{8,1},
181 {4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1},
182 {0,34},{0,48},{2,1},{0,3},{0,49},{6,1},{2,1},{0,19},{2,1},{0,50},
183 {0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{70,1},{28,1},{14,1},{6,1},
184 {2,1},{0,20},{2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1},
185 {0,67},{0,52},{4,1},{2,1},{0,81},{0,21},{4,1},{2,1},{0,5},{0,82},
186 {2,1},{0,37},{2,1},{0,68},{0,83},{14,1},{8,1},{4,1},{2,1},{0,96},
187 {0,6},{2,1},{0,97},{0,22},{4,1},{2,1},{0,128},{0,8},{0,129},{16,1},
188 {8,1},{4,1},{2,1},{0,53},{0,98},{2,1},{0,38},{0,84},{4,1},{2,1},
189 {0,69},{0,99},{2,1},{0,54},{0,112},{6,1},{4,1},{2,1},{0,7},{0,85},
190 {0,113},{2,1},{0,23},{2,1},{0,39},{0,55},{72,1},{24,1},{12,1},{4,1},
191 {2,1},{0,24},{0,130},{2,1},{0,40},{4,1},{2,1},{0,100},{0,70},{0,114},
192 {8,1},{4,1},{2,1},{0,132},{0,72},{2,1},{0,144},{0,9},{2,1},{0,145},
193 {0,25},{24,1},{14,1},{8,1},{4,1},{2,1},{0,115},{0,101},{2,1},{0,86},
194 {0,116},{4,1},{2,1},{0,71},{0,102},{0,131},{6,1},{2,1},{0,56},{2,1},
195 {0,117},{0,87},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,103},
196 {0,133},{2,1},{0,88},{0,57},{2,1},{0,147},{2,1},{0,73},{0,134},{6,1},
197 {2,1},{0,160},{2,1},{0,104},{0,10},{2,1},{0,161},{0,26},{68,1},{24,1},
198 {12,1},{4,1},{2,1},{0,162},{0,42},{4,1},{2,1},{0,149},{0,89},{2,1},
199 {0,163},{0,58},{8,1},{4,1},{2,1},{0,74},{0,150},{2,1},{0,176},{0,11},
200 {2,1},{0,177},{0,27},{20,1},{8,1},{2,1},{0,178},{4,1},{2,1},{0,118},
201 {0,119},{0,148},{6,1},{4,1},{2,1},{0,135},{0,120},{0,164},{4,1},{2,1},
202 {0,105},{0,165},{0,43},{12,1},{6,1},{4,1},{2,1},{0,90},{0,136},{0,179},
203 {2,1},{0,59},{2,1},{0,121},{0,166},{6,1},{4,1},{2,1},{0,106},{0,180},
204 {0,192},{4,1},{2,1},{0,12},{0,152},{0,193},{60,1},{22,1},{10,1},{6,1},
205 {2,1},{0,28},{2,1},{0,137},{0,181},{2,1},{0,91},{0,194},{4,1},{2,1},
206 {0,44},{0,60},{4,1},{2,1},{0,182},{0,107},{2,1},{0,196},{0,76},{16,1},
207 {8,1},{4,1},{2,1},{0,168},{0,138},{2,1},{0,208},{0,13},{2,1},{0,209},
208 {2,1},{0,75},{2,1},{0,151},{0,167},{12,1},{6,1},{2,1},{0,195},{2,1},
209 {0,122},{0,153},{4,1},{2,1},{0,197},{0,92},{0,183},{4,1},{2,1},{0,29},
210 {0,210},{2,1},{0,45},{2,1},{0,123},{0,211},{52,1},{28,1},{12,1},{4,1},
211 {2,1},{0,61},{0,198},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212},
212 {8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1},
213 {0,124},{0,213},{2,1},{0,93},{0,224},{10,1},{4,1},{2,1},{0,225},{0,30},
214 {4,1},{2,1},{0,14},{0,46},{0,226},{8,1},{4,1},{2,1},{0,227},{0,109},
215 {2,1},{0,140},{0,228},{4,1},{2,1},{0,229},{0,186},{0,240},{38,1},{16,1},
216 {4,1},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1},{0,170},{0,155},{0,185},
217 {2,1},{0,62},{2,1},{0,214},{0,200},{12,1},{6,1},{2,1},{0,78},{2,1},
218 {0,215},{0,125},{2,1},{0,171},{2,1},{0,94},{0,201},{6,1},{2,1},{0,15},
219 {2,1},{0,156},{0,110},{2,1},{0,242},{0,47},{32,1},{16,1},{6,1},{4,1},
220 {2,1},{0,216},{0,141},{0,63},{6,1},{2,1},{0,243},{2,1},{0,230},{0,202},
221 {2,1},{0,244},{0,79},{8,1},{4,1},{2,1},{0,187},{0,172},{2,1},{0,231},
222 {0,245},{4,1},{2,1},{0,217},{0,157},{2,1},{0,95},{0,232},{30,1},{12,1},
223 {6,1},{2,1},{0,111},{2,1},{0,246},{0,203},{4,1},{2,1},{0,188},{0,173},
224 {0,218},{8,1},{2,1},{0,247},{4,1},{2,1},{0,126},{0,127},{0,142},{6,1},
225 {4,1},{2,1},{0,158},{0,174},{0,204},{2,1},{0,248},{0,143},{18,1},{8,1},
226 {4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{4,1},{2,1},{0,159},
227 {0,235},{2,1},{0,190},{2,1},{0,205},{0,250},{14,1},{4,1},{2,1},{0,221},
228 {0,236},{6,1},{4,1},{2,1},{0,233},{0,175},{0,220},{2,1},{0,206},{0,251},
229 {8,1},{4,1},{2,1},{0,191},{0,222},{2,1},{0,207},{0,238},{4,1},{2,1},
230 {0,223},{0,239},{2,1},{0,255},{2,1},{0,237},{2,1},{0,253},{2,1},{0,252},
231 {0,254},
232 };
233
234 private static int ValTab14[][] = {
235 {0,0} // dummy
236 };
237
238 private static int ValTab15[][] = {
239 {16,1},{6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},
240 {2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{50,1},{16,1},{6,1},{2,1},
241 {0,34},{2,1},{0,48},{0,49},{6,1},{2,1},{0,19},{2,1},{0,3},{0,64},
242 {2,1},{0,50},{0,35},{14,1},{6,1},{4,1},{2,1},{0,4},{0,20},{0,65},
243 {4,1},{2,1},{0,51},{0,66},{2,1},{0,36},{0,67},{10,1},{6,1},{2,1},
244 {0,52},{2,1},{0,80},{0,5},{2,1},{0,81},{0,21},{4,1},{2,1},{0,82},
245 {0,37},{4,1},{2,1},{0,68},{0,83},{0,97},{90,1},{36,1},{18,1},{10,1},
246 {6,1},{2,1},{0,53},{2,1},{0,96},{0,6},{2,1},{0,22},{0,98},{4,1},
247 {2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{10,1},{6,1},{2,1},{0,54},
248 {2,1},{0,112},{0,7},{2,1},{0,113},{0,85},{4,1},{2,1},{0,23},{0,100},
249 {2,1},{0,114},{0,39},{24,1},{16,1},{8,1},{4,1},{2,1},{0,70},{0,115},
250 {2,1},{0,55},{0,101},{4,1},{2,1},{0,86},{0,128},{2,1},{0,8},{0,116},
251 {4,1},{2,1},{0,129},{0,24},{2,1},{0,130},{0,40},{16,1},{8,1},{4,1},
252 {2,1},{0,71},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117},{0,87},
253 {2,1},{0,132},{0,72},{6,1},{4,1},{2,1},{0,144},{0,25},{0,145},{4,1},
254 {2,1},{0,146},{0,118},{2,1},{0,103},{0,41},{92,1},{36,1},{18,1},{10,1},
255 {4,1},{2,1},{0,133},{0,88},{4,1},{2,1},{0,9},{0,119},{0,147},{4,1},
256 {2,1},{0,57},{0,148},{2,1},{0,73},{0,134},{10,1},{6,1},{2,1},{0,104},
257 {2,1},{0,160},{0,10},{2,1},{0,161},{0,26},{4,1},{2,1},{0,162},{0,42},
258 {2,1},{0,149},{0,89},{26,1},{14,1},{6,1},{2,1},{0,163},{2,1},{0,58},
259 {0,135},{4,1},{2,1},{0,120},{0,164},{2,1},{0,74},{0,150},{6,1},{4,1},
260 {2,1},{0,105},{0,176},{0,177},{4,1},{2,1},{0,27},{0,165},{0,178},{14,1},
261 {8,1},{4,1},{2,1},{0,90},{0,43},{2,1},{0,136},{0,151},{2,1},{0,179},
262 {2,1},{0,121},{0,59},{8,1},{4,1},{2,1},{0,106},{0,180},{2,1},{0,75},
263 {0,193},{4,1},{2,1},{0,152},{0,137},{2,1},{0,28},{0,181},{80,1},{34,1},
264 {16,1},{6,1},{4,1},{2,1},{0,91},{0,44},{0,194},{6,1},{4,1},{2,1},
265 {0,11},{0,192},{0,166},{2,1},{0,167},{0,122},{10,1},{4,1},{2,1},{0,195},
266 {0,60},{4,1},{2,1},{0,12},{0,153},{0,182},{4,1},{2,1},{0,107},{0,196},
267 {2,1},{0,76},{0,168},{20,1},{10,1},{4,1},{2,1},{0,138},{0,197},{4,1},
268 {2,1},{0,208},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1},{0,29},
269 {2,1},{0,13},{0,45},{12,1},{4,1},{2,1},{0,210},{0,211},{4,1},{2,1},
270 {0,61},{0,198},{2,1},{0,108},{0,169},{6,1},{4,1},{2,1},{0,154},{0,184},
271 {0,212},{4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{68,1},{34,1},
272 {18,1},{10,1},{4,1},{2,1},{0,213},{0,93},{4,1},{2,1},{0,224},{0,14},
273 {0,225},{4,1},{2,1},{0,30},{0,226},{2,1},{0,170},{0,46},{8,1},{4,1},
274 {2,1},{0,185},{0,155},{2,1},{0,227},{0,214},{4,1},{2,1},{0,109},{0,62},
275 {2,1},{0,200},{0,140},{16,1},{8,1},{4,1},{2,1},{0,228},{0,78},{2,1},
276 {0,215},{0,125},{4,1},{2,1},{0,229},{0,186},{2,1},{0,171},{0,94},{8,1},
277 {4,1},{2,1},{0,201},{0,156},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1},
278 {0,240},{0,110},{0,242},{2,1},{0,47},{0,230},{38,1},{18,1},{8,1},{4,1},
279 {2,1},{0,216},{0,243},{2,1},{0,63},{0,244},{6,1},{2,1},{0,79},{2,1},
280 {0,141},{0,217},{2,1},{0,187},{0,202},{8,1},{4,1},{2,1},{0,172},{0,231},
281 {2,1},{0,126},{0,245},{8,1},{4,1},{2,1},{0,157},{0,95},{2,1},{0,232},
282 {0,142},{2,1},{0,246},{0,203},{34,1},{18,1},{10,1},{6,1},{4,1},{2,1},
283 {0,15},{0,174},{0,111},{2,1},{0,188},{0,218},{4,1},{2,1},{0,173},{0,247},
284 {2,1},{0,127},{0,233},{8,1},{4,1},{2,1},{0,158},{0,204},{2,1},{0,248},
285 {0,143},{4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{16,1},{8,1},
286 {4,1},{2,1},{0,159},{0,220},{2,1},{0,205},{0,235},{4,1},{2,1},{0,190},
287 {0,250},{2,1},{0,175},{0,221},{14,1},{6,1},{4,1},{2,1},{0,236},{0,206},
288 {0,251},{4,1},{2,1},{0,191},{0,237},{2,1},{0,222},{0,252},{6,1},{4,1},
289 {2,1},{0,207},{0,253},{0,238},{4,1},{2,1},{0,223},{0,254},{2,1},{0,239},
290 {0,255},
291 };
292
293 private static int ValTab16[][] = {
294 {2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{42,1},{8,1},
295 {4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{10,1},{6,1},{2,1},
296 {0,34},{2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{10,1},{4,1},{2,1},
297 {0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{6,1},{2,1},{0,20},
298 {2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1},{0,67},{0,52},
299 {138,1},{40,1},{16,1},{6,1},{4,1},{2,1},{0,5},{0,21},{0,81},{4,1},
300 {2,1},{0,82},{0,37},{4,1},{2,1},{0,68},{0,53},{0,83},{10,1},{6,1},
301 {4,1},{2,1},{0,96},{0,6},{0,97},{2,1},{0,22},{0,98},{8,1},{4,1},
302 {2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{4,1},{2,1},{0,54},{0,112},
303 {0,113},{40,1},{18,1},{8,1},{2,1},{0,23},{2,1},{0,7},{2,1},{0,85},
304 {0,100},{4,1},{2,1},{0,114},{0,39},{4,1},{2,1},{0,70},{0,101},{0,115},
305 {10,1},{6,1},{2,1},{0,55},{2,1},{0,86},{0,8},{2,1},{0,128},{0,129},
306 {6,1},{2,1},{0,24},{2,1},{0,116},{0,71},{2,1},{0,130},{2,1},{0,40},
307 {0,102},{24,1},{14,1},{8,1},{4,1},{2,1},{0,131},{0,56},{2,1},{0,117},
308 {0,132},{4,1},{2,1},{0,72},{0,144},{0,145},{6,1},{2,1},{0,25},{2,1},
309 {0,9},{0,118},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,133},
310 {0,88},{2,1},{0,147},{0,57},{4,1},{2,1},{0,160},{0,10},{0,26},{8,1},
311 {2,1},{0,162},{2,1},{0,103},{2,1},{0,87},{0,73},{6,1},{2,1},{0,148},
312 {2,1},{0,119},{0,134},{2,1},{0,161},{2,1},{0,104},{0,149},{220,1},{126,1},
313 {50,1},{26,1},{12,1},{6,1},{2,1},{0,42},{2,1},{0,89},{0,58},{2,1},
314 {0,163},{2,1},{0,135},{0,120},{8,1},{4,1},{2,1},{0,164},{0,74},{2,1},
315 {0,150},{0,105},{4,1},{2,1},{0,176},{0,11},{0,177},{10,1},{4,1},{2,1},
316 {0,27},{0,178},{2,1},{0,43},{2,1},{0,165},{0,90},{6,1},{2,1},{0,179},
317 {2,1},{0,166},{0,106},{4,1},{2,1},{0,180},{0,75},{2,1},{0,12},{0,193},
318 {30,1},{14,1},{6,1},{4,1},{2,1},{0,181},{0,194},{0,44},{4,1},{2,1},
319 {0,167},{0,195},{2,1},{0,107},{0,196},{8,1},{2,1},{0,29},{4,1},{2,1},
320 {0,136},{0,151},{0,59},{4,1},{2,1},{0,209},{0,210},{2,1},{0,45},{0,211},
321 {18,1},{6,1},{4,1},{2,1},{0,30},{0,46},{0,226},{6,1},{4,1},{2,1},
322 {0,121},{0,152},{0,192},{2,1},{0,28},{2,1},{0,137},{0,91},{14,1},{6,1},
323 {2,1},{0,60},{2,1},{0,122},{0,182},{4,1},{2,1},{0,76},{0,153},{2,1},
324 {0,168},{0,138},{6,1},{2,1},{0,13},{2,1},{0,197},{0,92},{4,1},{2,1},
325 {0,61},{0,198},{2,1},{0,108},{0,154},{88,1},{86,1},{36,1},{16,1},{8,1},
326 {4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{4,1},{2,1},{0,213},
327 {0,93},{2,1},{0,224},{0,14},{8,1},{2,1},{0,227},{4,1},{2,1},{0,208},
328 {0,183},{0,123},{6,1},{4,1},{2,1},{0,169},{0,184},{0,212},{2,1},{0,225},
329 {2,1},{0,170},{0,185},{24,1},{10,1},{6,1},{4,1},{2,1},{0,155},{0,214},
330 {0,109},{2,1},{0,62},{0,200},{6,1},{4,1},{2,1},{0,140},{0,228},{0,78},
331 {4,1},{2,1},{0,215},{0,229},{2,1},{0,186},{0,171},{12,1},{4,1},{2,1},
332 {0,156},{0,230},{4,1},{2,1},{0,110},{0,216},{2,1},{0,141},{0,187},{8,1},
333 {4,1},{2,1},{0,231},{0,157},{2,1},{0,232},{0,142},{4,1},{2,1},{0,203},
334 {0,188},{0,158},{0,241},{2,1},{0,31},{2,1},{0,15},{0,47},{66,1},{56,1},
335 {2,1},{0,242},{52,1},{50,1},{20,1},{8,1},{2,1},{0,189},{2,1},{0,94},
336 {2,1},{0,125},{0,201},{6,1},{2,1},{0,202},{2,1},{0,172},{0,126},{4,1},
337 {2,1},{0,218},{0,173},{0,204},{10,1},{6,1},{2,1},{0,174},{2,1},{0,219},
338 {0,220},{2,1},{0,205},{0,190},{6,1},{4,1},{2,1},{0,235},{0,237},{0,238},
339 {6,1},{4,1},{2,1},{0,217},{0,234},{0,233},{2,1},{0,222},{4,1},{2,1},
340 {0,221},{0,236},{0,206},{0,63},{0,240},{4,1},{2,1},{0,243},{0,244},{2,1},
341 {0,79},{2,1},{0,245},{0,95},{10,1},{2,1},{0,255},{4,1},{2,1},{0,246},
342 {0,111},{2,1},{0,247},{0,127},{12,1},{6,1},{2,1},{0,143},{2,1},{0,248},
343 {0,249},{4,1},{2,1},{0,159},{0,250},{0,175},{8,1},{4,1},{2,1},{0,251},
344 {0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1},{0,254},
345 {0,239},
346 };
347
348 private static int ValTab24[][] = {
349 {60,1},{8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{14,1},
350 {6,1},{4,1},{2,1},{0,32},{0,2},{0,33},{2,1},{0,18},{2,1},{0,34},
351 {2,1},{0,48},{0,3},{14,1},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},
352 {0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{8,1},{4,1},{2,1},
353 {0,20},{0,51},{2,1},{0,66},{0,36},{6,1},{4,1},{2,1},{0,67},{0,52},
354 {0,81},{6,1},{4,1},{2,1},{0,80},{0,5},{0,21},{2,1},{0,82},{0,37},
355 {250,1},{98,1},{34,1},{18,1},{10,1},{4,1},{2,1},{0,68},{0,83},{2,1},
356 {0,53},{2,1},{0,96},{0,6},{4,1},{2,1},{0,97},{0,22},{2,1},{0,98},
357 {0,38},{8,1},{4,1},{2,1},{0,84},{0,69},{2,1},{0,99},{0,54},{4,1},
358 {2,1},{0,113},{0,85},{2,1},{0,100},{0,70},{32,1},{14,1},{6,1},{2,1},
359 {0,114},{2,1},{0,39},{0,55},{2,1},{0,115},{4,1},{2,1},{0,112},{0,7},
360 {0,23},{10,1},{4,1},{2,1},{0,101},{0,86},{4,1},{2,1},{0,128},{0,8},
361 {0,129},{4,1},{2,1},{0,116},{0,71},{2,1},{0,24},{0,130},{16,1},{8,1},
362 {4,1},{2,1},{0,40},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117},
363 {0,87},{2,1},{0,132},{0,72},{8,1},{4,1},{2,1},{0,145},{0,25},{2,1},
364 {0,146},{0,118},{4,1},{2,1},{0,103},{0,41},{2,1},{0,133},{0,88},{92,1},
365 {34,1},{16,1},{8,1},{4,1},{2,1},{0,147},{0,57},{2,1},{0,148},{0,73},
366 {4,1},{2,1},{0,119},{0,134},{2,1},{0,104},{0,161},{8,1},{4,1},{2,1},
367 {0,162},{0,42},{2,1},{0,149},{0,89},{4,1},{2,1},{0,163},{0,58},{2,1},
368 {0,135},{2,1},{0,120},{0,74},{22,1},{12,1},{4,1},{2,1},{0,164},{0,150},
369 {4,1},{2,1},{0,105},{0,177},{2,1},{0,27},{0,165},{6,1},{2,1},{0,178},
370 {2,1},{0,90},{0,43},{2,1},{0,136},{0,179},{16,1},{10,1},{6,1},{2,1},
371 {0,144},{2,1},{0,9},{0,160},{2,1},{0,151},{0,121},{4,1},{2,1},{0,166},
372 {0,106},{0,180},{12,1},{6,1},{2,1},{0,26},{2,1},{0,10},{0,176},{2,1},
373 {0,59},{2,1},{0,11},{0,192},{4,1},{2,1},{0,75},{0,193},{2,1},{0,152},
374 {0,137},{67,1},{34,1},{16,1},{8,1},{4,1},{2,1},{0,28},{0,181},{2,1},
375 {0,91},{0,194},{4,1},{2,1},{0,44},{0,167},{2,1},{0,122},{0,195},{10,1},
376 {6,1},{2,1},{0,60},{2,1},{0,12},{0,208},{2,1},{0,182},{0,107},{4,1},
377 {2,1},{0,196},{0,76},{2,1},{0,153},{0,168},{16,1},{8,1},{4,1},{2,1},
378 {0,138},{0,197},{2,1},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1},
379 {0,29},{0,210},{9,1},{4,1},{2,1},{0,45},{0,211},{2,1},{0,61},{0,198},
380 {85,250},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212},{32,1},{16,1},
381 {8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1},
382 {0,124},{0,213},{2,1},{0,93},{0,225},{8,1},{4,1},{2,1},{0,30},{0,226},
383 {2,1},{0,170},{0,185},{4,1},{2,1},{0,155},{0,227},{2,1},{0,214},{0,109},
384 {20,1},{10,1},{6,1},{2,1},{0,62},{2,1},{0,46},{0,78},{2,1},{0,200},
385 {0,140},{4,1},{2,1},{0,228},{0,215},{4,1},{2,1},{0,125},{0,171},{0,229},
386 {10,1},{4,1},{2,1},{0,186},{0,94},{2,1},{0,201},{2,1},{0,156},{0,110},
387 {8,1},{2,1},{0,230},{2,1},{0,13},{2,1},{0,224},{0,14},{4,1},{2,1},
388 {0,216},{0,141},{2,1},{0,187},{0,202},{74,1},{2,1},{0,255},{64,1},{58,1},
389 {32,1},{16,1},{8,1},{4,1},{2,1},{0,172},{0,231},{2,1},{0,126},{0,217},
390 {4,1},{2,1},{0,157},{0,232},{2,1},{0,142},{0,203},{8,1},{4,1},{2,1},
391 {0,188},{0,218},{2,1},{0,173},{0,233},{4,1},{2,1},{0,158},{0,204},{2,1},
392 {0,219},{0,189},{16,1},{8,1},{4,1},{2,1},{0,234},{0,174},{2,1},{0,220},
393 {0,205},{4,1},{2,1},{0,235},{0,190},{2,1},{0,221},{0,236},{8,1},{4,1},
394 {2,1},{0,206},{0,237},{2,1},{0,222},{0,238},{0,15},{4,1},{2,1},{0,240},
395 {0,31},{0,241},{4,1},{2,1},{0,242},{0,47},{2,1},{0,243},{0,63},{18,1},
396 {8,1},{4,1},{2,1},{0,244},{0,79},{2,1},{0,245},{0,95},{4,1},{2,1},
397 {0,246},{0,111},{2,1},{0,247},{2,1},{0,127},{0,143},{10,1},{4,1},{2,1},
398 {0,248},{0,249},{4,1},{2,1},{0,159},{0,175},{0,250},{8,1},{4,1},{2,1},
399 {0,251},{0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1},
400 {0,254},{0,239},
401 };
402
403 private static int ValTab32[][] = {
404 {2,1},{0,0},{8,1},{4,1},{2,1},{0,8},{0,4},{2,1},{0,1},{0,2},
405 {8,1},{4,1},{2,1},{0,12},{0,10},{2,1},{0,3},{0,6},{6,1},{2,1},
406 {0,9},{2,1},{0,5},{0,7},{4,1},{2,1},{0,14},{0,13},{2,1},{0,15},
407 {0,11},
408 };
409
410 private static int ValTab33[][] = {
411 {16,1},{8,1},{4,1},{2,1},{0,0},{0,1},{2,1},{0,2},{0,3},{4,1},
412 {2,1},{0,4},{0,5},{2,1},{0,6},{0,7},{8,1},{4,1},{2,1},{0,8},
413 {0,9},{2,1},{0,10},{0,11},{4,1},{2,1},{0,12},{0,13},{2,1},{0,14},
414 {0,15},
415 };
416
417
418 public static huffcodetab[] ht = null; /* Simulate extern struct */
419
420 private static int[] bitbuf = new int[32];
421
422 /**
423 * Big Constructor : Computes all Huffman Tables.
424 */
425 private huffcodetab(String S,int XLEN, int YLEN, int LINBITS, int LINMAX, int REF,
426 int[] TABLE, int[] HLEN, int[][] VAL, int TREELEN)
427 {
428 tablename0 = S.charAt(0);
429 tablename1 = S.charAt(1);
430 tablename2 = S.charAt(2);
431 xlen = XLEN;
432 ylen = YLEN;
433 linbits = LINBITS;
434 linmax = LINMAX;
435 ref = REF;
436 table = TABLE;
437 hlen = HLEN;
438 val = VAL;
439 treelen = TREELEN;
440 }
441
442
443
444 /**
445 * Do the huffman-decoding.
446 * note! for counta,countb -the 4 bit value is returned in y,
447 * discard x.
448 */
449 public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br)
450 {
451 // array of all huffcodtable headers
452 // 0..31 Huffman code table 0..31
453 // 32,33 count1-tables
454
455 int dmask = 1 << ((4 * 8) - 1);
456 int hs = 4 * 8;
457 int level;
458 int point = 0;
459 int error = 1;
460 level = dmask;
461
462 if (h.val == null) return 2;
463
464 /* table 0 needs no bits */
465 if ( h.treelen == 0)
466 {
467 x[0] = y[0] = 0;
468 return 0;
469 }
470
471 /* Lookup in Huffman table. */
472
473 /*int bitsAvailable = 0;
474 int bitIndex = 0;
475
476 int bits[] = bitbuf;*/
477 do
478 {
479 if (h.val[point][0]==0)
480 { /*end of tree*/
481 x[0] = h.val[point][1] >>> 4;
482 y[0] = h.val[point][1] & 0xf;
483 error = 0;
484 break;
485 }
486
487 // hget1bit() is called thousands of times, and so needs to be
488 // ultra fast.
489 /*
490 if (bitIndex==bitsAvailable)
491 {
492 bitsAvailable = br.readBits(bits, 32);
493 bitIndex = 0;
494 }
495 */
496 //if (bits[bitIndex++]!=0)
497 if (br.hget1bit()!=0)
498 {
499 while (h.val[point][1] >= MXOFF) point += h.val[point][1];
500 point += h.val[point][1];
501 }
502 else
503 {
504 while (h.val[point][0] >= MXOFF) point += h.val[point][0];
505 point += h.val[point][0];
506 }
507 level >>>= 1;
508 // MDM: ht[0] is always 0;
509 } while ((level !=0 ) || (point < 0 /*ht[0].treelen*/) );
510
511 // put back any bits not consumed
512 /*
513 int unread = (bitsAvailable-bitIndex);
514 if (unread>0)
515 br.rewindNbits(unread);
516 */
517 /* Process sign encodings for quadruples tables. */
518 // System.out.println(h.tablename);
519 if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3'))
520 {
521 v[0] = (y[0]>>3) & 1;
522 w[0] = (y[0]>>2) & 1;
523 x[0] = (y[0]>>1) & 1;
524 y[0] = y[0] & 1;
525
526 /* v, w, x and y are reversed in the bitstream.
527 switch them around to make test bistream work. */
528
529 if (v[0]!=0)
530 if (br.hget1bit() != 0) v[0] = -v[0];
531 if (w[0]!=0)
532 if (br.hget1bit() != 0) w[0] = -w[0];
533 if (x[0]!=0)
534 if (br.hget1bit() != 0) x[0] = -x[0];
535 if (y[0]!=0)
536 if (br.hget1bit() != 0) y[0] = -y[0];
537 }
538 else
539 {
540 // Process sign and escape encodings for dual tables.
541 // x and y are reversed in the test bitstream.
542 // Reverse x and y here to make test bitstream work.
543
544 if (h.linbits != 0)
545 if ((h.xlen-1) == x[0])
546 x[0] += br.hgetbits(h.linbits);
547 if (x[0] != 0)
548 if (br.hget1bit() != 0) x[0] = -x[0];
549 if (h.linbits != 0)
550 if ((h.ylen-1) == y[0])
551 y[0] += br.hgetbits(h.linbits);
552 if (y[0] != 0)
553 if (br.hget1bit() != 0) y[0] = -y[0];
554 }
555 return error;
556 }
557
558 public static void inithuff()
559 {
560
561 if (ht!=null)
562 return;
563
564 ht = new huffcodetab[HTN];
565 ht[0] = new huffcodetab("0 ",0,0,0,0,-1,null,null,ValTab0,0);
566 ht[1] = new huffcodetab("1 ",2,2,0,0,-1,null,null,ValTab1,7);
567 ht[2] = new huffcodetab("2 ",3,3,0,0,-1,null,null,ValTab2,17);
568 ht[3] = new huffcodetab("3 ",3,3,0,0,-1,null,null,ValTab3,17);
569 ht[4] = new huffcodetab("4 ",0,0,0,0,-1,null,null,ValTab4,0);
570 ht[5] = new huffcodetab("5 ",4,4,0,0,-1,null,null,ValTab5,31);
571 ht[6] = new huffcodetab("6 ",4,4,0,0,-1,null,null,ValTab6,31);
572 ht[7] = new huffcodetab("7 ",6,6,0,0,-1,null,null,ValTab7,71);
573 ht[8] = new huffcodetab("8 ",6,6,0,0,-1,null,null,ValTab8,71);
574 ht[9] = new huffcodetab("9 ",6,6,0,0,-1,null,null,ValTab9,71);
575 ht[10] = new huffcodetab("10 ",8,8,0,0,-1,null,null,ValTab10,127);
576 ht[11] = new huffcodetab("11 ",8,8,0,0,-1,null,null,ValTab11,127);
577 ht[12] = new huffcodetab("12 ",8,8,0,0,-1,null,null,ValTab12,127);
578 ht[13] = new huffcodetab("13 ",16,16,0,0,-1,null,null,ValTab13,511);
579 ht[14] = new huffcodetab("14 ",0,0,0,0,-1,null,null,ValTab14,0);
580 ht[15] = new huffcodetab("15 ",16,16,0,0,-1,null,null,ValTab15,511);
581 ht[16] = new huffcodetab("16 ",16,16,1,1,-1,null,null,ValTab16,511);
582 ht[17] = new huffcodetab("17 ",16,16,2,3,16,null,null,ValTab16,511);
583 ht[18] = new huffcodetab("18 ",16,16,3,7,16,null,null,ValTab16,511);
584 ht[19] = new huffcodetab("19 ",16,16,4,15,16,null,null,ValTab16,511);
585 ht[20] = new huffcodetab("20 ",16,16,6,63,16,null,null,ValTab16,511);
586 ht[21] = new huffcodetab("21 ",16,16,8,255,16,null,null,ValTab16,511);
587 ht[22] = new huffcodetab("22 ",16,16,10,1023,16,null,null,ValTab16,511);
588 ht[23] = new huffcodetab("23 ",16,16,13,8191,16,null,null,ValTab16,511);
589 ht[24] = new huffcodetab("24 ",16,16,4,15,-1,null,null,ValTab24,512);
590 ht[25] = new huffcodetab("25 ",16,16,5,31,24,null,null,ValTab24,512);
591 ht[26] = new huffcodetab("26 ",16,16,6,63,24,null,null,ValTab24,512);
592 ht[27] = new huffcodetab("27 ",16,16,7,127,24,null,null,ValTab24,512);
593 ht[28] = new huffcodetab("28 ",16,16,8,255,24,null,null,ValTab24,512);
594 ht[29] = new huffcodetab("29 ",16,16,9,511,24,null,null,ValTab24,512);
595 ht[30] = new huffcodetab("30 ",16,16,11,2047,24,null,null,ValTab24,512);
596 ht[31] = new huffcodetab("31 ",16,16,13,8191,24,null,null,ValTab24,512);
597 ht[32] = new huffcodetab("32 ",1,16,0,0,-1,null,null,ValTab32,31);
598 ht[33] = new huffcodetab("33 ",1,16,0,0,-1,null,null,ValTab33,31);
599 }
600}
diff --git a/songdbj/javazoom/jl/decoder/l3reorder.ser b/songdbj/javazoom/jl/decoder/l3reorder.ser
new file mode 100644
index 0000000000..d7e3e0fa61
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/l3reorder.ser
Binary files differ
diff --git a/songdbj/javazoom/jl/decoder/lin2au.ser b/songdbj/javazoom/jl/decoder/lin2au.ser
new file mode 100644
index 0000000000..258231516e
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/lin2au.ser
Binary files differ
diff --git a/songdbj/javazoom/jl/decoder/readme.txt b/songdbj/javazoom/jl/decoder/readme.txt
new file mode 100644
index 0000000000..7a765ec7dc
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/readme.txt
@@ -0,0 +1,15 @@
1
2TODO:
3
4
5Implement high-level Player and Converter classes.
6
7Add MP1 and MP2 support and test.
8
9Add option to run each "stage" on own thread.
10E.g. read & parse input, decode subbands, subband synthesis, audio output.
11
12Retrofit seek support (temporarily removed when reworking classes.)
13
14
15Document and give example code. \ No newline at end of file
diff --git a/songdbj/javazoom/jl/decoder/sfd.ser b/songdbj/javazoom/jl/decoder/sfd.ser
new file mode 100644
index 0000000000..e65b782f36
--- /dev/null
+++ b/songdbj/javazoom/jl/decoder/sfd.ser
Binary files differ
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23import javazoom.jl.decoder.Decoder;
24import javazoom.jl.decoder.JavaLayerException;
25
26/**
27 * The <code>AudioDevice</code> interface provides an abstraction for
28 * a device capable of sounding audio samples. Samples are written to
29 * the device wia the write() method. The device assumes
30 * that these samples are signed 16-bit samples taken at the output frequency
31 * of the decoder. If the decoder outputs more than one channel, the samples for
32 * each channel are assumed to appear consecutively, with the lower numbered
33 * channels preceeding higher-numbered channels. E.g. if there are two
34 * channels, the samples will appear in this order:
35 * <pre><code>
36 *
37 * l0, r0, l1, r1, l2, r2...
38 *
39 * where
40 * l<i>x</i> indicates the <i>x</i>th sample on channel 0
41 * r<i>x</i> indicates the <i>x</i>th sample on channel 1
42 * </code></pre>
43 *
44 * @since 0.0.8
45 * @author Mat McGowan
46 */
47public interface AudioDevice
48{
49 /**
50 * Prepares the AudioDevice for playback of audio samples.
51 * @param decoder The decoder that will be providing the audio
52 * samples.
53 *
54 * If the audio device is already open, this method returns silently.
55 *
56 */
57 public void open(Decoder decoder) throws JavaLayerException;
58
59 /**
60 * Retrieves the open state of this audio device.
61 *
62 * @return <code>true</code> if this audio device is open and playing
63 * audio samples, or <code>false</code> otherwise.
64 */
65 public boolean isOpen();
66
67 /**
68 * Writes a number of samples to this <code>AudioDevice</code>.
69 *
70 * @param samples The array of signed 16-bit samples to write
71 * to the audio device.
72 * @param offs The offset of the first sample.
73 * @param len The number of samples to write.
74 *
75 * This method may return prior to the samples actually being played
76 * by the audio device.
77 */
78 public void write(short[] samples, int offs, int len) throws JavaLayerException;
79
80
81 /**
82 * Closes this audio device. Any currently playing audio is stopped
83 * as soon as possible. Any previously written audio data that has not been heard
84 * is discarded.
85 *
86 * The implementation should ensure that any threads currently blocking
87 * on the device (e.g. during a <code>write</code> or <code>flush</code>
88 * operation should be unblocked by this method.
89 */
90 public void close();
91
92
93 /**
94 * Blocks until all audio samples previously written to this audio device have
95 * been heard.
96 */
97 public void flush();
98
99 /**
100 * Retrieves the current playback position in milliseconds.
101 */
102 public int getPosition();
103}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23import javazoom.jl.decoder.Decoder;
24import javazoom.jl.decoder.JavaLayerException;
25
26/**
27 * The <code>AudioDeviceBase</code> class provides a simple thread-safe
28 * implementation of the <code>AudioDevice</code> interface.
29 * Template methods are provided for subclasses to override and
30 * in doing so provide the implementation for the main operations
31 * of the <code>AudioDevice</code> interface.
32 *
33 * @since 0.0.8
34 * @author Mat McGowan
35 */
36/*
37 * REVIEW: It is desirable to be able to use the decoder whe
38 * in the implementation of open(), but the decoder
39 * has not yet read a frame, and so much of the
40 * desired information (sample rate, channels etc.)
41 * are not available.
42 */
43public abstract class AudioDeviceBase implements AudioDevice
44{
45 private boolean open = false;
46
47 private Decoder decoder = null;
48
49 /**
50 * Opens this audio device.
51 *
52 * @param decoder The decoder that will provide audio data
53 * to this audio device.
54 */
55 public synchronized void open(Decoder decoder) throws JavaLayerException
56 {
57 if (!isOpen())
58 {
59 this.decoder = decoder;
60 openImpl();
61 setOpen(true);
62 }
63 }
64
65 /**
66 * Template method to provide the
67 * implementation for the opening of the audio device.
68 */
69 protected void openImpl() throws JavaLayerException
70 {
71 }
72
73 /**
74 * Sets the open state for this audio device.
75 */
76 protected void setOpen(boolean open)
77 {
78 this.open = open;
79 }
80
81 /**
82 * Determines if this audio device is open or not.
83 *
84 * @return <code>true</code> if the audio device is open,
85 * <code>false</code> if it is not.
86 */
87 public synchronized boolean isOpen()
88 {
89 return open;
90 }
91
92 /**
93 * Closes this audio device. If the device is currently playing
94 * audio, playback is stopped immediately without flushing
95 * any buffered audio data.
96 */
97 public synchronized void close()
98 {
99 if (isOpen())
100 {
101 closeImpl();
102 setOpen(false);
103 decoder = null;
104 }
105 }
106
107 /**
108 * Template method to provide the implementation for
109 * closing the audio device.
110 */
111 protected void closeImpl()
112 {
113 }
114
115 /**
116 * Writes audio data to this audio device. Audio data is
117 * assumed to be in the output format of the decoder. This
118 * method may return before the data has actually been sounded
119 * by the device if the device buffers audio samples.
120 *
121 * @param samples The samples to write to the audio device.
122 * @param offs The offset into the array of the first sample to write.
123 * @param len The number of samples from the array to write.
124 * @throws JavaLayerException if the audio data could not be
125 * written to the audio device.
126 * If the audio device is not open, this method does nthing.
127 */
128 public void write(short[] samples, int offs, int len)
129 throws JavaLayerException
130 {
131 if (isOpen())
132 {
133 writeImpl(samples, offs, len);
134 }
135 }
136
137 /**
138 * Template method to provide the implementation for
139 * writing audio samples to the audio device.
140 */
141 protected void writeImpl(short[] samples, int offs, int len)
142 throws JavaLayerException
143 {
144 }
145
146 /**
147 * Waits for any buffered audio samples to be played by the
148 * audio device. This method should only be called prior
149 * to closing the device.
150 */
151 public void flush()
152 {
153 if (isOpen())
154 {
155 flushImpl();
156 }
157 }
158
159 /**
160 * Template method to provide the implementation for
161 * flushing any buffered audio data.
162 */
163 protected void flushImpl()
164 {
165 }
166
167 /**
168 * Retrieves the decoder that provides audio data to this
169 * audio device.
170 *
171 * @return The associated decoder.
172 */
173 protected Decoder getDecoder()
174 {
175 return decoder;
176 }
177}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23import javazoom.jl.decoder.JavaLayerException;
24
25/**
26 * An <code>AudioDeviceFactory</code> class is responsible for creating
27 * a specific <code>AudioDevice</code> implementation. A factory implementation
28 * can be as simple or complex as desired and may support just one implementation
29 * or may return several implementations depending upon the execution
30 * environment.
31 * <p>
32 * When implementing a factory that provides an AudioDevice that uses
33 * class that may not be present, the factory should dynamically link to any
34 * specific implementation classes required to instantiate or test the audio
35 * implementation. This is so that the application as a whole
36 * can run without these classes being present. The audio
37 * device implementation, however, will usually statically link to the classes
38 * required. (See the JavaSound deivce and factory for an example
39 * of this.)
40 *
41 * @see FactoryRegistry
42 *
43 * @since 0.0.8
44 * @author Mat McGowan
45 */
46public abstract class AudioDeviceFactory
47{
48 /**
49 * Creates a new <code>AudioDevice</code>.
50 *
51 * @return a new instance of a specific class of <code>AudioDevice</code>.
52 * @throws JavaLayerException if an instance of AudioDevice could not
53 * be created.
54 */
55 public abstract AudioDevice createAudioDevice() throws JavaLayerException;
56
57 /**
58 * Creates an instance of an AudioDevice implementation.
59 * @param loader The <code>ClassLoader</code> to use to
60 * load the named class, or null to use the
61 * system class loader.
62 * @param name The name of the class to load.
63 * @return A newly-created instance of the audio device class.
64 */
65 protected AudioDevice instantiate(ClassLoader loader, String name)
66 throws ClassNotFoundException,
67 IllegalAccessException,
68 InstantiationException
69 {
70 AudioDevice dev = null;
71
72 Class cls = null;
73 if (loader==null)
74 {
75 cls = Class.forName(name);
76 }
77 else
78 {
79 cls = loader.loadClass(name);
80 }
81
82 Object o = cls.newInstance();
83 dev = (AudioDevice)o;
84
85 return dev;
86 }
87}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23import java.util.Enumeration;
24import java.util.Hashtable;
25
26import javazoom.jl.decoder.JavaLayerException;
27
28/**
29 * The <code>FactoryRegistry</code> class stores the factories
30 * for all the audio device implementations available in the system.
31 * <p>
32 * Instances of this class are thread-safe.
33 *
34 * @since 0.0.8
35 * @author Mat McGowan
36 */
37
38public class FactoryRegistry extends AudioDeviceFactory
39{
40 static private FactoryRegistry instance = null;
41
42 static synchronized public FactoryRegistry systemRegistry()
43 {
44 if (instance==null)
45 {
46 instance = new FactoryRegistry();
47 instance.registerDefaultFactories();
48 }
49 return instance;
50 }
51
52
53 protected Hashtable factories = new Hashtable();
54
55 /**
56 * Registers an <code>AudioDeviceFactory</code> instance
57 * with this registry.
58 */
59 public void addFactory(AudioDeviceFactory factory)
60 {
61 factories.put(factory.getClass(), factory);
62 }
63
64 public void removeFactoryType(Class cls)
65 {
66 factories.remove(cls);
67 }
68
69 public void removeFactory(AudioDeviceFactory factory)
70 {
71 factories.remove(factory.getClass());
72 }
73
74 public AudioDevice createAudioDevice() throws JavaLayerException
75 {
76 AudioDevice device = null;
77 AudioDeviceFactory[] factories = getFactoriesPriority();
78
79 if (factories==null)
80 throw new JavaLayerException(this+": no factories registered");
81
82 JavaLayerException lastEx = null;
83 for (int i=0; (device==null) && (i<factories.length); i++)
84 {
85 try
86 {
87 device = factories[i].createAudioDevice();
88 }
89 catch (JavaLayerException ex)
90 {
91 lastEx = ex;
92 }
93 }
94
95 if (device==null && lastEx!=null)
96 {
97 throw new JavaLayerException("Cannot create AudioDevice", lastEx);
98 }
99
100 return device;
101 }
102
103
104 protected AudioDeviceFactory[] getFactoriesPriority()
105 {
106 AudioDeviceFactory[] fa = null;
107 synchronized (factories)
108 {
109 int size = factories.size();
110 if (size!=0)
111 {
112 fa = new AudioDeviceFactory[size];
113 int idx = 0;
114 Enumeration e = factories.elements();
115 while (e.hasMoreElements())
116 {
117 AudioDeviceFactory factory = (AudioDeviceFactory)e.nextElement();
118 fa[idx++] = factory;
119 }
120 }
121 }
122 return fa;
123 }
124
125 protected void registerDefaultFactories()
126 {
127 addFactory(new JavaSoundAudioDeviceFactory());
128 }
129}
diff --git a/songdbj/javazoom/jl/player/JavaSoundAudioDevice.java b/songdbj/javazoom/jl/player/JavaSoundAudioDevice.java
new file mode 100644
index 0000000000..caa92cd6fc
--- /dev/null
+++ b/songdbj/javazoom/jl/player/JavaSoundAudioDevice.java
@@ -0,0 +1,215 @@
1/*
2 * 11/26/04 Buffer size modified to support JRE 1.5 optimizations.
3 * (CPU usage < 1% under P4/2Ghz, RAM < 12MB).
4 * jlayer@javazoom.net
5 * 11/19/04 1.0 moved to LGPL.
6 * 06/04/01 Too fast playback fixed. mdm@techie.com
7 * 29/01/00 Initial version. mdm@techie.com
8 *-----------------------------------------------------------------------
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *----------------------------------------------------------------------
23 */
24
25package javazoom.jl.player;
26
27import javax.sound.sampled.AudioFormat;
28import javax.sound.sampled.AudioSystem;
29import javax.sound.sampled.DataLine;
30import javax.sound.sampled.Line;
31import javax.sound.sampled.LineUnavailableException;
32import javax.sound.sampled.SourceDataLine;
33
34import javazoom.jl.decoder.Decoder;
35import javazoom.jl.decoder.JavaLayerException;
36
37/**
38 * The <code>JavaSoundAudioDevice</code> implements an audio
39 * device by using the JavaSound API.
40 *
41 * @since 0.0.8
42 * @author Mat McGowan
43 */
44public class JavaSoundAudioDevice extends AudioDeviceBase
45{
46 private SourceDataLine source = null;
47
48 private AudioFormat fmt = null;
49
50 private byte[] byteBuf = new byte[4096];
51
52 protected void setAudioFormat(AudioFormat fmt0)
53 {
54 fmt = fmt0;
55 }
56
57 protected AudioFormat getAudioFormat()
58 {
59 if (fmt==null)
60 {
61 Decoder decoder = getDecoder();
62 fmt = new AudioFormat(decoder.getOutputFrequency(),
63 16,
64 decoder.getOutputChannels(),
65 true,
66 false);
67 }
68 return fmt;
69 }
70
71 protected DataLine.Info getSourceLineInfo()
72 {
73 AudioFormat fmt = getAudioFormat();
74 //DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt, 4000);
75 DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt);
76 return info;
77 }
78
79 public void open(AudioFormat fmt) throws JavaLayerException
80 {
81 if (!isOpen())
82 {
83 setAudioFormat(fmt);
84 openImpl();
85 setOpen(true);
86 }
87 }
88
89 protected void openImpl()
90 throws JavaLayerException
91 {
92 }
93
94
95 // createSource fix.
96 protected void createSource() throws JavaLayerException
97 {
98 Throwable t = null;
99 try
100 {
101 Line line = AudioSystem.getLine(getSourceLineInfo());
102 if (line instanceof SourceDataLine)
103 {
104 source = (SourceDataLine)line;
105 //source.open(fmt, millisecondsToBytes(fmt, 2000));
106 source.open(fmt);
107 /*
108 if (source.isControlSupported(FloatControl.Type.MASTER_GAIN))
109 {
110 FloatControl c = (FloatControl)source.getControl(FloatControl.Type.MASTER_GAIN);
111 c.setValue(c.getMaximum());
112 }*/
113 source.start();
114
115 }
116 } catch (RuntimeException ex)
117 {
118 t = ex;
119 }
120 catch (LinkageError ex)
121 {
122 t = ex;
123 }
124 catch (LineUnavailableException ex)
125 {
126 t = ex;
127 }
128 if (source==null) throw new JavaLayerException("cannot obtain source audio line", t);
129 }
130
131 public int millisecondsToBytes(AudioFormat fmt, int time)
132 {
133 return (int)(time*(fmt.getSampleRate()*fmt.getChannels()*fmt.getSampleSizeInBits())/8000.0);
134 }
135
136 protected void closeImpl()
137 {
138 if (source!=null)
139 {
140 source.close();
141 }
142 }
143
144 protected void writeImpl(short[] samples, int offs, int len)
145 throws JavaLayerException
146 {
147 if (source==null)
148 createSource();
149
150 byte[] b = toByteArray(samples, offs, len);
151 source.write(b, 0, len*2);
152 }
153
154 protected byte[] getByteArray(int length)
155 {
156 if (byteBuf.length < length)
157 {
158 byteBuf = new byte[length+1024];
159 }
160 return byteBuf;
161 }
162
163 protected byte[] toByteArray(short[] samples, int offs, int len)
164 {
165 byte[] b = getByteArray(len*2);
166 int idx = 0;
167 short s;
168 while (len-- > 0)
169 {
170 s = samples[offs++];
171 b[idx++] = (byte)s;
172 b[idx++] = (byte)(s>>>8);
173 }
174 return b;
175 }
176
177 protected void flushImpl()
178 {
179 if (source!=null)
180 {
181 source.drain();
182 }
183 }
184
185 public int getPosition()
186 {
187 int pos = 0;
188 if (source!=null)
189 {
190 pos = (int)(source.getMicrosecondPosition()/1000);
191 }
192 return pos;
193 }
194
195 /**
196 * Runs a short test by playing a short silent sound.
197 */
198 public void test()
199 throws JavaLayerException
200 {
201 try
202 {
203 open(new AudioFormat(22050, 16, 1, true, false));
204 short[] data = new short[22050/10];
205 write(data, 0, data.length);
206 flush();
207 close();
208 }
209 catch (RuntimeException ex)
210 {
211 throw new JavaLayerException("Device test failed: "+ex);
212 }
213
214 }
215}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23import javazoom.jl.decoder.JavaLayerException;
24
25/**
26 * This class is responsible for creating instances of the
27 * JavaSoundAudioDevice. The audio device implementation is loaded
28 * and tested dynamically as not all systems will have support
29 * for JavaSound, or they may have the incorrect version.
30 */
31public class JavaSoundAudioDeviceFactory extends AudioDeviceFactory
32{
33 private boolean tested = false;
34
35 static private final String DEVICE_CLASS_NAME = "javazoom.jl.player.JavaSoundAudioDevice";
36
37 public synchronized AudioDevice createAudioDevice()
38 throws JavaLayerException
39 {
40 if (!tested)
41 {
42 testAudioDevice();
43 tested = true;
44 }
45
46 try
47 {
48 return createAudioDeviceImpl();
49 }
50 catch (Exception ex)
51 {
52 throw new JavaLayerException("unable to create JavaSound device: "+ex);
53 }
54 catch (LinkageError ex)
55 {
56 throw new JavaLayerException("unable to create JavaSound device: "+ex);
57 }
58 }
59
60 protected JavaSoundAudioDevice createAudioDeviceImpl()
61 throws JavaLayerException
62 {
63 ClassLoader loader = getClass().getClassLoader();
64 try
65 {
66 JavaSoundAudioDevice dev = (JavaSoundAudioDevice)instantiate(loader, DEVICE_CLASS_NAME);
67 return dev;
68 }
69 catch (Exception ex)
70 {
71 throw new JavaLayerException("Cannot create JavaSound device", ex);
72 }
73 catch (LinkageError ex)
74 {
75 throw new JavaLayerException("Cannot create JavaSound device", ex);
76 }
77
78 }
79
80 public void testAudioDevice() throws JavaLayerException
81 {
82 JavaSoundAudioDevice dev = createAudioDeviceImpl();
83 dev.test();
84 }
85}
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 @@
1/*
2 * 11/19/04 1.0 moved o LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23/**
24 * The <code>NullAudioDevice</code> implements a silent, no-op
25 * audio device. This is useful for testing purposes.
26 *
27 * @since 0.0.8
28 * @author Mat McGowan
29 */
30public class NullAudioDevice extends AudioDeviceBase
31{
32
33 public int getPosition()
34 {
35 return 0;
36 }
37}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23import java.io.InputStream;
24
25import javazoom.jl.decoder.Bitstream;
26import javazoom.jl.decoder.BitstreamException;
27import javazoom.jl.decoder.Decoder;
28import javazoom.jl.decoder.Header;
29import javazoom.jl.decoder.JavaLayerException;
30import javazoom.jl.decoder.SampleBuffer;
31
32/**
33 * The <code>Player</code> class implements a simple player for playback
34 * of an MPEG audio stream.
35 *
36 * @author Mat McGowan
37 * @since 0.0.8
38 */
39
40// REVIEW: the audio device should not be opened until the
41// first MPEG audio frame has been decoded.
42public class Player
43{
44 /**
45 * The current frame number.
46 */
47 private int frame = 0;
48
49 /**
50 * The MPEG audio bitstream.
51 */
52 // javac blank final bug.
53 /*final*/ private Bitstream bitstream;
54
55 /**
56 * The MPEG audio decoder.
57 */
58 /*final*/ private Decoder decoder;
59
60 /**
61 * The AudioDevice the audio samples are written to.
62 */
63 private AudioDevice audio;
64
65 /**
66 * Has the player been closed?
67 */
68 private boolean closed = false;
69
70 /**
71 * Has the player played back all frames from the stream?
72 */
73 private boolean complete = false;
74
75 private int lastPosition = 0;
76
77 /**
78 * Creates a new <code>Player</code> instance.
79 */
80 public Player(InputStream stream) throws JavaLayerException
81 {
82 this(stream, null);
83 }
84
85 public Player(InputStream stream, AudioDevice device) throws JavaLayerException
86 {
87 bitstream = new Bitstream(stream);
88 decoder = new Decoder();
89
90 if (device!=null)
91 {
92 audio = device;
93 }
94 else
95 {
96 FactoryRegistry r = FactoryRegistry.systemRegistry();
97 audio = r.createAudioDevice();
98 }
99 audio.open(decoder);
100 }
101
102 public void play() throws JavaLayerException
103 {
104 play(Integer.MAX_VALUE);
105 }
106
107 /**
108 * Plays a number of MPEG audio frames.
109 *
110 * @param frames The number of frames to play.
111 * @return true if the last frame was played, or false if there are
112 * more frames.
113 */
114 public boolean play(int frames) throws JavaLayerException
115 {
116 boolean ret = true;
117
118 while (frames-- > 0 && ret)
119 {
120 ret = decodeFrame();
121 }
122
123 if (!ret)
124 {
125 // last frame, ensure all data flushed to the audio device.
126 AudioDevice out = audio;
127 if (out!=null)
128 {
129 out.flush();
130 synchronized (this)
131 {
132 complete = (!closed);
133 close();
134 }
135 }
136 }
137 return ret;
138 }
139
140 /**
141 * Cloases this player. Any audio currently playing is stopped
142 * immediately.
143 */
144 public synchronized void close()
145 {
146 AudioDevice out = audio;
147 if (out!=null)
148 {
149 closed = true;
150 audio = null;
151 // this may fail, so ensure object state is set up before
152 // calling this method.
153 out.close();
154 lastPosition = out.getPosition();
155 try
156 {
157 bitstream.close();
158 }
159 catch (BitstreamException ex)
160 {
161 }
162 }
163 }
164
165 /**
166 * Returns the completed status of this player.
167 *
168 * @return true if all available MPEG audio frames have been
169 * decoded, or false otherwise.
170 */
171 public synchronized boolean isComplete()
172 {
173 return complete;
174 }
175
176 /**
177 * Retrieves the position in milliseconds of the current audio
178 * sample being played. This method delegates to the <code>
179 * AudioDevice</code> that is used by this player to sound
180 * the decoded audio samples.
181 */
182 public int getPosition()
183 {
184 int position = lastPosition;
185
186 AudioDevice out = audio;
187 if (out!=null)
188 {
189 position = out.getPosition();
190 }
191 return position;
192 }
193
194 /**
195 * Decodes a single frame.
196 *
197 * @return true if there are no more frames to decode, false otherwise.
198 */
199 protected boolean decodeFrame() throws JavaLayerException
200 {
201 try
202 {
203 AudioDevice out = audio;
204 if (out==null)
205 return false;
206
207 Header h = bitstream.readFrame();
208
209 if (h==null)
210 return false;
211
212 // sample buffer set when decoder constructed
213 SampleBuffer output = (SampleBuffer)decoder.decodeFrame(h, bitstream);
214
215 synchronized (this)
216 {
217 out = audio;
218 if (out!=null)
219 {
220 out.write(output.getBuffer(), 0, output.getBufferLength());
221 }
222 }
223
224 bitstream.closeFrame();
225 }
226 catch (RuntimeException ex)
227 {
228 throw new JavaLayerException("Exception decoding audio frame", ex);
229 }
230/*
231 catch (IOException ex)
232 {
233 System.out.println("exception decoding audio frame: "+ex);
234 return false;
235 }
236 catch (BitstreamException bitex)
237 {
238 System.out.println("exception decoding audio frame: "+bitex);
239 return false;
240 }
241 catch (DecoderException decex)
242 {
243 System.out.println("exception decoding audio frame: "+decex);
244 return false;
245 }
246*/
247 return true;
248 }
249
250
251}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 * 29/01/00 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
21package javazoom.jl.player;
22
23import java.applet.Applet;
24import java.io.IOException;
25import java.io.InputStream;
26import java.net.URL;
27
28import javazoom.jl.decoder.JavaLayerException;
29
30/**
31 * A simple applet that plays an MPEG audio file.
32 * The URL (relative to the document base)
33 * is passed as the "audioURL" parameter.
34 *
35 * @author Mat McGowan
36 * @since 0.0.8
37 */
38public class PlayerApplet extends Applet implements Runnable
39{
40 static public final String AUDIO_PARAMETER = "audioURL";
41
42 /**
43 * The Player used to play the MPEG audio file.
44 */
45 private Player player = null;
46
47 /**
48 * The thread that runs the player.
49 */
50 private Thread playerThread = null;
51
52 private String fileName = null;
53
54
55 /**
56 * Retrieves the <code>AudioDevice</code> instance that will
57 * be used to sound the audio data.
58 *
59 * @return an audio device instance that will be used to
60 * sound the audio stream.
61 */
62 protected AudioDevice getAudioDevice() throws JavaLayerException
63 {
64 return FactoryRegistry.systemRegistry().createAudioDevice();
65 }
66
67 /**
68 * Retrieves the InputStream that provides the MPEG audio
69 * stream data.
70 *
71 * @return an InputStream from which the MPEG audio data
72 * is read, or null if an error occurs.
73 */
74 protected InputStream getAudioStream()
75 {
76 InputStream in = null;
77
78 try
79 {
80 URL url = getAudioURL();
81 if (url!=null)
82 in = url.openStream();
83 }
84 catch (IOException ex)
85 {
86 System.err.println(ex);
87 }
88 return in;
89 }
90
91 protected String getAudioFileName()
92 {
93 String urlString = fileName;
94 if (urlString==null)
95 {
96 urlString = getParameter(AUDIO_PARAMETER);
97 }
98 return urlString;
99 }
100
101 protected URL getAudioURL()
102 {
103 String urlString = getAudioFileName();
104 URL url = null;
105 if (urlString!=null)
106 {
107 try
108 {
109 url = new URL(getDocumentBase(), urlString);
110 }
111 catch (Exception ex)
112 {
113 System.err.println(ex);
114 }
115 }
116 return url;
117 }
118
119 /**
120 * Sets the URL of the audio stream to play.
121 */
122 public void setFileName(String name)
123 {
124 fileName = name;
125 }
126
127 public String getFileName()
128 {
129 return fileName;
130 }
131
132 /**
133 * Stops the audio player. If the player is already stopped
134 * this method is a no-op.
135 */
136 protected void stopPlayer() throws JavaLayerException
137 {
138 if (player!=null)
139 {
140 player.close();
141 player = null;
142 playerThread = null;
143 }
144 }
145
146 /**
147 * Decompresses audio data from an InputStream and plays it
148 * back through an AudioDevice. The playback is run on a newly
149 * created thread.
150 *
151 * @param in The InputStream that provides the MPEG audio data.
152 * @param dev The AudioDevice to use to sound the decompressed data.
153 *
154 * @throws JavaLayerException if there was a problem decoding
155 * or playing the audio data.
156 */
157 protected void play(InputStream in, AudioDevice dev) throws JavaLayerException
158 {
159 stopPlayer();
160
161 if (in!=null && dev!=null)
162 {
163 player = new Player(in, dev);
164 playerThread = createPlayerThread();
165 playerThread.start();
166 }
167 }
168
169 /**
170 * Creates a new thread used to run the audio player.
171 * @return A new Thread that, once started, runs the audio player.
172 */
173 protected Thread createPlayerThread()
174 {
175 return new Thread(this, "Audio player thread");
176 }
177
178 /**
179 * Initializes this applet.
180 */
181 public void init()
182 {
183 }
184
185 /**
186 * Starts this applet. An input stream and audio device
187 * are created and passed to the play() method.
188 */
189 public void start()
190 {
191 String name = getAudioFileName();
192 try
193 {
194 InputStream in = getAudioStream();
195 AudioDevice dev = getAudioDevice();
196 play(in, dev);
197 }
198 catch (JavaLayerException ex)
199 {
200 synchronized (System.err)
201 {
202 System.err.println("Unable to play "+name);
203 ex.printStackTrace(System.err);
204 }
205 }
206 }
207
208 /**
209 * Stops this applet. If audio is currently playing, it is
210 * stopped.
211 */
212 public void stop()
213 {
214 try
215 {
216 stopPlayer();
217 }
218 catch (JavaLayerException ex)
219 {
220 System.err.println(ex);
221 }
222 }
223
224 public void destroy()
225 {
226 }
227
228 /**
229 * The run method for the audio player thread. Simply calls
230 * play() on the player to play the entire stream.
231 */
232 public void run()
233 {
234 if (player!=null)
235 {
236 try
237 {
238 player.play();
239 }
240 catch (JavaLayerException ex)
241 {
242 System.err.println("Problem playing audio: "+ex);
243 }
244 }
245 }
246}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.player.advanced;
21
22import java.io.InputStream;
23
24import javazoom.jl.decoder.Bitstream;
25import javazoom.jl.decoder.BitstreamException;
26import javazoom.jl.decoder.Decoder;
27import javazoom.jl.decoder.Header;
28import javazoom.jl.decoder.JavaLayerException;
29import javazoom.jl.decoder.SampleBuffer;
30import javazoom.jl.player.AudioDevice;
31import javazoom.jl.player.FactoryRegistry;
32
33/**
34 * a hybrid of javazoom.jl.player.Player tweeked to include <code>play(startFrame, endFrame)</code>
35 * hopefully this will be included in the api
36 */
37public class AdvancedPlayer
38{
39 /** The MPEG audio bitstream.*/
40 private Bitstream bitstream;
41 /** The MPEG audio decoder. */
42 private Decoder decoder;
43 /** The AudioDevice the audio samples are written to. */
44 private AudioDevice audio;
45 /** Has the player been closed? */
46 private boolean closed = false;
47 /** Has the player played back all frames from the stream? */
48 private boolean complete = false;
49 private int lastPosition = 0;
50 /** Listener for the playback process */
51 private PlaybackListener listener;
52
53 /**
54 * Creates a new <code>Player</code> instance.
55 */
56 public AdvancedPlayer(InputStream stream) throws JavaLayerException
57 {
58 this(stream, null);
59 }
60
61 public AdvancedPlayer(InputStream stream, AudioDevice device) throws JavaLayerException
62 {
63 bitstream = new Bitstream(stream);
64
65 if (device!=null) audio = device;
66 else audio = FactoryRegistry.systemRegistry().createAudioDevice();
67 audio.open(decoder = new Decoder());
68 }
69
70 public void play() throws JavaLayerException
71 {
72 play(Integer.MAX_VALUE);
73 }
74
75 /**
76 * Plays a number of MPEG audio frames.
77 *
78 * @param frames The number of frames to play.
79 * @return true if the last frame was played, or false if there are
80 * more frames.
81 */
82 public boolean play(int frames) throws JavaLayerException
83 {
84 boolean ret = true;
85
86 // report to listener
87 if(listener != null) listener.playbackStarted(createEvent(PlaybackEvent.STARTED));
88
89 while (frames-- > 0 && ret)
90 {
91 ret = decodeFrame();
92 }
93
94// if (!ret)
95 {
96 // last frame, ensure all data flushed to the audio device.
97 AudioDevice out = audio;
98 if (out != null)
99 {
100// System.out.println(audio.getPosition());
101 out.flush();
102// System.out.println(audio.getPosition());
103 synchronized (this)
104 {
105 complete = (!closed);
106 close();
107 }
108
109 // report to listener
110 if(listener != null) listener.playbackFinished(createEvent(out, PlaybackEvent.STOPPED));
111 }
112 }
113 return ret;
114 }
115
116 /**
117 * Cloases this player. Any audio currently playing is stopped
118 * immediately.
119 */
120 public synchronized void close()
121 {
122 AudioDevice out = audio;
123 if (out != null)
124 {
125 closed = true;
126 audio = null;
127 // this may fail, so ensure object state is set up before
128 // calling this method.
129 out.close();
130 lastPosition = out.getPosition();
131 try
132 {
133 bitstream.close();
134 }
135 catch (BitstreamException ex)
136 {}
137 }
138 }
139
140 /**
141 * Decodes a single frame.
142 *
143 * @return true if there are no more frames to decode, false otherwise.
144 */
145 protected boolean decodeFrame() throws JavaLayerException
146 {
147 try
148 {
149 AudioDevice out = audio;
150 if (out == null) return false;
151
152 Header h = bitstream.readFrame();
153 if (h == null) return false;
154
155 // sample buffer set when decoder constructed
156 SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);
157
158 synchronized (this)
159 {
160 out = audio;
161 if(out != null)
162 {
163 out.write(output.getBuffer(), 0, output.getBufferLength());
164 }
165 }
166
167 bitstream.closeFrame();
168 }
169 catch (RuntimeException ex)
170 {
171 throw new JavaLayerException("Exception decoding audio frame", ex);
172 }
173 return true;
174 }
175
176 /**
177 * skips over a single frame
178 * @return false if there are no more frames to decode, true otherwise.
179 */
180 protected boolean skipFrame() throws JavaLayerException
181 {
182 Header h = bitstream.readFrame();
183 if (h == null) return false;
184 bitstream.closeFrame();
185 return true;
186 }
187
188 /**
189 * Plays a range of MPEG audio frames
190 * @param start The first frame to play
191 * @param end The last frame to play
192 * @return true if the last frame was played, or false if there are more frames.
193 */
194 public boolean play(final int start, final int end) throws JavaLayerException
195 {
196 boolean ret = true;
197 int offset = start;
198 while (offset-- > 0 && ret) ret = skipFrame();
199 return play(end - start);
200 }
201
202 /**
203 * Constructs a <code>PlaybackEvent</code>
204 */
205 private PlaybackEvent createEvent(int id)
206 {
207 return createEvent(audio, id);
208 }
209
210 /**
211 * Constructs a <code>PlaybackEvent</code>
212 */
213 private PlaybackEvent createEvent(AudioDevice dev, int id)
214 {
215 return new PlaybackEvent(this, id, dev.getPosition());
216 }
217
218 /**
219 * sets the <code>PlaybackListener</code>
220 */
221 public void setPlayBackListener(PlaybackListener listener)
222 {
223 this.listener = listener;
224 }
225
226 /**
227 * gets the <code>PlaybackListener</code>
228 */
229 public PlaybackListener getPlayBackListener()
230 {
231 return listener;
232 }
233
234 /**
235 * closes the player and notifies <code>PlaybackListener</code>
236 */
237 public void stop()
238 {
239 listener.playbackFinished(createEvent(PlaybackEvent.STOPPED));
240 close();
241 }
242} \ 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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.player.advanced;
21
22/**
23 * An event which indicates a <code>Player</code> has performed an 'playback action'
24 * @author Paul Stanton (http://wanto.f2o.org/)
25 */
26public class PlaybackEvent
27{
28 public static int STOPPED = 1;
29 public static int STARTED = 2;
30
31 private AdvancedPlayer source;
32 private int frame;
33 private int id;
34
35 public PlaybackEvent(AdvancedPlayer source, int id, int frame)
36 {
37 this.id = id;
38 this.source = source;
39 this.frame = frame;
40 }
41
42 public int getId(){return id;}
43 public void setId(int id){this.id = id;}
44
45 public int getFrame(){return frame;}
46 public void setFrame(int frame){this.frame = frame;}
47
48 public AdvancedPlayer getSource(){return source;}
49 public void setSource(AdvancedPlayer source){this.source = source;}
50
51}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.player.advanced;
21
22/**
23 * Listener for javalayer Player playback
24 * @author Paul Stanton (http://wanto.f2o.org/)
25 */
26public abstract class PlaybackListener
27{
28 public void playbackStarted(PlaybackEvent evt){}
29 public void playbackFinished(PlaybackEvent evt){}
30}
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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *-----------------------------------------------------------------------
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *----------------------------------------------------------------------
18 */
19
20package javazoom.jl.player.advanced;
21
22import java.io.BufferedInputStream;
23import java.io.File;
24import java.io.FileInputStream;
25import java.io.IOException;
26import java.io.InputStream;
27
28import javazoom.jl.decoder.JavaLayerException;
29
30/**
31 * This class implements a sample player using Playback listener.
32 */
33public class jlap
34{
35
36 public static void main(String[] args)
37 {
38 jlap test = new jlap();
39 if (args.length != 1)
40 {
41 test.showUsage();
42 System.exit(0);
43 }
44 else
45 {
46 try
47 {
48 test.play(args[0]);
49 }
50 catch (Exception ex)
51 {
52 System.err.println(ex.getMessage());
53 System.exit(0);
54 }
55 }
56 }
57
58 public void play(String filename) throws JavaLayerException, IOException
59 {
60 InfoListener lst = new InfoListener();
61 playMp3(new File(filename), lst);
62 }
63
64 public void showUsage()
65 {
66 System.out.println("Usage: jla <filename>");
67 System.out.println("");
68 System.out.println(" e.g. : java javazoom.jl.player.advanced.jlap localfile.mp3");
69 }
70
71 public static AdvancedPlayer playMp3(File mp3, PlaybackListener listener) throws IOException, JavaLayerException
72 {
73 return playMp3(mp3, 0, Integer.MAX_VALUE, listener);
74 }
75
76 public static AdvancedPlayer playMp3(File mp3, int start, int end, PlaybackListener listener) throws IOException, JavaLayerException
77 {
78 return playMp3(new BufferedInputStream(new FileInputStream(mp3)), start, end, listener);
79 }
80
81 public static AdvancedPlayer playMp3(final InputStream is, final int start, final int end, PlaybackListener listener) throws JavaLayerException
82 {
83 final AdvancedPlayer player = new AdvancedPlayer(is);
84 player.setPlayBackListener(listener);
85 // run in new thread
86 new Thread()
87 {
88 public void run()
89 {
90 try
91 {
92 player.play(start, end);
93 }
94 catch (Exception e)
95 {
96 throw new RuntimeException(e.getMessage());
97 }
98 }
99 }.start();
100 return player;
101 }
102
103 public class InfoListener extends PlaybackListener
104 {
105 public void playbackStarted(PlaybackEvent evt)
106 {
107 System.out.println("Play started from frame " + evt.getFrame());
108 }
109
110 public void playbackFinished(PlaybackEvent evt)
111 {
112 System.out.println("Play completed at frame " + evt.getFrame());
113 System.exit(0);
114 }
115 }
116} \ 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 @@
1/*
2 * 11/19/04 1.0 moved to LGPL.
3 *
4 * 06/04/01 Streaming support added. javalayer@javazoom.net
5 *
6 * 29/01/00 Initial version. mdm@techie.com
7 *-----------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------
22 */
23
24package javazoom.jl.player;
25
26import java.io.BufferedInputStream;
27import java.io.FileInputStream;
28import java.io.IOException;
29import java.io.InputStream;
30import java.net.URL;
31
32import javazoom.jl.decoder.JavaLayerException;
33
34/**
35 * The <code>jlp</code> class implements a simple command-line
36 * player for MPEG audio files.
37 *
38 * @author Mat McGowan (mdm@techie.com)
39 */
40public class jlp
41{
42 private String fFilename = null;
43 private boolean remote = false;
44
45 public static void main(String[] args)
46 {
47 int retval = 0;
48 try
49 {
50 jlp player = createInstance(args);
51 if (player!=null)
52 player.play();
53 }
54 catch (Exception ex)
55 {
56 System.err.println(ex);
57 ex.printStackTrace(System.err);
58 retval = 1;
59 }
60 System.exit(retval);
61 }
62
63 static public jlp createInstance(String[] args)
64 {
65 jlp player = new jlp();
66 if (!player.parseArgs(args))
67 player = null;
68 return player;
69 }
70
71 private jlp()
72 {
73 }
74
75 public jlp(String filename)
76 {
77 init(filename);
78 }
79
80 protected void init(String filename)
81 {
82 fFilename = filename;
83 }
84
85 protected boolean parseArgs(String[] args)
86 {
87 boolean parsed = false;
88 if (args.length == 1)
89 {
90 init(args[0]);
91 parsed = true;
92 remote = false;
93 }
94 else if (args.length == 2)
95 {
96 if (!(args[0].equals("-url")))
97 {
98 showUsage();
99 }
100 else
101 {
102 init(args[1]);
103 parsed = true;
104 remote = true;
105 }
106 }
107 else
108 {
109 showUsage();
110 }
111 return parsed;
112 }
113
114 public void showUsage()
115 {
116 System.out.println("Usage: jlp [-url] <filename>");
117 System.out.println("");
118 System.out.println(" e.g. : java javazoom.jl.player.jlp localfile.mp3");
119 System.out.println(" java javazoom.jl.player.jlp -url http://www.server.com/remotefile.mp3");
120 System.out.println(" java javazoom.jl.player.jlp -url http://www.shoutcastserver.com:8000");
121 }
122
123 public void play()
124 throws JavaLayerException
125 {
126 try
127 {
128 System.out.println("playing "+fFilename+"...");
129 InputStream in = null;
130 if (remote == true) in = getURLInputStream();
131 else in = getInputStream();
132 AudioDevice dev = getAudioDevice();
133 Player player = new Player(in, dev);
134 player.play();
135 }
136 catch (IOException ex)
137 {
138 throw new JavaLayerException("Problem playing file "+fFilename, ex);
139 }
140 catch (Exception ex)
141 {
142 throw new JavaLayerException("Problem playing file "+fFilename, ex);
143 }
144 }
145
146 /**
147 * Playing file from URL (Streaming).
148 */
149 protected InputStream getURLInputStream()
150 throws Exception
151 {
152
153 URL url = new URL(fFilename);
154 InputStream fin = url.openStream();
155 BufferedInputStream bin = new BufferedInputStream(fin);
156 return bin;
157 }
158
159 /**
160 * Playing file from FileInputStream.
161 */
162 protected InputStream getInputStream()
163 throws IOException
164 {
165 FileInputStream fin = new FileInputStream(fFilename);
166 BufferedInputStream bin = new BufferedInputStream(fin);
167 return bin;
168 }
169
170 protected AudioDevice getAudioDevice()
171 throws JavaLayerException
172 {
173 return FactoryRegistry.systemRegistry().createAudioDevice();
174 }
175
176}
diff --git a/songdbj/javazoom/spi/PropertiesContainer.java b/songdbj/javazoom/spi/PropertiesContainer.java
new file mode 100644
index 0000000000..27ed85f904
--- /dev/null
+++ b/songdbj/javazoom/spi/PropertiesContainer.java
@@ -0,0 +1,31 @@
1/*
2 * PropertiesContainer.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 *-----------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------
22 */
23
24package javazoom.spi;
25
26import java.util.Map;
27
28public interface PropertiesContainer
29{
30 public Map properties();
31}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/convert/DecodedMpegAudioInputStream.java b/songdbj/javazoom/spi/mpeg/sampled/convert/DecodedMpegAudioInputStream.java
new file mode 100644
index 0000000000..e4e6fed00a
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/convert/DecodedMpegAudioInputStream.java
@@ -0,0 +1,334 @@
1/*
2 * DecodedMpegAudioInputStream.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 *-----------------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *------------------------------------------------------------------------
22 */
23
24package javazoom.spi.mpeg.sampled.convert;
25import java.io.IOException;
26import java.io.InputStream;
27import java.util.HashMap;
28import java.util.Map;
29
30import javax.sound.sampled.AudioFormat;
31import javax.sound.sampled.AudioInputStream;
32
33import javazoom.jl.decoder.Bitstream;
34import javazoom.jl.decoder.BitstreamException;
35import javazoom.jl.decoder.Decoder;
36import javazoom.jl.decoder.DecoderException;
37import javazoom.jl.decoder.Equalizer;
38import javazoom.jl.decoder.Header;
39import javazoom.jl.decoder.Obuffer;
40import javazoom.spi.PropertiesContainer;
41import javazoom.spi.mpeg.sampled.file.IcyListener;
42import javazoom.spi.mpeg.sampled.file.tag.TagParseEvent;
43import javazoom.spi.mpeg.sampled.file.tag.TagParseListener;
44
45import org.tritonus.share.TDebug;
46import org.tritonus.share.sampled.convert.TAsynchronousFilteredAudioInputStream;
47
48/**
49 * Main decoder.
50 */
51public class DecodedMpegAudioInputStream extends TAsynchronousFilteredAudioInputStream implements PropertiesContainer, TagParseListener
52{
53 private InputStream m_encodedStream;
54 private Bitstream m_bitstream;
55 private Decoder m_decoder;
56 private Equalizer m_equalizer;
57 private float[] m_equalizer_values;
58 private Header m_header;
59 private DMAISObuffer m_oBuffer;
60
61 // Bytes info.
62 private long byteslength = -1;
63 private long currentByte = 0;
64 // Frame info.
65 private int frameslength = -1;
66 private long currentFrame = 0;
67 private int currentFramesize = 0;
68 private int currentBitrate = -1;
69 // Time info.
70 private long currentMicrosecond = 0;
71 // Shoutcast stream info
72 private IcyListener shoutlst = null;
73
74
75 private HashMap properties = null;
76
77 public DecodedMpegAudioInputStream(AudioFormat outputFormat, AudioInputStream inputStream)
78 {
79 super(outputFormat, -1);
80 if (TDebug.TraceAudioConverter)
81 {
82 TDebug.out(">DecodedMpegAudioInputStream(AudioFormat outputFormat, AudioInputStream inputStream)");
83 }
84 try
85 {
86 // Try to find out inputstream length to allow skip.
87 byteslength = inputStream.available();
88 }
89 catch (IOException e)
90 {
91 TDebug.out("DecodedMpegAudioInputStream : Cannot run inputStream.available() : "+e.getMessage());
92 byteslength = -1;
93 }
94 m_encodedStream = inputStream;
95 shoutlst = IcyListener.getInstance();
96 shoutlst.reset();
97 m_bitstream = new Bitstream(inputStream);
98 m_decoder = new Decoder(null);
99 m_equalizer = new Equalizer();
100 m_equalizer_values = new float[32];
101 for (int b=0;b<m_equalizer.getBandCount();b++)
102 {
103 m_equalizer_values[b] = m_equalizer.getBand(b);
104 }
105 m_decoder.setEqualizer(m_equalizer);
106 m_oBuffer = new DMAISObuffer(outputFormat.getChannels());
107 m_decoder.setOutputBuffer(m_oBuffer);
108 try
109 {
110 m_header = m_bitstream.readFrame();
111 if ((m_header != null) && (frameslength == -1) && (byteslength > 0)) frameslength = m_header.max_number_of_frames((int)byteslength);
112 }
113 catch (BitstreamException e)
114 {
115 TDebug.out("DecodedMpegAudioInputStream : Cannot read first frame : "+e.getMessage());
116 byteslength = -1;
117 }
118 properties = new HashMap();
119 }
120
121 /**
122 * Return dynamic properties.
123 *
124 * <ul>
125 * <li><b>mp3.frame</b> [Long], current frame position.
126 * <li><b>mp3.frame.bitrate</b> [Integer], bitrate of the current frame.
127 * <li><b>mp3.frame.size.bytes</b> [Integer], size in bytes of the current frame.
128 * <li><b>mp3.position.byte</b> [Long], current position in bytes in the stream.
129 * <li><b>mp3.position.microseconds</b> [Long], elapsed microseconds.
130 * <li><b>mp3.equalizer</b> float[32], interactive equalizer array, values could be in [-1.0, +1.0].
131 * <li><b>mp3.shoutcast.metadata.key</b> [String], Shoutcast meta key with matching value.
132 * <br>For instance :
133 * <br>mp3.shoutcast.metadata.StreamTitle=Current song playing in stream.
134 * <br>mp3.shoutcast.metadata.StreamUrl=Url info.
135 * </ul>
136 */
137 public Map properties()
138 {
139 properties.put("mp3.frame",new Long(currentFrame));
140 properties.put("mp3.frame.bitrate",new Integer(currentBitrate));
141 properties.put("mp3.frame.size.bytes",new Integer(currentFramesize));
142 properties.put("mp3.position.byte",new Long(currentByte));
143 properties.put("mp3.position.microseconds",new Long(currentMicrosecond));
144 properties.put("mp3.equalizer",m_equalizer_values);
145 // Optionnal shoutcast stream meta-data.
146 if (shoutlst != null)
147 {
148 String surl = shoutlst.getStreamUrl();
149 String stitle = shoutlst.getStreamTitle();
150 if ((stitle != null) && (stitle.trim().length()>0)) properties.put("mp3.shoutcast.metadata.StreamTitle",stitle);
151 if ((surl != null) && (surl.trim().length()>0)) properties.put("mp3.shoutcast.metadata.StreamUrl",surl);
152 }
153 return properties;
154 }
155
156 public void execute()
157 {
158 if (TDebug.TraceAudioConverter) TDebug.out("execute() : begin");
159 try
160 {
161 // Following line hangs when FrameSize is available in AudioFormat.
162 Header header = null;
163 if (m_header == null) header = m_bitstream.readFrame();
164 else header = m_header;
165 if (TDebug.TraceAudioConverter) TDebug.out("execute() : header = "+header);
166 if (header == null)
167 {
168 if (TDebug.TraceAudioConverter)
169 {
170 TDebug.out("header is null (end of mpeg stream)");
171 }
172 getCircularBuffer().close();
173 return;
174 }
175 currentFrame++;
176 currentBitrate = header.bitrate_instant();
177 currentFramesize = header.calculate_framesize();
178 currentByte = currentByte + currentFramesize;
179 currentMicrosecond = (long) (currentFrame* header.ms_per_frame()*1000.0f);
180 for (int b=0;b<m_equalizer_values.length;b++)
181 {
182 m_equalizer.setBand(b,m_equalizer_values[b]);
183 }
184 m_decoder.setEqualizer(m_equalizer);
185 Obuffer decoderOutput = m_decoder.decodeFrame(header, m_bitstream);
186 m_bitstream.closeFrame();
187 getCircularBuffer().write(m_oBuffer.getBuffer(), 0, m_oBuffer.getCurrentBufferSize());
188 m_oBuffer.reset();
189 if (m_header != null) m_header = null;
190 }
191 catch (BitstreamException e)
192 {
193 if (TDebug.TraceAudioConverter)
194 {
195 TDebug.out(e);
196 }
197 }
198 catch (DecoderException e)
199 {
200 if (TDebug.TraceAudioConverter)
201 {
202 TDebug.out(e);
203 }
204 }
205 if (TDebug.TraceAudioConverter) TDebug.out("execute() : end");
206 }
207
208 public long skip(long bytes)
209 {
210 if ((byteslength > 0) && (frameslength > 0))
211 {
212 float ratio = bytes*1.0f/byteslength*1.0f;
213 long bytesread = skipFrames((long) (ratio*frameslength));
214 currentByte = currentByte + bytesread;
215 return bytesread;
216 }
217 else return -1;
218 }
219
220 /**
221 * Skip frames.
222 * You don't need to call it severals times, it will exactly skip given frames number.
223 * @param frames
224 * @return bytes length skipped matching to frames skipped.
225 */
226 public long skipFrames(long frames)
227 {
228 if (TDebug.TraceAudioConverter) TDebug.out("skip(long frames) : begin");
229 int framesRead = 0;
230 int bytesReads = 0;
231 try
232 {
233 for (int i=0;i<frames;i++)
234 {
235 Header header = m_bitstream.readFrame();
236 if (header != null)
237 {
238 int fsize = header.calculate_framesize();
239 bytesReads = bytesReads + fsize;
240 }
241 m_bitstream.closeFrame();
242 framesRead++;
243 }
244 }
245 catch (BitstreamException e)
246 {
247 if (TDebug.TraceAudioConverter) TDebug.out(e);
248 }
249 if (TDebug.TraceAudioConverter) TDebug.out("skip(long frames) : end");
250 currentFrame = currentFrame + framesRead;
251 return bytesReads;
252 }
253
254 private boolean isBigEndian()
255 {
256 return getFormat().isBigEndian();
257 }
258
259 public void close() throws IOException
260 {
261 super.close();
262 m_encodedStream.close();
263 }
264
265 private class DMAISObuffer extends Obuffer
266 {
267 private int m_nChannels;
268 private byte[] m_abBuffer;
269 private int[] m_anBufferPointers;
270 private boolean m_bIsBigEndian;
271 public DMAISObuffer(int nChannels)
272 {
273 m_nChannels = nChannels;
274 m_abBuffer = new byte[OBUFFERSIZE * nChannels];
275 m_anBufferPointers = new int[nChannels];
276 reset();
277 m_bIsBigEndian = DecodedMpegAudioInputStream.this.isBigEndian();
278 }
279 public void append(int nChannel, short sValue)
280 {
281 byte bFirstByte;
282 byte bSecondByte;
283 if (m_bIsBigEndian)
284 {
285 bFirstByte = (byte) ((sValue >>> 8) & 0xFF);
286 bSecondByte = (byte) (sValue & 0xFF);
287 }
288 else // little endian
289 {
290 bFirstByte = (byte) (sValue & 0xFF);
291 bSecondByte = (byte) ((sValue >>> 8) & 0xFF);
292 }
293 m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte;
294 m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte;
295 m_anBufferPointers[nChannel] += m_nChannels * 2;
296 }
297 public void set_stop_flag()
298 {
299 }
300 public void close()
301 {
302 }
303 public void write_buffer(int nValue)
304 {
305 }
306 public void clear_buffer()
307 {
308 }
309 public byte[] getBuffer()
310 {
311 return m_abBuffer;
312 }
313 public int getCurrentBufferSize()
314 {
315 return m_anBufferPointers[0];
316 }
317 public void reset()
318 {
319 for (int i = 0; i < m_nChannels; i++)
320 {
321 /* Points to byte location,
322 * implicitely assuming 16 bit
323 * samples.
324 */
325 m_anBufferPointers[i] = i * 2;
326 }
327 }
328 }
329
330 public void tagParsed(TagParseEvent tpe)
331 {
332 System.out.println("TAG:"+tpe.getTag());
333 }
334}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/convert/MpegFormatConversionProvider.java b/songdbj/javazoom/spi/mpeg/sampled/convert/MpegFormatConversionProvider.java
new file mode 100644
index 0000000000..1a3d51d9ad
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/convert/MpegFormatConversionProvider.java
@@ -0,0 +1,120 @@
1/*
2 * MpegFormatConversionProvider.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * ---------------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * --------------------------------------------------------------------------
22 */
23
24
25package javazoom.spi.mpeg.sampled.convert;
26
27
28import java.util.Arrays;
29
30import javax.sound.sampled.AudioFormat;
31import javax.sound.sampled.AudioInputStream;
32import javax.sound.sampled.AudioSystem;
33
34import javazoom.spi.mpeg.sampled.file.MpegEncoding;
35
36import org.tritonus.share.TDebug;
37import org.tritonus.share.sampled.Encodings;
38import org.tritonus.share.sampled.convert.TEncodingFormatConversionProvider;
39
40/**
41 * ConversionProvider for MPEG files.
42 */
43public class MpegFormatConversionProvider extends TEncodingFormatConversionProvider
44{
45 private static final AudioFormat.Encoding MP3 = Encodings.getEncoding("MP3");
46 private static final AudioFormat.Encoding PCM_SIGNED = Encodings.getEncoding("PCM_SIGNED");
47
48 private static final AudioFormat[] INPUT_FORMATS =
49 {
50 // mono
51 new AudioFormat(MP3, -1.0F, -1, 1, -1, -1.0F, false),
52 new AudioFormat(MP3, -1.0F, -1, 1, -1, -1.0F, true),
53 // stereo
54 new AudioFormat(MP3, -1.0F, -1, 2, -1, -1.0F, false),
55 new AudioFormat(MP3, -1.0F, -1, 2, -1, -1.0F, true),
56 };
57
58
59 private static final AudioFormat[] OUTPUT_FORMATS =
60 {
61 // mono, 16 bit signed
62 new AudioFormat(PCM_SIGNED, -1.0F, 16, 1, 2, -1.0F, false),
63 new AudioFormat(PCM_SIGNED, -1.0F, 16, 1, 2, -1.0F, true),
64 // stereo, 16 bit signed
65 new AudioFormat(PCM_SIGNED, -1.0F, 16, 2, 4, -1.0F, false),
66 new AudioFormat(PCM_SIGNED, -1.0F, 16, 2, 4, -1.0F, true),
67 };
68
69 /**
70 * Constructor.
71 */
72 public MpegFormatConversionProvider()
73 {
74 super(Arrays.asList(INPUT_FORMATS), Arrays.asList(OUTPUT_FORMATS));
75 if (TDebug.TraceAudioConverter)
76 {
77 TDebug.out(">MpegFormatConversionProvider()");
78 }
79 }
80
81 public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream audioInputStream)
82 {
83 if (TDebug.TraceAudioConverter)
84 {
85 TDebug.out(">MpegFormatConversionProvider.getAudioInputStream(AudioFormat targetFormat, AudioInputStream audioInputStream):");
86 }
87 return new DecodedMpegAudioInputStream(targetFormat, audioInputStream);
88 }
89
90 /**
91 * Add conversion support for any MpegEncoding source with FrameRate or FrameSize not empty.
92 * @param targetFormat
93 * @param sourceFormat
94 * @return
95 */
96 public boolean isConversionSupported(AudioFormat targetFormat, AudioFormat sourceFormat)
97 {
98 if (TDebug.TraceAudioConverter)
99 {
100 TDebug.out(">MpegFormatConversionProvider.isConversionSupported(AudioFormat targetFormat, AudioFormat sourceFormat):");
101 TDebug.out("checking if conversion possible");
102 TDebug.out("from: " + sourceFormat);
103 TDebug.out("to: " + targetFormat);
104 }
105
106 boolean conversion = super.isConversionSupported(targetFormat, sourceFormat);
107 if (conversion == false)
108 {
109 AudioFormat.Encoding enc = sourceFormat.getEncoding();
110 if (enc instanceof MpegEncoding)
111 {
112 if ((sourceFormat.getFrameRate() != AudioSystem.NOT_SPECIFIED) || (sourceFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED))
113 {
114 conversion = true;
115 }
116 }
117 }
118 return conversion;
119 }
120}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/IcyListener.java b/songdbj/javazoom/spi/mpeg/sampled/file/IcyListener.java
new file mode 100644
index 0000000000..8e49e6e2ef
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/IcyListener.java
@@ -0,0 +1,131 @@
1/*
2 * IcyListener.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 *-----------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------
22 */
23
24package javazoom.spi.mpeg.sampled.file;
25
26import javazoom.spi.mpeg.sampled.file.tag.MP3Tag;
27import javazoom.spi.mpeg.sampled.file.tag.TagParseEvent;
28import javazoom.spi.mpeg.sampled.file.tag.TagParseListener;
29
30/**
31 * This class (singleton) allow to be notified on shoutcast meta data
32 * while playing the stream (such as song title).
33 */
34public class IcyListener implements TagParseListener
35{
36 private static IcyListener instance = null;
37 private MP3Tag lastTag = null;
38 private String streamTitle = null;
39 private String streamUrl = null;
40
41
42 private IcyListener()
43 {
44 super();
45 }
46
47 public static synchronized IcyListener getInstance()
48 {
49 if (instance == null)
50 {
51 instance = new IcyListener();
52 }
53 return instance;
54 }
55
56 /* (non-Javadoc)
57 * @see javazoom.spi.mpeg.sampled.file.tag.TagParseListener#tagParsed(javazoom.spi.mpeg.sampled.file.tag.TagParseEvent)
58 */
59 public void tagParsed(TagParseEvent tpe)
60 {
61 lastTag = tpe.getTag();
62 String name = lastTag.getName();
63 if ((name != null) && (name.equalsIgnoreCase("streamtitle")))
64 {
65 streamTitle = (String) lastTag.getValue();
66 }
67 else if ((name != null) && (name.equalsIgnoreCase("streamurl")))
68 {
69 streamUrl = (String) lastTag.getValue();
70 }
71 }
72
73 /**
74 * @return
75 */
76 public MP3Tag getLastTag()
77 {
78 return lastTag;
79 }
80
81 /**
82 * @param tag
83 */
84 public void setLastTag(MP3Tag tag)
85 {
86 lastTag = tag;
87 }
88
89 /**
90 * @return
91 */
92 public String getStreamTitle()
93 {
94 return streamTitle;
95 }
96
97 /**
98 * @return
99 */
100 public String getStreamUrl()
101 {
102 return streamUrl;
103 }
104
105 /**
106 * @param string
107 */
108 public void setStreamTitle(String string)
109 {
110 streamTitle = string;
111 }
112
113 /**
114 * @param string
115 */
116 public void setStreamUrl(String string)
117 {
118 streamUrl = string;
119 }
120
121 /**
122 * Reset all properties.
123 */
124 public void reset()
125 {
126 lastTag = null;
127 streamTitle = null;
128 streamUrl = null;
129 }
130
131}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileFormat.java b/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileFormat.java
new file mode 100644
index 0000000000..afdc4c5e9c
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileFormat.java
@@ -0,0 +1,103 @@
1/*
2 * MpegAudioFileFormat.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 *-----------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------
22 */
23package javazoom.spi.mpeg.sampled.file;
24
25import java.util.Map;
26
27import javax.sound.sampled.AudioFormat;
28
29import org.tritonus.share.sampled.file.TAudioFileFormat;
30
31/**
32 * @author JavaZOOM
33 */
34public class MpegAudioFileFormat extends TAudioFileFormat
35{
36 /**
37 * Contructor.
38 * @param type
39 * @param audioFormat
40 * @param nLengthInFrames
41 * @param nLengthInBytes
42 */
43 public MpegAudioFileFormat(Type type, AudioFormat audioFormat, int nLengthInFrames, int nLengthInBytes, Map properties)
44 {
45 super(type, audioFormat, nLengthInFrames, nLengthInBytes, properties);
46 }
47
48 /**
49 * MP3 audio file format parameters.
50 * Some parameters might be unavailable. So availability test is required before reading any parameter.
51 *
52 * <br>AudioFileFormat parameters.
53 * <ul>
54 * <li><b>duration</b> [Long], duration in microseconds.
55 * <li><b>title</b> [String], Title of the stream.
56 * <li><b>author</b> [String], Name of the artist of the stream.
57 * <li><b>album</b> [String], Name of the album of the stream.
58 * <li><b>date</b> [String], The date (year) of the recording or release of the stream.
59 * <li><b>copyright</b> [String], Copyright message of the stream.
60 * <li><b>comment</b> [String], Comment of the stream.
61 * </ul>
62 * <br>MP3 parameters.
63 * <ul>
64 * <li><b>mp3.version.mpeg</b> [String], mpeg version : 1,2 or 2.5
65 * <li><b>mp3.version.layer</b> [String], layer version 1, 2 or 3
66 * <li><b>mp3.version.encoding</b> [String], mpeg encoding : MPEG1, MPEG2-LSF, MPEG2.5-LSF
67 * <li><b>mp3.channels</b> [Integer], number of channels 1 : mono, 2 : stereo.
68 * <li><b>mp3.frequency.hz</b> [Integer], sampling rate in hz.
69 * <li><b>mp3.bitrate.nominal.bps</b> [Integer], nominal bitrate in bps.
70 * <li><b>mp3.length.bytes</b> [Integer], length in bytes.
71 * <li><b>mp3.length.frames</b> [Integer], length in frames.
72 * <li><b>mp3.framesize.bytes</b> [Integer], framesize of the first frame. framesize is not constant for VBR streams.
73 * <li><b>mp3.framerate.fps</b> [Float], framerate in frames per seconds.
74 * <li><b>mp3.header.pos</b> [Integer], position of first audio header (or ID3v2 size).
75 * <li><b>mp3.vbr</b> [Boolean], vbr flag.
76 * <li><b>mp3.vbr.scale</b> [Integer], vbr scale.
77 * <li><b>mp3.crc</b> [Boolean], crc flag.
78 * <li><b>mp3.original</b> [Boolean], original flag.
79 * <li><b>mp3.copyright</b> [Boolean], copyright flag.
80 * <li><b>mp3.padding</b> [Boolean], padding flag.
81 * <li><b>mp3.mode</b> [Integer], mode 0:STEREO 1:JOINT_STEREO 2:DUAL_CHANNEL 3:SINGLE_CHANNEL
82 * <li><b>mp3.id3tag.genre</b> [String], ID3 tag (v1 or v2) genre.
83 * <li><b>mp3.id3tag.track</b> [String], ID3 tag (v1 or v2) track info.
84 * <li><b>mp3.id3tag.encoded</b> [String], ID3 tag v2 encoded by info.
85 * <li><b>mp3.id3tag.composer</b> [String], ID3 tag v2 composer info.
86 * <li><b>mp3.id3tag.grouping</b> [String], ID3 tag v2 grouping info.
87 * <li><b>mp3.id3tag.disc</b> [String], ID3 tag v2 track info.
88 * <li><b>mp3.id3tag.v2</b> [InputStream], ID3v2 frames.
89 * <li><b>mp3.id3tag.v2.version</b> [String], ID3v2 major version (2=v2.2.0, 3=v2.3.0, 4=v2.4.0).
90 * <li><b>mp3.shoutcast.metadata.key</b> [String], Shoutcast meta key with matching value.
91 * <br>For instance :
92 * <br>mp3.shoutcast.metadata.icy-irc=#shoutcast
93 * <br>mp3.shoutcast.metadata.icy-metaint=8192
94 * <br>mp3.shoutcast.metadata.icy-genre=Trance Techno Dance
95 * <br>mp3.shoutcast.metadata.icy-url=http://www.di.fm
96 * <br>and so on ...
97 * </ul>
98 */
99 public Map properties()
100 {
101 return super.properties();
102 }
103}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java b/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
new file mode 100644
index 0000000000..54440551a1
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
@@ -0,0 +1,772 @@
1/*
2 * MpegAudioFileReader.
3 *
4 * 12/31/04 : mp3spi.weak system property added to skip controls.
5 *
6 * 11/29/04 : ID3v2.2, v2.3 & v2.4 support improved.
7 * "mp3.id3tag.composer" (TCOM/TCM) added
8 * "mp3.id3tag.grouping" (TIT1/TT1) added
9 * "mp3.id3tag.disc" (TPA/TPOS) added
10 * "mp3.id3tag.encoded" (TEN/TENC) added
11 * "mp3.id3tag.v2.version" added
12 *
13 * 11/28/04 : String encoding bug fix in chopSubstring method.
14 *
15 * JavaZOOM : mp3spi@javazoom.net
16 * http://www.javazoom.net
17 *
18 *-----------------------------------------------------------------------
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU Library General Public License as published
21 * by the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU Library General Public License for more details.
28 *
29 * You should have received a copy of the GNU Library General Public
30 * License along with this program; if not, write to the Free Software
31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 *----------------------------------------------------------------------
33 */
34
35package javazoom.spi.mpeg.sampled.file;
36
37
38import java.io.BufferedInputStream;
39import java.io.File;
40import java.io.FileInputStream;
41import java.io.IOException;
42import java.io.InputStream;
43import java.io.PushbackInputStream;
44import java.io.UnsupportedEncodingException;
45import java.net.URL;
46import java.net.URLConnection;
47import java.security.AccessControlException;
48import java.util.HashMap;
49
50import javax.sound.sampled.AudioFileFormat;
51import javax.sound.sampled.AudioFormat;
52import javax.sound.sampled.AudioInputStream;
53import javax.sound.sampled.AudioSystem;
54import javax.sound.sampled.UnsupportedAudioFileException;
55
56import javazoom.jl.decoder.Bitstream;
57import javazoom.jl.decoder.Header;
58import javazoom.spi.mpeg.sampled.file.tag.IcyInputStream;
59import javazoom.spi.mpeg.sampled.file.tag.MP3Tag;
60
61import org.tritonus.share.TDebug;
62import org.tritonus.share.sampled.file.TAudioFileReader;
63
64/**
65 * This class implements AudioFileReader for MP3 SPI.
66 */
67public class MpegAudioFileReader extends TAudioFileReader
68{
69 private final int SYNC = 0xFFE00000;
70 private String weak = null;
71 private final AudioFormat.Encoding[][] sm_aEncodings =
72 {
73 {MpegEncoding.MPEG2L1, MpegEncoding.MPEG2L2, MpegEncoding.MPEG2L3},
74 {MpegEncoding.MPEG1L1, MpegEncoding.MPEG1L2, MpegEncoding.MPEG1L3},
75 {MpegEncoding.MPEG2DOT5L1, MpegEncoding.MPEG2DOT5L2, MpegEncoding.MPEG2DOT5L3},
76
77 };
78
79 private static final int INITAL_READ_LENGTH = 64000;
80 private static final int MARK_LIMIT = INITAL_READ_LENGTH + 1;
81
82 private static final String[] id3v1genres = {
83 "Blues"
84 , "Classic Rock"
85 , "Country"
86 , "Dance"
87 , "Disco"
88 , "Funk"
89 , "Grunge"
90 , "Hip-Hop"
91 , "Jazz"
92 , "Metal"
93 , "New Age"
94 , "Oldies"
95 , "Other"
96 , "Pop"
97 , "R&B"
98 , "Rap"
99 , "Reggae"
100 , "Rock"
101 , "Techno"
102 , "Industrial"
103 , "Alternative"
104 , "Ska"
105 , "Death Metal"
106 , "Pranks"
107 , "Soundtrack"
108 , "Euro-Techno"
109 , "Ambient"
110 , "Trip-Hop"
111 , "Vocal"
112 , "Jazz+Funk"
113 , "Fusion"
114 , "Trance"
115 , "Classical"
116 , "Instrumental"
117 , "Acid"
118 , "House"
119 , "Game"
120 , "Sound Clip"
121 , "Gospel"
122 , "Noise"
123 , "AlternRock"
124 , "Bass"
125 , "Soul"
126 , "Punk"
127 , "Space"
128 , "Meditative"
129 , "Instrumental Pop"
130 , "Instrumental Rock"
131 , "Ethnic"
132 , "Gothic"
133 , "Darkwave"
134 , "Techno-Industrial"
135 , "Electronic"
136 , "Pop-Folk"
137 , "Eurodance"
138 , "Dream"
139 , "Southern Rock"
140 , "Comedy"
141 , "Cult"
142 , "Gangsta"
143 , "Top 40"
144 , "Christian Rap"
145 , "Pop/Funk"
146 , "Jungle"
147 , "Native American"
148 , "Cabaret"
149 , "New Wave"
150 , "Psychadelic"
151 , "Rave"
152 , "Showtunes"
153 , "Trailer"
154 , "Lo-Fi"
155 , "Tribal"
156 , "Acid Punk"
157 , "Acid Jazz"
158 , "Polka"
159 , "Retro"
160 , "Musical"
161 , "Rock & Roll"
162 , "Hard Rock"
163 , "Folk"
164 , "Folk-Rock"
165 , "National Folk"
166 , "Swing"
167 , "Fast Fusion"
168 , "Bebob"
169 , "Latin"
170 , "Revival"
171 , "Celtic"
172 , "Bluegrass"
173 , "Avantgarde"
174 , "Gothic Rock"
175 , "Progressive Rock"
176 , "Psychedelic Rock"
177 , "Symphonic Rock"
178 , "Slow Rock"
179 , "Big Band"
180 , "Chorus"
181 , "Easy Listening"
182 , "Acoustic"
183 , "Humour"
184 , "Speech"
185 , "Chanson"
186 , "Opera"
187 , "Chamber Music"
188 , "Sonata"
189 , "Symphony"
190 , "Booty Brass"
191 , "Primus"
192 , "Porn Groove"
193 , "Satire"
194 , "Slow Jam"
195 , "Club"
196 , "Tango"
197 , "Samba"
198 , "Folklore"
199 , "Ballad"
200 , "Power Ballad"
201 , "Rhythmic Soul"
202 , "Freestyle"
203 , "Duet"
204 , "Punk Rock"
205 , "Drum Solo"
206 , "A Capela"
207 , "Euro-House"
208 , "Dance Hall"
209 , "Goa"
210 , "Drum & Bass"
211 , "Club-House"
212 , "Hardcore"
213 , "Terror"
214 , "Indie"
215 , "BritPop"
216 , "Negerpunk"
217 , "Polsk Punk"
218 , "Beat"
219 , "Christian Gangsta Rap"
220 , "Heavy Metal"
221 , "Black Metal"
222 , "Crossover"
223 , "Contemporary Christian"
224 , "Christian Rock"
225 , "Merengue"
226 , "Salsa"
227 , "Thrash Metal"
228 , "Anime"
229 , "JPop"
230 , "SynthPop"
231 };
232
233 public MpegAudioFileReader()
234 {
235 super(MARK_LIMIT, true);
236 if (TDebug.TraceAudioFileReader) TDebug.out(">MpegAudioFileReader(1.9.2-FINAL)");
237 try
238 {
239 weak = System.getProperty("mp3spi.weak");
240 }
241 catch(AccessControlException e)
242 {}
243 }
244
245 /**
246 * Returns AudioFileFormat from File.
247 */
248 public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException
249 {
250 return super.getAudioFileFormat(file);
251 }
252
253 /**
254 * Returns AudioFileFormat from URL.
255 */
256 public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException
257 {
258 if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioFileFormat(URL): begin"); }
259 long lFileLengthInBytes = AudioSystem.NOT_SPECIFIED;
260 URLConnection conn = url.openConnection();
261 // Tell shoucast server (if any) that SPI support shoutcast stream.
262 conn.setRequestProperty ("Icy-Metadata", "1");
263 InputStream inputStream = conn.getInputStream();
264 AudioFileFormat audioFileFormat = null;
265 try
266 {
267 audioFileFormat = getAudioFileFormat(inputStream, lFileLengthInBytes);
268 }
269 finally
270 {
271 inputStream.close();
272 }
273 if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioFileFormat(URL): end"); }
274 return audioFileFormat;
275 }
276
277 /**
278 * Returns AudioFileFormat from inputstream and medialength.
279 */
280 public AudioFileFormat getAudioFileFormat(InputStream inputStream, long mediaLength) throws UnsupportedAudioFileException, IOException
281 {
282 if (TDebug.TraceAudioFileReader) TDebug.out(">MpegAudioFileReader.getAudioFileFormat(InputStream inputStream, long mediaLength): begin");
283 HashMap aff_properties = new HashMap();
284 HashMap af_properties = new HashMap();
285 int mLength = (int) mediaLength;
286 int size = inputStream.available();
287 PushbackInputStream pis = new PushbackInputStream(inputStream, MARK_LIMIT);
288 byte head[] = new byte[12];
289 pis.read(head);
290 if (TDebug.TraceAudioFileReader)
291 {
292 TDebug.out("InputStream : "+inputStream + " =>" + new String(head));
293 }
294 /*
295 * Check for WAV, AU, and AIFF file formats.
296 *
297 * Next check for Shoutcast (supported) and OGG (unsupported) streams.
298 *
299 * Note -- the check for WAV files will reject Broadcast WAV files.
300 * This may be incorrect as broadcast WAV files may contain MPEG data.
301 * Need to investigate.
302 *
303 */
304 if ((head[0] == 'R') && (head[1] == 'I') && (head[2] == 'F') && (head[3] == 'F') && (head[8] == 'W') && (head[9] == 'A') && (head[10] == 'V') && (head[11] == 'E'))
305 {
306 if (TDebug.TraceAudioFileReader) TDebug.out("WAV stream found");
307 if (weak == null) throw new UnsupportedAudioFileException("WAV stream found");
308 }
309 else if ((head[0] == '.') && (head[1] == 's') && (head[2] == 'n') && (head[3] == 'd'))
310 {
311 if (TDebug.TraceAudioFileReader) TDebug.out("AU stream found");
312 if (weak == null) throw new UnsupportedAudioFileException("AU stream found");
313 }
314 else if ((head[0] == 'F') && (head[1] == 'O') && (head[2] == 'R') && (head[3] == 'M') && (head[8] == 'A') && (head[9] == 'I') && (head[10] == 'F') && (head[11] == 'F'))
315 {
316 if (TDebug.TraceAudioFileReader) TDebug.out("AIFF stream found");
317 if (weak == null) throw new UnsupportedAudioFileException("AIFF stream found");
318 }
319 // Shoutcast stream ?
320 else if (((head[0] == 'I') | (head[0] == 'i')) && ((head[1] == 'C') | (head[1] == 'c')) && ((head[2] == 'Y') | (head[2] == 'y')))
321 {
322 pis.unread(head);
323 // Load shoutcast meta data.
324 loadShoutcastInfo(pis, aff_properties);
325 }
326 // Ogg stream ?
327 else if (((head[0] == 'O') | (head[0] == 'o')) && ((head[1] == 'G') | (head[1] == 'g')) && ((head[2] == 'G') | (head[2] == 'g')))
328 {
329 if (TDebug.TraceAudioFileReader) TDebug.out("Ogg stream found");
330 if (weak == null) throw new UnsupportedAudioFileException("Ogg stream found");
331 }
332 // No, so pushback.
333 else
334 {
335 pis.unread(head);
336 }
337 // MPEG header info.
338 int nVersion = AudioSystem.NOT_SPECIFIED;
339 int nLayer = AudioSystem.NOT_SPECIFIED;
340 int nSFIndex = AudioSystem.NOT_SPECIFIED;
341 int nMode = AudioSystem.NOT_SPECIFIED;
342 int FrameSize = AudioSystem.NOT_SPECIFIED;
343 int nFrameSize = AudioSystem.NOT_SPECIFIED;
344 int nFrequency = AudioSystem.NOT_SPECIFIED;
345 int nTotalFrames = AudioSystem.NOT_SPECIFIED;
346 float FrameRate = AudioSystem.NOT_SPECIFIED;
347 int BitRate = AudioSystem.NOT_SPECIFIED;
348 int nChannels = AudioSystem.NOT_SPECIFIED;
349 int nHeader = AudioSystem.NOT_SPECIFIED;
350 int nTotalMS = AudioSystem.NOT_SPECIFIED;
351 boolean nVBR = false;
352 AudioFormat.Encoding encoding = null;
353 try
354 {
355 Bitstream m_bitstream = new Bitstream(pis);
356 aff_properties.put("mp3.header.pos",new Integer(m_bitstream.header_pos()));
357 Header m_header = m_bitstream.readFrame();
358 // nVersion = 0 => MPEG2-LSF (Including MPEG2.5), nVersion = 1 => MPEG1
359 nVersion = m_header.version();
360 if (nVersion == 2) aff_properties.put("mp3.version.mpeg",Float.toString(2.5f));
361 else aff_properties.put("mp3.version.mpeg",Integer.toString(2-nVersion));
362 // nLayer = 1,2,3
363 nLayer = m_header.layer();
364 aff_properties.put("mp3.version.layer",Integer.toString(nLayer));
365 nSFIndex = m_header.sample_frequency();
366 nMode = m_header.mode();
367 aff_properties.put("mp3.mode",new Integer(nMode));
368 nChannels = nMode == 3 ? 1 : 2;
369 aff_properties.put("mp3.channels",new Integer(nChannels));
370 nVBR = m_header.vbr();
371 af_properties.put("vbr",new Boolean(nVBR));
372 aff_properties.put("mp3.vbr",new Boolean(nVBR));
373 aff_properties.put("mp3.vbr.scale",new Integer(m_header.vbr_scale()));
374 FrameSize = m_header.calculate_framesize();
375 aff_properties.put("mp3.framesize.bytes",new Integer(FrameSize));
376 if (FrameSize < 0) throw new UnsupportedAudioFileException("Invalid FrameSize : " + FrameSize);
377 nFrequency = m_header.frequency();
378 aff_properties.put("mp3.frequency.hz",new Integer(nFrequency));
379 FrameRate = (float) ((1.0 / (m_header.ms_per_frame())) * 1000.0);
380 aff_properties.put("mp3.framerate.fps",new Float(FrameRate));
381 if (FrameRate < 0) throw new UnsupportedAudioFileException("Invalid FrameRate : " + FrameRate);
382 if (mLength != AudioSystem.NOT_SPECIFIED)
383 {
384 aff_properties.put("mp3.length.bytes",new Integer(mLength));
385 nTotalFrames = m_header.max_number_of_frames(mLength);
386 aff_properties.put("mp3.length.frames",new Integer(nTotalFrames));
387 }
388 BitRate = m_header.bitrate();
389 af_properties.put("bitrate",new Integer(BitRate));
390 aff_properties.put("mp3.bitrate.nominal.bps",new Integer(BitRate));
391 nHeader = m_header.getSyncHeader();
392 encoding = sm_aEncodings[nVersion][nLayer - 1];
393 aff_properties.put("mp3.version.encoding",encoding.toString());
394 if (mLength != AudioSystem.NOT_SPECIFIED)
395 {
396 nTotalMS = Math.round(m_header.total_ms(mLength));
397 aff_properties.put("duration",new Long((long)nTotalMS*1000L));
398 }
399 aff_properties.put("mp3.copyright",new Boolean(m_header.copyright()));
400 aff_properties.put("mp3.original",new Boolean(m_header.original()));
401 aff_properties.put("mp3.crc",new Boolean(m_header.checksums()));
402 aff_properties.put("mp3.padding",new Boolean(m_header.padding()));
403 InputStream id3v2 = m_bitstream.getRawID3v2();
404 if (id3v2 != null)
405 {
406 aff_properties.put("mp3.id3tag.v2",id3v2);
407 parseID3v2Frames(id3v2,aff_properties);
408 }
409 if (TDebug.TraceAudioFileReader) TDebug.out(m_header.toString());
410 }
411 catch (Exception e)
412 {
413 if (TDebug.TraceAudioFileReader) TDebug.out("not a MPEG stream:" + e.getMessage());
414 throw new UnsupportedAudioFileException("not a MPEG stream:" + e.getMessage());
415 }
416
417 // Deeper checks ?
418 int cVersion = (nHeader >> 19) & 0x3;
419 if (cVersion == 1)
420 {
421 if (TDebug.TraceAudioFileReader) TDebug.out("not a MPEG stream: wrong version");
422 throw new UnsupportedAudioFileException("not a MPEG stream: wrong version");
423 }
424
425 int cSFIndex = (nHeader >> 10) & 0x3;
426 if (cSFIndex == 3)
427 {
428 if (TDebug.TraceAudioFileReader) TDebug.out("not a MPEG stream: wrong sampling rate");
429 throw new UnsupportedAudioFileException("not a MPEG stream: wrong sampling rate");
430 }
431
432 // Look up for ID3v1 tag
433 if ((size == mediaLength) && (mediaLength != AudioSystem.NOT_SPECIFIED))
434 {
435 FileInputStream fis = (FileInputStream) inputStream;
436 byte[] id3v1 = new byte[128];
437 long bytesSkipped = fis.skip(inputStream.available()-id3v1.length);
438 int read = fis.read(id3v1,0,id3v1.length);
439 if ((id3v1[0]=='T') && (id3v1[1]=='A') && (id3v1[2]=='G'))
440 {
441 parseID3v1Frames(id3v1, aff_properties);
442 }
443 }
444
445 AudioFormat format = new MpegAudioFormat(encoding, (float) nFrequency, AudioSystem.NOT_SPECIFIED // SampleSizeInBits - The size of a sample
446 , nChannels // Channels - The number of channels
447 , -1 // The number of bytes in each frame
448 , FrameRate // FrameRate - The number of frames played or recorded per second
449 , true
450 , af_properties);
451 return new MpegAudioFileFormat(MpegFileFormatType.MP3, format, nTotalFrames, mLength,aff_properties);
452 }
453
454 /**
455 * Returns AudioInputStream from file.
456 */
457 public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException
458 {
459 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(File file)");
460 InputStream inputStream = new FileInputStream(file);
461 try
462 {
463 return getAudioInputStream(inputStream);
464 }
465 catch (UnsupportedAudioFileException e)
466 {
467 if (inputStream != null) inputStream.close();
468 throw e;
469 }
470 catch (IOException e)
471 {
472 if (inputStream != null) inputStream.close();
473 throw e;
474 }
475 }
476
477 /**
478 * Returns AudioInputStream from url.
479 */
480 public AudioInputStream getAudioInputStream(URL url)
481 throws UnsupportedAudioFileException, IOException
482 {
483 if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioInputStream(URL): begin"); }
484 long lFileLengthInBytes = AudioSystem.NOT_SPECIFIED;
485 URLConnection conn = url.openConnection();
486 // Tell shoucast server (if any) that SPI support shoutcast stream.
487 boolean isShout = false;
488 int toRead=4;
489 byte[] head = new byte[toRead];
490
491 conn.setRequestProperty ("Icy-Metadata", "1");
492 BufferedInputStream bInputStream = new BufferedInputStream(conn.getInputStream());
493 bInputStream.mark(toRead);
494 int read = bInputStream.read(head,0,toRead);
495 if ((read>2) && (((head[0] == 'I') | (head[0] == 'i')) && ((head[1] == 'C') | (head[1] == 'c')) && ((head[2] == 'Y') | (head[2] == 'y')))) isShout = true;
496 bInputStream.reset();
497 InputStream inputStream = null;
498 // Is is a shoutcast server ?
499 if (isShout == true)
500 {
501 // Yes
502 IcyInputStream icyStream = new IcyInputStream(bInputStream);
503 icyStream.addTagParseListener(IcyListener.getInstance());
504 inputStream = icyStream;
505 }
506 else
507 {
508 // No, is Icecast 2 ?
509 String metaint = conn.getHeaderField("icy-metaint");
510 if (metaint != null)
511 {
512 // Yes, it might be icecast 2 mp3 stream.
513 IcyInputStream icyStream = new IcyInputStream(bInputStream,metaint);
514 icyStream.addTagParseListener(IcyListener.getInstance());
515 inputStream = icyStream;
516 }
517 else
518 {
519 // No
520 inputStream = bInputStream;
521 }
522 }
523 AudioInputStream audioInputStream = null;
524 try
525 {
526 audioInputStream = getAudioInputStream(inputStream, lFileLengthInBytes);
527 }
528 catch (UnsupportedAudioFileException e)
529 {
530 inputStream.close();
531 throw e;
532 }
533 catch (IOException e)
534 {
535 inputStream.close();
536 throw e;
537 }
538 if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioInputStream(URL): end"); }
539 return audioInputStream;
540 }
541
542 /**
543 * Return the AudioInputStream from the given InputStream.
544 */
545 public AudioInputStream getAudioInputStream(InputStream inputStream) throws UnsupportedAudioFileException, IOException
546 {
547 if (TDebug.TraceAudioFileReader) TDebug.out("MpegAudioFileReader.getAudioInputStream(InputStream inputStream)");
548 if (!inputStream.markSupported()) inputStream = new BufferedInputStream(inputStream);
549 return super.getAudioInputStream(inputStream);
550 }
551
552 /**
553 * Parser ID3v1 frames
554 * @param frames
555 * @param props
556 */
557 protected void parseID3v1Frames(byte[] frames, HashMap props)
558 {
559 if (TDebug.TraceAudioFileReader) TDebug.out("Parsing ID3v1");
560 String tag = null;
561 try
562 {
563 tag = new String(frames, 0, frames.length, "ISO-8859-1");
564 }
565 catch (UnsupportedEncodingException e)
566 {
567 tag = new String(frames, 0, frames.length);
568 if (TDebug.TraceAudioFileReader) TDebug.out("Cannot use ISO-8859-1");
569 }
570 if (TDebug.TraceAudioFileReader) TDebug.out("ID3v1 frame dump='"+tag+"'");
571 int start = 3;
572 String titlev1 = chopSubstring(tag, start, start += 30);
573 String titlev2 = (String) props.get("title");
574 if (((titlev2==null) || (titlev2.length()==0)) && (titlev1 != null)) props.put("title",titlev1);
575 String artistv1 = chopSubstring(tag, start, start += 30);
576 String artistv2 = (String) props.get("author");
577 if (((artistv2==null) || (artistv2.length()==0)) && (artistv1 != null)) props.put("author",artistv1);
578 String albumv1 = chopSubstring(tag, start, start += 30);
579 String albumv2 = (String) props.get("album");
580 if (((albumv2==null) || (albumv2.length()==0)) && (albumv1 != null)) props.put("album",albumv1);
581 String yearv1 = chopSubstring(tag, start, start += 4);
582 String yearv2 = (String) props.get("year");
583 if (((yearv2==null) || (yearv2.length()==0)) && (yearv1 != null)) props.put("date",yearv1);
584 String commentv1 = chopSubstring(tag, start, start += 28);
585 String commentv2 = (String) props.get("comment");
586 if (((commentv2==null) || (commentv2.length()==0)) && (commentv1 != null)) props.put("comment",commentv1);
587 String trackv1 = ""+((int) (frames[126] & 0xff));
588 String trackv2 = (String) props.get("mp3.id3tag.track");
589 if (((trackv2==null) || (trackv2.length()==0)) && (trackv1 != null)) props.put("mp3.id3tag.track",trackv1);
590
591 int genrev1 = (int) (frames[127] & 0xff);
592 if ((genrev1 >=0) && (genrev1<id3v1genres.length))
593 {
594 String genrev2 = (String) props.get("mp3.id3tag.genre");
595 if (((genrev2==null) || (genrev2.length()==0))) props.put("mp3.id3tag.genre",id3v1genres[genrev1]);
596 }
597 if (TDebug.TraceAudioFileReader) TDebug.out("ID3v1 parsed");
598 }
599
600 /**
601 * Extract
602 * @param s
603 * @param start
604 * @param end
605 * @return
606 */
607 private String chopSubstring(String s, int start, int end)
608 {
609 String str = null;
610 // 11/28/04 - String encoding bug fix.
611 try
612 {
613 str = s.substring(start, end);
614 int loc = str.indexOf('\0');
615 if (loc != -1) str = str.substring(0, loc);
616 }
617 catch (StringIndexOutOfBoundsException e)
618 {
619 // Skip encoding issues.
620 if (TDebug.TraceAudioFileReader) TDebug.out("Cannot chopSubString "+e.getMessage());
621 }
622 return str;
623 }
624 /**
625 * Parse ID3v2 frames to add album (TALB), title (TIT2), date (TYER), author (TPE1), copyright (TCOP), comment (COMM) ...
626 * @param frames
627 * @param props
628 */
629 protected void parseID3v2Frames(InputStream frames, HashMap props)
630 {
631 if (TDebug.TraceAudioFileReader) TDebug.out("Parsing ID3v2");
632 byte[] bframes = null;
633 int size = -1;
634 try
635 {
636 size = frames.available();
637 bframes = new byte[size];
638 frames.mark(size);
639 frames.read(bframes);
640 frames.reset();
641 }
642 catch (IOException e)
643 {
644 if (TDebug.TraceAudioFileReader) TDebug.out("Cannot parse ID3v2 :"+e.getMessage());
645 }
646
647 try
648 {
649 if (TDebug.TraceAudioFileReader) TDebug.out("ID3v2 frame dump='"+new String(bframes,0,bframes.length)+"'");
650 /* ID3 tags : http://www.unixgods.org/~tilo/ID3/docs/ID3_comparison.html */
651 String value = null;
652 for (int i=0;i<bframes.length-4;i++)
653 {
654 String code = new String(bframes,i,4);
655 String scode = new String(bframes,i,3);
656 // ID3v2.3 & v2.4
657 if ((code.equals("TALB")) || (code.equals("TIT2")) || (code.equals("TYER")) || (code.equals("TPE1")) || (code.equals("TCOP")) || (code.equals("COMM")) || (code.equals("TCON")) || (code.equals("TRCK")) || (code.equals("TPOS")) || (code.equals("TDRC")) || (code.equals("TCOM")) || (code.equals("TIT1")) || (code.equals("TENC")))
658 {
659 i=i+10;
660 size = (int) (bframes[i-6] << 24) + (bframes[i-5] << 16) + (bframes[i-4] << 8) + (bframes[i-3]);
661 if (code.equals("COMM")) value = parseText(bframes, i, size, 5);
662 else value = parseText(bframes,i, size, 1);
663 if ((value != null) && (value.length()>0))
664 {
665 if (code.equals("TALB")) props.put("album",value);
666 else if (code.equals("TIT2")) props.put("title",value);
667 else if (code.equals("TYER")) props.put("date",value);
668 // ID3v2.4 date fix.
669 else if (code.equals("TDRC")) props.put("date",value);
670 else if (code.equals("TPE1")) props.put("author",value);
671 else if (code.equals("TCOP")) props.put("copyright",value);
672 else if (code.equals("COMM")) props.put("comment",value);
673 else if (code.equals("TCON")) props.put("mp3.id3tag.genre",value);
674 else if (code.equals("TRCK")) props.put("mp3.id3tag.track",value);
675 else if (code.equals("TPOS")) props.put("mp3.id3tag.disc",value);
676 else if (code.equals("TCOM")) props.put("mp3.id3tag.composer",value);
677 else if (code.equals("TIT1")) props.put("mp3.id3tag.grouping",value);
678 else if (code.equals("TENC")) props.put("mp3.id3tag.encoded",value);
679 }
680 i=i+size-1;
681 }
682 // ID3v2.2.
683 else if ((scode.equals("TAL")) || (scode.equals("TT2")) || (scode.equals("TP1")) || (scode.equals("TYE")) || (scode.equals("TRK")) || (scode.equals("TPA")) || (scode.equals("TCR")) || (scode.equals("TCO")) || (scode.equals("TCM")) || (scode.equals("COM")) || (scode.equals("TT1")) || (scode.equals("TEN")))
684 {
685 i=i+6;
686 size = (int) (0x00000000) + (bframes[i-3] << 16) + (bframes[i-2] << 8) + (bframes[i-1]);
687 if (scode.equals("COM")) value = parseText(bframes, i, size, 5);
688 else value = parseText(bframes,i, size, 1);
689 if ((value != null) && (value.length()>0))
690 {
691 if (scode.equals("TAL")) props.put("album",value);
692 else if (scode.equals("TT2")) props.put("title",value);
693 else if (scode.equals("TYE")) props.put("date",value);
694 else if (scode.equals("TP1")) props.put("author",value);
695 else if (scode.equals("TCR")) props.put("copyright",value);
696 else if (scode.equals("COM")) props.put("comment",value);
697 else if (scode.equals("TCO")) props.put("mp3.id3tag.genre",value);
698 else if (scode.equals("TRK")) props.put("mp3.id3tag.track",value);
699 else if (scode.equals("TPA")) props.put("mp3.id3tag.disc",value);
700 else if (scode.equals("TCM")) props.put("mp3.id3tag.composer",value);
701 else if (scode.equals("TT1")) props.put("mp3.id3tag.grouping",value);
702 else if (scode.equals("TEN")) props.put("mp3.id3tag.encoded",value);
703 }
704 i=i+size-1;
705 }
706 else if (code.startsWith("ID3"))
707 {
708 // ID3v2 Header.
709 int v2version = (int) (bframes[3] & 0xFF);
710 props.put("mp3.id3tag.v2.version",String.valueOf(v2version));
711 i=i+4;
712 }
713 }
714 }
715 catch (RuntimeException e)
716 {
717 // Ignore all parsing errors.
718 if (TDebug.TraceAudioFileReader) TDebug.out("Cannot parse ID3v2 :"+e.getMessage());
719 }
720 if (TDebug.TraceAudioFileReader) TDebug.out("ID3v2 parsed");
721 }
722
723 /**
724 * Parse Text Frames.
725 * @param bframes
726 * @param offset
727 * @param size
728 * @param skip
729 * @return
730 */
731 protected String parseText(byte[] bframes, int offset, int size, int skip)
732 {
733 String value = null;
734 try
735 {
736 String[] ENC_TYPES = {"ISO-8859-1", "UTF16","UTF-16BE", "UTF-8"};
737 value = new String(bframes,offset+skip,size-skip,ENC_TYPES[bframes[offset]]);
738 value = chopSubstring(value,0,value.length());
739 }
740 catch (UnsupportedEncodingException e)
741 {
742 if (TDebug.TraceAudioFileReader) TDebug.out("ID3v2 Encoding error :"+e.getMessage());
743 }
744 return value;
745 }
746
747 /**
748 * Load shoutcast (ICY) info.
749 * @param input
750 * @param props
751 * @throws IOException
752 */
753 protected void loadShoutcastInfo(InputStream input, HashMap props) throws IOException
754 {
755 IcyInputStream icy = new IcyInputStream(new BufferedInputStream(input));
756 HashMap metadata = icy.getTagHash();
757 MP3Tag titleMP3Tag = icy.getTag("icy-name");
758 if (titleMP3Tag != null) props.put("title",((String) titleMP3Tag.getValue()).trim());
759 MP3Tag[] meta = icy.getTags();
760 if (meta != null)
761 {
762 StringBuffer metaStr = new StringBuffer();
763 for (int i=0;i<meta.length;i++)
764 {
765 String key = meta[i].getName();
766 String value = ((String) icy.getTag(key).getValue()).trim();
767 props.put("mp3.shoutcast.metadata."+key, value);
768 }
769 }
770 }
771
772} \ No newline at end of file
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFormat.java b/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFormat.java
new file mode 100644
index 0000000000..29a66a3d93
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFormat.java
@@ -0,0 +1,67 @@
1/*
2 * MpegAudioFormat.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 *-----------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------
22 */
23
24package javazoom.spi.mpeg.sampled.file;
25
26import java.util.Map;
27
28import javax.sound.sampled.AudioFormat;
29
30import org.tritonus.share.sampled.TAudioFormat;
31
32/**
33 * @author JavaZOOM
34 */
35public class MpegAudioFormat extends TAudioFormat
36{
37 /**
38 * Constructor.
39 * @param encoding
40 * @param nFrequency
41 * @param SampleSizeInBits
42 * @param nChannels
43 * @param FrameSize
44 * @param FrameRate
45 * @param isBigEndian
46 * @param properties
47 */
48 public MpegAudioFormat(AudioFormat.Encoding encoding, float nFrequency, int SampleSizeInBits, int nChannels, int FrameSize, float FrameRate, boolean isBigEndian, Map properties)
49 {
50 super(encoding, nFrequency, SampleSizeInBits, nChannels, FrameSize, FrameRate, isBigEndian, properties);
51 }
52
53 /**
54 * MP3 audio format parameters.
55 * Some parameters might be unavailable. So availability test is required before reading any parameter.
56 *
57 * <br>AudioFormat parameters.
58 * <ul>
59 * <li><b>bitrate</b> [Integer], bitrate in bits per seconds, average bitrate for VBR enabled stream.
60 * <li><b>vbr</b> [Boolean], VBR flag.
61 * </ul>
62 */
63 public Map properties()
64 {
65 return super.properties();
66 }
67}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/MpegEncoding.java b/songdbj/javazoom/spi/mpeg/sampled/file/MpegEncoding.java
new file mode 100644
index 0000000000..6306d9ec80
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/MpegEncoding.java
@@ -0,0 +1,47 @@
1/*
2 * MpegEncoding.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 *-----------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------
22 */
23
24package javazoom.spi.mpeg.sampled.file;
25
26import javax.sound.sampled.AudioFormat;
27
28/**
29 * Encodings used by the MPEG audio decoder.
30 */
31public class MpegEncoding extends AudioFormat.Encoding
32{
33 public static final AudioFormat.Encoding MPEG1L1 = new MpegEncoding("MPEG1L1");
34 public static final AudioFormat.Encoding MPEG1L2 = new MpegEncoding("MPEG1L2");
35 public static final AudioFormat.Encoding MPEG1L3 = new MpegEncoding("MPEG1L3");
36 public static final AudioFormat.Encoding MPEG2L1 = new MpegEncoding("MPEG2L1");
37 public static final AudioFormat.Encoding MPEG2L2 = new MpegEncoding("MPEG2L2");
38 public static final AudioFormat.Encoding MPEG2L3 = new MpegEncoding("MPEG2L3");
39 public static final AudioFormat.Encoding MPEG2DOT5L1 = new MpegEncoding("MPEG2DOT5L1");
40 public static final AudioFormat.Encoding MPEG2DOT5L2 = new MpegEncoding("MPEG2DOT5L2");
41 public static final AudioFormat.Encoding MPEG2DOT5L3 = new MpegEncoding("MPEG2DOT5L3");
42
43 public MpegEncoding(String strName)
44 {
45 super(strName);
46 }
47}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/MpegFileFormatType.java b/songdbj/javazoom/spi/mpeg/sampled/file/MpegFileFormatType.java
new file mode 100644
index 0000000000..2c59ad8621
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/MpegFileFormatType.java
@@ -0,0 +1,40 @@
1/*
2 * MpegFileFormatType.
3 *
4 * JavaZOOM : mp3spi@javazoom.net
5 * http://www.javazoom.net
6 *
7 *-----------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *----------------------------------------------------------------------
22 */
23
24package javazoom.spi.mpeg.sampled.file;
25
26import javax.sound.sampled.AudioFileFormat;
27
28/**
29 * FileFormatTypes used by the MPEG audio decoder.
30 */
31public class MpegFileFormatType extends AudioFileFormat.Type
32{
33 public static final AudioFileFormat.Type MPEG = new MpegFileFormatType("MPEG", "mpeg");
34 public static final AudioFileFormat.Type MP3 = new MpegFileFormatType("MP3", "mp3");
35
36 public MpegFileFormatType(String strName, String strExtension)
37 {
38 super(strName, strExtension);
39 }
40}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyInputStream.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyInputStream.java
new file mode 100644
index 0000000000..22aa4439fe
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyInputStream.java
@@ -0,0 +1,412 @@
1/*
2 * IcyInputStream.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27
28import java.io.BufferedInputStream;
29import java.io.IOException;
30import java.io.InputStream;
31import java.net.URL;
32import java.net.URLConnection;
33import java.util.HashMap;
34import java.util.StringTokenizer;
35
36/** An BufferedInputStream that parses Shoutcast's "icy" metadata
37 from the stream. Gets headers at the beginning and if the
38 "icy-metaint" tag is found, it parses and strips in-stream
39 metadata.
40 <p>
41 <b>The deal with metaint</b>: Icy streams don't try to put
42 tags between MP3 frames the way that ID3 does. Instead, it
43 requires the client to strip metadata from the stream before
44 it hits the decoder. You get an
45 <code>icy-metaint</code> name/val in the beginning of the
46 stream iff you sent "Icy-Metadata" with value "1" in the
47 request headers (SimpleMP3DataSource does this if the
48 "parseStreamMetadata" boolean is true). If this is the case
49 then the value of icy-metaint is the amount of real data
50 between metadata blocks. Each block begins with an int
51 indicating how much metadata there is -- the block is this
52 value times 16 (it can be, and often is, 0).
53 <p>
54 Originally thought that "icy" implied Icecast, but this is
55 completely wrong -- real Icecast servers, found through
56 www.icecast.net and typified by URLs with a trailing directory
57 (like CalArts School of Music - http://65.165.174.100:8000/som)
58 do not have the "ICY 200 OK" magic string or any of the
59 CRLF-separated headers. Apparently, "icy" means "Shoutcast".
60 Yep, that's weird.
61 @author Chris Adamson, invalidname@mac.com
62 */
63public class IcyInputStream
64 extends BufferedInputStream
65 implements MP3MetadataParser {
66
67 public static boolean DEBUG = false;
68
69 MP3TagParseSupport tagParseSupport;
70 /** inline tags are delimited by ';', also filter out
71 null bytes
72 */
73 protected static final String INLINE_TAG_SEPARATORS = ";\u0000";
74 /* looks like icy streams start start with
75 ICY 200 OK\r\n
76 then the tags are like
77 icy-notice1:<BR>This stream requires <a href="http://www.winamp.com/">Winamp</a><BR>\r\n
78 icy-notice2:SHOUTcast Distributed Network Audio Server/win32 v1.8.2<BR>\r\n
79 icy-name:Core-upt Radio\r\n
80 icy-genre:Punk Ska Emo\r\n
81 icy-url:http://www.core-uptrecords.com\r\n
82 icy-pub:1\r\n
83 icy-metaint:8192\r\n
84 icy-br:56\r\n
85 \r\n (signifies end of headers)
86 we only get icy-metaint if the http request that created
87 this stream sent the header "icy-metadata:1"
88 //
89 in in-line metadata, we read a byte that tells us how
90 many 16-byte blocks there are (presumably, we still use
91 \r\n for the separator... the block is padded out with
92 0x00's that we can ignore)
93
94 // when server is full/down/etc, we get the following for
95 // one of the notice lines:
96 icy-notice2:This server has reached its user limit<BR>
97 or
98 icy-notice2:The resource requested is currently unavailable<BR>
99 */
100 /** Tags that have been discovered in the stream.
101 */
102 HashMap tags;
103 /** Buffer for readCRLF line... note this limits lines to
104 1024 chars (I've read that WinAmp barfs at 128, so
105 this is generous)
106 */
107 protected byte[] crlfBuffer = new byte[1024];
108 /** value of the "metaint" tag, which tells us how many bytes
109 of real data are between the metadata tags. if -1, this stream
110 does not have metadata after the header.
111 */
112 protected int metaint = -1;
113 /** how many bytes of real data remain before the next
114 block of metadata. Only meaningful if metaint != -1.
115 */
116 protected int bytesUntilNextMetadata = -1;
117 // TODO: comment for constructor
118 /** Reads the initial headers of the stream and adds
119 tags appropriatly. Gets set up to find, read,
120 and strip blocks of in-line metadata if the
121 <code>icy-metaint</code> header is found.
122 */
123 public IcyInputStream(InputStream in) throws IOException {
124 super(in);
125 tags = new HashMap();
126 tagParseSupport = new MP3TagParseSupport();
127 // read the initial tags here, including the metaint
128 // and set the counter for how far we read until
129 // the next metadata block (if any).
130 readInitialHeaders();
131 IcyTag metaIntTag = (IcyTag) getTag("icy-metaint");
132 if (DEBUG) System.out.println("METATAG:"+metaIntTag);
133 if (metaIntTag != null) {
134 String metaIntString = metaIntTag.getValueAsString();
135 try {
136 metaint = Integer.parseInt(metaIntString.trim());
137 if (DEBUG) System.out.println("METAINT:"+metaint);
138 bytesUntilNextMetadata = metaint;
139 }
140 catch (NumberFormatException nfe) {
141 }
142 }
143 }
144
145 /**
146 * IcyInputStream constructor for know meta-interval (Icecast 2)
147 * @param in
148 * @param metaint
149 * @throws IOException
150 */
151 public IcyInputStream(InputStream in, String metaIntString) throws IOException {
152 super(in);
153 tags = new HashMap();
154 tagParseSupport = new MP3TagParseSupport();
155 try
156 {
157 metaint = Integer.parseInt(metaIntString.trim());
158 if (DEBUG) System.out.println("METAINT:"+metaint);
159 bytesUntilNextMetadata = metaint;
160 }
161 catch (NumberFormatException nfe) {
162 }
163 }
164
165 /** Assuming we're at the top of the stream, read lines one
166 by one until we hit a completely blank \r\n. Parse the
167 data as IcyTags.
168 */
169 protected void readInitialHeaders() throws IOException {
170 String line = null;
171 while (!((line = readCRLFLine()).equals(""))) {
172 int colonIndex = line.indexOf(':');
173 // does it have a ':' separator
174 if (colonIndex == -1)
175 continue;
176 IcyTag tag =
177 new IcyTag(
178 line.substring(0, colonIndex),
179 line.substring(colonIndex + 1));
180 //System.out.println(tag);
181 addTag(tag);
182 }
183 }
184 /** Read everything up to the next CRLF, return it as
185 a String.
186 */
187 protected String readCRLFLine() throws IOException {
188 int i = 0;
189 for (; i < crlfBuffer.length; i++) {
190 byte aByte = (byte) read();
191 if (aByte == '\r') {
192 // possible end of line
193 byte anotherByte = (byte) read();
194 i++; // since we read again
195 if (anotherByte == '\n') {
196 break; // break out of while
197 }
198 else {
199 // oops, not end of line - put these in array
200 crlfBuffer[i - 1] = aByte;
201 crlfBuffer[i] = anotherByte;
202 }
203 }
204 else {
205 // if not \r
206 crlfBuffer[i] = aByte;
207 }
208 } // for
209 // get the string from the byte[]. i is 1 too high because of
210 // read-ahead in crlf block
211 return new String(crlfBuffer, 0, i - 1);
212 }
213 /** Reads and returns a single byte.
214 If the next byte is a metadata block, then that
215 block is read, stripped, and parsed before reading
216 and returning the first byte after the metadata block.
217 */
218 public int read() throws IOException {
219 if (bytesUntilNextMetadata > 0) {
220 bytesUntilNextMetadata--;
221 return super.read();
222 }
223 else if (bytesUntilNextMetadata == 0) {
224 // we need to read next metadata block
225 readMetadata();
226 bytesUntilNextMetadata = metaint - 1;
227 // -1 because we read byte on next line
228 return super.read();
229 }
230 else {
231 // no metadata in this stream
232 return super.read();
233 }
234 }
235 /** Reads a block of bytes. If the next byte is known
236 to be a block of metadata, then that is read, parsed,
237 and stripped, and then a block of bytes is read and
238 returned.
239 Otherwise, it may read up to but
240 not into the next metadata block if
241 <code>bytesUntilNextMetadata &lt; length</code>
242 */
243 public int read(byte[] buf, int offset, int length) throws IOException {
244 // if not on metadata, do the usual read so long as we
245 // don't read past metadata
246 if (bytesUntilNextMetadata > 0) {
247 int adjLength = Math.min(length, bytesUntilNextMetadata);
248 int got = super.read(buf, offset, adjLength);
249 bytesUntilNextMetadata -= got;
250 return got;
251 }
252 else if (bytesUntilNextMetadata == 0) {
253 // read/parse the metadata
254 readMetadata();
255 // now as above, except that we reset
256 // bytesUntilNextMetadata differently
257
258 //int adjLength = Math.min(length, bytesUntilNextMetadata);
259 //int got = super.read(buf, offset, adjLength);
260 //bytesUntilNextMetadata = metaint - got;
261
262 // Chop Fix - JavaZOOM (3 lines above seem buggy)
263 bytesUntilNextMetadata = metaint;
264 int adjLength = Math.min(length, bytesUntilNextMetadata);
265 int got = super.read(buf, offset, adjLength);
266 bytesUntilNextMetadata -= got;
267 // End fix - JavaZOOM
268
269
270 return got;
271 }
272 else {
273 // not even reading metadata
274 return super.read(buf, offset, length);
275 }
276 }
277 /** trivial <code>return read (buf, 0, buf.length)</code>
278 */
279 public int read(byte[] buf) throws IOException {
280 return read(buf, 0, buf.length);
281 }
282 /** Read the next segment of metadata. The stream <b>must</b>
283 be right on the segment, ie, the next byte to read is
284 the metadata block count. The metadata is parsed and
285 new tags are added with addTag(), which fires events
286 */
287 protected void readMetadata() throws IOException {
288 int blockCount = super.read();
289 if (DEBUG) System.out.println("BLOCKCOUNT:"+blockCount);
290 // System.out.println ("blocks to read: " + blockCount);
291 int byteCount = (blockCount * 16); // 16 bytes per block
292 if (byteCount < 0)
293 return; // WTF?!
294 byte[] metadataBlock = new byte[byteCount];
295 int index = 0;
296 // build an array of this metadata
297 while (byteCount > 0) {
298 int bytesRead = super.read(metadataBlock, index, byteCount);
299 index += bytesRead;
300 byteCount -= bytesRead;
301 }
302 // now parse it
303 if (blockCount > 0)
304 parseInlineIcyTags(metadataBlock);
305 } // readMetadata
306 /** Parse metadata from an in-stream "block" of bytes, add
307 a tag for each one.
308 <p>
309 Hilariously, the inline data format is totally different
310 than the top-of-stream header. For example, here's a
311 block I saw on "Final Fantasy Radio":
312 <pre>
313 StreamTitle='Final Fantasy 8 - Nobuo Uematsu - Blue Fields';StreamUrl='';
314 </pre>
315 In other words:
316 <ol>
317 <li>Tags are delimited by semicolons
318 <li>Keys/values are delimited by equals-signs
319 <li>Values are wrapped in single-quotes
320 <li>Key names are in SentenceCase, not lowercase-dashed
321 </ol>
322 */
323 protected void parseInlineIcyTags(byte[] tagBlock) {
324 String blockString = new String(tagBlock);
325 if (DEBUG) System.out.println("BLOCKSTR:"+blockString);
326 StringTokenizer izer =
327 new StringTokenizer(blockString, INLINE_TAG_SEPARATORS);
328 int i = 0;
329 while (izer.hasMoreTokens()) {
330 String tagString = izer.nextToken();
331 int separatorIdx = tagString.indexOf('=');
332 if (separatorIdx == -1)
333 continue; // bogus tagString if no '='
334 // try to strip single-quotes around value, if present
335 int valueStartIdx =
336 (tagString.charAt(separatorIdx + 1) == '\'')
337 ? separatorIdx + 2
338 : separatorIdx + 1;
339 int valueEndIdx =
340 (tagString.charAt(tagString.length() - 1)) == '\''
341 ? tagString.length() - 1
342 : tagString.length();
343 String name = tagString.substring(0, separatorIdx);
344 String value = tagString.substring(valueStartIdx, valueEndIdx);
345 // System.out.println (i++ + " " + name + ":" + value);
346 IcyTag tag = new IcyTag(name, value);
347 addTag(tag);
348 }
349 }
350 /** adds the tag to the HashMap of tags we have encountered
351 either in-stream or as headers, replacing any previous
352 tag with this name.
353 */
354 protected void addTag(IcyTag tag) {
355 tags.put(tag.getName(), tag);
356 // fire this as an event too
357 tagParseSupport.fireTagParsed(this, tag);
358 }
359 /** Get the named tag from the HashMap of headers and
360 in-line tags. Null if no such tag has been encountered.
361 */
362 public MP3Tag getTag(String tagName) {
363 return (MP3Tag) tags.get(tagName);
364 }
365 /** Get all tags (headers or in-stream) encountered thus far.
366 */
367 public MP3Tag[] getTags() {
368 return (MP3Tag[]) tags.values().toArray(new MP3Tag[0]);
369 }
370 /** Returns a HashMap of all headers and in-stream tags
371 parsed so far.
372 */
373 public HashMap getTagHash() {
374 return tags;
375 }
376 /** Adds a TagParseListener to be notified when this stream
377 parses MP3Tags.
378 */
379 public void addTagParseListener(TagParseListener tpl) {
380 tagParseSupport.addTagParseListener(tpl);
381 }
382 /** Removes a TagParseListener, so it won't be notified when
383 this stream parses MP3Tags.
384 */
385 public void removeTagParseListener(TagParseListener tpl) {
386 tagParseSupport.removeTagParseListener(tpl);
387 }
388 /** Quickie unit-test.
389 */
390 public static void main(String args[]) {
391 byte[] chow = new byte[200];
392 if (args.length != 1) {
393 //System.out.println("Usage: IcyInputStream <url>");
394 return;
395 }
396 try {
397 URL url = new URL(args[0]);
398 URLConnection conn = url.openConnection();
399 conn.setRequestProperty("Icy-Metadata", "1");
400 IcyInputStream icy =
401 new IcyInputStream(
402 new BufferedInputStream(conn.getInputStream()));
403 while (icy.available() > -1) {
404 // icy.read();
405 icy.read(chow, 0, chow.length);
406 }
407 }
408 catch (Exception e) {
409 e.printStackTrace();
410 }
411 }
412}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyTag.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyTag.java
new file mode 100644
index 0000000000..bbe70f1f3c
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/IcyTag.java
@@ -0,0 +1,42 @@
1/*
2 * IcyTag.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27/**
28 * A tag parsed from an icecast tag.
29 */
30public class IcyTag extends MP3Tag implements StringableTag {
31 /** Create a new tag, from the parsed name and (String) value.
32 It looks like all Icecast tags are Strings (safe to assume
33 this going forward?)
34 */
35 public IcyTag(String name, String stringValue) {
36 super(name, stringValue);
37 }
38 // so far as I know, all Icecast tags are strings
39 public String getValueAsString() {
40 return (String) getValue();
41 }
42}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3MetadataParser.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3MetadataParser.java
new file mode 100644
index 0000000000..81511064b8
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3MetadataParser.java
@@ -0,0 +1,50 @@
1/*
2 * MP3MetadataParser.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27
28/** An object that fires off TagParseEvents as they are parsed
29 from a stream, ServerSocket, or other metadata source
30 */
31public interface MP3MetadataParser {
32 /** Adds a TagParseListener to be notified when this object
33 parses MP3Tags.
34 */
35 public void addTagParseListener(TagParseListener tpl);
36 /** Removes a TagParseListener, so it won't be notified when
37 this object parses MP3Tags.
38 */
39 public void removeTagParseListener(TagParseListener tpl);
40 /** Get all tags (headers or in-stream) encountered thusfar.
41 This is included in this otherwise Listener-like scheme
42 because most standards are a mix of start-of-stream
43 metadata tags (like the http headers or the stuff at the
44 top of an ice stream) and inline data. Implementations should
45 hang onto all tags they parse and provide them with this
46 call. Callers should first use this call to get initial
47 tags, then subscribe for events as the stream continues.
48 */
49 public MP3Tag[] getTags();
50}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3Tag.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3Tag.java
new file mode 100644
index 0000000000..b545356240
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3Tag.java
@@ -0,0 +1,52 @@
1/*
2 * MP3Tag.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27
28/** An individual piece of mp3 metadata, as a name/value pair.
29 Abstract just so that subclasses will indicate their
30 tagging scheme (Icy, ID3, etc.).
31 */
32public abstract class MP3Tag extends Object {
33 protected String name;
34 protected Object value;
35 public MP3Tag(String name, Object value) {
36 this.name = name;
37 this.value = value;
38 }
39 public String getName() {
40 return name;
41 }
42 public Object getValue() {
43 return value;
44 }
45 public String toString() {
46 return getClass().getName()
47 + " -- "
48 + getName()
49 + ":"
50 + getValue().toString();
51 }
52}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3TagParseSupport.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3TagParseSupport.java
new file mode 100644
index 0000000000..1ab6525512
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/MP3TagParseSupport.java
@@ -0,0 +1,62 @@
1/*
2 * MP3TagParseSupport.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27
28import java.util.ArrayList;
29/**
30*/
31public class MP3TagParseSupport extends Object {
32 ArrayList tagParseListeners;
33 /** trivial constructor, sets up listeners list.
34 */
35 public MP3TagParseSupport() {
36 super();
37 tagParseListeners = new ArrayList();
38 }
39 /** Adds a TagParseListener to be notified when a stream
40 parses MP3Tags.
41 */
42 public void addTagParseListener(TagParseListener tpl) {
43 tagParseListeners.add(tpl);
44 }
45 /** Removes a TagParseListener, so it won't be notified when
46 a stream parses MP3Tags.
47 */
48 public void removeTagParseListener(TagParseListener tpl) {
49 tagParseListeners.add(tpl);
50 }
51 /** Fires the given event to all registered listeners
52 */
53 public void fireTagParseEvent(TagParseEvent tpe) {
54 for (int i = 0; i < tagParseListeners.size(); i++) {
55 TagParseListener l = (TagParseListener) tagParseListeners.get(i);
56 l.tagParsed(tpe);
57 }
58 }
59 public void fireTagParsed(Object source, MP3Tag tag) {
60 fireTagParseEvent(new TagParseEvent(source, tag));
61 }
62}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/StringableTag.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/StringableTag.java
new file mode 100644
index 0000000000..685c5207f9
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/StringableTag.java
@@ -0,0 +1,36 @@
1/*
2 * StringableTag.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27
28/** Indicates that the value of a tag is a string, and
29 provides a getValueAsString() method to get it.
30 Appropriate for tags like artist, title, etc.
31 */
32public interface StringableTag {
33 /** Return the value of this tag as a string.
34 */
35 public String getValueAsString();
36}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseEvent.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseEvent.java
new file mode 100644
index 0000000000..97e9ec1e19
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseEvent.java
@@ -0,0 +1,44 @@
1/*
2 * TagParseEvent.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27
28import java.util.EventObject;
29/** Event to indicate that an MP3 tag was received through
30 some means (parsed in stream, received via UDP, whatever)
31 and converted into an MP3Tag object.
32 */
33public class TagParseEvent extends EventObject {
34 protected MP3Tag tag;
35 public TagParseEvent(Object source, MP3Tag tag) {
36 super(source);
37 this.tag = tag;
38 }
39 /** Get the tag that was parsed.
40 */
41 public MP3Tag getTag() {
42 return tag;
43 }
44}
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseListener.java b/songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseListener.java
new file mode 100644
index 0000000000..a630827297
--- /dev/null
+++ b/songdbj/javazoom/spi/mpeg/sampled/file/tag/TagParseListener.java
@@ -0,0 +1,37 @@
1/*
2 * TagParseListener.
3 *
4 * jicyshout : http://sourceforge.net/projects/jicyshout/
5 *
6 * JavaZOOM : mp3spi@javazoom.net
7 * http://www.javazoom.net
8 *
9 *-----------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *----------------------------------------------------------------------
24 */
25
26package javazoom.spi.mpeg.sampled.file.tag;
27
28import java.util.EventListener;
29/** EventListener to be implemented by objects that want to
30 get callbacks when MP3 tags are received.
31 */
32public interface TagParseListener extends EventListener {
33 /** Called when a tag is found (parsed from the stream,
34 received via UDP, etc.)
35 */
36 public void tagParsed(TagParseEvent tpe);
37}
diff --git a/songdbj/javazoom/spi/vorbis/sampled/convert/DecodedVorbisAudioInputStream.java b/songdbj/javazoom/spi/vorbis/sampled/convert/DecodedVorbisAudioInputStream.java
new file mode 100644
index 0000000000..b8e8577e13
--- /dev/null
+++ b/songdbj/javazoom/spi/vorbis/sampled/convert/DecodedVorbisAudioInputStream.java
@@ -0,0 +1,519 @@
1/*
2 * DecodedVorbisAudioInputStream
3 *
4 * JavaZOOM : vorbisspi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * ----------------------------------------------------------------------------
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Library General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * ----------------------------------------------------------------------------
22 */
23
24package javazoom.spi.vorbis.sampled.convert;
25
26import java.io.IOException;
27import java.io.InputStream;
28import java.util.HashMap;
29import java.util.Map;
30
31import javax.sound.sampled.AudioFormat;
32import javax.sound.sampled.AudioInputStream;
33
34import javazoom.spi.PropertiesContainer;
35
36import org.tritonus.share.TDebug;
37import org.tritonus.share.sampled.convert.TAsynchronousFilteredAudioInputStream;
38
39import com.jcraft.jogg.Packet;
40import com.jcraft.jogg.Page;
41import com.jcraft.jogg.StreamState;
42import com.jcraft.jogg.SyncState;
43import com.jcraft.jorbis.Block;
44import com.jcraft.jorbis.Comment;
45import com.jcraft.jorbis.DspState;
46import com.jcraft.jorbis.Info;
47
48/**
49 * This class implements the Vorbis decoding.
50 */
51public class DecodedVorbisAudioInputStream extends TAsynchronousFilteredAudioInputStream implements PropertiesContainer
52{
53 private InputStream oggBitStream_ = null;
54
55 private SyncState oggSyncState_ = null;
56 private StreamState oggStreamState_ = null;
57 private Page oggPage_ = null;
58 private Packet oggPacket_ = null;
59 private Info vorbisInfo = null;
60 private Comment vorbisComment = null;
61 private DspState vorbisDspState = null;
62 private Block vorbisBlock = null;
63
64 static final int playState_NeedHeaders = 0;
65 static final int playState_ReadData = 1;
66 static final int playState_WriteData = 2;
67 static final int playState_Done = 3;
68 static final int playState_BufferFull = 4;
69 static final int playState_Corrupt = -1;
70 private int playState;
71
72 private int bufferMultiple_ = 4;
73 private int bufferSize_ = bufferMultiple_ * 256 * 2;
74 private int convsize = bufferSize_ * 2;
75 private byte[] convbuffer = new byte[convsize];
76 private byte[] buffer = null;
77 private int bytes = 0;
78 private float[][][] _pcmf = null;
79 private int[] _index = null;
80 private int index = 0;
81 private int i = 0;
82 // bout is now a global so that we can continue from when we have a buffer full.
83 int bout = 0;
84
85 private HashMap properties = null;
86 private long currentBytes = 0;
87
88 /**
89 * Constructor.
90 */
91 public DecodedVorbisAudioInputStream(AudioFormat outputFormat, AudioInputStream bitStream)
92 {
93 super(outputFormat, -1);
94 this.oggBitStream_ = bitStream;
95 init_jorbis();
96 index = 0;
97 playState = playState_NeedHeaders;
98 properties = new HashMap();
99 }
100
101 /**
102 * Initializes all the jOrbis and jOgg vars that are used for song playback.
103 */
104 private void init_jorbis()
105 {
106 oggSyncState_ = new SyncState();
107 oggStreamState_ = new StreamState();
108 oggPage_ = new Page();
109 oggPacket_ = new Packet();
110 vorbisInfo = new Info();
111 vorbisComment = new Comment();
112 vorbisDspState = new DspState();
113 vorbisBlock = new Block(vorbisDspState);
114 buffer = null;
115 bytes = 0;
116 currentBytes = 0L;
117 oggSyncState_.init();
118 }
119
120 /**
121 * Return dynamic properties.
122 *
123 * <ul>
124 * <li><b>ogg.position.byte</b> [Long], current position in bytes in the stream.
125 *</ul>
126 */
127 public Map properties()
128 {
129 properties.put("ogg.position.byte",new Long(currentBytes));
130 return properties;
131 }
132 /**
133 * Main loop.
134 */
135 public void execute()
136 {
137 if(TDebug.TraceAudioConverter)
138 {
139 switch(playState)
140 {
141 case playState_NeedHeaders:
142 TDebug.out("playState = playState_NeedHeaders");
143 break;
144 case playState_ReadData:
145 TDebug.out("playState = playState_ReadData");
146 break;
147 case playState_WriteData:
148 TDebug.out("playState = playState_WriteData");
149 break;
150 case playState_Done:
151 TDebug.out("playState = playState_Done");
152 break;
153 case playState_BufferFull:
154 TDebug.out("playState = playState_BufferFull");
155 break;
156 case playState_Corrupt:
157 TDebug.out("playState = playState_Corrupt");
158 break;
159 }
160 }
161 // This code was developed by the jCraft group, as JOrbisPlayer.java, slightly
162 // modified by jOggPlayer developer and adapted by JavaZOOM to suit the JavaSound
163 // SPI. Then further modified by Tom Kimpton to correctly play ogg files that
164 // would hang the player.
165 switch(playState)
166 {
167 case playState_NeedHeaders:
168 try
169 {
170 // Headers (+ Comments).
171 readHeaders();
172 }
173 catch(IOException ioe)
174 {
175 playState = playState_Corrupt;
176 return;
177 }
178 playState = playState_ReadData;
179 break;
180
181 case playState_ReadData:
182 int result;
183 index = oggSyncState_.buffer(bufferSize_);
184 buffer = oggSyncState_.data;
185 bytes = readFromStream(buffer, index, bufferSize_);
186 if(TDebug.TraceAudioConverter) TDebug.out("More data : " + bytes);
187 if(bytes == -1)
188 {
189 playState = playState_Done;
190 if(TDebug.TraceAudioConverter) TDebug.out("Ogg Stream empty. Settings playState to playState_Done.");
191 break;
192 }
193 else
194 {
195 oggSyncState_.wrote(bytes);
196 if(bytes == 0)
197 {
198 if((oggPage_.eos() != 0) || (oggStreamState_.e_o_s != 0) || (oggPacket_.e_o_s != 0))
199 {
200 if(TDebug.TraceAudioConverter) TDebug.out("oggSyncState wrote 0 bytes: settings playState to playState_Done.");
201 playState = playState_Done;
202 }
203 if(TDebug.TraceAudioConverter) TDebug.out("oggSyncState wrote 0 bytes: but stream not yet empty.");
204 break;
205 }
206 }
207
208 result = oggSyncState_.pageout(oggPage_);
209 if(result == 0)
210 {
211 if(TDebug.TraceAudioConverter) TDebug.out("Setting playState to playState_ReadData.");
212 playState = playState_ReadData;
213 break;
214 } // need more data
215 if(result == -1)
216 { // missing or corrupt data at this page position
217 if(TDebug.TraceAudioConverter) TDebug.out("Corrupt or missing data in bitstream; setting playState to playState_ReadData");
218 playState = playState_ReadData;
219 break;
220 }
221
222 oggStreamState_.pagein(oggPage_);
223
224 if(TDebug.TraceAudioConverter) TDebug.out("Setting playState to playState_WriteData.");
225 playState = playState_WriteData;
226 break;
227
228 case playState_WriteData:
229 // Decoding !
230 if(TDebug.TraceAudioConverter) TDebug.out("Decoding");
231 while(true)
232 {
233 result = oggStreamState_.packetout(oggPacket_);
234 if(result == 0)
235 {
236 if(TDebug.TraceAudioConverter) TDebug.out("Packetout returned 0, going to read state.");
237 playState = playState_ReadData;
238 break;
239 } // need more data
240 else if(result == -1)
241 {
242 // missing or corrupt data at this page position
243 // no reason to complain; already complained above
244 if(TDebug.TraceAudioConverter) TDebug.out("Corrupt or missing data in packetout bitstream; going to read state...");
245 // playState = playState_ReadData;
246 // break;
247 continue;
248 }
249 else
250 {
251 // we have a packet. Decode it
252 if(vorbisBlock.synthesis(oggPacket_) == 0)
253 { // test for success!
254 vorbisDspState.synthesis_blockin(vorbisBlock);
255 }
256 else
257 {
258 //if(TDebug.TraceAudioConverter) TDebug.out("vorbisBlock.synthesis() returned !0, going to read state");
259 if(TDebug.TraceAudioConverter) TDebug.out("VorbisBlock.synthesis() returned !0, continuing.");
260 continue;
261 }
262
263 outputSamples();
264 if(playState == playState_BufferFull)
265 return;
266
267 } // else result != -1
268 } // while(true)
269 if(oggPage_.eos() != 0)
270 {
271 if(TDebug.TraceAudioConverter) TDebug.out("Settings playState to playState_Done.");
272 playState = playState_Done;
273 }
274 break;
275 case playState_BufferFull:
276 continueFromBufferFull();
277 break;
278
279 case playState_Corrupt:
280 if(TDebug.TraceAudioConverter) TDebug.out("Corrupt Song.");
281 // drop through to playState_Done...
282 case playState_Done:
283 oggStreamState_.clear();
284 vorbisBlock.clear();
285 vorbisDspState.clear();
286 vorbisInfo.clear();
287 oggSyncState_.clear();
288 if(TDebug.TraceAudioConverter) TDebug.out("Done Song.");
289 try
290 {
291 if(oggBitStream_ != null)
292 {
293 oggBitStream_.close();
294 }
295 getCircularBuffer().close();
296 }
297 catch(Exception e)
298 {
299 if(TDebug.TraceAudioConverter) TDebug.out(e.getMessage());
300 }
301 break;
302 } // switch
303 }
304
305 /**
306 * This routine was extracted so that when the output buffer fills up,
307 * we can break out of the loop, let the music channel drain, then
308 * continue from where we were.
309 */
310 private void outputSamples()
311 {
312 int samples;
313 while((samples = vorbisDspState.synthesis_pcmout(_pcmf, _index)) > 0)
314 {
315 float[][] pcmf = _pcmf[0];
316 bout = (samples < convsize ? samples : convsize);
317 double fVal = 0.0;
318 // convert doubles to 16 bit signed ints (host order) and
319 // interleave
320 for(i = 0; i < vorbisInfo.channels; i++)
321 {
322 int pointer = i * 2;
323 //int ptr=i;
324 int mono = _index[i];
325 for(int j = 0; j < bout; j++)
326 {
327 fVal = pcmf[i][mono + j] * 32767.;
328 int val = (int) (fVal);
329 if(val > 32767)
330 {
331 val = 32767;
332 }
333 if(val < -32768)
334 {
335 val = -32768;
336 }
337 if(val < 0)
338 {
339 val = val | 0x8000;
340 }
341 convbuffer[pointer] = (byte) (val);
342 convbuffer[pointer + 1] = (byte) (val >>> 8);
343 pointer += 2 * (vorbisInfo.channels);
344 }
345 }
346 if(TDebug.TraceAudioConverter) TDebug.out("about to write: " + 2 * vorbisInfo.channels * bout);
347 if(getCircularBuffer().availableWrite() < 2 * vorbisInfo.channels * bout)
348 {
349 if(TDebug.TraceAudioConverter) TDebug.out("Too much data in this data packet, better return, let the channel drain, and try again...");
350 playState = playState_BufferFull;
351 return;
352 }
353 getCircularBuffer().write(convbuffer, 0, 2 * vorbisInfo.channels * bout);
354 if(bytes < bufferSize_)
355 if(TDebug.TraceAudioConverter) TDebug.out("Finished with final buffer of music?");
356 if(vorbisDspState.synthesis_read(bout) != 0)
357 {
358 if(TDebug.TraceAudioConverter) TDebug.out("VorbisDspState.synthesis_read returned -1.");
359 }
360 } // while(samples...)
361 playState = playState_ReadData;
362 }
363
364 private void continueFromBufferFull()
365 {
366 if(getCircularBuffer().availableWrite() < 2 * vorbisInfo.channels * bout)
367 {
368 if(TDebug.TraceAudioConverter) TDebug.out("Too much data in this data packet, better return, let the channel drain, and try again...");
369 // Don't change play state.
370 return;
371 }
372 getCircularBuffer().write(convbuffer, 0, 2 * vorbisInfo.channels * bout);
373 // Don't change play state. Let outputSamples change play state, if necessary.
374 outputSamples();
375 }
376 /**
377 * Reads headers and comments.
378 */
379 private void readHeaders() throws IOException
380 {
381 if(TDebug.TraceAudioConverter) TDebug.out("readHeaders(");
382 index = oggSyncState_.buffer(bufferSize_);
383 buffer = oggSyncState_.data;
384 bytes = readFromStream(buffer, index, bufferSize_);
385 if(bytes == -1)
386 {
387 if(TDebug.TraceAudioConverter) TDebug.out("Cannot get any data from selected Ogg bitstream.");
388 throw new IOException("Cannot get any data from selected Ogg bitstream.");
389 }
390 oggSyncState_.wrote(bytes);
391 if(oggSyncState_.pageout(oggPage_) != 1)
392 {
393 if(bytes < bufferSize_)
394 {
395 throw new IOException("EOF");
396 }
397 if(TDebug.TraceAudioConverter) TDebug.out("Input does not appear to be an Ogg bitstream.");
398 throw new IOException("Input does not appear to be an Ogg bitstream.");
399 }
400 oggStreamState_.init(oggPage_.serialno());
401 vorbisInfo.init();
402 vorbisComment.init();
403 if(oggStreamState_.pagein(oggPage_) < 0)
404 {
405 // error; stream version mismatch perhaps
406 if(TDebug.TraceAudioConverter) TDebug.out("Error reading first page of Ogg bitstream data.");
407 throw new IOException("Error reading first page of Ogg bitstream data.");
408 }
409 if(oggStreamState_.packetout(oggPacket_) != 1)
410 {
411 // no page? must not be vorbis
412 if(TDebug.TraceAudioConverter) TDebug.out("Error reading initial header packet.");
413 throw new IOException("Error reading initial header packet.");
414 }
415 if(vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_) < 0)
416 {
417 // error case; not a vorbis header
418 if(TDebug.TraceAudioConverter) TDebug.out("This Ogg bitstream does not contain Vorbis audio data.");
419 throw new IOException("This Ogg bitstream does not contain Vorbis audio data.");
420 }
421 //int i = 0;
422 i = 0;
423 while(i < 2)
424 {
425 while(i < 2)
426 {
427 int result = oggSyncState_.pageout(oggPage_);
428 if(result == 0)
429 {
430 break;
431 } // Need more data
432 if(result == 1)
433 {
434 oggStreamState_.pagein(oggPage_);
435 while(i < 2)
436 {
437 result = oggStreamState_.packetout(oggPacket_);
438 if(result == 0)
439 {
440 break;
441 }
442 if(result == -1)
443 {
444 if(TDebug.TraceAudioConverter) TDebug.out("Corrupt secondary header. Exiting.");
445 throw new IOException("Corrupt secondary header. Exiting.");
446 }
447 vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_);
448 i++;
449 }
450 }
451 }
452 index = oggSyncState_.buffer(bufferSize_);
453 buffer = oggSyncState_.data;
454 bytes = readFromStream(buffer, index, bufferSize_);
455 if(bytes == -1)
456 {
457 break;
458 }
459 if(bytes == 0 && i < 2)
460 {
461 if(TDebug.TraceAudioConverter) TDebug.out("End of file before finding all Vorbis headers!");
462 throw new IOException("End of file before finding all Vorbis headers!");
463 }
464 oggSyncState_.wrote(bytes);
465 }
466
467 byte[][] ptr = vorbisComment.user_comments;
468 String currComment = "";
469
470 for(int j = 0; j < ptr.length; j++)
471 {
472 if(ptr[j] == null)
473 {
474 break;
475 }
476 currComment = (new String(ptr[j], 0, ptr[j].length - 1)).trim();
477 if(TDebug.TraceAudioConverter) TDebug.out("Comment: " + currComment);
478 }
479 convsize = bufferSize_ / vorbisInfo.channels;
480 vorbisDspState.synthesis_init(vorbisInfo);
481 vorbisBlock.init(vorbisDspState);
482 _pcmf = new float[1][][];
483 _index = new int[vorbisInfo.channels];
484 }
485
486 /**
487 * Reads from the oggBitStream_ a specified number of Bytes(bufferSize_) worth
488 * starting at index and puts them in the specified buffer[].
489 *
490 * @param buffer
491 * @param index
492 * @param bufferSize_
493 * @return the number of bytes read or -1 if error.
494 */
495 private int readFromStream(byte[] buffer, int index, int bufferSize_)
496 {
497 int bytes = 0;
498 try
499 {
500 bytes = oggBitStream_.read(buffer, index, bufferSize_);
501 }
502 catch(Exception e)
503 {
504 if(TDebug.TraceAudioConverter) TDebug.out("Cannot Read Selected Song");
505 bytes = -1;
506 }
507 currentBytes = currentBytes + bytes;
508 return bytes;
509 }
510
511 /**
512 * Close the stream.
513 */
514 public void close() throws IOException
515 {
516 super.close();
517 oggBitStream_.close();
518 }
519}
diff --git a/songdbj/javazoom/spi/vorbis/sampled/convert/VorbisFormatConversionProvider.java b/songdbj/javazoom/spi/vorbis/sampled/convert/VorbisFormatConversionProvider.java
new file mode 100644
index 0000000000..d1321f2590
--- /dev/null
+++ b/songdbj/javazoom/spi/vorbis/sampled/convert/VorbisFormatConversionProvider.java
@@ -0,0 +1,244 @@
1/*
2 * VorbisFormatConversionProvider.
3 *
4 * JavaZOOM : vorbisspi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Library General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23package javazoom.spi.vorbis.sampled.convert;
24
25import java.util.Arrays;
26import javazoom.spi.vorbis.sampled.file.VorbisEncoding;
27import javax.sound.sampled.AudioFormat;
28import javax.sound.sampled.AudioInputStream;
29
30import org.tritonus.share.sampled.convert.TMatrixFormatConversionProvider;
31
32/**
33 * ConversionProvider for VORBIS files.
34 */
35public class VorbisFormatConversionProvider extends TMatrixFormatConversionProvider
36{
37 private static final AudioFormat[] INPUT_FORMATS =
38 {
39 new AudioFormat(VorbisEncoding.VORBISENC, 32000.0F, -1, 1, -1, -1, false), // 0
40 new AudioFormat(VorbisEncoding.VORBISENC, 32000.0F, -1, 2, -1, -1, false), // 1
41 new AudioFormat(VorbisEncoding.VORBISENC, 44100.0F, -1, 1, -1, -1, false), // 2
42 new AudioFormat(VorbisEncoding.VORBISENC, 44100.0F, -1, 2, -1, -1, false), // 3
43 new AudioFormat(VorbisEncoding.VORBISENC, 48000.0F, -1, 1, -1, -1, false), // 4
44 new AudioFormat(VorbisEncoding.VORBISENC, 48000.0F, -1, 2, -1, -1, false), // 5
45
46 new AudioFormat(VorbisEncoding.VORBISENC, 16000.0F, -1, 1, -1, -1, false), // 18
47 new AudioFormat(VorbisEncoding.VORBISENC, 16000.0F, -1, 2, -1, -1, false), // 19
48 new AudioFormat(VorbisEncoding.VORBISENC, 22050.0F, -1, 1, -1, -1, false), // 20
49 new AudioFormat(VorbisEncoding.VORBISENC, 22050.0F, -1, 2, -1, -1, false), // 21
50 new AudioFormat(VorbisEncoding.VORBISENC, 24000.0F, -1, 1, -1, -1, false), // 22
51 new AudioFormat(VorbisEncoding.VORBISENC, 24000.0F, -1, 2, -1, -1, false), // 23
52
53 new AudioFormat(VorbisEncoding.VORBISENC, 8000.0F, -1, 1, -1, -1, false), // 36
54 new AudioFormat(VorbisEncoding.VORBISENC, 8000.0F, -1, 2, -1, -1, false), // 37
55 new AudioFormat(VorbisEncoding.VORBISENC, 11025.0F, -1, 1, -1, -1, false), // 38
56 new AudioFormat(VorbisEncoding.VORBISENC, 11025.0F, -1, 2, -1, -1, false), // 39
57 new AudioFormat(VorbisEncoding.VORBISENC, 12000.0F, -1, 1, -1, -1, false), // 40
58 new AudioFormat(VorbisEncoding.VORBISENC, 12000.0F, -1, 2, -1, -1, false), // 41
59 };
60
61 private static final AudioFormat[] OUTPUT_FORMATS =
62 {
63 new AudioFormat(8000.0F, 16, 1, true, false), // 0
64 new AudioFormat(8000.0F, 16, 1, true, true), // 1
65 new AudioFormat(8000.0F, 16, 2, true, false), // 2
66 new AudioFormat(8000.0F, 16, 2, true, true), // 3
67 /* 24 and 32 bit not yet possible
68 new AudioFormat(8000.0F, 24, 1, true, false),
69 new AudioFormat(8000.0F, 24, 1, true, true),
70 new AudioFormat(8000.0F, 24, 2, true, false),
71 new AudioFormat(8000.0F, 24, 2, true, true),
72 new AudioFormat(8000.0F, 32, 1, true, false),
73 new AudioFormat(8000.0F, 32, 1, true, true),
74 new AudioFormat(8000.0F, 32, 2, true, false),
75 new AudioFormat(8000.0F, 32, 2, true, true),
76 */
77 new AudioFormat(11025.0F, 16, 1, true, false), // 4
78 new AudioFormat(11025.0F, 16, 1, true, true), // 5
79 new AudioFormat(11025.0F, 16, 2, true, false), // 6
80 new AudioFormat(11025.0F, 16, 2, true, true), // 7
81 /* 24 and 32 bit not yet possible
82 new AudioFormat(11025.0F, 24, 1, true, false),
83 new AudioFormat(11025.0F, 24, 1, true, true),
84 new AudioFormat(11025.0F, 24, 2, true, false),
85 new AudioFormat(11025.0F, 24, 2, true, true),
86 new AudioFormat(11025.0F, 32, 1, true, false),
87 new AudioFormat(11025.0F, 32, 1, true, true),
88 new AudioFormat(11025.0F, 32, 2, true, false),
89 new AudioFormat(11025.0F, 32, 2, true, true),
90 */
91 new AudioFormat(12000.0F, 16, 1, true, false), // 8
92 new AudioFormat(12000.0F, 16, 1, true, true), // 9
93 new AudioFormat(12000.0F, 16, 2, true, false), // 10
94 new AudioFormat(12000.0F, 16, 2, true, true), // 11
95 /* 24 and 32 bit not yet possible
96 new AudioFormat(12000.0F, 24, 1, true, false),
97 new AudioFormat(12000.0F, 24, 1, true, true),
98 new AudioFormat(12000.0F, 24, 2, true, false),
99 new AudioFormat(12000.0F, 24, 2, true, true),
100 new AudioFormat(12000.0F, 32, 1, true, false),
101 new AudioFormat(12000.0F, 32, 1, true, true),
102 new AudioFormat(12000.0F, 32, 2, true, false),
103 new AudioFormat(12000.0F, 32, 2, true, true),
104 */
105 new AudioFormat(16000.0F, 16, 1, true, false), // 12
106 new AudioFormat(16000.0F, 16, 1, true, true), // 13
107 new AudioFormat(16000.0F, 16, 2, true, false), // 14
108 new AudioFormat(16000.0F, 16, 2, true, true), // 15
109 /* 24 and 32 bit not yet possible
110 new AudioFormat(16000.0F, 24, 1, true, false),
111 new AudioFormat(16000.0F, 24, 1, true, true),
112 new AudioFormat(16000.0F, 24, 2, true, false),
113 new AudioFormat(16000.0F, 24, 2, true, true),
114 new AudioFormat(16000.0F, 32, 1, true, false),
115 new AudioFormat(16000.0F, 32, 1, true, true),
116 new AudioFormat(16000.0F, 32, 2, true, false),
117 new AudioFormat(16000.0F, 32, 2, true, true),
118 */
119 new AudioFormat(22050.0F, 16, 1, true, false), // 16
120 new AudioFormat(22050.0F, 16, 1, true, true), // 17
121 new AudioFormat(22050.0F, 16, 2, true, false), // 18
122 new AudioFormat(22050.0F, 16, 2, true, true), // 19
123 /* 24 and 32 bit not yet possible
124 new AudioFormat(22050.0F, 24, 1, true, false),
125 new AudioFormat(22050.0F, 24, 1, true, true),
126 new AudioFormat(22050.0F, 24, 2, true, false),
127 new AudioFormat(22050.0F, 24, 2, true, true),
128 new AudioFormat(22050.0F, 32, 1, true, false),
129 new AudioFormat(22050.0F, 32, 1, true, true),
130 new AudioFormat(22050.0F, 32, 2, true, false),
131 new AudioFormat(22050.0F, 32, 2, true, true),
132 */
133 new AudioFormat(24000.0F, 16, 1, true, false), // 20
134 new AudioFormat(24000.0F, 16, 1, true, true), // 21
135 new AudioFormat(24000.0F, 16, 2, true, false), // 22
136 new AudioFormat(24000.0F, 16, 2, true, true), // 23
137 /* 24 and 32 bit not yet possible
138 new AudioFormat(24000.0F, 24, 1, true, false),
139 new AudioFormat(24000.0F, 24, 1, true, true),
140 new AudioFormat(24000.0F, 24, 2, true, false),
141 new AudioFormat(24000.0F, 24, 2, true, true),
142 new AudioFormat(24000.0F, 32, 1, true, false),
143 new AudioFormat(24000.0F, 32, 1, true, true),
144 new AudioFormat(24000.0F, 32, 2, true, false),
145 new AudioFormat(24000.0F, 32, 2, true, true),
146 */
147 new AudioFormat(32000.0F, 16, 1, true, false), // 24
148 new AudioFormat(32000.0F, 16, 1, true, true), // 25
149 new AudioFormat(32000.0F, 16, 2, true, false), // 26
150 new AudioFormat(32000.0F, 16, 2, true, true), // 27
151 /* 24 and 32 bit not yet possible
152 new AudioFormat(32000.0F, 24, 1, true, false),
153 new AudioFormat(32000.0F, 24, 1, true, true),
154 new AudioFormat(32000.0F, 24, 2, true, false),
155 new AudioFormat(32000.0F, 24, 2, true, true),
156 new AudioFormat(32000.0F, 32, 1, true, false),
157 new AudioFormat(32000.0F, 32, 1, true, true),
158 new AudioFormat(32000.0F, 32, 2, true, false),
159 new AudioFormat(32000.0F, 32, 2, true, true),
160 */
161 new AudioFormat(44100.0F, 16, 1, true, false), // 28
162 new AudioFormat(44100.0F, 16, 1, true, true), // 29
163 new AudioFormat(44100.0F, 16, 2, true, false), // 30
164 new AudioFormat(44100.0F, 16, 2, true, true), // 31
165 /* 24 and 32 bit not yet possible
166 new AudioFormat(44100.0F, 24, 1, true, false),
167 new AudioFormat(44100.0F, 24, 1, true, true),
168 new AudioFormat(44100.0F, 24, 2, true, false),
169 new AudioFormat(44100.0F, 24, 2, true, true),
170 new AudioFormat(44100.0F, 32, 1, true, false),
171 new AudioFormat(44100.0F, 32, 1, true, true),
172 new AudioFormat(44100.0F, 32, 2, true, false),
173 new AudioFormat(44100.0F, 32, 2, true, true),
174 */
175 new AudioFormat(48000.0F, 16, 1, true, false), // 32
176 new AudioFormat(48000.0F, 16, 1, true, true), // 33
177 new AudioFormat(48000.0F, 16, 2, true, false), // 34
178 new AudioFormat(48000.0F, 16, 2, true, true), // 35
179 /* 24 and 32 bit not yet possible
180 new AudioFormat(48000.0F, 24, 1, true, false),
181 new AudioFormat(48000.0F, 24, 1, true, true),
182 new AudioFormat(48000.0F, 24, 2, true, false),
183 new AudioFormat(48000.0F, 24, 2, true, true),
184 new AudioFormat(48000.0F, 32, 1, true, false),
185 new AudioFormat(48000.0F, 32, 1, true, true),
186 new AudioFormat(48000.0F, 32, 2, true, false),
187 new AudioFormat(48000.0F, 32, 2, true, true),
188 */
189 };
190
191 private static final boolean t = true;
192 private static final boolean f = false;
193
194 /*
195 * One row for each source format.
196 */
197 private static final boolean[][] CONVERSIONS =
198 {
199 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,t,t,f,f,f,f, f,f,f,f,f,f}, // 0
200 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,t,t,f,f, f,f,f,f,f,f}, // 1
201 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,t,t, f,f,f,f,f,f}, // 2
202 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, t,t,f,f,f,f}, // 3
203 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,t,t,f,f}, // 4
204 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,t,t}, // 5
205
206 {f,f,f,f,f,f,f,f,f,f, f,f,t,t,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 18
207 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,t,t,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 19
208 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,t,t,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 20
209 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,t,t, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 21
210 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, t,t,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 22
211 {f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,t,t,f,f,f,f,f,f, f,f,f,f,f,f}, // 23
212
213 {t,t,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 36
214 {f,f,t,t,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 37
215 {f,f,f,f,t,t,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 38
216 {f,f,f,f,f,f,t,t,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 39
217 {f,f,f,f,f,f,f,f,t,t, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 40
218 {f,f,f,f,f,f,f,f,f,f, t,t,f,f,f,f,f,f,f,f, f,f,f,f,f,f,f,f,f,f, f,f,f,f,f,f}, // 41
219
220 };
221
222 /**
223 * Constructor.
224 */
225 public VorbisFormatConversionProvider()
226 {
227 super(Arrays.asList(INPUT_FORMATS), Arrays.asList(OUTPUT_FORMATS), CONVERSIONS);
228 }
229
230 /**
231 * Returns converted AudioInputStream.
232 */
233 public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream audioInputStream)
234 {
235 if (isConversionSupported(targetFormat, audioInputStream.getFormat()))
236 {
237 return new DecodedVorbisAudioInputStream(targetFormat, audioInputStream);
238 }
239 else
240 {
241 throw new IllegalArgumentException("conversion not supported");
242 }
243 }
244}
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileFormat.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileFormat.java
new file mode 100644
index 0000000000..28b7c92a2a
--- /dev/null
+++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileFormat.java
@@ -0,0 +1,85 @@
1/*
2 * VorbisAudioFileFormat.
3 *
4 * JavaZOOM : vorbisspi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Library General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23package javazoom.spi.vorbis.sampled.file;
24
25import java.util.Map;
26
27import javax.sound.sampled.AudioFormat;
28
29import org.tritonus.share.sampled.file.TAudioFileFormat;
30
31/**
32 * @author JavaZOOM
33 */
34public class VorbisAudioFileFormat extends TAudioFileFormat
35{
36 /**
37 * Contructor.
38 * @param type
39 * @param audioFormat
40 * @param nLengthInFrames
41 * @param nLengthInBytes
42 */
43 public VorbisAudioFileFormat(Type type, AudioFormat audioFormat, int nLengthInFrames, int nLengthInBytes, Map properties)
44 {
45 super(type, audioFormat, nLengthInFrames, nLengthInBytes, properties);
46 }
47
48 /**
49 * Ogg Vorbis audio file format parameters.
50 * Some parameters might be unavailable. So availability test is required before reading any parameter.
51 *
52 * <br>AudioFileFormat parameters.
53 * <ul>
54 * <li><b>duration</b> [Long], duration in microseconds.
55 * <li><b>title</b> [String], Title of the stream.
56 * <li><b>author</b> [String], Name of the artist of the stream.
57 * <li><b>album</b> [String], Name of the album of the stream.
58 * <li><b>date</b> [String], The date (year) of the recording or release of the stream.
59 * <li><b>copyright</b> [String], Copyright message of the stream.
60 * <li><b>comment</b> [String], Comment of the stream.
61 * </ul>
62 * <br>Ogg Vorbis parameters.
63 * <ul>
64 * <li><b>ogg.length.bytes</b> [Integer], length in bytes.
65 * <li><b>ogg.bitrate.min.bps</b> [Integer], minimum bitrate.
66 * <li><b>ogg.bitrate.nominal.bps</b> [Integer], nominal bitrate.
67 * <li><b>ogg.bitrate.max.bps</b> [Integer], maximum bitrate.
68 * <li><b>ogg.channels</b> [Integer], number of channels 1 : mono, 2 : stereo.
69 * <li><b>ogg.frequency.hz</b> [Integer], sampling rate in hz.
70 * <li><b>ogg.version</b> [Integer], version.
71 * <li><b>ogg.serial</b> [Integer], serial number.
72 * <li><b>ogg.comment.track</b> [String], track number.
73 * <li><b>ogg.comment.genre</b> [String], genre field.
74 * <li><b>ogg.comment.encodedby</b> [String], encoded by field.
75 * <li><b>ogg.comment.ext</b> [String], extended comments (indexed):
76 * <br>For instance :
77 * <br>ogg.comment.ext.1=Something
78 * <br>ogg.comment.ext.2=Another comment
79 * </ul>
80 */
81 public Map properties()
82 {
83 return super.properties();
84 }
85}
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileReader.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileReader.java
new file mode 100644
index 0000000000..40bc9cadee
--- /dev/null
+++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileReader.java
@@ -0,0 +1,502 @@
1/*
2 * VorbisAudioFileReader.
3 *
4 * JavaZOOM : vorbisspi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Library General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23package javazoom.spi.vorbis.sampled.file;
24
25import java.io.BufferedInputStream;
26import java.io.File;
27import java.io.FileInputStream;
28import java.io.IOException;
29import java.io.InputStream;
30import java.net.URL;
31import java.util.HashMap;
32import java.util.StringTokenizer;
33
34import javax.sound.sampled.AudioFileFormat;
35import javax.sound.sampled.AudioFormat;
36import javax.sound.sampled.AudioInputStream;
37import javax.sound.sampled.AudioSystem;
38import javax.sound.sampled.UnsupportedAudioFileException;
39
40import org.tritonus.share.TDebug;
41import org.tritonus.share.sampled.file.TAudioFileReader;
42
43import com.jcraft.jogg.Packet;
44import com.jcraft.jogg.Page;
45import com.jcraft.jogg.StreamState;
46import com.jcraft.jogg.SyncState;
47import com.jcraft.jorbis.Block;
48import com.jcraft.jorbis.Comment;
49import com.jcraft.jorbis.DspState;
50import com.jcraft.jorbis.Info;
51import com.jcraft.jorbis.JOrbisException;
52import com.jcraft.jorbis.VorbisFile;
53
54/**
55 * This class implements the AudioFileReader class and provides an
56 * Ogg Vorbis file reader for use with the Java Sound Service Provider Interface.
57 */
58public class VorbisAudioFileReader extends TAudioFileReader
59{
60 private SyncState oggSyncState_ = null;
61 private StreamState oggStreamState_ = null;
62 private Page oggPage_ = null;
63 private Packet oggPacket_ = null;
64 private Info vorbisInfo = null;
65 private Comment vorbisComment = null;
66 private DspState vorbisDspState = null;
67 private Block vorbisBlock = null;
68 private int bufferMultiple_ = 4;
69 private int bufferSize_ = bufferMultiple_ * 256 * 2;
70 private int convsize = bufferSize_ * 2;
71 private byte[] convbuffer = new byte[convsize];
72 private byte[] buffer = null;
73 private int bytes = 0;
74 private int rate = 0;
75 private int channels = 0;
76
77 private int index = 0;
78 private InputStream oggBitStream_ = null;
79
80 private static final int INITAL_READ_LENGTH = 64000;
81 private static final int MARK_LIMIT = INITAL_READ_LENGTH + 1;
82
83 public VorbisAudioFileReader()
84 {
85 super(MARK_LIMIT, true);
86 }
87
88 /**
89 * Return the AudioFileFormat from the given file.
90 */
91 public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException
92 {
93 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioFileFormat(File file)");
94 InputStream inputStream = null;
95 try
96 {
97 inputStream = new BufferedInputStream(new FileInputStream(file));
98 inputStream.mark(MARK_LIMIT);
99 AudioFileFormat aff = getAudioFileFormat(inputStream);
100 inputStream.reset();
101 // Get Vorbis file info such as length in seconds.
102 VorbisFile vf = new VorbisFile(file.getAbsolutePath());
103 return getAudioFileFormat(inputStream,(int) file.length(), (int) Math.round((vf.time_total(-1))*1000));
104 }
105 catch (JOrbisException e)
106 {
107 throw new IOException(e.getMessage());
108 }
109 finally
110 {
111 if (inputStream != null) inputStream.close();
112 }
113 }
114
115 /**
116 * Return the AudioFileFormat from the given URL.
117 */
118 public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException
119 {
120 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioFileFormat(URL url)");
121 InputStream inputStream = url.openStream();
122 try
123 {
124 return getAudioFileFormat(inputStream);
125 }
126 finally
127 {
128 if (inputStream != null) inputStream.close();
129 }
130 }
131
132 /**
133 * Return the AudioFileFormat from the given InputStream.
134 */
135 public AudioFileFormat getAudioFileFormat(InputStream inputStream) throws UnsupportedAudioFileException, IOException
136 {
137 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioFileFormat(InputStream inputStream)");
138 try
139 {
140 if (!inputStream.markSupported()) inputStream = new BufferedInputStream(inputStream);
141 inputStream.mark(MARK_LIMIT);
142 return getAudioFileFormat(inputStream, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED);
143 }
144 finally
145 {
146 inputStream.reset();
147 }
148 }
149
150 /**
151 * Return the AudioFileFormat from the given InputStream and length in bytes.
152 */
153 public AudioFileFormat getAudioFileFormat(InputStream inputStream, long medialength) throws UnsupportedAudioFileException, IOException
154 {
155 return getAudioFileFormat(inputStream, (int) medialength, AudioSystem.NOT_SPECIFIED);
156 }
157
158
159 /**
160 * Return the AudioFileFormat from the given InputStream, length in bytes and length in milliseconds.
161 */
162 protected AudioFileFormat getAudioFileFormat(InputStream bitStream, int mediaLength, int totalms) throws UnsupportedAudioFileException, IOException
163 {
164 HashMap aff_properties = new HashMap();
165 HashMap af_properties = new HashMap();
166 if (totalms == AudioSystem.NOT_SPECIFIED)
167 {
168 totalms = 0;
169 }
170 if (totalms <= 0)
171 {
172 totalms = 0;
173 }
174 else
175 {
176 aff_properties.put("duration",new Long(totalms*1000));
177 }
178 oggBitStream_ = bitStream;
179 init_jorbis();
180 index = 0;
181 try
182 {
183 readHeaders(aff_properties, af_properties);
184 }
185 catch (IOException ioe)
186 {
187 if (TDebug.TraceAudioFileReader)
188 {
189 TDebug.out(ioe.getMessage());
190 }
191 throw new UnsupportedAudioFileException(ioe.getMessage());
192 }
193
194 String dmp = vorbisInfo.toString();
195 if (TDebug.TraceAudioFileReader)
196 {
197 TDebug.out(dmp);
198 }
199 int ind = dmp.lastIndexOf("bitrate:");
200 int minbitrate = -1;
201 int nominalbitrate = -1;
202 int maxbitrate = -1;
203 if (ind != -1)
204 {
205 dmp = dmp.substring(ind + 8, dmp.length());
206 StringTokenizer st = new StringTokenizer(dmp, ",");
207 if (st.hasMoreTokens())
208 {
209 minbitrate = Integer.parseInt(st.nextToken());
210 }
211 if (st.hasMoreTokens())
212 {
213 nominalbitrate = Integer.parseInt(st.nextToken());
214 }
215 if (st.hasMoreTokens())
216 {
217 maxbitrate = Integer.parseInt(st.nextToken());
218 }
219 }
220 if (nominalbitrate > 0) af_properties.put("bitrate",new Integer(nominalbitrate));
221 af_properties.put("vbr",new Boolean(true));
222
223 if (minbitrate > 0) aff_properties.put("ogg.bitrate.min.bps",new Integer(minbitrate));
224 if (maxbitrate > 0) aff_properties.put("ogg.bitrate.max.bps",new Integer(maxbitrate));
225 if (nominalbitrate > 0) aff_properties.put("ogg.bitrate.nominal.bps",new Integer(nominalbitrate));
226 if (vorbisInfo.channels > 0) aff_properties.put("ogg.channels",new Integer(vorbisInfo.channels));
227 if (vorbisInfo.rate > 0) aff_properties.put("ogg.frequency.hz",new Integer(vorbisInfo.rate));
228 if (mediaLength > 0) aff_properties.put("ogg.length.bytes",new Integer(mediaLength));
229 aff_properties.put("ogg.version",new Integer(vorbisInfo.version));
230
231 AudioFormat.Encoding encoding = VorbisEncoding.VORBISENC;
232 AudioFormat format = new VorbisAudioFormat(encoding, vorbisInfo.rate, AudioSystem.NOT_SPECIFIED, vorbisInfo.channels, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED, true,af_properties);
233 AudioFileFormat.Type type = VorbisFileFormatType.OGG;
234 return new VorbisAudioFileFormat(VorbisFileFormatType.OGG, format, AudioSystem.NOT_SPECIFIED, mediaLength,aff_properties);
235 }
236
237 /**
238 * Return the AudioInputStream from the given InputStream.
239 */
240 public AudioInputStream getAudioInputStream(InputStream inputStream) throws UnsupportedAudioFileException, IOException
241 {
242 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(InputStream inputStream)");
243 return getAudioInputStream(inputStream, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED);
244 }
245
246 /**
247 * Return the AudioInputStream from the given InputStream.
248 */
249 public AudioInputStream getAudioInputStream(InputStream inputStream, int medialength, int totalms) throws UnsupportedAudioFileException, IOException
250 {
251 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(InputStream inputStreamint medialength, int totalms)");
252 try
253 {
254 if (!inputStream.markSupported()) inputStream = new BufferedInputStream(inputStream);
255 inputStream.mark(MARK_LIMIT);
256 AudioFileFormat audioFileFormat = getAudioFileFormat(inputStream, medialength, totalms);
257 inputStream.reset();
258 return new AudioInputStream(inputStream, audioFileFormat.getFormat(), audioFileFormat.getFrameLength());
259 }
260 catch (UnsupportedAudioFileException e)
261 {
262 inputStream.reset();
263 throw e;
264 }
265 catch (IOException e)
266 {
267 inputStream.reset();
268 throw e;
269 }
270 }
271
272 /**
273 * Return the AudioInputStream from the given File.
274 */
275 public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException
276 {
277 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(File file)");
278 InputStream inputStream = new FileInputStream(file);
279 try
280 {
281 return getAudioInputStream(inputStream);
282 }
283 catch (UnsupportedAudioFileException e)
284 {
285 if (inputStream != null) inputStream.close();
286 throw e;
287 }
288 catch (IOException e)
289 {
290 if (inputStream != null) inputStream.close();
291 throw e;
292 }
293 }
294
295 /**
296 * Return the AudioInputStream from the given URL.
297 */
298 public AudioInputStream getAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException
299 {
300 if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(URL url)");
301 InputStream inputStream = url.openStream();
302 try
303 {
304 return getAudioInputStream(inputStream);
305 }
306 catch (UnsupportedAudioFileException e)
307 {
308 if (inputStream != null) inputStream.close();
309 throw e;
310 }
311 catch (IOException e)
312 {
313 if (inputStream != null) inputStream.close();
314 throw e;
315 }
316 }
317
318 /**
319 * Reads headers and comments.
320 */
321 private void readHeaders(HashMap aff_properties, HashMap af_properties) throws IOException
322 {
323 if(TDebug.TraceAudioConverter) TDebug.out("readHeaders(");
324 index = oggSyncState_.buffer(bufferSize_);
325 buffer = oggSyncState_.data;
326 bytes = readFromStream(buffer, index, bufferSize_);
327 if(bytes == -1)
328 {
329 if(TDebug.TraceAudioConverter) TDebug.out("Cannot get any data from selected Ogg bitstream.");
330 throw new IOException("Cannot get any data from selected Ogg bitstream.");
331 }
332 oggSyncState_.wrote(bytes);
333 if(oggSyncState_.pageout(oggPage_) != 1)
334 {
335 if(bytes < bufferSize_)
336 {
337 throw new IOException("EOF");
338 }
339 if(TDebug.TraceAudioConverter) TDebug.out("Input does not appear to be an Ogg bitstream.");
340 throw new IOException("Input does not appear to be an Ogg bitstream.");
341 }
342 oggStreamState_.init(oggPage_.serialno());
343 vorbisInfo.init();
344 vorbisComment.init();
345 aff_properties.put("ogg.serial",new Integer(oggPage_.serialno()));
346 if(oggStreamState_.pagein(oggPage_) < 0)
347 {
348 // error; stream version mismatch perhaps
349 if(TDebug.TraceAudioConverter) TDebug.out("Error reading first page of Ogg bitstream data.");
350 throw new IOException("Error reading first page of Ogg bitstream data.");
351 }
352 if(oggStreamState_.packetout(oggPacket_) != 1)
353 {
354 // no page? must not be vorbis
355 if(TDebug.TraceAudioConverter) TDebug.out("Error reading initial header packet.");
356 throw new IOException("Error reading initial header packet.");
357 }
358 if(vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_) < 0)
359 {
360 // error case; not a vorbis header
361 if(TDebug.TraceAudioConverter) TDebug.out("This Ogg bitstream does not contain Vorbis audio data.");
362 throw new IOException("This Ogg bitstream does not contain Vorbis audio data.");
363 }
364 int i = 0;
365 while(i < 2)
366 {
367 while(i < 2)
368 {
369 int result = oggSyncState_.pageout(oggPage_);
370 if(result == 0)
371 {
372 break;
373 } // Need more data
374 if(result == 1)
375 {
376 oggStreamState_.pagein(oggPage_);
377 while(i < 2)
378 {
379 result = oggStreamState_.packetout(oggPacket_);
380 if(result == 0)
381 {
382 break;
383 }
384 if(result == -1)
385 {
386 if(TDebug.TraceAudioConverter) TDebug.out("Corrupt secondary header. Exiting.");
387 throw new IOException("Corrupt secondary header. Exiting.");
388 }
389 vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_);
390 i++;
391 }
392 }
393 }
394 index = oggSyncState_.buffer(bufferSize_);
395 buffer = oggSyncState_.data;
396 bytes = readFromStream(buffer, index, bufferSize_);
397 if(bytes == -1)
398 {
399 break;
400 }
401 if(bytes == 0 && i < 2)
402 {
403 if(TDebug.TraceAudioConverter) TDebug.out("End of file before finding all Vorbis headers!");
404 throw new IOException("End of file before finding all Vorbis headers!");
405 }
406 oggSyncState_.wrote(bytes);
407 }
408 // Read Ogg Vorbis comments.
409 byte[][] ptr = vorbisComment.user_comments;
410 String currComment = "";
411 int c = 0;
412 for(int j = 0; j < ptr.length; j++)
413 {
414 if(ptr[j] == null)
415 {
416 break;
417 }
418 currComment = (new String(ptr[j], 0, ptr[j].length - 1)).trim();
419 if(TDebug.TraceAudioConverter) TDebug.out(currComment);
420 if (currComment.toLowerCase().startsWith("artist"))
421 {
422 aff_properties.put("author",currComment.substring(7));
423 }
424 else if (currComment.toLowerCase().startsWith("title"))
425 {
426 aff_properties.put("title",currComment.substring(6));
427 }
428 else if (currComment.toLowerCase().startsWith("album"))
429 {
430 aff_properties.put("album",currComment.substring(6));
431 }
432 else if (currComment.toLowerCase().startsWith("date"))
433 {
434 aff_properties.put("date",currComment.substring(5));
435 }
436 else if (currComment.toLowerCase().startsWith("copyright"))
437 {
438 aff_properties.put("copyright",currComment.substring(10));
439 }
440 else if (currComment.toLowerCase().startsWith("comment"))
441 {
442 aff_properties.put("comment",currComment.substring(8));
443 }
444 else if (currComment.toLowerCase().startsWith("genre"))
445 {
446 aff_properties.put("ogg.comment.genre",currComment.substring(6));
447 }
448 else if (currComment.toLowerCase().startsWith("tracknumber"))
449 {
450 aff_properties.put("ogg.comment.track",currComment.substring(12));
451 }
452 else
453 {
454 c++;
455 aff_properties.put("ogg.comment.ext."+c,currComment);
456 }
457 aff_properties.put("ogg.comment.encodedby",new String(vorbisComment.vendor, 0, vorbisComment.vendor.length - 1));
458 }
459 }
460
461 /**
462 * Reads from the oggBitStream_ a specified number of Bytes(bufferSize_) worth
463 * starting at index and puts them in the specified buffer[].
464 *
465 * @return the number of bytes read or -1 if error.
466 */
467 private int readFromStream(byte[] buffer, int index, int bufferSize_)
468 {
469 int bytes = 0;
470 try
471 {
472 bytes = oggBitStream_.read(buffer, index, bufferSize_);
473 }
474 catch (Exception e)
475 {
476 if (TDebug.TraceAudioFileReader)
477 {
478 TDebug.out("Cannot Read Selected Song");
479 }
480 bytes = -1;
481 }
482 return bytes;
483 }
484
485 /**
486 * Initializes all the jOrbis and jOgg vars that are used for song playback.
487 */
488 private void init_jorbis()
489 {
490 oggSyncState_ = new SyncState();
491 oggStreamState_ = new StreamState();
492 oggPage_ = new Page();
493 oggPacket_ = new Packet();
494 vorbisInfo = new Info();
495 vorbisComment = new Comment();
496 vorbisDspState = new DspState();
497 vorbisBlock = new Block(vorbisDspState);
498 buffer = null;
499 bytes = 0;
500 oggSyncState_.init();
501 }
502}
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFormat.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFormat.java
new file mode 100644
index 0000000000..829ab2f8cd
--- /dev/null
+++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFormat.java
@@ -0,0 +1,66 @@
1/*
2 * VorbisAudioFormat.
3 *
4 * JavaZOOM : vorbisspi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Library General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23package javazoom.spi.vorbis.sampled.file;
24
25import java.util.Map;
26
27import javax.sound.sampled.AudioFormat;
28
29import org.tritonus.share.sampled.TAudioFormat;
30
31/**
32 * @author JavaZOOM
33 */
34public class VorbisAudioFormat extends TAudioFormat
35{
36 /**
37 * Constructor.
38 * @param encoding
39 * @param nFrequency
40 * @param SampleSizeInBits
41 * @param nChannels
42 * @param FrameSize
43 * @param FrameRate
44 * @param isBigEndian
45 * @param properties
46 */
47 public VorbisAudioFormat(AudioFormat.Encoding encoding, float nFrequency, int SampleSizeInBits, int nChannels, int FrameSize, float FrameRate, boolean isBigEndian, Map properties)
48 {
49 super(encoding, nFrequency, SampleSizeInBits, nChannels, FrameSize, FrameRate, isBigEndian, properties);
50 }
51
52 /**
53 * Ogg Vorbis audio format parameters.
54 * Some parameters might be unavailable. So availability test is required before reading any parameter.
55 *
56 * <br>AudioFormat parameters.
57 * <ul>
58 * <li><b>bitrate</b> [Integer], bitrate in bits per seconds, average bitrate for VBR enabled stream.
59 * <li><b>vbr</b> [Boolean], VBR flag.
60 * </ul>
61 */
62 public Map properties()
63 {
64 return super.properties();
65 }
66}
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisEncoding.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisEncoding.java
new file mode 100644
index 0000000000..7800f1556d
--- /dev/null
+++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisEncoding.java
@@ -0,0 +1,41 @@
1/*
2 * VorbisEncoding.
3 *
4 * JavaZOOM : vorbisspi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Library General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23package javazoom.spi.vorbis.sampled.file;
24
25import javax.sound.sampled.AudioFormat;
26
27/**
28 * Encodings used by the VORBIS audio decoder.
29 */
30public class VorbisEncoding extends AudioFormat.Encoding
31{
32 public static final AudioFormat.Encoding VORBISENC = new VorbisEncoding("VORBISENC");
33
34 /**
35 * Constructors.
36 */
37 public VorbisEncoding(String name)
38 {
39 super(name);
40 }
41}
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisFileFormatType.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisFileFormatType.java
new file mode 100644
index 0000000000..f006bbfe1d
--- /dev/null
+++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisFileFormatType.java
@@ -0,0 +1,41 @@
1/*
2 * VorbisFileFormatType.
3 *
4 * JavaZOOM : vorbisspi@javazoom.net
5 * http://www.javazoom.net
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Library General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23package javazoom.spi.vorbis.sampled.file;
24
25import javax.sound.sampled.AudioFileFormat;
26
27/**
28 * FileFormatTypes used by the VORBIS audio decoder.
29 */
30public class VorbisFileFormatType extends AudioFileFormat.Type
31{
32 public static final AudioFileFormat.Type VORBIS = new VorbisFileFormatType("VORBIS", "ogg");
33 public static final AudioFileFormat.Type OGG = new VorbisFileFormatType("OGG", "ogg");
34 /**
35 * Constructor.
36 */
37 public VorbisFileFormatType(String name, String extension)
38 {
39 super(name, extension);
40 }
41}