| [4597] | 1 | /* | 
|---|
| [4504] | 2 |    orxonox - the future of 3D-vertical-scrollers | 
|---|
 | 3 |  | 
|---|
 | 4 |    Copyright (C) 2004 orx | 
|---|
 | 5 |  | 
|---|
 | 6 |    This program is free software; you can redistribute it and/or modify | 
|---|
 | 7 |    it under the terms of the GNU General Public License as published by | 
|---|
 | 8 |    the Free Software Foundation; either version 2, or (at your option) | 
|---|
 | 9 |    any later version. | 
|---|
 | 10 |  | 
|---|
 | 11 |    ### File Specific: | 
|---|
 | 12 |    main-programmer: Benjamin Grauer | 
|---|
 | 13 |    co-programmer: ... | 
|---|
 | 14 |  | 
|---|
 | 15 |    code has been taken from http://www.devmaster.net/articles.php?catID=6 | 
|---|
 | 16 |    The code has been applied to our needs, and many things have been changed. | 
|---|
 | 17 | */ | 
|---|
 | 18 |  | 
|---|
| [5386] | 19 | #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND | 
|---|
| [4504] | 20 |  | 
|---|
 | 21 | #include "sound_engine.h" | 
|---|
 | 22 |  | 
|---|
 | 23 | #include "p_node.h" | 
|---|
 | 24 | #include "debug.h" | 
|---|
| [9869] | 25 | #include "parser/preferences/preferences.h" | 
|---|
| [5427] | 26 | #include "globals.h" | 
|---|
| [9869] | 27 | #include "resource_sound_buffer.h" | 
|---|
| [4504] | 28 |  | 
|---|
| [7460] | 29 | namespace OrxSound | 
|---|
| [4504] | 30 | { | 
|---|
| [9869] | 31 |   ObjectListDefinition(SoundEngine); | 
|---|
| [7460] | 32 |   ////////////////// | 
|---|
 | 33 |   /* SOUND-ENGINE */ | 
|---|
 | 34 |   ////////////////// | 
|---|
 | 35 |   /** | 
|---|
 | 36 |    * @brief standard constructor | 
|---|
 | 37 |   */ | 
|---|
 | 38 |   SoundEngine::SoundEngine () | 
|---|
 | 39 |   { | 
|---|
| [9869] | 40 |     this->registerObject(this, SoundEngine::_objectList); | 
|---|
| [7460] | 41 |     this->setName("SoundEngine"); | 
|---|
| [5930] | 42 |  | 
|---|
| [7460] | 43 |     this->listener = NULL; | 
|---|
| [5930] | 44 |  | 
|---|
| [7460] | 45 |     this->device = NULL; | 
|---|
 | 46 |     this->context = NULL; | 
|---|
| [6829] | 47 |  | 
|---|
| [7460] | 48 |     this->maxSourceCount = 32; | 
|---|
| [7298] | 49 |  | 
|---|
| [7460] | 50 |     this->effectsVolume = .80; | 
|---|
 | 51 |     this->musicVolume = .75; | 
|---|
| [4504] | 52 |  | 
|---|
| [7460] | 53 |     this->sourceMutex = SDL_CreateMutex(); | 
|---|
| [4960] | 54 |   } | 
|---|
| [4504] | 55 |  | 
|---|
| [7460] | 56 |   /** | 
|---|
 | 57 |    * @brief the singleton reference to this class | 
|---|
 | 58 |   */ | 
|---|
 | 59 |   SoundEngine* SoundEngine::singletonRef = NULL; | 
|---|
 | 60 |  | 
|---|
 | 61 |   /** | 
|---|
 | 62 |    * @brief standard destructor | 
|---|
 | 63 |    */ | 
|---|
 | 64 |   SoundEngine::~SoundEngine () | 
|---|
| [5930] | 65 |   { | 
|---|
| [7460] | 66 |     // deleting all the SoundSources | 
|---|
| [9869] | 67 |     while (!SoundSource::objectList().empty()) | 
|---|
 | 68 |       delete (SoundSource::objectList().front()); | 
|---|
| [7291] | 69 |  | 
|---|
| [7460] | 70 |     while(!this->ALSources.empty()) | 
|---|
 | 71 |     { | 
|---|
 | 72 |       if (alIsSource(this->ALSources.top())) | 
|---|
 | 73 |       { | 
|---|
 | 74 |         alDeleteSources(1, &this->ALSources.top()); | 
|---|
 | 75 |         SoundEngine::checkError("Deleting Source", __LINE__); | 
|---|
 | 76 |       } | 
|---|
 | 77 |       else | 
|---|
 | 78 |         PRINTF(1)("%d is not a Source\n", this->ALSources.top()); | 
|---|
| [5930] | 79 |  | 
|---|
| [7460] | 80 |       this->ALSources.pop(); | 
|---|
 | 81 |     } | 
|---|
| [5293] | 82 |  | 
|---|
| [7460] | 83 |     // deleting all the SoundBuffers | 
|---|
| [9869] | 84 |     //    while(!SoundBuffer::objectList().empty()) | 
|---|
 | 85 |     //ResourceManager::getInstance()->unload(SoundBuffer::objectList().front()); | 
|---|
| [5293] | 86 |  | 
|---|
| [7460] | 87 |     // removing openAL from AudioResource | 
|---|
 | 88 |     //! @todo this should be terminated through alc | 
|---|
 | 89 |     //alutExit(); | 
|---|
| [7298] | 90 |  | 
|---|
| [7460] | 91 |     SDL_DestroyMutex(this->sourceMutex); | 
|---|
| [4504] | 92 |  | 
|---|
| [7460] | 93 |     SoundEngine::singletonRef = NULL; | 
|---|
 | 94 |   } | 
|---|
| [4985] | 95 |  | 
|---|
| [7460] | 96 |   /** | 
|---|
 | 97 |    * @brief loads the settings of the SoundEngine from an ini-file | 
|---|
 | 98 |    */ | 
|---|
 | 99 |   void SoundEngine::loadSettings() | 
|---|
 | 100 |   { | 
|---|
 | 101 |     MultiType channels = Preferences::getInstance()->getString(CONFIG_SECTION_AUDIO, CONFIG_NAME_AUDIO_CHANNELS, "32"); | 
|---|
 | 102 |     this->maxSourceCount = channels.getInt(); | 
|---|
| [6830] | 103 |  | 
|---|
| [7460] | 104 |     MultiType effectsVolume = Preferences::getInstance()->getString(CONFIG_SECTION_AUDIO, CONFIG_NAME_EFFECTS_VOLUME, "80"); | 
|---|
 | 105 |     this->effectsVolume = effectsVolume.getFloat()/100.0; | 
|---|
| [4985] | 106 |  | 
|---|
| [7460] | 107 |     MultiType musicVolume = Preferences::getInstance()->getString(CONFIG_SECTION_AUDIO, CONFIG_NAME_MUSIC_VOLUME, "75"); | 
|---|
 | 108 |     this->musicVolume = musicVolume.getFloat()/100.0; | 
|---|
 | 109 |   } | 
|---|
 | 110 |  | 
|---|
 | 111 |   /** | 
|---|
 | 112 |    * @brief creates a new SoundSource. | 
|---|
 | 113 |    * @param fileName The Name to load the SoundBuffer from | 
|---|
 | 114 |    * @param sourceNode The sourceNode to bind this SoundSource to. | 
|---|
 | 115 |    * @returns The newly created SoundSource | 
|---|
 | 116 |    * | 
|---|
 | 117 |    * acctualy this is nothing more than a wrapper around the ResourceManager. | 
|---|
 | 118 |   */ | 
|---|
 | 119 |   SoundSource* SoundEngine::createSource(const std::string& fileName, PNode* sourceNode) | 
|---|
| [7318] | 120 |   { | 
|---|
| [9869] | 121 |     SoundBuffer buffer; | 
|---|
| [7460] | 122 |     if (!fileName.empty()) | 
|---|
 | 123 |     { | 
|---|
| [9869] | 124 |       buffer = ResourceSoundBuffer(fileName); | 
|---|
 | 125 |       if (!buffer.loaded()) | 
|---|
| [7460] | 126 |         PRINTF(2)("Wav-Sound %s could not be loaded onto new Source\n", fileName.c_str()); | 
|---|
 | 127 |     } | 
|---|
 | 128 |     return new SoundSource(sourceNode, buffer); | 
|---|
| [7318] | 129 |   } | 
|---|
| [4504] | 130 |  | 
|---|
| [7460] | 131 |   /** | 
|---|
 | 132 |    * @brief Sets the doppler values of openAL | 
|---|
 | 133 |    * @param dopplerFactor the extent of the doppler-effect | 
|---|
 | 134 |    * @param dopplerVelocity the Speed the sound travels | 
|---|
 | 135 |   */ | 
|---|
 | 136 |   void SoundEngine::setDopplerValues(ALfloat dopplerFactor, ALfloat dopplerVelocity) | 
|---|
 | 137 |   { | 
|---|
 | 138 |     alDopplerFactor(dopplerFactor); | 
|---|
 | 139 |     this->checkError("Setting Doppler Factor", __LINE__); | 
|---|
| [6840] | 140 |  | 
|---|
| [7460] | 141 |     alDopplerVelocity(dopplerVelocity); | 
|---|
 | 142 |     this->checkError("Setting Doppler Velocity", __LINE__); | 
|---|
 | 143 |   } | 
|---|
| [4504] | 144 |  | 
|---|
 | 145 |  | 
|---|
| [7460] | 146 |   /** | 
|---|
 | 147 |    * @brief retrieves an OpenAL Source from the availiable Sources. | 
|---|
 | 148 |    * @param source the Source to fill with the Value. | 
|---|
 | 149 |    */ | 
|---|
 | 150 |   void SoundEngine::popALSource(ALuint& source) | 
|---|
| [5930] | 151 |   { | 
|---|
| [7460] | 152 |     assert (source == 0); | 
|---|
 | 153 |     /// @TODO try to create more sources if needed | 
|---|
 | 154 |     if (!this->ALSources.empty()) | 
|---|
 | 155 |     { | 
|---|
 | 156 |       SDL_mutexP(this->sourceMutex); | 
|---|
 | 157 |       source = this->ALSources.top(); | 
|---|
 | 158 |       this->ALSources.pop(); | 
|---|
 | 159 |       SDL_mutexV(this->sourceMutex); | 
|---|
 | 160 |     } | 
|---|
| [7284] | 161 |   } | 
|---|
| [4504] | 162 |  | 
|---|
| [7299] | 163 |  | 
|---|
| [7460] | 164 |   /** | 
|---|
 | 165 |    * @brief Pushes an OpenAL Source back into the Stack of known sources | 
|---|
 | 166 |    * @param source the Source to push onto the top of the SourceStack | 
|---|
 | 167 |    */ | 
|---|
 | 168 |   void SoundEngine::pushALSource(ALuint& source) | 
|---|
| [7298] | 169 |   { | 
|---|
| [7460] | 170 |     if (source != 0) | 
|---|
 | 171 |     { | 
|---|
 | 172 |       SDL_mutexP(this->sourceMutex); | 
|---|
 | 173 |       this->ALSources.push(source); | 
|---|
 | 174 |       SDL_mutexV(this->sourceMutex); | 
|---|
 | 175 |     } | 
|---|
 | 176 |   }; | 
|---|
| [4504] | 177 |  | 
|---|
| [7298] | 178 |  | 
|---|
| [7460] | 179 |   /** | 
|---|
 | 180 |    * @brief updates all The positions, Directions and Velocities of all Sounds | 
|---|
 | 181 |    */ | 
|---|
 | 182 |   void SoundEngine::update() | 
|---|
| [6846] | 183 |   { | 
|---|
| [7460] | 184 |     // updating the Listeners Position | 
|---|
 | 185 |     if (likely(this->listener != NULL)) | 
|---|
 | 186 |     { | 
|---|
 | 187 |       alListener3f(AL_POSITION, | 
|---|
 | 188 |                    this->listener->getAbsCoor().x, | 
|---|
 | 189 |                    this->listener->getAbsCoor().y, | 
|---|
 | 190 |                    this->listener->getAbsCoor().z); | 
|---|
 | 191 |       alListener3f(AL_VELOCITY, | 
|---|
 | 192 |                    this->listener->getVelocity().x, | 
|---|
 | 193 |                    this->listener->getVelocity().y, | 
|---|
 | 194 |                    this->listener->getVelocity().z); | 
|---|
 | 195 |       Vector absDirV = this->listener->getAbsDirV(); | 
|---|
 | 196 |       ALfloat orientation [6] = {1,0,0, absDirV.x, absDirV.y, absDirV.z}; | 
|---|
 | 197 |       alListenerfv(AL_ORIENTATION, orientation); | 
|---|
 | 198 |       SoundEngine::checkError("SoundEngine::update() - Listener Error", __LINE__); | 
|---|
 | 199 |     } | 
|---|
 | 200 |     else | 
|---|
 | 201 |       PRINTF(2)("no listener defined\n"); | 
|---|
| [4504] | 202 |  | 
|---|
| [7460] | 203 |     // updating all the Sources positions | 
|---|
| [9869] | 204 |     ObjectList<SoundSource>::const_iterator sourceIT; | 
|---|
 | 205 |     for (sourceIT = SoundSource::objectList().begin(); | 
|---|
 | 206 |          sourceIT != SoundSource::objectList().end(); | 
|---|
 | 207 |          sourceIT++) | 
|---|
| [4504] | 208 |     { | 
|---|
| [9869] | 209 |       if ((*sourceIT)->isPlaying()) | 
|---|
| [4504] | 210 |       { | 
|---|
| [9869] | 211 |         int play = 0x000; | 
|---|
 | 212 |         alGetSourcei((*sourceIT)->getID(), AL_SOURCE_STATE, &play); | 
|---|
 | 213 |         if (DEBUG_LEVEL > 2) | 
|---|
 | 214 |           SoundEngine::checkError("SoundEngine::update() Play", __LINE__); | 
|---|
 | 215 |         if(play == AL_PLAYING) | 
|---|
| [5930] | 216 |         { | 
|---|
| [9869] | 217 |           if (likely((*sourceIT)->getNode() != NULL)) | 
|---|
| [5930] | 218 |           { | 
|---|
| [9869] | 219 |             alSource3f((*sourceIT)->getID(), AL_POSITION, | 
|---|
 | 220 |                        (*sourceIT)->getNode()->getAbsCoor().x, | 
|---|
 | 221 |                        (*sourceIT)->getNode()->getAbsCoor().y, | 
|---|
 | 222 |                        (*sourceIT)->getNode()->getAbsCoor().z); | 
|---|
 | 223 |             if (DEBUG_LEVEL > 2) | 
|---|
 | 224 |               SoundEngine::checkError("SoundEngine::update() Set Source Position", __LINE__); | 
|---|
 | 225 |             alSource3f((*sourceIT)->getID(), AL_VELOCITY, | 
|---|
 | 226 |                        (*sourceIT)->getNode()->getVelocity().x, | 
|---|
 | 227 |                        (*sourceIT)->getNode()->getVelocity().y, | 
|---|
 | 228 |                        (*sourceIT)->getNode()->getVelocity().z); | 
|---|
 | 229 |             if (DEBUG_LEVEL > 2) | 
|---|
 | 230 |               SoundEngine::checkError("SoundEngine::update() Set Source Velocity", __LINE__); | 
|---|
| [5930] | 231 |           } | 
|---|
 | 232 |         } | 
|---|
| [9869] | 233 |         else | 
|---|
 | 234 |         { | 
|---|
 | 235 |           (*sourceIT)->stop(); | 
|---|
 | 236 |         } | 
|---|
| [4504] | 237 |       } | 
|---|
 | 238 |     } | 
|---|
| [7460] | 239 |     SoundEngine::checkError("SoundEngine::update()", __LINE__); | 
|---|
| [4960] | 240 |   } | 
|---|
| [4504] | 241 |  | 
|---|
 | 242 |  | 
|---|
| [7460] | 243 |   /** | 
|---|
 | 244 |    *  initializes Audio in general | 
|---|
 | 245 |   */ | 
|---|
 | 246 |   bool SoundEngine::initAudio() | 
|---|
 | 247 |   { | 
|---|
 | 248 |     //   ALenum result; | 
|---|
 | 249 |     //   PRINTF(3)("Initialisazing openAL sound engine\n"); | 
|---|
 | 250 |     //   const char* defaultDevice =(const char*) alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); | 
|---|
 | 251 |     //   const char* deviceList = (const char*)alcGetString(NULL,ALC_DEVICE_SPECIFIER); | 
|---|
 | 252 |     //   const char* devWalk = deviceList; | 
|---|
 | 253 |     //   //  if (alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE) | 
|---|
 | 254 |     //   { // try out enumeration extension | 
|---|
 | 255 |     //     PRINTF(3)("Enumeration-extension found\n"); | 
|---|
 | 256 |     // | 
|---|
 | 257 |     //     PRINTF(3)("Default device: %s\n", defaultDevice); | 
|---|
 | 258 |     //     do | 
|---|
 | 259 |     //     { | 
|---|
 | 260 |     //       PRINTF(3)("%s\n", devWalk); | 
|---|
 | 261 |     //       devWalk += strlen(devWalk)+1; | 
|---|
 | 262 |     //     } | 
|---|
 | 263 |     //     while (devWalk[0] != '\0'); | 
|---|
 | 264 |     //  } | 
|---|
| [4504] | 265 |  | 
|---|
| [7460] | 266 |     // INITIALIZING THE DEVICE: | 
|---|
 | 267 |     //   char deviceName[] = | 
|---|
 | 268 |     //   #ifdef __WIN32__ | 
|---|
 | 269 |     //     "Direct3D"; | 
|---|
 | 270 |     //   #else | 
|---|
 | 271 |     //     "'( ( devices '( native null ) ) )"; | 
|---|
 | 272 |     //   #endif | 
|---|
| [5385] | 273 |  | 
|---|
| [7460] | 274 |     this->device = alcOpenDevice(NULL); | 
|---|
 | 275 |     this->checkALCError("opening Device", __LINE__); | 
|---|
| [5819] | 276 |  | 
|---|
| [7460] | 277 |     PRINTF(4)("Audio-Specifier: %s\n", (const char*)alcGetString(this->device, ALC_DEVICE_SPECIFIER)); | 
|---|
 | 278 |     PRINTF(4)("Audio-Extensions: %s\n", (const char*)alcGetString(this->device, ALC_EXTENSIONS)); | 
|---|
| [6849] | 279 |  | 
|---|
| [6856] | 280 |  | 
|---|
| [7460] | 281 |     this->context = alcCreateContext(this->device, NULL); | 
|---|
 | 282 |     this->checkALCError("creating Context", __LINE__); | 
|---|
| [6849] | 283 |  | 
|---|
| [7460] | 284 |     alcMakeContextCurrent(this->context); | 
|---|
 | 285 |     this->checkALCError("making Context Current", __LINE__); | 
|---|
 | 286 |     // #endif | 
|---|
| [5819] | 287 |  | 
|---|
| [7460] | 288 |     this->setDopplerValues(SOUND_DOPPLER_FACTOR, SOUND_DOPPLER_VELOCITY); | 
|---|
 | 289 |     this->allocateSources(this->maxSourceCount); | 
|---|
 | 290 |     this->checkError("Allocating Sources", __LINE__); | 
|---|
| [8350] | 291 |  | 
|---|
 | 292 |     return true; | 
|---|
| [7460] | 293 |   } | 
|---|
| [4504] | 294 |  | 
|---|
| [5917] | 295 |  | 
|---|
| [7460] | 296 |   /** | 
|---|
 | 297 |    * Allocates openAL sources | 
|---|
 | 298 |    * @param count how many sources to allocate | 
|---|
 | 299 |    * @returns true on success, false if at least one source could not be allocated | 
|---|
 | 300 |    */ | 
|---|
 | 301 |   bool SoundEngine::allocateSources(unsigned int count) | 
|---|
| [5917] | 302 |   { | 
|---|
| [7460] | 303 |     unsigned int failCount = 0; | 
|---|
 | 304 |     for (unsigned int i = 0; i < count; i++) | 
|---|
 | 305 |     { | 
|---|
 | 306 |       ALuint source = 0; | 
|---|
| [5917] | 307 |  | 
|---|
| [7460] | 308 |       alGenSources(1, &source); | 
|---|
 | 309 |       this->checkError("allocate Source", __LINE__); | 
|---|
 | 310 |       if (!alIsSource(source)) | 
|---|
 | 311 |       { | 
|---|
 | 312 |         PRINTF(5)("not allocated Source\n"); | 
|---|
 | 313 |         failCount++; | 
|---|
 | 314 |         continue; | 
|---|
 | 315 |       } | 
|---|
 | 316 |  | 
|---|
 | 317 |       alSourcef (source, AL_PITCH,    1.0      ); | 
|---|
 | 318 |       alSourcef (source, AL_GAIN,     this->getEffectsVolume() ); | 
|---|
 | 319 |       alSourcei (source, AL_LOOPING,  AL_FALSE ); | 
|---|
 | 320 |       this->ALSources.push(source); | 
|---|
 | 321 |     } | 
|---|
 | 322 |     if (failCount == 0) | 
|---|
 | 323 |       return true; | 
|---|
 | 324 |     else | 
|---|
| [6842] | 325 |     { | 
|---|
| [7460] | 326 |       PRINTF(2)("Failed to allocate %d of %d SoundSources\n", failCount, count); | 
|---|
| [8350] | 327 |       return false; | 
|---|
| [6842] | 328 |     } | 
|---|
| [5917] | 329 |   } | 
|---|
 | 330 |  | 
|---|
| [7460] | 331 |   /** | 
|---|
 | 332 |    * @brief checks for an OpenAL error | 
|---|
 | 333 |    * @param error the ErrorMessage to display | 
|---|
 | 334 |    * @param line on what line did the error occure. | 
|---|
 | 335 |    */ | 
|---|
 | 336 |   bool SoundEngine::checkError(const std::string& error, unsigned int line) | 
|---|
| [6836] | 337 |   { | 
|---|
| [7460] | 338 |     ALenum errorCode; | 
|---|
 | 339 |     if ((errorCode = alGetError()) != AL_NO_ERROR) | 
|---|
 | 340 |     { | 
|---|
| [9235] | 341 |       //PRINTF(1)("Error %s (line:%d): '%s'\n", error.c_str(), line, SoundEngine::getALErrorString(errorCode)); | 
|---|
| [7460] | 342 |       return false; | 
|---|
 | 343 |     } | 
|---|
 | 344 |     else | 
|---|
 | 345 |       return true; | 
|---|
| [6836] | 346 |   } | 
|---|
 | 347 |  | 
|---|
| [7460] | 348 |   /** | 
|---|
 | 349 |    * @brief check for an ALC error. | 
|---|
 | 350 |    * @brief error the Error-String to display | 
|---|
 | 351 |    * @param line on that line, the error occured (debugging mode). | 
|---|
 | 352 |    */ | 
|---|
 | 353 |   bool SoundEngine::checkALCError(const std::string& error, unsigned int line) | 
|---|
| [6849] | 354 |   { | 
|---|
| [7460] | 355 |     ALenum errorCode; | 
|---|
 | 356 |     if ((errorCode = alcGetError(this->device)) != ALC_NO_ERROR) | 
|---|
 | 357 |     { | 
|---|
 | 358 |       PRINTF(1)("Error %s (line:%d): '%s'\n", error.c_str(), line, SoundEngine::getALCErrorString(errorCode)); | 
|---|
 | 359 |       return false; | 
|---|
 | 360 |     } | 
|---|
 | 361 |     else | 
|---|
 | 362 |       return true; | 
|---|
| [6849] | 363 |   } | 
|---|
 | 364 |  | 
|---|
 | 365 |  | 
|---|
 | 366 |  | 
|---|
| [7460] | 367 |   void SoundEngine::listDevices() | 
|---|
 | 368 |   { | 
|---|
 | 369 |     printf("%s\n",(const char*)alcGetString(NULL, ALC_DEVICE_SPECIFIER)); | 
|---|
 | 370 |   } | 
|---|
| [6849] | 371 |  | 
|---|
| [7460] | 372 |   /** | 
|---|
 | 373 |    *  Transforms AL-errors into something readable | 
|---|
 | 374 |    * @param err The error found | 
|---|
 | 375 |   */ | 
|---|
 | 376 |   const char* SoundEngine::getALErrorString(ALenum err) | 
|---|
| [6846] | 377 |   { | 
|---|
| [7460] | 378 |     switch(err) | 
|---|
 | 379 |     { | 
|---|
| [8350] | 380 |       default: | 
|---|
 | 381 |       case AL_NO_ERROR: | 
|---|
| [9869] | 382 |       return ("AL_NO_ERROR"); | 
|---|
| [8350] | 383 |       case AL_INVALID_NAME: | 
|---|
| [9869] | 384 |       return ("AL_INVALID_NAME"); | 
|---|
| [8350] | 385 |       case AL_INVALID_ENUM: | 
|---|
| [9869] | 386 |       return ("AL_INVALID_ENUM"); | 
|---|
| [8350] | 387 |       case AL_INVALID_VALUE: | 
|---|
| [9869] | 388 |       return ("AL_INVALID_VALUE"); | 
|---|
| [8350] | 389 |       case AL_INVALID_OPERATION: | 
|---|
| [9869] | 390 |       return ("AL_INVALID_OPERATION"); | 
|---|
| [8350] | 391 |       case AL_OUT_OF_MEMORY: | 
|---|
| [9869] | 392 |       return ("AL_OUT_OF_MEMORY"); | 
|---|
| [7460] | 393 |     }; | 
|---|
 | 394 |   } | 
|---|
| [4504] | 395 |  | 
|---|
| [4959] | 396 |  | 
|---|
| [7460] | 397 |   const char* SoundEngine::getALCErrorString(ALenum err) | 
|---|
| [7284] | 398 |   { | 
|---|
| [7460] | 399 |     switch(err) | 
|---|
 | 400 |     { | 
|---|
| [8350] | 401 |       default: | 
|---|
 | 402 |       case ALC_NO_ERROR: | 
|---|
| [9869] | 403 |       return ("AL_NO_ERROR"); | 
|---|
| [8350] | 404 |       case ALC_INVALID_DEVICE: | 
|---|
| [9869] | 405 |       return ("ALC_INVALID_DEVICE"); | 
|---|
| [8350] | 406 |       case ALC_INVALID_CONTEXT: | 
|---|
| [9869] | 407 |       return("ALC_INVALID_CONTEXT"); | 
|---|
| [8350] | 408 |       case ALC_INVALID_ENUM: | 
|---|
| [9869] | 409 |       return("ALC_INVALID_ENUM"); | 
|---|
| [8350] | 410 |       case ALC_INVALID_VALUE: | 
|---|
| [9869] | 411 |       return ("ALC_INVALID_VALUE"); | 
|---|
| [8350] | 412 |       case ALC_OUT_OF_MEMORY: | 
|---|
| [9869] | 413 |       return("ALC_OUT_OF_MEMORY"); | 
|---|
| [7460] | 414 |     }; | 
|---|
 | 415 |   } | 
|---|
| [4504] | 416 | } | 
|---|