__FORCE_ALIGN_STACK__ void CSound::StartThread(int maxSounds) { { boost::recursive_mutex::scoped_lock lck(soundMutex); // alc... will create its own thread it will copy the name from the current thread. // Later we finally rename `our` audio thread. Threading::SetThreadName("openal"); // NULL -> default device const ALchar* deviceName = NULL; std::string configDeviceName = ""; // we do not want to set a default for snd_device, // so we do it like this ... if (configHandler->IsSet("snd_device")) { configDeviceName = configHandler->GetString("snd_device"); deviceName = configDeviceName.c_str(); } ALCdevice* device = alcOpenDevice(deviceName); if ((device == NULL) && (deviceName != NULL)) { LOG_L(L_WARNING, "Could not open the sound device \"%s\", trying the default device ...", deviceName); configDeviceName = ""; deviceName = NULL; device = alcOpenDevice(deviceName); } if (device == NULL) { LOG_L(L_ERROR, "Could not open a sound device, disabling sounds"); CheckError("CSound::InitAL"); return; } else { ALCcontext *context = alcCreateContext(device, NULL); if (context != NULL) { alcMakeContextCurrent(context); CheckError("CSound::CreateContext"); } else { alcCloseDevice(device); LOG_L(L_ERROR, "Could not create OpenAL audio context"); return; } } maxSounds = GetMaxMonoSources(device, maxSounds); LOG("OpenAL info:"); if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) { LOG(" Available Devices:"); const char* deviceSpecifier = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); while (*deviceSpecifier != '\0') { LOG(" %s", deviceSpecifier); while (*deviceSpecifier++ != '\0') ; } LOG(" Device: %s", (const char*)alcGetString(device, ALC_DEVICE_SPECIFIER)); } LOG(" Vendor: %s", (const char*)alGetString(AL_VENDOR)); LOG(" Version: %s", (const char*)alGetString(AL_VERSION)); LOG(" Renderer: %s", (const char*)alGetString(AL_RENDERER)); LOG(" AL Extensions: %s", (const char*)alGetString(AL_EXTENSIONS)); LOG(" ALC Extensions: %s", (const char*)alcGetString(device, ALC_EXTENSIONS)); // Init EFX efx = new CEFX(device); // Generate sound sources for (int i = 0; i < maxSounds; i++) { CSoundSource* thenewone = new CSoundSource(); if (thenewone->IsValid()) { sources.push_back(thenewone); } else { maxSounds = std::max(i-1, 0); LOG_L(L_WARNING, "Your hardware/driver can not handle more than %i soundsources", maxSounds); delete thenewone; break; } } LOG(" Max Sounds: %i", maxSounds); // Set distance model (sound attenuation) alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); alDopplerFactor(0.2f); alListenerf(AL_GAIN, masterVolume); } Threading::SetThreadName("audio"); Watchdog::RegisterThread(WDT_AUDIO); while (!soundThreadQuit) { boost::this_thread::sleep(boost::posix_time::millisec(50)); //! 20Hz Watchdog::ClearTimer(WDT_AUDIO); Update(); } Watchdog::DeregisterThread(WDT_AUDIO); sources.clear(); // delete all sources delete efx; // must happen after sources and before context efx = NULL; ALCcontext* curcontext = alcGetCurrentContext(); ALCdevice* curdevice = alcGetContextsDevice(curcontext); alcMakeContextCurrent(NULL); alcDestroyContext(curcontext); alcCloseDevice(curdevice); }
void CSound::StartThread(int maxSounds) { { boost::recursive_mutex::scoped_lock lck(soundMutex); // NULL -> default device const ALchar* deviceName = NULL; std::string configDeviceName = ""; // we do not want to set a default for snd_device, // so we do it like this ... if (configHandler->IsSet("snd_device")) { configDeviceName = configHandler->GetString("snd_device", "YOU_SHOULD_NOT_EVER_SEE_THIS"); deviceName = configDeviceName.c_str(); } ALCdevice* device = alcOpenDevice(deviceName); if ((device == NULL) && (deviceName != NULL)) { LogObject(LOG_SOUND) << "Could not open the sound device \"" << deviceName << "\", trying the default device ..."; configDeviceName = ""; deviceName = NULL; device = alcOpenDevice(deviceName); } if (device == NULL) { LogObject(LOG_SOUND) << "Could not open a sound device, disabling sounds"; CheckError("CSound::InitAL"); return; } else { ALCcontext *context = alcCreateContext(device, NULL); if (context != NULL) { alcMakeContextCurrent(context); CheckError("CSound::CreateContext"); } else { alcCloseDevice(device); LogObject(LOG_SOUND) << "Could not create OpenAL audio context"; return; } } const bool airAbsorptionSupported = alcIsExtensionPresent(device, "ALC_EXT_EFX"); LogObject(LOG_SOUND) << "OpenAL info:\n"; if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) { LogObject(LOG_SOUND) << " Available Devices:"; const char *s = alcGetString(NULL, ALC_DEVICE_SPECIFIER); while (*s != '\0') { LogObject(LOG_SOUND) << " " << s; while (*s++ != '\0') ; } LogObject(LOG_SOUND) << " Device: " << alcGetString(device, ALC_DEVICE_SPECIFIER); } LogObject(LOG_SOUND) << " Vendor: " << (const char*)alGetString(AL_VENDOR ); LogObject(LOG_SOUND) << " Version: " << (const char*)alGetString(AL_VERSION); LogObject(LOG_SOUND) << " Renderer: " << (const char*)alGetString(AL_RENDERER); LogObject(LOG_SOUND) << " AL Extensions: " << (const char*)alGetString(AL_EXTENSIONS); LogObject(LOG_SOUND) << " ALC Extensions: " << (const char*)alcGetString(device, ALC_EXTENSIONS); // Init EFX efx = new CEFX(device); // Generate sound sources for (int i = 0; i < maxSounds; i++) { CSoundSource* thenewone = new CSoundSource(); if (thenewone->IsValid()) { sources.push_back(thenewone); } else { maxSounds = std::max(i-1, 0); LogObject(LOG_SOUND) << "Your hardware/driver can not handle more than " << maxSounds << " soundsources"; delete thenewone; break; } } LogObject(LOG_SOUND) << " Max Sounds: " << maxSounds; // Set distance model (sound attenuation) alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); alDopplerFactor(0.2f); alListenerf(AL_GAIN, masterVolume); } configHandler->Set("MaxSounds", maxSounds); while (!soundThreadQuit) { boost::this_thread::sleep(boost::posix_time::millisec(50)); //! 20Hz Update(); } sources.clear(); // delete all sources delete efx; // must happen after sources and before context ALCcontext* curcontext = alcGetCurrentContext(); ALCdevice* curdevice = alcGetContextsDevice(curcontext); alcMakeContextCurrent(NULL); alcDestroyContext(curcontext); alcCloseDevice(curdevice); }