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

src/audio/src/OpenAL_util.cpp

Go to the documentation of this file.
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                         /* Raw files have no magic number - so use the fileName extension */
00051 
00052                         fileName = stream->fileName;
00053                         if(fileName != NULL && getFormatByExt(UTIL::STR::fileExt(fileName)) == fileRAW)
00054                                 return loadRawFile(stream);
00055 
00056                         /* For other file formats, read the quasi-standard four byte magic number */
00057                         if(!_alutInputStreamReadInt32BE(stream, &magic))
00058                                 return AL_FALSE;
00059 
00060                         /* Magic number 'RIFF' == Microsoft '.wav' format */
00061                         if(magic == 0x52494646)
00062                                 return loadWavFile(stream);
00063 
00064                         /* Magic number '.snd' == Sun & Next's '.au' format */
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   /* GCC is a bit picky about casting function calls, so we do it in two
00256      steps... */
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 }

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