From 9293d8e2715f3e883fee4c0ed617636a785f20d1 Mon Sep 17 00:00:00 2001 From: nOOb3167 Date: Fri, 23 Mar 2018 15:31:43 +0100 Subject: [PATCH] Global initialization of sound using SoundManagerGlobal (#7063) * Global initialization of sound using SoundManagerGlobal --- src/client/clientlauncher.cpp | 9 ++ src/game.cpp | 2 +- src/gui/guiEngine.cpp | 2 +- src/sound_openal.cpp | 179 +++++++++++++++++++--------------- src/sound_openal.h | 8 +- 5 files changed, 116 insertions(+), 84 deletions(-) diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index b02f1b438949..2f85911795fa 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -35,6 +35,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "renderingengine.h" #include "network/networkexceptions.h" +#if USE_SOUND + #include "sound_openal.h" +#endif + /* mainmenumanager.h */ gui::IGUIEnvironment *guienv = nullptr; @@ -71,6 +75,11 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args) if (list_video_modes) return RenderingEngine::print_video_modes(); +#if USE_SOUND + if (g_settings->getBool("enable_sound")) + g_sound_manager_singleton = createSoundManagerSingleton(); +#endif + if (!init_engine()) { errorstream << "Could not initialize game engine." << std::endl; return false; diff --git a/src/game.cpp b/src/game.cpp index f1c27d3bbd84..fada349db7c4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1219,7 +1219,7 @@ bool Game::initSound() #if USE_SOUND if (g_settings->getBool("enable_sound")) { infostream << "Attempting to use OpenAL audio" << std::endl; - sound = createOpenALSoundManager(&soundfetcher); + sound = createOpenALSoundManager(g_sound_manager_singleton.get(), &soundfetcher); if (!sound) infostream << "Failed to initialize OpenAL audio" << std::endl; } else diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index 3f9bcd888668..00c3f85bcfa6 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -137,7 +137,7 @@ GUIEngine::GUIEngine(JoystickController *joystick, //create soundmanager MenuMusicFetcher soundfetcher; #if USE_SOUND - m_sound_manager = createOpenALSoundManager(&soundfetcher); + m_sound_manager = createOpenALSoundManager(g_sound_manager_singleton.get(), &soundfetcher); #endif if(!m_sound_manager) m_sound_manager = &dummySoundManager; diff --git a/src/sound_openal.cpp b/src/sound_openal.cpp index b33a85703f34..853aba1cc505 100644 --- a/src/sound_openal.cpp +++ b/src/sound_openal.cpp @@ -45,9 +45,29 @@ with this program; ifnot, write to the Free Software Foundation, Inc., #include #include #include +#include #define BUFFER_SIZE 30000 +std::shared_ptr g_sound_manager_singleton; + +typedef std::unique_ptr unique_ptr_alcdevice; +typedef std::unique_ptr unique_ptr_alccontext; + +static void delete_alcdevice(ALCdevice *p) +{ + if (p) + alcCloseDevice(p); +} + +static void delete_alccontext(ALCcontext *p) +{ + if (p) { + alcMakeContextCurrent(nullptr); + alcDestroyContext(p); + } +} + static const char *alcErrorString(ALCenum err) { switch (err) { @@ -146,7 +166,7 @@ SoundBuffer *load_opened_ogg_file(OggVorbis_File *oggFile, infostream << "Audio: Error decoding " << filename_for_logging << std::endl; delete snd; - return NULL; + return nullptr; } // Append to end of buffer @@ -161,8 +181,8 @@ SoundBuffer *load_opened_ogg_file(OggVorbis_File *oggFile, ALenum error = alGetError(); if(error != AL_NO_ERROR){ - infostream<<"Audio: OpenAL error: "< m_sounds_fading; float m_fade_delay; public: - bool m_is_initialized; - OpenALSoundManager(OnDemandSoundFetcher *fetcher): + OpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher): m_fetcher(fetcher), - m_device(NULL), - m_context(NULL), + m_device(smg->m_device.get()), + m_context(smg->m_context.get()), m_next_id(1), - m_fade_delay(0), - m_is_initialized(false) + m_fade_delay(0) { - ALCenum error = ALC_NO_ERROR; - - infostream<<"Audio: Initializing..."< source_del_list; + + for (const auto &sp : m_sounds_playing) + source_del_list.insert(sp.second->source_id); + + for (const auto &id : source_del_list) + deleteSound(id); for (auto &buffer : m_buffers) { for (SoundBuffer *sb : buffer.second) { @@ -360,7 +376,8 @@ class OpenALSoundManager: public ISoundManager buffer.second.clear(); } m_buffers.clear(); - infostream<<"Audio: Deinitialized."<>::iterator i = m_buffers.find(name); if(i == m_buffers.end()) - return NULL; + return nullptr; std::vector &bufs = i->second; int j = myrand() % bufs.size(); return bufs[j]; @@ -395,7 +412,7 @@ class OpenALSoundManager: public ISoundManager PlayingSound* createPlayingSound(SoundBuffer *buf, bool loop, float volume, float pitch) { - infostream<<"OpenALSoundManager: Creating playing sound"< paths; std::set datas; m_fetcher->fetchSounds(name, paths, datas); @@ -505,8 +522,8 @@ class OpenALSoundManager: public ISoundManager verbosestream<<"OpenALSoundManager::maintain(): " < del_list; - for (auto &sp : m_sounds_playing) { + std::unordered_set del_list; + for (const auto &sp : m_sounds_playing) { int id = sp.first; PlayingSound *sound = sp.second; // If not playing, remove it @@ -570,8 +587,8 @@ class OpenALSoundManager: public ISoundManager return 0; SoundBuffer *buf = getFetchBuffer(name); if(!buf){ - infostream<<"OpenALSoundManager: \""< createSoundManagerSingleton() { - OpenALSoundManager *m = new OpenALSoundManager(fetcher); - if(m->m_is_initialized) - return m; - delete m; - return NULL; -}; + return std::shared_ptr(new SoundManagerSingleton()); +} +ISoundManager *createOpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher) +{ + return new OpenALSoundManager(smg, fetcher); +}; diff --git a/src/sound_openal.h b/src/sound_openal.h index 6d538c8f9358..f2cff4daa471 100644 --- a/src/sound_openal.h +++ b/src/sound_openal.h @@ -19,6 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once +#include + #include "sound.h" -ISoundManager *createOpenALSoundManager(OnDemandSoundFetcher *fetcher); +class SoundManagerSingleton; +extern std::shared_ptr g_sound_manager_singleton; + +std::shared_ptr createSoundManagerSingleton(); +ISoundManager *createOpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher);