feat(audio): suport d'efectes (eco i reverb) per a sons puntuals

Afig una capa d'efectes oberta a la unitat d'àudio. Els sons puntuals
es poden reproduir processats per un eco o un reverb (Freeverb 8C/4AP)
sense afectar la música ni canviar el camí ràpid existent (playSound
sense efecte segueix sent una sola crida sense cost extra).

  - data/sounds.yaml: catàleg de presets nominats (echo: cave/short,
    reverb: stone_hall/small_room).
  - core/audio/audio_effects: processadors purs que prenen un Ja::Sound
    (U8/S16, mono o estèreo) i tornen PCM S16 amb la cua de l'efecte
    (cap a 800 ms eco, 1500 ms reverb).
  - core/audio/sound_effects_config: Meyers singleton que parseja
    sounds.yaml a EchoParams/ReverbParams indexats per nom; l'API
    pública d'Audio fa el lookup per nom.
  - jail_audio::Engine: nou camí playSoundWith{Echo,Reverb} que empenta
    el buffer ja processat a un canal lliure marcat com a has_effect.
    El cap MAX_EFFECT_CHANNELS limita a 4 sons amb efecte simultanis;
    si està al límit, l'engine retorna -1 i Audio cau a la versió seca.
  - Audio::playSoundWith{Echo,Reverb}(name, preset, group) com a única
    via pública. Si el preset no existeix, fallback dry amb avís.
  - director: load("data/sounds.yaml") abans d'Audio::init.
This commit is contained in:
JailDesigner committed 2026-04-27 08:16:16 +02:00
1 parent 42062dca55
commit d3698a1504
11 files changed
+593 -5

No files matched your search

+45 -3
View File
@@ -5,9 +5,10 @@
#include <algorithm> // Per a clamp
#include <cstdio> // Per a std::fprintf
#include "core/audio/audio_adapter.hpp" // Per a AudioResource::getMusic/getSound
#include "core/audio/jail_audio.hpp" // Per a Ja::* (motor jailgames)
#include "utils/defaults.hpp" // Per a Defaults::Audio::FREQUENCY
#include "core/audio/audio_adapter.hpp" // Per a AudioResource::getMusic/getSound
#include "core/audio/jail_audio.hpp" // Per a Ja::* (motor jailgames)
#include "core/audio/sound_effects_config.hpp" // Per a SoundEffectsConfig
#include "utils/defaults.hpp" // Per a Defaults::Audio::FREQUENCY
// Invariant compile-time: tots els valors d'Audio::Group han de cabre als slots
// de volum per grup que manté l'engine. Si s'afegeix una nova entrada a Group
@@ -128,6 +129,47 @@ void Audio::playSound(Ja::Sound* sound, Group group) {
}
}
// Reprodueix un so processat per un eco definit a sounds.yaml. Si el preset no
// existeix o l'engine retorna -1 (cap de canals d'efecte plé), cau a playSound
// sec — l'usuari sent el so encara que la cua no s'apliqui.
// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_
void Audio::playSoundWithEcho(const std::string& name, const std::string& preset_name, Group group) {
if (!sound_enabled_) { return; }
auto* sound = AudioResource::getSound(name);
if (sound == nullptr) { return; }
const auto* params = SoundEffectsConfig::get().findEcho(preset_name);
if (params == nullptr) {
std::fprintf(stderr, "Audio: preset d'eco '%s' desconegut — so '%s' es reprodueix sec\n", preset_name.c_str(), name.c_str());
engine_->playSound(sound, 0, static_cast<int>(group));
return;
}
if (engine_->playSoundWithEcho(sound, *params, static_cast<int>(group)) < 0) {
engine_->playSound(sound, 0, static_cast<int>(group));
}
}
// Reprodueix un so processat per un reverb definit a sounds.yaml. Mateix
// fallback que playSoundWithEcho.
// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_
void Audio::playSoundWithReverb(const std::string& name, const std::string& preset_name, Group group) {
if (!sound_enabled_) { return; }
auto* sound = AudioResource::getSound(name);
if (sound == nullptr) { return; }
const auto* params = SoundEffectsConfig::get().findReverb(preset_name);
if (params == nullptr) {
std::fprintf(stderr, "Audio: preset de reverb '%s' desconegut — so '%s' es reprodueix sec\n", preset_name.c_str(), name.c_str());
engine_->playSound(sound, 0, static_cast<int>(group));
return;
}
if (engine_->playSoundWithReverb(sound, *params, static_cast<int>(group)) < 0) {
engine_->playSound(sound, 0, static_cast<int>(group));
}
}
// Atura tots els sons
// NOLINTNEXTLINE(readability-make-member-function-const) — muta estat via engine_; unique_ptr::operator-> no propaga const
void Audio::stopAllSounds() {