@@ -9,54 +9,73 @@ import :audio;
99const pragma::audio::ISoundSystem *pragma::CEngine::GetSoundSystem () const { return const_cast <CEngine *>(this )->GetSoundSystem (); }
1010pragma::audio::ISoundSystem *pragma::CEngine::GetSoundSystem () { return m_soundSystem.get (); }
1111
12- pragma::audio::ISoundSystem * pragma::CEngine::InitializeSoundEngine ( )
12+ static std::pair<std::string, std::string> get_audio_api_path (std::string_view audioAPI )
1313{
14- spdlog::info (" Initializing sound engine..." );
14+ auto location = pragma::audio::get_audio_api_module_location (std::string {audioAPI});
15+ auto modulePath = pragma::util::get_normalized_module_path (location);
16+ return {std::move (location), std::move (modulePath)};
17+ }
1518
16- auto &audioAPI = GetAudioAPI ();
17- auto getAudioApiPath = [](const std::string &audioAPI, std::string &outLocation, std::string &outModulePath) {
18- outLocation = audio::get_audio_api_module_location (audioAPI);
19- outModulePath = util::get_normalized_module_path (outLocation);
20- };
21- auto loadAudioApiModule = [this , &getAudioApiPath](const std::string &audioAPI, std::string &outErr) -> bool {
22- std::string location;
23- std::string modulePath;
24- getAudioApiPath (audioAPI, location, modulePath);
25- m_audioAPILib = util::load_library_module (modulePath, util::get_default_additional_library_search_directories (modulePath), {}, &outErr);
26- return (m_audioAPILib != nullptr );
27- };
19+ static std::expected<std::shared_ptr<pragma::util::Library>, std::string> load_audio_library_module (std::string_view audioAPI, std::string_view modulePath)
20+ {
2821 std::string err;
29- std::vector<std::string> fallbackApis {audioAPI, " soloud" , " dummy" };
30- for (auto &apiName : fallbackApis) {
31- m_audioAPI = apiName;
32- if (loadAudioApiModule (apiName, err))
33- break ;
34- spdlog::warn (" Failed to load audio API '{}': {}" , audioAPI, err);
35- }
22+ auto lib = pragma::util::load_library_module (std::string {modulePath}, pragma::util::get_default_additional_library_search_directories (std::string {modulePath}), {}, &err);
23+ if (!lib)
24+ return std::unexpected {err};
25+ return lib;
26+ }
27+
28+ struct SoundSystemInfo {
29+ std::shared_ptr<pragma::audio::ISoundSystem> soundSystem;
30+ std::shared_ptr<pragma::util::Library> library;
31+ };
32+ static std::expected<SoundSystemInfo, std::string> load_audio_library (std::string_view audioAPI)
33+ {
34+ auto [location, modulePath] = get_audio_api_path (audioAPI);
35+ auto lib = load_audio_library_module (audioAPI, modulePath);
36+ if (!lib)
37+ return std::unexpected {std::format (" Failed to load audio library '{}': {}" , modulePath, lib.error ())};
38+
39+ auto fInitAudioAPI = (*lib)->FindSymbolAddress <bool (*)(float , std::shared_ptr<pragma::audio::ISoundSystem> &, std::string &)>(" initialize_audio_api" );
40+ if (!fInitAudioAPI )
41+ return std::unexpected {std::format (" Symbol 'initialize_audio_api' not found in audio library '{}'!" , modulePath)};
3642
37- if (!m_audioAPILib)
38- Con::CRIT << " No valid audio module found!" << Con::endl;
39- auto lib = m_audioAPILib;
40- std::string location;
41- std::string modulePath;
42- getAudioApiPath (audioAPI, location, modulePath);
43+ std::string errMsg;
44+ std::shared_ptr<pragma::audio::ISoundSystem> soundSystem;
45+ auto success = fInitAudioAPI (pragma::units_to_metres (1 .f ), soundSystem, errMsg);
46+ if (!success || !soundSystem)
47+ return std::unexpected {std::format (" Failed to initialize audio library '{}': {}!" , modulePath, errMsg)};
48+ return SoundSystemInfo {soundSystem, lib.value ()};
49+ }
50+
51+ pragma::audio::ISoundSystem *pragma::CEngine::InitializeSoundEngine ()
52+ {
53+ spdlog::info (" Initializing sound engine..." );
4354
44- if (lib != nullptr ) {
45- spdlog::info (" Loading audio module '{}'..." , location);
46- auto fInitAudioAPI = lib->FindSymbolAddress <bool (*)(float , std::shared_ptr<audio::ISoundSystem> &, std::string &)>(" initialize_audio_api" );
47- if (fInitAudioAPI == nullptr )
48- err = " Symbol 'initialize_audio_api' not found in library '" + location + " '!" ;
49- else {
50- std::string errMsg;
51- auto success = fInitAudioAPI (units_to_metres (1 .f ), m_soundSystem, errMsg);
52- if (success == false )
53- err = errMsg;
55+ auto &baseAudioAPI = GetAudioAPI ();
56+ std::vector<std::string> fallbackApis {};
57+ if (baseAudioAPI != " soloud" )
58+ fallbackApis.push_back (" soloud" );
59+ if (baseAudioAPI != " dummy" )
60+ fallbackApis.push_back (" dummy" );
61+ for (auto &audioAPI : fallbackApis) {
62+ spdlog::info (" Loading audio library '{}'..." , audioAPI);
63+ auto res = load_audio_library (audioAPI);
64+ if (!res) {
65+ spdlog::warn (" Failed to load audio library '{}': {}" , audioAPI, res.error ());
66+ continue ;
5467 }
68+ auto &info = res.value ();
69+ m_audioAPI = audioAPI;
70+ m_soundSystem = info.soundSystem ;
71+ m_audioAPILib = info.library ;
5572 }
56- else
57- err = " Module '" + modulePath + " ' not found!" ;
58- if (m_soundSystem == nullptr )
59- throw std::runtime_error {" Unable to load audio implementation library: " + err + " !" };
73+
74+ if (!m_soundSystem) {
75+ CriticalFailure (" Failed to initialize sound system: No audio library could be loaded. See log messages for more information." );
76+ return nullptr ;
77+ }
78+
6079 m_soundSystem->SetSoundSourceFactory ([](const audio::PSoundChannel &channel) -> audio::PSoundSource { return audio::CALSound::Create (get_cengine ()->GetClientState (), channel); });
6180 audio::set_world_scale (units_to_metres (1.0 ));
6281 return m_soundSystem.get ();
0 commit comments