diff --git a/include/Cubed/app.hpp b/include/Cubed/app.hpp index a65376c..e16d02b 100644 --- a/include/Cubed/app.hpp +++ b/include/Cubed/app.hpp @@ -49,6 +49,7 @@ public: ClientWorld& client_world(); ServerWorld& server_world(); const Argument& argument() const; + AudioEngine& audio(); private: Camera m_camera; diff --git a/include/Cubed/audio/audio_engine.hpp b/include/Cubed/audio/audio_engine.hpp index 7a1abaa..1d1e9c2 100644 --- a/include/Cubed/audio/audio_engine.hpp +++ b/include/Cubed/audio/audio_engine.hpp @@ -30,7 +30,10 @@ public: bool check = false); void update_listener(const glm::vec3& pos, const glm::vec3& forward, const glm::vec3& up); - void update(float dt); + void update(); + void reload_config(); + + float& bgm_target_volume(); private: using FadeMap = std::unordered_map; @@ -42,5 +45,8 @@ private: FadeMap m_fade_map; SoundManager m_sounds; std::shared_ptr m_pool; + + float m_music_volume = 1.0f; + float m_sfx_volume = 1.0f; }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/audio/audio_fade.hpp b/include/Cubed/audio/audio_fade.hpp index 39144c7..138943b 100644 --- a/include/Cubed/audio/audio_fade.hpp +++ b/include/Cubed/audio/audio_fade.hpp @@ -12,7 +12,6 @@ private: float m_in_duration = 0.0f; float m_out_duration = 0.0f; float m_start_gain = 0.0f; - float m_end_gain = 0.0f; bool m_fade_in = true; bool m_active = true; }; diff --git a/include/Cubed/audio/audio_source.hpp b/include/Cubed/audio/audio_source.hpp index 34ff76d..045cac1 100644 --- a/include/Cubed/audio/audio_source.hpp +++ b/include/Cubed/audio/audio_source.hpp @@ -9,7 +9,7 @@ enum class AudioState { INITIAL, PLAYING, PAUSED, STOPPED }; class AudioSource { public: - AudioSource(); + AudioSource(float volume = 1.0f); ~AudioSource(); void set_buffer_2d(const AudioBuffer& buffer); @@ -25,7 +25,9 @@ public: void pause(); float duration() const; float current_time() const; - float volume() const; + float target_volume() const; + float& target_volume(); + void set_target_volume(float volume); AudioState state() const; void mark_in_use(); @@ -34,7 +36,7 @@ public: private: ALuint m_source = 0; - float m_volume = 1.0f; + float m_target_volume = 1.0f; float m_duration = 0.0f; bool m_using; }; diff --git a/include/Cubed/dev_panel.hpp b/include/Cubed/dev_panel.hpp index f020657..e237c3a 100644 --- a/include/Cubed/dev_panel.hpp +++ b/include/Cubed/dev_panel.hpp @@ -20,6 +20,8 @@ class DevPanel { bool is_enable_aniso = false; bool is_support_aniso = true; bool is_reload = true; + float volume_music = 1.0f; + float volume_sfx = 1.0f; }; struct PlayerProfile { int game_mode = 0; diff --git a/src/app.cpp b/src/app.cpp index f5b72a5..26b89df 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -361,7 +361,7 @@ void App::update() { } m_audio.update_listener(m_camera.get_camera_pos(), m_camera.get_camera_front(), glm::vec3(0, 1, 0)); - m_audio.update(dt); + m_audio.update(); m_renderer.update(dt); } @@ -396,4 +396,5 @@ Window& App::window() { return m_window; } ClientWorld& App::client_world() { return m_client_world; } ServerWorld& App::server_world() { return m_server.server_world(); } const App::Argument& App::argument() const { return m_argument; } +AudioEngine& App::audio() { return m_audio; } } // namespace Cubed \ No newline at end of file diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index ff644f1..1204e3d 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -1,5 +1,6 @@ #include "Cubed/audio/audio_engine.hpp" +#include "Cubed/config.hpp" #include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/log.hpp" @@ -33,8 +34,15 @@ void AudioEngine::init() { } alcMakeContextCurrent(context); + auto& config = Config::get(); + + m_music_volume = static_cast(config.get("volume.music")); + m_sfx_volume = static_cast(config.get("volume.SFX")); + m_sounds.init(); - m_bgm = std::make_unique(); + + m_bgm = std::make_unique(m_music_volume); + m_bgm->set_buffer_2d(m_sounds.get_buffer("bgm/bgm001.mp3")); m_fade_map.try_emplace("bgm", m_bgm.get(), 5.0f, 2.0f); @@ -66,6 +74,7 @@ void AudioEngine::play_3d(const std::string& sound, const glm::vec3& pos, return; } auto* source = m_pool->acquire(); + source->set_volume(m_sfx_volume); if (!source) { Logger::error("Source is Full"); } @@ -91,11 +100,24 @@ void AudioEngine::update_listener(const glm::vec3& pos, alListenerfv(AL_ORIENTATION, orientation); } -void AudioEngine::update(float dt) { +void AudioEngine::update() { for (auto& [key, fade] : m_fade_map) { fade.update(); } m_pool->update(); } + +void AudioEngine::reload_config() { + auto& config = Config::get(); + + m_music_volume = static_cast(config.get("volume.music")); + m_sfx_volume = static_cast(config.get("volume.SFX")); + if (m_bgm) { + m_bgm->set_target_volume(m_music_volume); + } +} + +float& AudioEngine::bgm_target_volume() { return m_bgm->target_volume(); } + } // namespace Cubed \ No newline at end of file diff --git a/src/audio/audio_fade.cpp b/src/audio/audio_fade.cpp index 6d3ee37..98f4af7 100644 --- a/src/audio/audio_fade.cpp +++ b/src/audio/audio_fade.cpp @@ -10,8 +10,9 @@ AudioFade::AudioFade(AudioSource* source, float fade_in, float fade_out) m_active = false; return; } + m_start_gain = 0.0f; - m_end_gain = m_source->volume(); + m_source->set_volume(0.0f); } AudioFade::~AudioFade() {} @@ -27,13 +28,12 @@ void AudioFade::update() { // Ease Out Sine t = std::sin(t * std::numbers::pi_v * 0.5f); - float gain = std::lerp(m_start_gain, m_end_gain, t); + float gain = std::lerp(m_start_gain, m_source->target_volume(), t); m_source->set_volume(gain); if (t >= 1.0f) { - m_source->set_volume(m_end_gain); + m_source->set_volume(m_source->target_volume()); m_fade_in = false; - m_start_gain = m_end_gain; - m_end_gain = 0.0f; + m_start_gain = m_source->target_volume(); } } else { float start_time = @@ -50,11 +50,11 @@ void AudioFade::update() { // Smoothstep t = t * t * (3.0f - 2.0f * t); - float gain = std::lerp(m_start_gain, m_end_gain, t); + float gain = std::lerp(m_start_gain, 0.0f, t); m_source->set_volume(gain); if (t >= 1.0f) { - m_source->set_volume(m_end_gain); + m_source->set_volume(0.0f); m_active = false; } } diff --git a/src/audio/audio_source.cpp b/src/audio/audio_source.cpp index 063ec82..5cfc709 100644 --- a/src/audio/audio_source.cpp +++ b/src/audio/audio_source.cpp @@ -7,7 +7,10 @@ #include namespace Cubed { -AudioSource::AudioSource() { alGenSources(1, &m_source); } +AudioSource::AudioSource(float volume) { + alGenSources(1, &m_source); + set_target_volume(volume); +} AudioSource::~AudioSource() { if (m_source != 0) { stop(); @@ -62,7 +65,6 @@ void AudioSource::set_loop(bool on) { void AudioSource::set_volume(float volume) { volume = std::clamp(volume, 0.0f, 1.0f); - m_volume = volume; alSourcef(m_source, AL_GAIN, volume); } @@ -76,7 +78,6 @@ void AudioSource::play_2d(const AudioBuffer& buffer) { void AudioSource::play_3d(const AudioBuffer& buffer, const glm::vec3& pos) { set_buffer_3d(buffer, pos); play(); - check_al_error(); } void AudioSource::stop() { alSourceStop(m_source); } @@ -88,7 +89,14 @@ float AudioSource::current_time() const { alGetSourcef(m_source, AL_SEC_OFFSET, &sec); return static_cast(sec); } -float AudioSource::volume() const { return m_volume; } + +float AudioSource::target_volume() const { return m_target_volume; } +float& AudioSource::target_volume() { return m_target_volume; } + +void AudioSource::set_target_volume(float volume) { + m_target_volume = volume; + set_volume(m_target_volume); +} AudioState AudioSource::state() const { ALint state; @@ -111,11 +119,33 @@ AudioState AudioSource::state() const { void AudioSource::mark_in_use() { m_using = true; } bool AudioSource::in_use() const { return m_using; } void AudioSource::reset() { + alSourceStop(m_source); + alSourcei(m_source, AL_BUFFER, 0); + alSourcef(m_source, AL_GAIN, 1.0f); alSourcef(m_source, AL_PITCH, 1.0f); + alSource3f(m_source, AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(m_source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(m_source, AL_DIRECTION, 0.0f, 0.0f, 0.0f); + + alSourcef(m_source, AL_REFERENCE_DISTANCE, 1.0f); + alSourcef(m_source, AL_ROLLOFF_FACTOR, 1.0f); + alSourcef(m_source, AL_MAX_DISTANCE, FLT_MAX); + + alSourcef(m_source, AL_CONE_INNER_ANGLE, 360.0f); + alSourcef(m_source, AL_CONE_OUTER_ANGLE, 360.0f); + alSourcef(m_source, AL_CONE_OUTER_GAIN, 0.0f); + alSourcei(m_source, AL_LOOPING, AL_FALSE); + + alSourcei(m_source, AL_SOURCE_RELATIVE, AL_FALSE); + + alSourcef(m_source, AL_SEC_OFFSET, 0.0f); + + m_duration = 0.0f; + m_target_volume = 1.0f; m_using = false; } } // namespace Cubed \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 239ed28..9af4922 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -44,6 +44,11 @@ void Config::create_config() { [texture] aniso = 1 # i is the minimun value, indicating off + [volume] + music = 1.0 + SFX = 1.0 + + )"sv; try { diff --git a/src/dev_panel.cpp b/src/dev_panel.cpp index d2d9361..e46ec54 100644 --- a/src/dev_panel.cpp +++ b/src/dev_panel.cpp @@ -436,6 +436,17 @@ void DevPanel::show_settings_tab_item() { ImGui::SameLine(); ImGui::Text("Your need to click this button to apply config\n"); } + + if (ImGui::SliderFloat("Music", &m_config.volume_music, 0.0f, 1.0f)) { + Config::get().set("volume.music", + static_cast(m_config.volume_music)); + m_app.audio().reload_config(); + } + if (ImGui::SliderFloat("SFX", &m_config.volume_sfx, 0.0f, 1.0f)) { + Config::get().set("volume.SFX", + static_cast(m_config.volume_sfx)); + m_app.audio().reload_config(); + } if (ImGui::Combo("Theme", &m_theme, THEMES, IM_ARRAYSIZE(THEMES))) { if (m_theme == 0) { ImGui::StyleColorsDark(); @@ -752,6 +763,10 @@ void DevPanel::update_config_view() { } else { m_config.is_enable_aniso = true; } + m_config.volume_music = + static_cast(config.val_view("volume.music").value_or(1.0)); + m_config.volume_sfx = + static_cast(config.val_view("volume.SFX").value_or(1.0)); } void DevPanel::update_player_profile() { if (!m_player) {