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
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
00033 WaveInfo.pData = new char[WaveInfo.ulDataSize];
00034 if(WaveInfo.pData){
00035
00036 fseek(WaveInfo.pFile, WaveInfo.ulDataOffset, SEEK_SET);
00037
00038
00039 if(fread(WaveInfo.pData, 1, WaveInfo.ulDataSize, WaveInfo.pFile) == WaveInfo.ulDataSize){
00040
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
00077 if(_wfopen_s(&pWaveInfo->pFile, file, TEXT("rb")) == 0){
00078
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
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
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