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>
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>
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>
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>
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>
{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>