00001 #include "../h/OpenAL.h"
00002
00003 namespace REAL
00004 {
00005 namespace AUDIO
00006 {
00007 FILEFORMAT getFormatByExt(rchar* ext)
00008 {
00009 if(ext == 0)
00010 return fileUnknown;
00011 const int len = UTIL::STR::strlen(ext);
00012
00013 switch(ext[0])
00014 {
00015 case 'w':
00016 case 'W':
00017 if(len >= 3 && (ext[1] == 'a' || ext[1] == 'A') && (ext[2] == 'v' || ext[2] == 'V'))
00018 return fileWAVE;
00019 break;
00020 case 'o':
00021 case 'O':
00022 if(len == 3 && (ext[1] == 'g' || ext[1] == 'G') && (ext[2] == 'g' || ext[2] == 'G'))
00023 return fileOGG;
00024 break;
00025 case 'a':
00026 case 'A':
00027 if(len == 2 && (ext[1] == 'u' || ext[1] == 'U'))
00028 return fileAU;
00029 break;
00030 case 'r':
00031 case 'R':
00032 if(len == 3 && (ext[1] == 'a' || ext[1] == 'A') && (ext[2] == 'w' || ext[2] == 'W'))
00033 return fileRAW;
00034 break;
00035 }
00036 return fileUnknown;
00037 }
00038
00039 ALuint alutCreateBufferFromFile(rchar *fileName)
00040 {
00041 InputStream* stream = _alutInputStreamConstructFromFile(fileName);
00042 return _alutCreateBufferFromInputStream(stream);
00043 }
00044
00045 BufferData* loadFile(InputStream *stream)
00046 {
00047 rchar *fileName;
00048 int magic;
00049
00050
00051
00052 fileName = stream->fileName;
00053 if(fileName != NULL && getFormatByExt(UTIL::STR::fileExt(fileName)) == fileRAW)
00054 return loadRawFile(stream);
00055
00056
00057 if(!_alutInputStreamReadInt32BE(stream, &magic))
00058 return AL_FALSE;
00059
00060
00061 if(magic == 0x52494646)
00062 return loadWavFile(stream);
00063
00064
00065 if(magic == 0x2E736E64)
00066 return loadAUFile(stream);
00067
00068 return AL_FALSE;
00069 }
00070
00071 InputStream* _alutInputStreamConstructFromFile(rchar *fileName)
00072 {
00073 InputStream *stream;
00074 structStat statBuf;
00075 FILE *fileDescriptor;
00076
00077 stream = new InputStream;
00078 if(stream == NULL)
00079 return 0;
00080
00081 if(stat(fileName, &statBuf))
00082 {
00083 delete stream;
00084 return 0;
00085 }
00086
00087 if(FOPEN(&fileDescriptor, fileName, _T("rb")) == false)
00088 {
00089 delete stream;
00090 return 0;
00091 }
00092
00093 stream->isFileStream = AL_TRUE;
00094 stream->fileName = fileName;
00095 stream->remainingLength = statBuf.st_size;
00096 stream->u.fileDescriptor = fileDescriptor;
00097 return stream;
00098 }
00099
00100 ALboolean _alutInputStreamDestroy(InputStream *stream)
00101 {
00102 ALboolean status =
00103 (stream->isFileStream && FCLOSE(stream->u.fileDescriptor)) ?
00104 AL_FALSE : AL_TRUE;
00105 if(stream->fileName)
00106 memfree(stream->fileName);
00107 memfree(stream);
00108 return status;
00109 }
00110
00111 ALboolean streamRead(InputStream *stream, void *ptr, size_t numBytesToRead)
00112 {
00113 if(stream->isFileStream)
00114 {
00115 size_t numBytesRead = FREAD(ptr, 1, numBytesToRead, stream->u.fileDescriptor);
00116 return (numBytesToRead == numBytesRead);
00117 }
00118 else
00119 {
00120 if(stream->remainingLength < numBytesToRead)
00121 return AL_FALSE;
00122 memcpy(ptr, stream->u.data, numBytesToRead);
00123 stream->u.data = ((const char *) (stream->u.data) + numBytesToRead);
00124 return AL_TRUE;
00125 }
00126 }
00127
00128 ALvoid* _alutInputStreamRead(InputStream *stream, size_t length)
00129 {
00130 ALvoid *data = memalloc(length);
00131 if(data == NULL)
00132 return NULL;
00133
00134 if(!streamRead(stream, data, length))
00135 {
00136 memfree(data);
00137 return NULL;
00138 }
00139
00140 return data;
00141 }
00142
00143 BufferData* _alutBufferDataConstruct(ALvoid *data, size_t length, ALint numChannels,
00144 ALint bitsPerSample, ALfloat sampleFrequency)
00145 {
00146 BufferData *bufferData = new BufferData;
00147 if (bufferData == NULL)
00148 return NULL;
00149
00150 bufferData->data = data;
00151 bufferData->length = length;
00152 bufferData->numChannels = numChannels;
00153 bufferData->bitsPerSample = bitsPerSample;
00154 bufferData->sampleFrequency = sampleFrequency;
00155
00156 return bufferData;
00157 }
00158
00159 ALvoid* _alutCodecLinear(ALvoid *data, size_t length, ALint numChannels,
00160 ALint bitsPerSample, ALfloat sampleFrequency)
00161 {
00162 return _alutBufferDataConstruct(data, length, numChannels, bitsPerSample,
00163 sampleFrequency);
00164 }
00165
00166 ALboolean _alutInputStreamReadInt32BE(InputStream *stream, int *value)
00167 {
00168 unsigned char buf[4];
00169 if (!streamRead(stream, buf, sizeof(buf)))
00170 return AL_FALSE;
00171 *value =
00172 ((int) buf[0] << 24) |
00173 ((int) buf[1] << 16) |
00174 ((int) buf[2] << 8) | ((int) buf[3]);
00175 return AL_TRUE;
00176 }
00177
00178 ALboolean _alutInputStreamReadUInt16LE(InputStream *stream, unsigned short *value)
00179 {
00180 unsigned char buf[2];
00181 if (!streamRead (stream, buf, sizeof (buf)))
00182 return AL_FALSE;
00183 *value = ((unsigned short) buf[1] << 8) | ((UInt16LittleEndian) buf[0]);
00184 return AL_TRUE;
00185 }
00186
00187 ALboolean _alutInputStreamReadUInt32LE(InputStream *stream, unsigned int *value)
00188 {
00189 unsigned char buf[4];
00190 if (!streamRead (stream, buf, sizeof (buf)))
00191 return AL_FALSE;
00192 *value =
00193 ((unsigned int) buf[3] << 24) |
00194 ((unsigned int) buf[2] << 16) |
00195 ((unsigned int) buf[1] << 8) | ((unsigned int) buf[0]);
00196 return AL_TRUE;
00197 }
00198
00199 ALboolean _alutInputStreamSkip (InputStream *stream, size_t numBytesToSkip)
00200 {
00201 ALboolean status;
00202 char *buf;
00203 if(numBytesToSkip == 0)
00204 return AL_TRUE;
00205
00206 buf = (char*) memalloc(numBytesToSkip);
00207 if(buf == NULL)
00208 return AL_FALSE;
00209
00210 status = streamRead(stream, buf, numBytesToSkip);
00211 memfree(buf);
00212 return status;
00213 }
00214
00215 ALboolean _alutInputStreamEOF(InputStream *stream)
00216 {
00217 if (stream->isFileStream)
00218 {
00219 int c = fgetc (stream->u.fileDescriptor);
00220 if (c != EOF)
00221 {
00222 ungetc (c, stream->u.fileDescriptor);
00223 }
00224 return (c == EOF) ? AL_TRUE : AL_FALSE;
00225 }
00226 else
00227 {
00228 return (stream->remainingLength == 0) ? AL_TRUE : AL_FALSE;
00229 }
00230 }
00231
00232 static ALuint
00233 generateBuffer (void)
00234 {
00235 ALuint buffer;
00236 alGenBuffers (1, &buffer);
00237 if (alGetError () != AL_NO_ERROR)
00238 {
00239 _alutSetError (ALUT_ERROR_GEN_BUFFERS);
00240 return AL_NONE;
00241 }
00242 return buffer;
00243 }
00244
00245 static ALboolean
00246 passBufferData (BufferData *bufferData, ALuint bid)
00247 {
00248 ALenum format;
00249 size_t size;
00250 ALfloat frequency;
00251 if (!_alutGetFormat (bufferData, &format))
00252 {
00253 return AL_FALSE;
00254 }
00255
00256
00257 size = _alutBufferDataGetLength (bufferData);
00258 frequency = _alutBufferDataGetSampleFrequency (bufferData);
00259 alBufferData (bid, format, _alutBufferDataGetData (bufferData),
00260 (ALsizei) size, (ALsizei) frequency);
00261 if (alGetError () != AL_NO_ERROR)
00262 {
00263 _alutSetError (ALUT_ERROR_BUFFER_DATA);
00264 return AL_FALSE;
00265 }
00266 return AL_TRUE;
00267 }
00268
00269 ALuint
00270 _alutPassBufferData (BufferData *bufferData)
00271 {
00272 ALuint buffer = generateBuffer ();
00273 if (buffer == AL_NONE)
00274 {
00275 return AL_NONE;
00276 }
00277
00278 if (!passBufferData (bufferData, buffer))
00279 {
00280 return AL_NONE;
00281 }
00282
00283 return buffer;
00284 }
00285
00286 ALuint _alutCreateBufferFromInputStream (InputStream *stream)
00287 {
00288 BufferData *bufferData;
00289 ALuint buffer;
00290
00291 if(stream == NULL)
00292 return AL_NONE;
00293
00294 bufferData = loadFile(stream);
00295 _alutInputStreamDestroy(stream);
00296 if(bufferData == NULL)
00297 return AL_NONE;
00298
00299 buffer = _alutPassBufferData(bufferData);
00300 _alutBufferDataDestroy(bufferData);
00301
00302 return buffer;
00303 }
00304 }
00305 }