#pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace OpenVic { class SoundSingleton : public godot::Object { GDCLASS(SoundSingleton, godot::Object); static inline SoundSingleton* _singleton = nullptr; //cache of songs //names will be like "subfolder/songname", with "music/" base folder and the extension (.mp3) being excluded using song_asset_map_t = deque_ordered_map>; song_asset_map_t tracks; //cache of sfx (map file name to an audio stream), only used temporarily until the sfx_define_map is built using sfx_asset_map_t = deque_ordered_map>; sfx_asset_map_t sfx; //define name, stream ref, volume for sound effects so we can get these properties with a simple call in godot struct sound_asset_t { std::optional> audioStream; std::optional volume; }; using sfx_define_map_t = deque_ordered_map; sfx_define_map_t sfx_define; static constexpr std::string_view title_theme_name = "thecoronation_titletheme.mp3"; static constexpr std::string_view music_folder = "music/"; static constexpr std::string_view sound_folder = "sound/"; //property for gd scripts to access song names godot::Array PROPERTY(song_list); godot::String PROPERTY(title_theme); //property for gd scripts to access sound names godot::Array PROPERTY(sound_list); public: SoundSingleton(); ~SoundSingleton(); static SoundSingleton* get_singleton(); protected: static void _bind_methods(); godot::String to_define_file_name(godot::String const& path, std::string_view const& base_folder) const; godot::String read_riff_str(godot::Ref const& file, int size=4) const; private: /* Loads AudioStreams (.mp3 or .wav) at runtime using godot's functions*/ godot::Ref _load_godot_mp3(godot::String const& path) const; godot::Ref _load_godot_wav(godot::String const& path) const; public: //gets a song from the cache ('tracks' variable), or if not, then from the files using _load_godot_mp3 godot::Ref get_song(godot::String const& name); godot::Ref get_sound(godot::String const& path); //load the files into memory bool load_music(); bool load_sounds(); bool load_title_theme(); //for sound effects, get the stream and relative volume it should play at from the sfx map godot::Ref get_sound_stream(godot::String const& path); float get_sound_base_volume(godot::String const& path); }; }