Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

XFuWavLoad.cpp

Go to the documentation of this file.
00001 /*! \file 
00002  * X-Forge Util <br>
00003  * Copyright 2000-2003 Fathammer Ltd
00004  * 
00005  * \brief RIFF Wave loader
00006  * 
00007  * $Id: XFuWavLoad.cpp,v 1.8.2.1 2003/12/15 09:26:22 jari Exp $
00008  * $Date: 2003/12/15 09:26:22 $
00009  * $Revision: 1.8.2.1 $
00010  */
00011 
00012 #include <xfcore/XFcCore.h>
00013 #include <xfutil/XFuWavLoad.h>
00014 
00015 
00016 class WavLoaderTempData
00017 {
00018 public:
00019     XFcFile *mFile;
00020     INT16 mWavFormat;
00021     INT16 mChannels;
00022     INT32 mSamplingRate;
00023     INT16 mBitsPerSample;
00024     INT32 mTotalBytes;
00025     INT32 mTotalSamples;
00026     void *mData;
00027 };
00028 
00029 
00030 // All the formats we're even remotely likely to support here:
00031 //#define WAVE_FORMAT_PCM         0x0001
00032 //#define WAVE_FORMAT_ADPCM       0x0002  /*  Microsoft Corporation  */
00033 //#define WAVE_FORMAT_IEEE_FLOAT  0x0003  /*  Microsoft Corporation  */
00034 //                                        /*  IEEE754: range (+1, -1]  */
00035 //                                        /*  32-bit/64-bit format as defined by */
00036 //                                        /*  MSVC++ float/double type */
00037 //#define  WAVE_FORMAT_ALAW       0x0006  /*  Microsoft Corporation  */
00038 //#define  WAVE_FORMAT_MULAW      0x0007  /*  Microsoft Corporation  */
00039 //#define  WAVE_FORMAT_MPEGLAYER3 0x0055  /*  ISO/MPEG Layer3 Format Tag */
00040 
00041 // currently this loader only supports 8bit mono PCM data.
00042 
00043 
00044 static INT loadHeader(WavLoaderTempData &d)
00045 {
00046     INT32 t; 
00047     INT32 chunkSize;
00048     
00049     d.mFile->read(&t, 4, 1);
00050     if (t != 0x46464952) return 0; // "RIFF" reversed
00051 
00052     d.mFile->read(&t, 4, 1); // skip file len
00053 
00054     d.mFile->read(&t, 4, 1);
00055     if (t != 0x45564157) return 0; // "WAVE" reversed
00056 
00057     d.mFile->read(&t, 4, 1);
00058     if (t != 0x20746d66) return 0; // "fmt " reversed
00059 
00060     d.mFile->read(&chunkSize, 4, 1);
00061 
00062     d.mFile->read(&d.mWavFormat, 2, 1);
00063     if (!(d.mWavFormat == 0x0001)) return 0; // unsupported format
00064 
00065     d.mFile->read(&d.mChannels, 2, 1);
00066 
00067     d.mFile->read(&d.mSamplingRate, 4, 1);
00068 
00069     d.mFile->read(&t, 4, 1); // skip "avgbytespersec"
00070 
00071     d.mFile->read(&t, 2, 1); // skip "bytespersample"
00072 
00073     d.mFile->read(&d.mBitsPerSample, 2, 1);
00074 
00075     chunkSize -= 2 + 2 + 4 + 4 + 2 + 2;
00076     
00077     // skip the rest of the header, if any: 
00078     // (microsoft PCM has 2 more bytes, bits per sample,
00079     // which we can figure out already)
00080     d.mFile->seek(d.mFile->tell() + chunkSize, SEEK_SET);
00081     
00082     return 1;
00083 }
00084 
00085 //#define PANIC(x) XFcCore::systemPanic(x);
00086 #define PANIC(x)
00087 
00088 XFcAudioBuffer * xfuLoadWav(const CHAR *aFilename, UINT32 aFlags)
00089 {
00090     WavLoaderTempData d;
00091     
00092     d.mData = NULL;
00093     d.mFile = XFcFile::open(aFilename, XFCSTR("rb"));
00094 
00095     if (d.mFile == NULL) 
00096     {
00097         PANIC("LoadWav:File not found");
00098         return NULL;
00099     }
00100 
00101     if (!loadHeader(d)) 
00102     {
00103         d.mFile->close();
00104         PANIC("LoadWav:Bad header");
00105         return NULL;
00106     }
00107 
00108     aFlags &= ~(XFCAUDIO_16BIT | XFCAUDIO_STEREO);
00109 
00110     if (d.mBitsPerSample == 16) aFlags |= XFCAUDIO_16BIT;
00111     if (d.mChannels == 2) aFlags |= XFCAUDIO_STEREO;
00112 
00113     INT32 tgtXor = 0;
00114     if (aFlags & XFCAUDIO_SIGNED)
00115     {
00116         if (!(aFlags & XFCAUDIO_16BIT)) tgtXor = -128;
00117     }
00118     else
00119         if (aFlags & XFCAUDIO_16BIT) tgtXor = -32768;
00120 
00121     XFcAudioBuffer *sndBuf = NULL;
00122     INT dataFound = 0;
00123     INT32 chunkId;
00124     INT32 index = 0;
00125     // while not end of file
00126     while (d.mFile->read(&chunkId, 4, 1) && !dataFound) 
00127     {
00128         INT32 chunkSize;
00129         d.mFile->read(&chunkSize, 4, 1);
00130 
00131         if (chunkId == 0x61746164 && d.mData == NULL)
00132         {
00133             d.mTotalBytes = chunkSize;
00134             d.mTotalSamples = d.mTotalBytes / (d.mChannels * (d.mBitsPerSample / 8));
00135 
00136             sndBuf = XFcAudioBuffer::create((FLOAT32)d.mSamplingRate, aFlags, d.mTotalSamples, 1.0, 0.5);
00137             if (sndBuf == NULL) 
00138             {
00139                 PANIC("LoadWav:Sound buffer alloc failed");
00140                 d.mFile->close();
00141                 return NULL;
00142             }
00143 
00144             dataFound = 1;
00145 
00146             if (d.mBitsPerSample == 8)     // Sound is 8-bit
00147             {
00148                 INT8 *buf = (INT8 *)XFcAudio::lock(sndBuf);
00149                 UINT8 value;
00150 
00151                 if (d.mChannels == 1)   // Sound is 8-bit mono
00152                 {
00153                     while (index < d.mTotalSamples)
00154                     {
00155                         d.mFile->readUINT8(value);
00156                         buf[index] = (INT8)(value ^ tgtXor);
00157                         index++;
00158                     }
00159                 }
00160                 else    // Sound is 8-bit stereo
00161                 {
00162                     while (index < d.mTotalSamples)
00163                     {
00164                         d.mFile->readUINT8(value);
00165                         buf[(index * 2)] = (INT8)(value ^ tgtXor);
00166 
00167                         d.mFile->readUINT8(value);
00168                         buf[(index * 2) + 1] = (INT8)(value ^ tgtXor);
00169 
00170                         index++;
00171                     }
00172                 }
00173 
00174                 XFcAudio::unlock(sndBuf);
00175             }
00176             else    // Sound is 16-bit
00177             {
00178                 INT16 *buf = (INT16 *)XFcAudio::lock(sndBuf);
00179                 INT16 value;
00180 
00181                 if (d.mChannels == 1)   // Sound is 16-bit mono
00182                 {
00183                     while (index < d.mTotalSamples)
00184                     {
00185                         d.mFile->readINT16(value);
00186                         buf[index] = (INT16)(value ^ tgtXor);
00187                         index++;
00188                     }
00189                 }
00190                 else    // Sound is 16-bit stereo
00191                 {
00192                     while (index < d.mTotalSamples)
00193                     {
00194                         d.mFile->readINT16(value);
00195                         buf[(index * 2)] = (INT16)(value ^ tgtXor);
00196 
00197                         d.mFile->readINT16(value);
00198                         buf[(index * 2) + 1] = (INT16)(value ^ tgtXor);
00199 
00200                         index++;
00201                     }
00202                 }
00203 
00204                 XFcAudio::unlock(sndBuf);
00205             }
00206         }
00207         else
00208         {
00209             // skip chunk:
00210             d.mFile->seek(d.mFile->tell() + chunkSize, SEEK_SET);
00211         }
00212     }
00213 
00214     d.mFile->close();
00215 
00216     if (!dataFound)
00217     {
00218         PANIC("LoadWav:No data block");
00219         delete sndBuf;
00220         return NULL;
00221     }
00222 
00223     return sndBuf;
00224 }
00225 
00226 
00227 XFcAudioBuffer * xfuLoadWav(const CHAR *filename)
00228 {
00229     return xfuLoadWav(filename, 0);
00230 }
00231 

   
X-Forge Documentation
Confidential
Copyright © 2002-2003 Fathammer
   
Documentation generated
with doxygen
by Dimitri van Heesch