mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
Add a new `Timer` class that operates in seconds (using `TimeType`) alongside the existing `TickTimer` which uses `TickType`. Rename the original `Timer` to `TickTimer` throughout the codebase. Update `ClientWorld` to maintain separate maps for tick-based and time-based timers, and replace the hardcoded footstep timer in `ClientPlayer` with a time-based callback timer. Also add `play_2d` to `AudioEngine` and load an ambient bird sound to demonstrate the new timer functionality.
150 lines
3.8 KiB
C++
150 lines
3.8 KiB
C++
#include "Cubed/audio/audio_engine.hpp"
|
|
|
|
#include "Cubed/audio/audio_error.hpp"
|
|
#include "Cubed/config.hpp"
|
|
#include "Cubed/tools/cubed_assert.hpp"
|
|
#include "Cubed/tools/log.hpp"
|
|
|
|
#include <stdexcept>
|
|
namespace Cubed {
|
|
AudioEngine::AudioEngine() {};
|
|
|
|
AudioEngine::~AudioEngine() {
|
|
if (!m_init) {
|
|
return;
|
|
}
|
|
|
|
m_bgm.reset();
|
|
m_pool.reset();
|
|
m_sounds.clear();
|
|
|
|
alcMakeContextCurrent(nullptr);
|
|
alcDestroyContext(context);
|
|
alcCloseDevice(device);
|
|
}
|
|
|
|
void AudioEngine::init() {
|
|
device = alcOpenDevice(NULL);
|
|
if (!device) {
|
|
throw std::runtime_error("Failed to open OpenAL device.");
|
|
}
|
|
context = alcCreateContext(device, nullptr);
|
|
|
|
if (!context) {
|
|
throw std::runtime_error("Failed to create OpenAL context.");
|
|
}
|
|
alcMakeContextCurrent(context);
|
|
|
|
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
|
check_al_error();
|
|
|
|
auto& config = Config::get();
|
|
|
|
m_music_volume = static_cast<float>(config.get<double>("volume.music"));
|
|
m_sfx_volume = static_cast<float>(config.get<double>("volume.SFX"));
|
|
|
|
m_sounds.init();
|
|
|
|
m_bgm = std::make_unique<AudioSource>(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);
|
|
|
|
ALCint max_mono = 0;
|
|
|
|
alcGetIntegerv(device, ALC_MONO_SOURCES, 1, &max_mono);
|
|
|
|
if (max_mono <= 1) {
|
|
Logger::error("Can't get max mono");
|
|
max_mono = 4;
|
|
}
|
|
|
|
Logger::info("Set Source Pool Size {}", static_cast<int>(max_mono));
|
|
// Reserve a source for BGM
|
|
m_pool = std::make_shared<SourcePool>(max_mono - 1);
|
|
|
|
Logger::info("Audio Engine Init Success");
|
|
|
|
m_init = true;
|
|
}
|
|
|
|
void AudioEngine::play_bgm() { m_bgm->play(); }
|
|
|
|
void AudioEngine::play_3d(const std::string& sound, const glm::vec3& pos,
|
|
bool check) {
|
|
if (!m_pool) {
|
|
Logger::error("Source Pool is nullptr");
|
|
return;
|
|
}
|
|
auto* source = m_pool->acquire();
|
|
source->set_volume(m_sfx_volume);
|
|
if (!source) {
|
|
Logger::error("Source is Full");
|
|
}
|
|
|
|
try {
|
|
auto& buffer = m_sounds.get_buffer(sound);
|
|
source->play_3d(buffer, pos);
|
|
} catch (const std::exception& e) {
|
|
if (check) {
|
|
ASSERT_MSG(false, e.what());
|
|
Logger::error("Player Sound Error {}", e.what());
|
|
}
|
|
}
|
|
}
|
|
|
|
void AudioEngine::play_2d(const std::string& sound, bool check) {
|
|
if (!m_pool) {
|
|
Logger::error("Source Pool is nullptr");
|
|
return;
|
|
}
|
|
auto* source = m_pool->acquire();
|
|
source->set_volume(m_sfx_volume);
|
|
if (!source) {
|
|
Logger::error("Source is Full");
|
|
}
|
|
|
|
try {
|
|
auto& buffer = m_sounds.get_buffer(sound);
|
|
source->play_2d(buffer);
|
|
} catch (const std::exception& e) {
|
|
if (check) {
|
|
ASSERT_MSG(false, e.what());
|
|
Logger::error("Player Sound Error {}", e.what());
|
|
}
|
|
}
|
|
}
|
|
|
|
void AudioEngine::update_listener(const glm::vec3& pos,
|
|
const glm::vec3& forward,
|
|
const glm::vec3& up) {
|
|
alListener3f(AL_POSITION, pos.x, pos.y, pos.z);
|
|
|
|
float orientation[] = {forward.x, forward.y, forward.z,
|
|
|
|
up.x, up.y, up.z};
|
|
|
|
alListenerfv(AL_ORIENTATION, orientation);
|
|
}
|
|
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<float>(config.get<double>("volume.music"));
|
|
m_sfx_volume = static_cast<float>(config.get<double>("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
|