summaryrefslogtreecommitdiffstats
path: root/songdbj/javazoom/jl/converter/WaveFile.java
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/javazoom/jl/converter/WaveFile.java')
-rw-r--r--songdbj/javazoom/jl/converter/WaveFile.java522
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 @@
+/*
+ * 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