void sound_ShutdownLibrary( void ) { #if !defined(WZ_NOSOUND) AUDIO_STREAM* stream; #endif SAMPLE_LIST * aSample = active_samples, * tmpSample = NULL; if ( !openal_initialized ) { return; } debug(LOG_SOUND, "starting shutdown"); #if !defined(WZ_NOSOUND) // Stop all streams, sound_UpdateStreams() will deallocate all stopped streams for (stream = active_streams; stream != NULL; stream = stream->next) { sound_StopStream(stream); } sound_UpdateStreams(); alcGetError(device); // clear error codes /* On Linux since this caused some versions of OpenAL to hang on exit. - Per */ debug(LOG_SOUND, "make default context NULL"); alcMakeContextCurrent(NULL); sound_GetContextError(device); debug(LOG_SOUND, "destroy previous context"); alcDestroyContext(context); // this gives a long delay on some impl. sound_GetContextError(device); debug(LOG_SOUND, "close device"); if (alcCloseDevice(device) == ALC_FALSE) { debug(LOG_SOUND, "OpenAl could not close the audio device." ); } #endif while( aSample ) { tmpSample = aSample->next; free( aSample ); aSample = tmpSample; } active_samples = NULL; }
void sound_Update() { SAMPLE_LIST *node = active_samples; SAMPLE_LIST *previous = NULL; ALCenum err; ALfloat gain; if (!openal_initialized) { return; } // Update all streaming audio sound_UpdateStreams(); while (node != NULL) { ALenum state, err; // query what the gain is for this sample alGetSourcef(node->curr->iSample, AL_GAIN, &gain); err = sound_GetError(); // if gain is 0, then we can't hear it, so we kill it. if (gain == 0.0f) { sound_DestroyIteratedSample(&previous, &node); continue; } //ASSERT(alIsSource(node->curr->iSample), "Not a valid source!"); alGetSourcei(node->curr->iSample, AL_SOURCE_STATE, &state); // Check whether an error occurred while retrieving the state. // If one did, the state returned is useless. So instead of // using it continue with the next sample. err = sound_GetError(); if (err != AL_NO_ERROR) { // Make sure to invoke the "finished" callback sound_FinishedCallback(node->curr); // Destroy this object and move to the next object sound_DestroyIteratedSample(&previous, &node); continue; } switch (state) { case AL_PLAYING: case AL_PAUSED: // If we haven't finished playing yet, just // continue with the next item in the list. // sound_SetObjectPosition(i->curr->iSample, i->curr->x, i->curr->y, i->curr->z); // Move to the next object previous = node; node = node->next; break; // NOTE: if it isn't playing | paused, then it is most likely either done // or a error. In either case, we want to kill the sample in question. default: sound_DestroyIteratedSample(&previous, &node); break; } } // Reset the current error state alcGetError(device); alcProcessContext(context); err = sound_GetContextError(device); if (err != ALC_NO_ERROR) { debug(LOG_ERROR, "Error while processing audio context: %s", alGetString(err)); } }
//* // ======================================================================================================================= // ======================================================================================================================= // bool sound_InitLibrary(void) { int err; const ALfloat listenerVel[3] = { 0.0, 0.0, 0.0 }; const ALfloat listenerOri[6] = { 0.0, 0.0, 1.0, 0.0, 1.0, 0.0 }; char buf[512]; const ALCchar *deviceName; #if 0 // This code is disabled because enumerating devices apparently crashes PulseAudio on Fedora12 /* Get the available devices and print them. * Devices are separated by NUL chars ('\0') and the list of devices is * terminated by two NUL chars. */ deviceName = alcGetString(NULL, ALC_DEVICE_SPECIFIER); while (deviceName != NULL && *deviceName != '\0') { debug(LOG_SOUND, "available OpenAL device(s) are: %s", deviceName); deviceName += strlen(deviceName) + 1; } #endif #ifdef WZ_OS_WIN /* HACK: Select the "software" OpenAL device on Windows because it * provides 256 sound sources (unlike most Creative's default * which provides only 16), causing our lack of source-management * to be significantly less noticeable. */ device = alcOpenDevice("Generic Software"); // If the software device isn't available, fall back to default if (!device) #endif { // Open default device device = alcOpenDevice(NULL); } if (!device) { debug(LOG_ERROR, "Couldn't open audio device."); return false; } // Print current device name and add it to dump info deviceName = alcGetString(device, ALC_DEVICE_SPECIFIER); debug(LOG_SOUND, "Current audio device: %s", deviceName); ssprintf(buf, "OpenAL Device Name: %s", deviceName); addDumpInfo(buf); context = alcCreateContext(device, NULL); //NULL was contextAttributes if (!context) { debug(LOG_ERROR, "Couldn't open audio context."); return false; } alcMakeContextCurrent(context); err = sound_GetContextError(device); if (err != ALC_NO_ERROR) { debug(LOG_ERROR, "Couldn't initialize audio context: %s", alcGetString(device, err)); return false; } // Dump Open AL device info (depends on context) // to the crash handler for the dump file and debug log ssprintf(buf, "OpenAL Vendor: %s", alGetString(AL_VENDOR)); addDumpInfo(buf); debug(LOG_SOUND, "%s", buf); ssprintf(buf, "OpenAL Version: %s", alGetString(AL_VERSION)); addDumpInfo(buf); debug(LOG_SOUND, "%s", buf); ssprintf(buf, "OpenAL Renderer: %s", alGetString(AL_RENDERER)); addDumpInfo(buf); debug(LOG_SOUND, "%s", buf); ssprintf(buf, "OpenAL Extensions: %s", alGetString(AL_EXTENSIONS)); addDumpInfo(buf); debug(LOG_SOUND, "%s", buf); openal_initialized = true; // Clear Error Codes alGetError(); alcGetError(device); alListener3f(AL_POSITION, 0.f, 0.f, 0.f); alListenerfv(AL_VELOCITY, listenerVel); alListenerfv(AL_ORIENTATION, listenerOri); alDistanceModel(AL_NONE); sound_GetError(); return true; }