diff --git a/include/Cubed/audio/audio_effect.hpp b/include/Cubed/audio/audio_effect.hpp new file mode 100644 index 0000000..c206db7 --- /dev/null +++ b/include/Cubed/audio/audio_effect.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +namespace Cubed { +class AudioEffect { +public: + AudioEffect(); + AudioEffect(const AudioEffect&) = delete; + AudioEffect(AudioEffect&&) = delete; + AudioEffect& operator=(const AudioEffect&) = default; + AudioEffect& operator=(AudioEffect&&) = delete; + ~AudioEffect(); + void set_reverb(float decay_time, float reverb_gain, float gain_hf, + float density = 1.0f, float diffusion = 1.0f); + ALuint effect() const; + +private: + ALuint m_effect = 0; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/audio/audio_effect_slot.hpp b/include/Cubed/audio/audio_effect_slot.hpp new file mode 100644 index 0000000..629660a --- /dev/null +++ b/include/Cubed/audio/audio_effect_slot.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "Cubed/audio/audio_effect.hpp" +namespace Cubed { +class AudioEffectSlot { +public: + AudioEffectSlot(); + AudioEffectSlot(const AudioEffectSlot&) = delete; + AudioEffectSlot(AudioEffectSlot&&) = delete; + AudioEffectSlot& operator=(const AudioEffectSlot&) = delete; + AudioEffectSlot& operator=(AudioEffectSlot&&) = delete; + ~AudioEffectSlot(); + void set_effect(const AudioEffect& effect); + ALuint slot() const; + +private: + ALuint m_slot = 0; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/audio/audio_engine.hpp b/include/Cubed/audio/audio_engine.hpp index 98d8b5e..84342e7 100644 --- a/include/Cubed/audio/audio_engine.hpp +++ b/include/Cubed/audio/audio_engine.hpp @@ -54,5 +54,7 @@ private: float m_music_volume = 1.0f; float m_sfx_volume = 1.0f; std::unique_ptr m_low_pass_filter; + std::unique_ptr m_underwater_effect; + std::unique_ptr m_underwater_slot; }; } // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/audio/audio_source.hpp b/include/Cubed/audio/audio_source.hpp index 8e08f76..3c798ef 100644 --- a/include/Cubed/audio/audio_source.hpp +++ b/include/Cubed/audio/audio_source.hpp @@ -1,5 +1,6 @@ #pragma once #include "Cubed/audio/audio_buffer.hpp" +#include "Cubed/audio/audio_effect_slot.hpp" #include "Cubed/audio/audio_filter.hpp" #include @@ -37,6 +38,8 @@ public: void set_filter(const AudioFilter& filter); void clear_filter(); + void set_effect_slot(const AudioEffectSlot& slot); + void clear_effect_slot(); private: ALuint m_source = 0; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1216bb9..95026a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,4 +52,6 @@ target_sources(${PROJECT_NAME} audio/source_pool.cpp audio/audio_fade.cpp audio/audio_filter.cpp + audio/audio_effect.cpp + audio/audio_effect_slot.cpp ) \ No newline at end of file diff --git a/src/audio/audio_effect.cpp b/src/audio/audio_effect.cpp new file mode 100644 index 0000000..6de8eb6 --- /dev/null +++ b/src/audio/audio_effect.cpp @@ -0,0 +1,26 @@ +#include "Cubed/audio/audio_effect.hpp" +#ifndef AL_ALEXT_PROTOTYPES +#define AL_ALEXT_PROTOTYPES +#endif +#include + +namespace Cubed { +AudioEffect::AudioEffect() { alGenEffects(1, &m_effect); } + +AudioEffect::~AudioEffect() { + if (m_effect) { + alDeleteEffects(1, &m_effect); + } +} + +void AudioEffect::set_reverb(float decay_time, float reverb_gain, float gain_hf, + float density, float diffusion) { + alEffecti(m_effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + alEffectf(m_effect, AL_REVERB_DECAY_TIME, decay_time); + alEffectf(m_effect, AL_REVERB_GAIN, reverb_gain); + alEffectf(m_effect, AL_REVERB_GAINHF, gain_hf); + alEffectf(m_effect, AL_REVERB_DENSITY, density); + alEffectf(m_effect, AL_REVERB_DIFFUSION, diffusion); +} +ALuint AudioEffect::effect() const { return m_effect; } +} // namespace Cubed \ No newline at end of file diff --git a/src/audio/audio_effect_slot.cpp b/src/audio/audio_effect_slot.cpp new file mode 100644 index 0000000..682cdc8 --- /dev/null +++ b/src/audio/audio_effect_slot.cpp @@ -0,0 +1,19 @@ +#include "Cubed/audio/audio_effect_slot.hpp" +#ifndef AL_ALEXT_PROTOTYPES +#define AL_ALEXT_PROTOTYPES +#endif +#include +namespace Cubed { +AudioEffectSlot::AudioEffectSlot() { alGenAuxiliaryEffectSlots(1, &m_slot); } + +AudioEffectSlot::~AudioEffectSlot() { + if (m_slot) { + alDeleteAuxiliaryEffectSlots(1, &m_slot); + } +} + +void AudioEffectSlot::set_effect(const AudioEffect& effect) { + alAuxiliaryEffectSloti(m_slot, AL_EFFECTSLOT_EFFECT, effect.effect()); +} +ALuint AudioEffectSlot::slot() const { return m_slot; } +} // namespace Cubed \ No newline at end of file diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index 4a9dd1d..85b9372 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -19,6 +19,10 @@ AudioEngine::~AudioEngine() { m_pool.reset(); m_sounds.clear(); + m_low_pass_filter.reset(); + m_underwater_effect.reset(); + m_underwater_slot.reset(); + alcMakeContextCurrent(nullptr); alcDestroyContext(context); alcCloseDevice(device); @@ -49,6 +53,12 @@ void AudioEngine::init() { m_low_pass_filter = std::make_unique(); m_low_pass_filter->set_lowpass(1.0f, 0.15f); + + m_underwater_effect = std::make_unique(); + m_underwater_effect->set_reverb(0.8f, 0.3162f, 0.01f); + // m_underwater_effect->set_reverb(20.0f, 1.0f, 1.0f); + m_underwater_slot = std::make_unique(); + m_underwater_slot->set_effect(*m_underwater_effect); } alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); @@ -120,6 +130,7 @@ void AudioEngine::play_3d(const std::string& sound, const glm::vec3& pos, auto& buffer = m_sounds.get_buffer(sound); if (m_efx_supported && m_underwater) { source->set_filter(*m_low_pass_filter); + source->set_effect_slot(*m_underwater_slot); } source->play_3d(buffer, pos); } catch (const std::exception& e) { @@ -145,6 +156,7 @@ void AudioEngine::play_2d(const std::string& sound, bool check) { auto& buffer = m_sounds.get_buffer(sound); if (m_efx_supported && m_underwater) { source->set_filter(*m_low_pass_filter); + source->set_effect_slot(*m_underwater_slot); } source->play_2d(buffer); } catch (const std::exception& e) { @@ -195,9 +207,10 @@ void AudioEngine::underwater_change(bool underwater) { for (auto& source : m_pool->sources()) { if (m_underwater) { source.set_filter(*m_low_pass_filter); - + source.set_effect_slot(*m_underwater_slot); } else { source.clear_filter(); + source.clear_effect_slot(); } } if (underwater) { diff --git a/src/audio/audio_source.cpp b/src/audio/audio_source.cpp index 38756d4..22a4163 100644 --- a/src/audio/audio_source.cpp +++ b/src/audio/audio_source.cpp @@ -156,6 +156,7 @@ void AudioSource::reset() { alSourcef(m_source, AL_SEC_OFFSET, 0.0f); clear_filter(); + clear_effect_slot(); m_duration = 0.0f; m_target_volume = 1.0f; @@ -168,4 +169,15 @@ void AudioSource::set_filter(const AudioFilter& filter) { void AudioSource::clear_filter() { alSourcei(m_source, AL_DIRECT_FILTER, AL_FILTER_NULL); } + +void AudioSource::set_effect_slot(const AudioEffectSlot& slot) { + alSource3i(m_source, AL_AUXILIARY_SEND_FILTER, slot.slot(), 0, + AL_FILTER_NULL); +} + +void AudioSource::clear_effect_slot() { + alSource3i(m_source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, + AL_FILTER_NULL); +} + } // namespace Cubed \ No newline at end of file