#include "core/audio/sound_effects_config.hpp" #include #include "core/resources/resource_helper.hpp" #include "external/fkyaml_node.hpp" #include "utils/log.hpp" namespace { // Lector de camp amb fallback: deixa el destí intacte si la clau no // existeix (els defaults dels Ja::*Params s'inicialitzen al ctor del // struct, així que el comportament és "preset parcial = preset complet // amb defaults per als camps que falten"). template void readField(const fkyaml::node& node, const char* key, T& dst) { if (node.contains(key)) { dst = node[key].get_value(); } } } // namespace auto SoundEffectsConfig::get() -> SoundEffectsConfig& { static SoundEffectsConfig instance_; return instance_; } void SoundEffectsConfig::load(const std::string& file_path) { auto bytes = Resource::Helper::loadFile(file_path); if (bytes.empty()) { Log::warn("SoundEffectsConfig", "no s'ha pogut obrir {} — cap preset d'efecte disponible", file_path); return; } try { const auto* begin = reinterpret_cast(bytes.data()); const auto* end = begin + bytes.size(); auto yaml = fkyaml::node::deserialize(begin, end); if (yaml.contains("echo") && yaml["echo"].is_mapping()) { for (auto it = yaml["echo"].begin(); it != yaml["echo"].end(); ++it) { const auto NAME = it.key().get_value(); const auto& node = it.value(); Ja::EchoParams params{}; readField(node, "delay_ms", params.delay_ms); readField(node, "feedback", params.feedback); readField(node, "wet", params.wet); echoes_[NAME] = params; } } if (yaml.contains("reverb") && yaml["reverb"].is_mapping()) { for (auto it = yaml["reverb"].begin(); it != yaml["reverb"].end(); ++it) { const auto NAME = it.key().get_value(); const auto& node = it.value(); Ja::ReverbParams params{}; readField(node, "room_size", params.room_size); readField(node, "damping", params.damping); readField(node, "wet", params.wet); reverbs_[NAME] = params; } } Log::info("SoundEffectsConfig", "{} preset(s) d'eco i {} de reverb des de {}", echoes_.size(), reverbs_.size(), file_path); } catch (const std::exception& e) { Log::error("SoundEffectsConfig", "error parsejant {}: {}", file_path, e.what()); } } auto SoundEffectsConfig::findEcho(const std::string& name) const -> const Ja::EchoParams* { const auto IT = echoes_.find(name); return (IT == echoes_.end()) ? nullptr : &IT->second; } auto SoundEffectsConfig::findReverb(const std::string& name) const -> const Ja::ReverbParams* { const auto IT = reverbs_.find(name); return (IT == reverbs_.end()) ? nullptr : &IT->second; }