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