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
![]() | ||||
![]() |
Confidential Copyright © 2002-2003 Fathammer | with doxygen by Dimitri van Heesch |