Actualitza audit-core-audio.md amb els estats finals després del refactor
a refactor/audio-engine-class:
- COUP-01 (encapsular Ja::* globals): DONE — Ja::Engine classe RAII
- COUP-02 (header-only): DONE — jail_audio.cpp nou amb stb_vorbis.c
- PATCH-03 (#undef macros): DONE — migrats a jail_audio.cpp
- CONV-02 (engine no és classe): DONE — resolt amb COUP-01
- CONV-03 (callback music-ended): DONE — setOnMusicEnded
- INCONS-05 (enable/disable divergent): DONE complet — Audio silencia
per gain, flags de motor eliminats
Queda un sol ítem DEFERRED: PATCH-05 (voice-stealing policy), que és una
feature, no deute.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
10 KiB
10 KiB
Auditoría core/audio/
Rama inicial: audit/core-audio (ítems DONE/WONTFIX/DEFERRED inicials).
Rama posterior: refactor/audio-engine-class — tanca els DEFERRED principals (COUP-01/02, PATCH-03, CONV-02/03, INCONS-05 complet).
Estado global: auditoria + refactor aplicats. 22 ítems DONE, 4 WONTFIX, 1 DEFERRED (PATCH-05 — política voice-stealing, és feature no deute).
Estados posibles:
PENDING— identificado, sin tocarWIP— diff propuesto, pendiente de aplicarDONE— aplicado y commiteadoWONTFIX— se decide no tocar (justificación en la nota)DEFERRED— se hará en fase posterior
Los IDs se mantienen estables una vez asignados. Cada entrada apunta al(los) fichero(s) y líneas afectados en la rama de origen (main en el momento del clone).
Top 5 prioritario
| ID | Título | Estado |
|---|---|---|
| COUP-01 | Encapsular globals Ja:: en clase (engine sin estado global) |
DONE |
| HC-02 | Formato/canales/freq hardcodeado en 3+ sitios | DONE |
| INCONS-02 | Doble MusicState + getRealMusicState como cache paralelo |
DONE |
| HC-01 | Parámetros de audio no configurables (viola convención del proyecto) | DONE |
| PATCH-01 | toggleEnabled/toggleSound/toggleMusic no reaplican volumen |
DONE |
1. Duplicación
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|---|---|---|---|---|---|
| DUP-01 | audio.cpp:58-101 |
Dos playMusic (nombre/puntero) repiten el bloque crossfade/stop+play |
Menor | DONE | playMusicInternal(Ja::Music*, loop, crossfade_ms) privat; els dos overloads fan gating + name-handling i deleguen el dispatch |
| DUP-02 | audio.cpp:172-185 |
setSoundVolume/setMusicVolume idéntica estructura de clamp+gate+producto |
Menor | DONE | effectiveVolume(volume, channel_enabled) privat; els dos setters deleguen |
| DUP-03 | jail_audio.hpp:196-222 |
updateOutgoingFade/updateIncomingFade comparten la curva lineal |
Menor | DONE | fadeProgress(FadeState&) concentra la corba en un sol lloc; també cobreix duration_ms <= 0 com a 1.0 |
| DUP-04 | jail_audio.hpp:391-471 |
fadeOutMusic/crossfadeMusic repiten "destruir outgoing + pre-fill + robar stream + reset vorbis" |
Importante | DONE | stealCurrentIntoOutgoing(duration_ms) concentra el robatori; fadeOutMusic i crossfadeMusic hi deleguen. També homogeneïtza outgoing.fade.active = false en la destrucció (abans era inconsistent) |
| DUP-05 | jail_audio.hpp:575-631 |
pauseChannel/resumeChannel/stopChannel repiten dispatch channel==-1 / [0,MAX) |
Menor | DONE | Template forEachTargetChannel(channel, fn); cada funció només descriu què fa per canal |
2. Hardcoding
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|---|---|---|---|---|---|
| HC-01 | audio.hpp:53-55 |
VOLUME_STEP, FREQUENCY, DEFAULT_CROSSFADE_MS viven en la clase, no en Defaults::Audio |
Importante | DONE | Movidos a Defaults::Audio::{VOLUME_STEP, FREQUENCY, CROSSFADE_MS} en utils/defaults.hpp |
| HC-02 | jail_audio.hpp:57,76,110 + audio.cpp:208 |
{SDL_AUDIO_S16, 2, 48000} literal en 3 sitios; S16LE vs S16 inconsistente |
Importante | DONE | Defaults::Audio::{FORMAT,CHANNELS,FREQUENCY} al call-site d'Audio::initSDLAudio; Ja::DEFAULT_SPEC com a fallback local perquè l'engine no depengui del projecte |
| HC-03 | jail_audio.hpp:53-54 |
MAX_SIMULTANEOUS_CHANNELS=20, MAX_GROUPS=2 fijos sin justificación |
Menor | DONE | static_assert a audio.cpp protegeix Audio::Group ↔ Ja::MAX_GROUPS. No es mou a Defaults — el motor és independent del projecte per disseny |
| HC-04 | jail_audio.hpp:131,134 |
MUSIC_CHUNK_SHORTS=8192, MUSIC_LOW_WATER_SECONDS=0.5F tuning hidden |
Menor | WONTFIX | Són tuning intern del streaming (vorbis + SDL stream). Ja són inline constexpr amb comentaris; moure-les a Defaults trencaria la independència del motor (mateix criteri que HC-03) |
| HC-05 | jail_audio.hpp:266 |
fill(sound_volume, 0.5F) valor mágico que se sobreescribe enseguida |
Menor | DONE | Eliminada la línia. El inline float[] zero-inicialitza i Audio::initSDLAudio sobreescriu immediatament via enable() |
3. Parches e improvisaciones
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|---|---|---|---|---|---|
| PATCH-01 | audio.hpp:98,105,111 |
toggleEnabled/toggleSound/toggleMusic sólo flipan el flag; no reaplican volúmenes |
Importante | DONE | toggle*() i variants sense bool passen per `enable[Sound |
| PATCH-02 | audio.cpp:98 |
music_.name.clear() en overload por puntero → getCurrentMusicName() miente |
Importante | DONE | music_.name = music->filename. Si Ja::Music va ser carregat amb filename, getCurrentMusicName() ara retorna el nom correcte; si no, queda buit (contracte explícit) |
| PATCH-03 | audio.cpp:14-21 |
#undef L,C,R,PLAYBACK_* workaround para macros filtradas por stb_vorbis |
Importante | DONE | stb_vorbis.c + #undef migrats a jail_audio.cpp (TU únic). audio.cpp neta d'aquest workaround |
| PATCH-04 | jail_audio.hpp:501-507 |
setMusicPosition/getMusicPosition stubs no-op |
Importante | DONE | Eliminats (veure DEAD-01) |
| PATCH-05 | jail_audio.hpp:532-535 |
"No hay canal libre → canal 0" robo de voz arbitrario | Importante | DEFERRED | Política de voice-stealing es una feature; se documenta |
4. Acoplamiento innecesario
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|---|---|---|---|---|---|
| COUP-01 | jail_audio.hpp:107-118 |
inline globals en namespace: estado del engine sin encapsulación |
Crítico | DONE | Ja::Engine classe amb RAII; Audio en posseeix std::unique_ptr<Engine>. Engine::active() static accessor per als deleters de Resource::Cache. Branca refactor/audio-engine-class |
| COUP-02 | jail_audio.hpp entero |
Engine header-only: 678 líneas compilándose en cada TU | Importante | DONE | jail_audio.cpp nou conté totes les definicions + stb_vorbis.c. El .hpp baixa a ~130 línies de declaracions |
| COUP-03 | audio.cpp:3, jail_audio.hpp:8 |
#include <iostream> sólo para std::cout de errores |
Importante | DONE | <iostream> → <cstdio> als dos fitxers. jail_audio.hpp ja no arrossega iostream a cada TU que l'inclou. Missatges prefixats Ja:: / Audio: (convenció Module: message del projecte) |
| COUP-04 | audio.cpp:43-45, 208 |
Ja::init en initSDLAudio vs Ja::quit en destructor (asimetría) |
Menor | WONTFIX | Convive con singleton; se revisará con COUP-01 |
| COUP-05 | audio.hpp:71,79 |
API pública expone Ja::Music*/Ja::Sound* |
Menor | WONTFIX | Forward-declare ya mitiga; evita doble lookup por nombre |
5. Inconsistencias internas
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|---|---|---|---|---|---|
| INCONS-01 | audio.cpp:128,135,142,149,172,180 |
Métodos const que mutan globals de Ja (const miente) |
Importante | DONE | const tret de 6 mètodes (playSound x2, stopAllSounds, fadeOutMusic, setSoundVolume, setMusicVolume). effectiveVolume es queda const (pur sobre membres). Cap caller extern via const Audio* |
| INCONS-02 | audio.hpp:44-48 + jail_audio.hpp:44-50 |
Dos MusicState paralelos + getRealMusicState como puente |
Importante | DONE | Eliminat music_.state (cache) i getRealMusicState. getMusicState() consulta Ja::* directament i projecta INVALID/DISABLED → STOPPED. La font de veritat passa a ser Ja. update() ja no necessita sincronització |
| INCONS-03 | audio.cpp varios |
Comentarios mezclan catalán y español | Menor | DONE | Tots els comentaris en castellà passats a català (incloent-hi els dels enums, constants, --- Secció ---, includes Per a ..., variables membre). Resta els comentaris en català que ja hi eren |
| INCONS-04 | audio.hpp:70,78 |
playMusic loop=-1 vs playSound loop=0 |
Menor | WONTFIX | Convención razonable (música loop / sonido one-shot); documentar |
| INCONS-05 | audio.hpp:102-105 |
4 formas de enable/disable sound (API redundante) + divergencia con Ja::enableSound |
Importante | DONE | 4 variants no-arg eliminades. Divergència resolta: Ja::Engine::enableMusic/enableSound i els flags music_enabled_/sound_enabled_ del motor eliminats (decisió de l'usuari: silenciar per gain des d'Audio via effectiveVolume). Tanca amb el commit 4 del refactor |
6. Código muerto
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|---|---|---|---|---|---|
| DEAD-01 | jail_audio.hpp:501-507 |
setMusicPosition/getMusicPosition stubs |
Importante | DONE | Eliminats; cap caller |
| DEAD-02 | jail_audio.hpp:671-675 |
Ja::setVolume master no usado desde Audio |
Menor | DONE | Eliminat; Audio fa el gate per canal |
| DEAD-03 | jail_audio.hpp:346-350 |
getMusicFilename presunto unused |
Menor | DONE | Eliminat; Ja::Music::filename s'accedeix directe (PATCH-02) |
| DEAD-04 | jail_audio.hpp:633-638 |
getChannelState sin getter público en Audio |
Menor | DONE | Eliminat |
| DEAD-05 | audio.hpp:102-103 |
enableSound()/disableSound() sin argumento (duplican la versión con bool) |
Menor | DONE | Eliminades (veure INCONS-05) |
7. Violaciones de convenciones
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|---|---|---|---|---|---|
| CONV-01 | varios | Parámetros de audio fuera de Defaults/config.yaml |
Importante | DONE (parcial) | Els que encaixen (VOLUME_STEP, FREQUENCY, CROSSFADE_MS, FORMAT, CHANNELS) ja són a Defaults::Audio (HC-01, HC-02). La resta són tuning intern del motor i resten a jail_audio.hpp per preservar-ne la independència |
| CONV-02 | jail_audio.hpp |
Engine no es clase (namespace + globals), viola OOP | Importante | DONE | Resolt amb COUP-01: Ja::Engine és classe amb ctor/dtor RAII, membres privats i API explícita |
| CONV-03 | jail_audio.hpp |
No hay callback "music ended"; polling desde update() |
Menor | DONE | Ja::Engine::setOnMusicEnded(std::function<void()>) disparat des de updateCurrentMusic després de stopMusic(). Exposat via Audio::setOnMusicEnded. Commit 5 del refactor |