diff options
Diffstat (limited to 'songdbj/javazoom/jl/converter/WaveFile.java')
-rw-r--r-- | songdbj/javazoom/jl/converter/WaveFile.java | 522 |
1 files changed, 522 insertions, 0 deletions
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 | |||
26 | package javazoom.jl.converter; | ||
27 | |||
28 | /** | ||
29 | * Class allowing WaveFormat Access | ||
30 | */ | ||
31 | public 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 | ||