Commit Graph
17 Commits
Author SHA1 Message Date
JailDesignerandClaude Opus 4.7 3089177e69 refactor(core/audio): eliminar 5 funcions mortes a Ja:: (DEAD-01..04, PATCH-04)
Verificat amb grep que cap caller dins de source/ invoca:
  - Ja::setMusicPosition (stub no-op)
  - Ja::getMusicPosition (stub que retornava 0)
  - Ja::getMusicFilename (accessor a Music::filename, el camp s'accedeix
    directament des d'Audio)
  - Ja::getChannelState (getter sense consumidor públic)
  - Ja::setVolume (combinació master — Audio fa el gate per canal)

Es manté loadMusic(buffer, length, filename) perquè Resource::Cache
l'utilitza per registrar el path dins del Ja::Music.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:22:41 +02:00
JailDesignerandClaude Opus 4.7 355fcfb9de refactor(core/audio): iostream → cstdio per als missatges d'error (COUP-03)
jail_audio.hpp és un header inline que arrossegava <iostream> a cada
TU que l'incloïa, només per a std::cout de missatges d'error. <iostream>
és un include pesat i aquí no aporta res: estem fent logging simple.

Passem a <cstdio> + std::fprintf(stderr, ...) als dos fitxers (jail_audio
i audio.cpp). Missatges prefixats "Ja::funció:" / "Audio:" seguint la
convenció "Module: message" que ja fan servir director.cpp, options.cpp,
resource_cache.cpp, etc.

Efecte col·lateral: stderr és l'stream correcte per als errors (abans
anaven a stdout).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:20:08 +02:00
JailDesignerandClaude Opus 4.7 a917f6660a fix(core/audio): recuperar el nom del Ja::Music::filename (PATCH-02)
L'overload playMusic(Ja::Music*, ...) buidava music_.name a cegues, així
que getCurrentMusicName() mentia després d'aquest camí tot i que el
Ja::Music que li passaves podia portar filename (Ja::loadMusic té un
overload que l'accepta).

Ara copiem music->filename — si el caller va usar l'overload amb
filename, el nom es conserva; si no, queda buit i el contracte és
explícit al comentari.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:17:32 +02:00
JailDesignerandClaude Opus 4.7 66c5801725 refactor(core/audio): Ja::* és l'única font de veritat de MusicState (INCONS-02)
music_.state era una cache d'estat que podia divergir del real —
precisament per això existia getRealMusicState() com a "consulta honesta".
Es descarta la cache:

  - music_.state deixa d'existir; el struct privat Music només manté
    name i loop.
  - getMusicState() passa a ser static i consulta Ja::getMusicState(),
    projectant INVALID/DISABLED al STOPPED que exposa Audio::MusicState.
  - getRealMusicState() desapareix (getMusicState ja fa la consulta real).
  - update() ja no necessita el bloc de sincronització.
  - playMusicInternal/pauseMusic/resumeMusic/stopMusic/fadeOutMusic
    llegeixen getMusicState() en comptes de music_.state i deixen de
    reassignar-lo — Ja ja ho fa.

Externament: cap caller usa getMusicState/getRealMusicState, així que
canviar a static és segur (Audio::get()->getMusicState() continua
funcionant).

pauseMusic/resumeMusic/stopMusic es marquen amb NOLINT per
readability-make-member-function-const pel mateix motiu que INCONS-01
(muten globals de Ja::* que clang-tidy no veu).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:15:49 +02:00
JailDesignerandClaude Opus 4.7 964ff104ce refactor(core/audio): quitar const que mentia en 6 mètodes (INCONS-01)
playSound (x2), stopAllSounds, fadeOutMusic, setSoundVolume i
setMusicVolume es declaraven const però mutaven l'estat global de Ja::*
(channels[], outgoing_music, music_volume, sound_volume[]). El const no
protegia res: el compilador no detectava les mutacions perquè anaven a
globals, no a membres, i podia induir a error a qui llegia el header.

Els callers externs van via Audio* (no Audio const*), així que el canvi
és source-compatible.

Clang-tidy falla amb readability-make-member-function-const perquè
tampoc veu la mutació — és exactament el símptoma que motiva el
hallazgo. S'afegeix NOLINT localitzat a cada mètode amb la raó. Quan
s'executi COUP-01 (encapsular Ja::* en classe membre) els NOLINT
cauran sols perquè la mutació serà visible al compilador.

effectiveVolume es queda const — és un càlcul pur sobre els membres.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:10:44 +02:00
JailDesignerandClaude Opus 4.7 6a1ed37242 refactor(core/audio): template forEachTargetChannel (DUP-05)
pauseChannel, resumeChannel i stopChannel repetien tres vegades la
cadena "if channel == -1 forEach(channels) else if 0<=channel<MAX
apply()". S'extreu a forEachTargetChannel(channel, fn) i cada funció es
queda només amb la lògica per canal — pausar, reprendre, destruir.

Substitueix codi gairebé idèntic triplicat per una declaració de per
què fa el que fa cada funció.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:07:07 +02:00
JailDesignerandClaude Opus 4.7 dee00a8de7 refactor(core/audio): helper stealCurrentIntoOutgoing (DUP-04)
fadeOutMusic i crossfadeMusic repetien el bloc "destruir outgoing
anterior + preFillOutgoing + robar stream + reset state+vorbis". Es
treu a stealCurrentIntoOutgoing(duration_ms) i els dos callers deleguen.

Com a efecte secundari, homogeneïtza la neteja: abans fadeOutMusic no
posava outgoing.fade.active = false en destruir l'anterior i
crossfadeMusic sí. L'helper fa sempre les dues coses. El comportament
observable no canvia perquè la fade s'assigna completament just després,
però elimina una inconsistència latent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:05:28 +02:00
JailDesignerandClaude Opus 4.7 ee34638c89 refactor(core/audio): helper fadeProgress compartit per fades (DUP-03)
updateOutgoingFade i updateIncomingFade calculaven el mateix PERCENT
lineal (ELAPSED / duration_ms) per separat i prenien decisions sobre si
el fade havia acabat comparant bytes. Ara fadeProgress(FadeState)
retorna [0..1] i concentra la corba del fade — si cal passar-la a
logarítmica o quadràtica, es toca en un sol lloc.

També protegeix duration_ms<=0 com a "fade completat" (abans el divisor
donava una divisió per zero en debug o un progrés >> 1 en release).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:03:10 +02:00
JailDesignerandClaude Opus 4.7 893e5b27e4 refactor(core/audio): helper effectiveVolume compartit (DUP-02)
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>
2026-04-20 12:01:06 +02:00
JailDesignerandClaude Opus 4.7 256a232a95 refactor(core/audio): factoritzar overloads playMusic (DUP-01)
Els dos playMusic compartien el dispatch crossfade-vs-stop+play i
l'actualització de music_.state/loop. S'extreu playMusicInternal privat
que rep el Ja::Music* ja resolt i fa el camí comú.

Cada overload es queda només amb el seu gating propi: la variant per
nom fa early-return si ja sona la mateixa pista i posa music_.name; la
variant per punter buida el nom (PATCH-02 recuperarà el filename del
propi Ja::Music).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:59:26 +02:00
JailDesignerandClaude Opus 4.7 a6cd12a944 fix(core/audio): toggle* i enable[Sound|Music] reapliquen volum (PATCH-01)
Abans, toggleEnabled/toggleSound/toggleMusic i les variants sense bool
només flipaven el flag intern; els canals actius no notaven el canvi
fins a la pròxima crida explícita a setSoundVolume/setMusicVolume —
silenciós i fàcil de perdre.

Ara:
  - toggleEnabled passa per enable(bool), que ja reaplicava els volums.
  - enableSound(bool) i enableMusic(bool) es mouen a audio.cpp i
    reapliquen el volum gated cap a Ja::*.
  - Les variants enableSound()/disableSound()/enableMusic()/disableMusic()
    i els toggles passen per aquestes dues funcions, així que qualsevol
    camí d'activació produeix el mateix efecte sobre l'estat sonor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:57:10 +02:00
JailDesignerandClaude Opus 4.7 92f38bc51c refactor(core/audio): eliminar fill(0.5F) sobreescrit a Ja::init (HC-05)
sound_volume[] és un inline float[] amb zero-init per defecte i la capa
Audio crida setSoundVolume(config_.sound_volume) via enable() just
després de Ja::init, així que el fill(0.5F) no arribava mai a l'usuari.
Era un valor màgic heretat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:54:53 +02:00
JailDesignerandClaude Opus 4.7 5939cd3aa3 docs(audit): HC-04 com a WONTFIX (tuning intern del motor)
MUSIC_CHUNK_SHORTS i MUSIC_LOW_WATER_SECONDS són paràmetres del streaming
de vorbis/SDL; viuen dins de jail_audio i moure'ls a Defaults acoplaria
el motor al projecte. Mateix criteri que HC-03.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:54:02 +02:00
JailDesignerandClaude Opus 4.7 621d454563 refactor(core/audio): static_assert Audio::Group ↔ Ja::MAX_GROUPS (HC-03)
Ja::MAX_SIMULTANEOUS_CHANNELS i Ja::MAX_GROUPS són límits interns del
motor. La proposta inicial era moure'ls a Defaults::Audio, però jail_audio
és reutilitzable entre projectes (no depèn d'Options ni d'utils/); moure
els límits trencaria aquesta independència.

El valor real del hallazgo era la invariant Audio::Group ↔ MAX_GROUPS,
que cap codi protegia. S'afegeix un static_assert a audio.cpp que falla
en compilació si s'afegeix una entrada nova a Group sense tocar
MAX_GROUPS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:52:51 +02:00
JailDesignerandClaude Opus 4.7 deb0fc2a4b refactor(core/audio): unificar format/canals/freq a Defaults::Audio (HC-02)
{SDL_AUDIO_S16, 2, 48000} apareixia com a literal a tres llocs de
jail_audio (Sound/Music/audio_spec) i audio.cpp:208 passava SDL_AUDIO_S16LE
i 2 canals per separat — dues convencions de format conviuen i els 2
canals eren número màgic.

Defaults::Audio guanya FORMAT (SDL_AUDIO_S16) i CHANNELS (2). Audio::
initSDLAudio passa ambdós junts a Ja::init. jail_audio obté un fallback
local Ja::DEFAULT_SPEC que consolida les tres instàncies; es queda
independent del projecte (no inclou utils/defaults.hpp) perquè l'engine
és reutilitzable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:50:41 +02:00
JailDesignerandClaude Opus 4.7 6f0626c31f refactor(core/audio): moure constants UI/tuning a Defaults::Audio (HC-01)
VOLUME_STEP, FREQUENCY i DEFAULT_CROSSFADE_MS vivien com a membres
constexpr d'Audio. Eren valors de configuració — no invariants de la
classe — i la convenció del projecte és que tots els paràmetres
ajustables visquin a utils/defaults.hpp.

Passen a Defaults::Audio::{VOLUME_STEP, FREQUENCY, CROSSFADE_MS}. L'únic
ús intern (Ja::init al constructor d'Audio) es reapunta al Defaults. Cap
ús extern dels tres símbols.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:47:40 +02:00
JailDesignerandClaude Opus 4.7 8b73198209 docs(audit): crear audit-core-audio.md con hallazgos inicials
Plantilla d'auditoria per a core/audio/ amb els IDs estables (DUP/HC/
PATCH/COUP/INCONS/DEAD/CONV) i el top-5 prioritari. Mateix format que
l'auditoria de core/rendering/; les resolucions s'aniran anotant a
mesura que s'apliquin els canvis, commit a commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 11:45:38 +02:00