• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/audio/src/OpenAL_WAVE.cpp

Go to the documentation of this file.
00001 #include "../header/OpenAL.h"
00002 
00003 STARTNAMESPACE
00004 
00005 bool SoundBufferWAVE::load(const wchar* file){
00006         int iDataSize, iFrequency;
00007         ALenum eBufferFormat;
00008         char *pData;
00009         bool bReturn = false;
00010 
00011         // Generate an AL Buffer
00012         alGenBuffers(1, &buffer);
00013         if(buffer == 0)
00014                 return false;
00015 
00016         if(LoadWaveFile(file, &iDataSize, &pData, &iFrequency, &eBufferFormat)){
00017                 alBufferData(buffer, eBufferFormat, pData, iDataSize, iFrequency);
00018                 if(alGetError() == AL_NO_ERROR)
00019                         bReturn = true;
00020                 SAVEDELETE(pData);
00021         }
00022 
00023         return bReturn;
00024 }
00025 
00026 bool SoundBufferWAVE::LoadWaveFile(const wchar* file, int* iDataSize, char** pData, int* iFrequency, ALenum* eBufferFormat)
00027 {
00028         WAVEFILEINFO WaveInfo;
00029         bool ret = false;
00030 
00031         if(ParseFile(file, &WaveInfo)){
00032                 // Allocate memory for sample data
00033                 WaveInfo.pData = new char[WaveInfo.ulDataSize];
00034                 if(WaveInfo.pData){
00035                         // Seek to start of audio data
00036                         fseek(WaveInfo.pFile, WaveInfo.ulDataOffset, SEEK_SET);
00037 
00038                         // Read Sample Data
00039                         if(fread(WaveInfo.pData, 1, WaveInfo.ulDataSize, WaveInfo.pFile) == WaveInfo.ulDataSize){
00040                                 // set output info
00041                                 *pData = WaveInfo.pData;
00042                                 *iDataSize = WaveInfo.ulDataSize;
00043                                 *iFrequency = WaveInfo.wfEXT.Format.nSamplesPerSec;
00044                                 *eBufferFormat = GetBufferFormat(WaveInfo);
00045                                 if(*eBufferFormat == 0){
00046                                         SAVEDELETEARRAY(WaveInfo.pData);
00047                                         ret = false;
00048                                 }
00049                         }else{
00050                                 SAVEDELETEARRAY(WaveInfo.pData);
00051                                 ret = false;
00052                         }
00053                 }
00054                 else
00055                         ret = false;
00056 
00057                 ret = true;
00058                 fclose(WaveInfo.pFile);
00059         }
00060 
00061         return ret;
00062 }
00063 
00064 bool SoundBufferWAVE::ParseFile(const wchar *file, WAVEFILEINFO* pWaveInfo)
00065 {
00066         WAVEFILEHEADER waveFileHeader;
00067         RIFFCHUNK riffChunk;
00068         WAVEFMT waveFmt;
00069         bool res = false;
00070 
00071         if(!file || !pWaveInfo)
00072                 return false;
00073 
00074         memset(pWaveInfo, 0, sizeof(WAVEFILEINFO));
00075 
00076         // Open the wave file for reading
00077         if(_wfopen_s(&pWaveInfo->pFile, file, TEXT("rb")) == 0){
00078                 // Read Wave file header
00079                 fread(&waveFileHeader, 1, sizeof(WAVEFILEHEADER), pWaveInfo->pFile);
00080                 if(    strncmp(waveFileHeader.szRIFF, "RIFF", 4) == 0
00081                         || strncmp(waveFileHeader.szWAVE, "WAVE", 4) == 0)
00082                 {
00083                         while(fread(&riffChunk, 1, sizeof(RIFFCHUNK), pWaveInfo->pFile) == sizeof(RIFFCHUNK)){
00084                                 if(strncmp(riffChunk.szChunkName, "fmt ", 4) == 0){
00085                                         if(riffChunk.ulChunkSize <= sizeof(WAVEFMT)){
00086                                                 fread(&waveFmt, 1, riffChunk.ulChunkSize, pWaveInfo->pFile);
00087 
00088                                                 // Determine if this is a WAVEFORMATEX or WAVEFORMATEXTENSIBLE wave file
00089                                                 if(waveFmt.usFormatTag == WAVE_FORMAT_PCM){
00090                                                         pWaveInfo->wfType = WF_EX;
00091                                                         memcpy(&pWaveInfo->wfEXT.Format, &waveFmt, sizeof(PCMWAVEFORMAT));
00092                                                 }else if(waveFmt.usFormatTag == WAVE_FORMAT_EXTENSIBLE){
00093                                                         pWaveInfo->wfType = WF_EXT;
00094                                                         memcpy(&pWaveInfo->wfEXT, &waveFmt, sizeof(WAVEFORMATEXTENSIBLE));
00095                                                 }
00096                                         }else{
00097                                                 fseek(pWaveInfo->pFile, riffChunk.ulChunkSize, SEEK_CUR);
00098                                         }
00099                                 }else if(strncmp(riffChunk.szChunkName, "data", 4) == 0){
00100                                         pWaveInfo->ulDataSize = riffChunk.ulChunkSize;
00101                                         pWaveInfo->ulDataOffset = ftell(pWaveInfo->pFile);
00102                                         fseek(pWaveInfo->pFile, riffChunk.ulChunkSize, SEEK_CUR);
00103                                 }else{
00104                                         fseek(pWaveInfo->pFile, riffChunk.ulChunkSize, SEEK_CUR);
00105                                 }
00106 
00107                                 // Ensure that we are correctly aligned for next chunk
00108                                 if(riffChunk.ulChunkSize & 1)
00109                                         fseek(pWaveInfo->pFile, 1, SEEK_CUR);
00110                         }
00111 
00112                         if(pWaveInfo->ulDataSize && pWaveInfo->ulDataOffset && ((pWaveInfo->wfType == WF_EX) || (pWaveInfo->wfType == WF_EXT)))
00113                                 res = true;
00114                         else
00115                                 fclose(pWaveInfo->pFile);
00116                 }
00117         }
00118 
00119         return res;
00120 }
00121 
00122 ALenum SoundBufferWAVE::GetBufferFormat(WAVEFILEINFO& waveinfo){
00123         ALenum format = 0;
00124 
00125         if(waveinfo.wfType == WF_EX){
00126                 if(waveinfo.wfEXT.Format.nChannels == 1)
00127                         format = waveinfo.wfEXT.Format.wBitsPerSample == 16 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
00128                 else if(waveinfo.wfEXT.Format.nChannels == 2)
00129                         format = waveinfo.wfEXT.Format.wBitsPerSample == 16 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO8;
00130                 else if((waveinfo.wfEXT.Format.nChannels == 4) && (waveinfo.wfEXT.Format.wBitsPerSample == 16))
00131                         format = alGetEnumValue("AL_FORMAT_QUAD16");
00132         }else if(waveinfo.wfType == WF_EXT){
00133                 if ((waveinfo.wfEXT.Format.nChannels == 1) && (waveinfo.wfEXT.dwChannelMask == SPEAKER_FRONT_CENTER))
00134                         format = waveinfo.wfEXT.Format.wBitsPerSample == 16 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
00135                 else if ((waveinfo.wfEXT.Format.nChannels == 2) && (waveinfo.wfEXT.dwChannelMask == (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT)))
00136                         format = waveinfo.wfEXT.Format.wBitsPerSample == 16 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO8;
00137                 else if ((waveinfo.wfEXT.Format.nChannels == 2) && (waveinfo.wfEXT.Format.wBitsPerSample == 16) && (waveinfo.wfEXT.dwChannelMask == (SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)))
00138                         format =  alGetEnumValue("AL_FORMAT_REAR16");
00139                 else if ((waveinfo.wfEXT.Format.nChannels == 4) && (waveinfo.wfEXT.Format.wBitsPerSample == 16) && (waveinfo.wfEXT.dwChannelMask == (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)))
00140                         format = alGetEnumValue("AL_FORMAT_QUAD16");
00141                 else if ((waveinfo.wfEXT.Format.nChannels == 6) && (waveinfo.wfEXT.Format.wBitsPerSample == 16) && (waveinfo.wfEXT.dwChannelMask == (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)))
00142                         format = alGetEnumValue("AL_FORMAT_51CHN16");
00143                 else if ((waveinfo.wfEXT.Format.nChannels == 7) && (waveinfo.wfEXT.Format.wBitsPerSample == 16) && (waveinfo.wfEXT.dwChannelMask == (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_BACK_CENTER)))
00144                         format = alGetEnumValue("AL_FORMAT_61CHN16");
00145                 else if ((waveinfo.wfEXT.Format.nChannels == 8) && (waveinfo.wfEXT.Format.wBitsPerSample == 16) && (waveinfo.wfEXT.dwChannelMask == (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)))
00146                         format = alGetEnumValue("AL_FORMAT_71CHN16");
00147         }
00148 
00149         return format;
00150 }
00151 
00152 ENDNAMESPACE

Generated on Fri Jun 18 2010 17:48:39 for Cannonball by  doxygen 1.7.0