setSoundVolume i setMusicVolume repetien la mateixa lògica de clamp + gate (enabled_ && channel_enabled_) + multiplicació pel master config_.volume. S'extreu effectiveVolume(volume, channel_enabled) privat i els dos setters es limiten a la crida Ja::*. Any canvi futur a la política (p.ex. una corba logarítmica) queda en un sol lloc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
96 lines
8.2 KiB
Markdown
96 lines
8.2 KiB
Markdown
# Auditoría `core/audio/`
|
|
|
|
Rama: `audit/core-audio`
|
|
Estado global: en progreso.
|
|
|
|
Estados posibles:
|
|
- `PENDING` — identificado, sin tocar
|
|
- `WIP` — diff propuesto, pendiente de aplicar
|
|
- `DONE` — aplicado y commiteado
|
|
- `WONTFIX` — 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) | PENDING |
|
|
| HC-02 | Formato/canales/freq hardcodeado en 3+ sitios | DONE |
|
|
| INCONS-02 | Doble `MusicState` + `getRealMusicState` como cache paralelo | PENDING |
|
|
| 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 | PENDING | Helper `fadeProgress(FadeState&) -> float` |
|
|
| DUP-04 | `jail_audio.hpp:391-471` | `fadeOutMusic`/`crossfadeMusic` repiten "destruir outgoing + pre-fill + robar stream + reset vorbis" | Importante | PENDING | Función privada `stealCurrentIntoOutgoing(int ms)` |
|
|
| DUP-05 | `jail_audio.hpp:575-631` | `pauseChannel`/`resumeChannel`/`stopChannel` repiten dispatch `channel==-1 / [0,MAX)` | Menor | PENDING | Helper `forEachTargetChannel(int, fn)` |
|
|
|
|
## 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|Music](bool)`. Aquestes funcions ara reapliquen el volum cap a `Ja::` perquè els canals actius responguin al toggle |
|
|
| PATCH-02 | `audio.cpp:98` | `music_.name.clear()` en overload por puntero → `getCurrentMusicName()` miente | Importante | PENDING | Derivar nombre de `Ja::Music::filename` |
|
|
| PATCH-03 | `audio.cpp:14-21` | `#undef L,C,R,PLAYBACK_*` workaround para macros filtradas por stb_vorbis | Importante | WONTFIX | Documentado; aislar stb_vorbis en TU propio sería más invasivo — se hará con COUP-01 |
|
|
| PATCH-04 | `jail_audio.hpp:501-507` | `setMusicPosition`/`getMusicPosition` stubs no-op | Importante | PENDING | Borrar si nadie los llama |
|
|
| 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 | DEFERRED | Refactor grande; se hará en fase posterior |
|
|
| COUP-02 | `jail_audio.hpp` entero | Engine header-only: 678 líneas compilándose en cada TU | Importante | DEFERRED | Depende de COUP-01 |
|
|
| COUP-03 | `audio.cpp:3`, `jail_audio.hpp:8` | `#include <iostream>` sólo para `std::cout` de errores | Importante | PENDING | Sustituir por `std::fprintf(stderr,…)` con `<cstdio>` |
|
|
| 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 | PENDING | Quitar `const`; propagar a la declaración |
|
|
| INCONS-02 | `audio.hpp:44-48` + `jail_audio.hpp:44-50` | Dos `MusicState` paralelos + `getRealMusicState` como puente | Importante | PENDING | Un enum único; eliminar `getRealMusicState` |
|
|
| INCONS-03 | `audio.cpp` varios | Comentarios mezclan catalán y español | Menor | PENDING | Unificar a catalán |
|
|
| 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 | PENDING | Dejar `enableSound(bool)` + `toggleSound()`; delegar a `Ja` |
|
|
|
|
## 6. Código muerto
|
|
|
|
| ID | Fichero:línea | Hallazgo | Severidad | Estado | Notas |
|
|
|----|---------------|----------|-----------|--------|-------|
|
|
| DEAD-01 | `jail_audio.hpp:501-507` | `setMusicPosition`/`getMusicPosition` stubs | Importante | PENDING | Verificar grep y borrar (= PATCH-04) |
|
|
| DEAD-02 | `jail_audio.hpp:671-675` | `Ja::setVolume` master no usado desde `Audio` | Menor | PENDING | Borrar si nadie lo llama |
|
|
| DEAD-03 | `jail_audio.hpp:346-350` | `getMusicFilename` presunto unused | Menor | PENDING | Verificar y borrar |
|
|
| DEAD-04 | `jail_audio.hpp:633-638` | `getChannelState` sin getter público en `Audio` | Menor | PENDING | Verificar y borrar |
|
|
| DEAD-05 | `audio.hpp:102-103` | `enableSound()`/`disableSound()` sin argumento (duplican la versión con bool) | Menor | PENDING | Cubierto por 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 | PENDING | Cubierto por HC-01..HC-04 |
|
|
| CONV-02 | `jail_audio.hpp` | Engine no es clase (namespace + globals), viola OOP | Importante | DEFERRED | Cubierto por COUP-01 |
|
|
| CONV-03 | `jail_audio.hpp` | No hay callback "music ended"; polling desde `update()` | Menor | DEFERRED | Requiere COUP-01 |
|