From 9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e Mon Sep 17 00:00:00 2001 From: Michiel Van Der Kolk Date: Mon, 11 Jul 2005 15:42:37 +0000 Subject: Songdb java version, source. only 1.5 compatible git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7101 a1c6a512-1295-4272-9138-f99709370657 --- songdbj/javazoom/jl/converter/WaveFile.java | 522 ++++++++++++++++++++++++++++ 1 file changed, 522 insertions(+) create mode 100644 songdbj/javazoom/jl/converter/WaveFile.java (limited to 'songdbj/javazoom/jl/converter/WaveFile.java') 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 @@ +/* + * 11/19/04 1.0 moved to LGPL. + * 02/23/99 JavaConversion by E.B + * Don Cross, April 1993. + * RIFF file format classes. + * See Chapter 8 of "Multimedia Programmer's Reference" in + * the Microsoft Windows SDK. + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ + +package javazoom.jl.converter; + +/** + * Class allowing WaveFormat Access + */ +public class WaveFile extends RiffFile +{ + public static final int MAX_WAVE_CHANNELS = 2; + + class WaveFormat_ChunkData + { + public short wFormatTag = 0; // Format category (PCM=1) + public short nChannels = 0; // Number of channels (mono=1, stereo=2) + public int nSamplesPerSec = 0; // Sampling rate [Hz] + public int nAvgBytesPerSec = 0; + public short nBlockAlign = 0; + public short nBitsPerSample = 0; + + public WaveFormat_ChunkData() + { + wFormatTag = 1; // PCM + Config(44100,(short)16,(short)1); + } + + public void Config (int NewSamplingRate, short NewBitsPerSample, short NewNumChannels) + { + nSamplesPerSec = NewSamplingRate; + nChannels = NewNumChannels; + nBitsPerSample = NewBitsPerSample; + nAvgBytesPerSec = (nChannels * nSamplesPerSec * nBitsPerSample) / 8; + nBlockAlign = (short) ((nChannels * nBitsPerSample) / 8); + } + } + + + class WaveFormat_Chunk + { + public RiffChunkHeader header; + public WaveFormat_ChunkData data; + + public WaveFormat_Chunk() + { + header = new RiffChunkHeader(); + data = new WaveFormat_ChunkData(); + header.ckID = FourCC("fmt "); + header.ckSize = 16; + } + + public int VerifyValidity() + { + boolean ret = header.ckID == FourCC("fmt ") && + + (data.nChannels == 1 || data.nChannels == 2) && + + data.nAvgBytesPerSec == ( data.nChannels * + data.nSamplesPerSec * + data.nBitsPerSample ) / 8 && + + data.nBlockAlign == ( data.nChannels * + data.nBitsPerSample ) / 8; + if (ret == true) return 1; + else return 0; + } + } + + public class WaveFileSample + { + public short[] chan; + + public WaveFileSample() + {chan = new short[WaveFile.MAX_WAVE_CHANNELS];} + } + + private WaveFormat_Chunk wave_format; + private RiffChunkHeader pcm_data; + private long pcm_data_offset = 0; // offset of 'pcm_data' in output file + private int num_samples = 0; + + + /** + * Constructs a new WaveFile instance. + */ + public WaveFile() + { + pcm_data = new RiffChunkHeader(); + wave_format = new WaveFormat_Chunk(); + pcm_data.ckID = FourCC("data"); + pcm_data.ckSize = 0; + num_samples = 0; + } + + /** + * + * + public int OpenForRead (String Filename) + { + // Verify filename parameter as best we can... + if (Filename == null) + { + return DDC_INVALID_CALL; + } + int retcode = Open ( Filename, RFM_READ ); + + if ( retcode == DDC_SUCCESS ) + { + retcode = Expect ( "WAVE", 4 ); + + if ( retcode == DDC_SUCCESS ) + { + retcode = Read(wave_format,24); + + if ( retcode == DDC_SUCCESS && !wave_format.VerifyValidity() ) + { + // This isn't standard PCM, so we don't know what it is! + retcode = DDC_FILE_ERROR; + } + + if ( retcode == DDC_SUCCESS ) + { + pcm_data_offset = CurrentFilePosition(); + + // Figure out number of samples from + // file size, current file position, and + // WAVE header. + retcode = Read (pcm_data, 8 ); + num_samples = filelength(fileno(file)) - CurrentFilePosition(); + num_samples /= NumChannels(); + num_samples /= (BitsPerSample() / 8); + } + } + } + return retcode; + }*/ + + /** + * + */ + public int OpenForWrite (String Filename, int SamplingRate, short BitsPerSample, short NumChannels) + { + // Verify parameters... + if ( (Filename==null) || + (BitsPerSample != 8 && BitsPerSample != 16) || + NumChannels < 1 || NumChannels > 2 ) + { + return DDC_INVALID_CALL; + } + + wave_format.data.Config ( SamplingRate, BitsPerSample, NumChannels ); + + int retcode = Open ( Filename, RFM_WRITE ); + + if ( retcode == DDC_SUCCESS ) + { + byte [] theWave = {(byte)'W',(byte)'A',(byte)'V',(byte)'E'}; + retcode = Write ( theWave, 4 ); + + if ( retcode == DDC_SUCCESS ) + { + // Ecriture de wave_format + retcode = Write (wave_format.header, 8); + retcode = Write (wave_format.data.wFormatTag, 2); + retcode = Write (wave_format.data.nChannels, 2); + retcode = Write (wave_format.data.nSamplesPerSec, 4); + retcode = Write (wave_format.data.nAvgBytesPerSec, 4); + retcode = Write (wave_format.data.nBlockAlign, 2); + retcode = Write (wave_format.data.nBitsPerSample, 2); + /* byte[] br = new byte[16]; + br[0] = (byte) ((wave_format.data.wFormatTag >> 8) & 0x00FF); + br[1] = (byte) (wave_format.data.wFormatTag & 0x00FF); + + br[2] = (byte) ((wave_format.data.nChannels >> 8) & 0x00FF); + br[3] = (byte) (wave_format.data.nChannels & 0x00FF); + + br[4] = (byte) ((wave_format.data.nSamplesPerSec >> 24)& 0x000000FF); + br[5] = (byte) ((wave_format.data.nSamplesPerSec >> 16)& 0x000000FF); + br[6] = (byte) ((wave_format.data.nSamplesPerSec >> 8)& 0x000000FF); + br[7] = (byte) (wave_format.data.nSamplesPerSec & 0x000000FF); + + br[8] = (byte) ((wave_format.data.nAvgBytesPerSec>> 24)& 0x000000FF); + br[9] = (byte) ((wave_format.data.nAvgBytesPerSec >> 16)& 0x000000FF); + br[10] = (byte) ((wave_format.data.nAvgBytesPerSec >> 8)& 0x000000FF); + br[11] = (byte) (wave_format.data.nAvgBytesPerSec & 0x000000FF); + + br[12] = (byte) ((wave_format.data.nBlockAlign >> 8) & 0x00FF); + br[13] = (byte) (wave_format.data.nBlockAlign & 0x00FF); + + br[14] = (byte) ((wave_format.data.nBitsPerSample >> 8) & 0x00FF); + br[15] = (byte) (wave_format.data.nBitsPerSample & 0x00FF); + retcode = Write (br, 16); */ + + + if ( retcode == DDC_SUCCESS ) + { + pcm_data_offset = CurrentFilePosition(); + retcode = Write ( pcm_data, 8 ); + } + } + } + + return retcode; + } + + /** + * + * + public int ReadSample ( short[] Sample ) + { + + }*/ + + /** + * + * + public int WriteSample( short[] Sample ) + { + int retcode = DDC_SUCCESS; + switch ( wave_format.data.nChannels ) + { + case 1: + switch ( wave_format.data.nBitsPerSample ) + { + case 8: + pcm_data.ckSize += 1; + retcode = Write ( Sample, 1 ); + break; + + case 16: + pcm_data.ckSize += 2; + retcode = Write ( Sample, 2 ); + break; + + default: + retcode = DDC_INVALID_CALL; + } + break; + + case 2: + switch ( wave_format.data.nBitsPerSample ) + { + case 8: + retcode = Write ( Sample, 1 ); + if ( retcode == DDC_SUCCESS ) + { + // &Sample[1] + retcode = Write (Sample, 1 ); + if ( retcode == DDC_SUCCESS ) + { + pcm_data.ckSize += 2; + } + } + break; + + case 16: + retcode = Write ( Sample, 2 ); + if ( retcode == DDC_SUCCESS ) + { + // &Sample[1] + retcode = Write (Sample, 2 ); + if ( retcode == DDC_SUCCESS ) + { + pcm_data.ckSize += 4; + } + } + break; + + default: + retcode = DDC_INVALID_CALL; + } + break; + + default: + retcode = DDC_INVALID_CALL; + } + + return retcode; + }*/ + + /** + * + * + public int SeekToSample ( long SampleIndex ) + { + if ( SampleIndex >= NumSamples() ) + { + return DDC_INVALID_CALL; + } + int SampleSize = (BitsPerSample() + 7) / 8; + int rc = Seek ( pcm_data_offset + 8 + + SampleSize * NumChannels() * SampleIndex ); + return rc; + }*/ + + /** + * Write 16-bit audio + */ + public int WriteData ( short[] data, int numData ) + { + int extraBytes = numData * 2; + pcm_data.ckSize += extraBytes; + return super.Write ( data, extraBytes ); + } + + /** + * Read 16-bit audio. + * + public int ReadData (short[] data, int numData) + {return super.Read ( data, numData * 2);} */ + + /** + * Write 8-bit audio. + * + public int WriteData ( byte[] data, int numData ) + { + pcm_data.ckSize += numData; + return super.Write ( data, numData ); + }*/ + + /** + * Read 8-bit audio. + * + public int ReadData ( byte[] data, int numData ) + {return super.Read ( data, numData );} */ + + + /** + * + * + public int ReadSamples (int num, int [] WaveFileSample) + { + + }*/ + + /** + * + * + public int WriteMonoSample ( short[] SampleData ) + { + switch ( wave_format.data.nBitsPerSample ) + { + case 8: + pcm_data.ckSize += 1; + return Write ( SampleData, 1 ); + + case 16: + pcm_data.ckSize += 2; + return Write ( SampleData, 2 ); + } + return DDC_INVALID_CALL; + }*/ + + /** + * + * + public int WriteStereoSample ( short[] LeftSample, short[] RightSample ) + { + int retcode = DDC_SUCCESS; + switch ( wave_format.data.nBitsPerSample ) + { + case 8: + retcode = Write ( LeftSample, 1 ); + if ( retcode == DDC_SUCCESS ) + { + retcode = Write ( RightSample, 1 ); + if ( retcode == DDC_SUCCESS ) + { + pcm_data.ckSize += 2; + } + } + break; + + case 16: + retcode = Write ( LeftSample, 2 ); + if ( retcode == DDC_SUCCESS ) + { + retcode = Write ( RightSample, 2 ); + if ( retcode == DDC_SUCCESS ) + { + pcm_data.ckSize += 4; + } + } + break; + + default: + retcode = DDC_INVALID_CALL; + } + return retcode; + }*/ + + /** + * + * + public int ReadMonoSample ( short[] Sample ) + { + int retcode = DDC_SUCCESS; + switch ( wave_format.data.nBitsPerSample ) + { + case 8: + byte[] x = {0}; + retcode = Read ( x, 1 ); + Sample[0] = (short)(x[0]); + break; + + case 16: + retcode = Read ( Sample, 2 ); + break; + + default: + retcode = DDC_INVALID_CALL; + } + return retcode; + }*/ + + /** + * + * + public int ReadStereoSample ( short[] LeftSampleData, short[] RightSampleData ) + { + int retcode = DDC_SUCCESS; + byte[] x = new byte[2]; + short[] y = new short[2]; + switch ( wave_format.data.nBitsPerSample ) + { + case 8: + retcode = Read ( x, 2 ); + L[0] = (short) ( x[0] ); + R[0] = (short) ( x[1] ); + break; + + case 16: + retcode = Read ( y, 4 ); + L[0] = (short) ( y[0] ); + R[0] = (short) ( y[1] ); + break; + + default: + retcode = DDC_INVALID_CALL; + } + return retcode; + }*/ + + + /** + * + */ + public int Close() + { + int rc = DDC_SUCCESS; + + if ( fmode == RFM_WRITE ) + rc = Backpatch ( pcm_data_offset, pcm_data, 8 ); + if ( rc == DDC_SUCCESS ) + rc = super.Close(); + return rc; + } + + // [Hz] + public int SamplingRate() + {return wave_format.data.nSamplesPerSec;} + + public short BitsPerSample() + {return wave_format.data.nBitsPerSample;} + + public short NumChannels() + {return wave_format.data.nChannels;} + + public int NumSamples() + {return num_samples;} + + + /** + * Open for write using another wave file's parameters... + */ + public int OpenForWrite (String Filename, WaveFile OtherWave ) + { + return OpenForWrite ( Filename, + OtherWave.SamplingRate(), + OtherWave.BitsPerSample(), + OtherWave.NumChannels() ); + } + + /** + * + */ + public long CurrentFilePosition() + { + return super.CurrentFilePosition(); + } + + /* public int FourCC(String ChunkName) + { + byte[] p = {0x20,0x20,0x20,0x20}; + ChunkName.getBytes(0,4,p,0); + int ret = (((p[0] << 24)& 0xFF000000) | ((p[1] << 16)&0x00FF0000) | ((p[2] << 8)&0x0000FF00) | (p[3]&0x000000FF)); + return ret; + }*/ + +} \ No newline at end of file -- cgit v1.2.3