Apres la bascule des sources assets vers original/, le seul format restant
incompatible etait original/samples/*.fib (format compresse proprietaire AB3D2).
Le decompresseur est maintenant porte fidelement depuis l’ASM original.
Source de reference
Port direct de la routine io_LoadSample dans
ab3d2_source/modules/file_io.s (sources ASM AB3D2). Identification du format
par le magic ASCII 'C','S','F','X' (= Compressed Sound eFX), confirme
visuellement sur original/samples/BOOM.fib qui commence par cette signature.
Format binaire CSFX (proprietaire, PAS IFF FIBDELTA standard)
offset 0..3 : magic ASCII 'CSFX'
offset 4..7 : taille decompressee (4 bytes big-endian)
offset 8 : premier echantillon (PCM 8-bit signe brut, valeur initiale)
offset 9..N : chaque byte code 2 deltas via la table Fibonacci :
high_nibble (bits 4-7) -> delta1
low_nibble (bits 0-3) -> delta2
sample[i+1] = clip8(sample[i] + FIB[nibble])
Table Fibonacci-delta (16 entrees, identique a .fibonnaci_lookup_vb ASM) :
FIB = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 }
Clipping final a [-64, 63] reproduit fidelement (cf. .clip_loop dans l’ASM) :
vraisemblablement une marge de securite contre la saturation Paula apres
modulation de volume.
Nouveau fichier : tools/convert/FibSoundDecoder.java
Classe utilitaire avec deux methodes statiques :
– boolean isCsfx(byte[] raw) : test rapide du magic
– byte[] decode(byte[] raw) : decompression complete -> PCM 8-bit signe
Le code suit ligne par ligne la routine ASM (commentaires inline mappant chaque
etape vers son equivalent 68k). Le clip final reproduit .clip_loop y compris
pour le premier echantillon (verifie en test).
tools/convert/SoundConverter.java (modifie)
tryExtractPCMdetecte maintenant le magic CSFX en premier (avant FORM/IFF)
et delegue aFibSoundDecoder.decode(). Donc un fichier raw qui commencerait
par CSFX serait aussi decompresse correctement.main()scanne en plus duRAW_SFX_FILESun glob*.fib(cas-insensitive
pour gerer aussi.FIB) et applique le decompresseur. Les fichiers IFF
continuent d’etre traites normalement.- Deduplication par stem : si
BOOM(raw) ETBOOM.fibexistent dans le meme
dossier, le raw est traite en premier et le.fibest skip pour ne pas
produire un doublonboom.wav. - Default arg
srcDirmis a jour :"original/samples"(au lieu de
"src/main/resources/sounds/raw") pour que les runs IDE depuis le project
root pointent au bon endroit par defaut.
build.gradle (tache convertSounds modifiee)
Nouvel ordre de priorite :
1. -PsoundsFrom=<chemin> (override CLI)
2. <findSourceResources()>/samples (layout original/, contient les .fib CSFX)
3. <findSourceResources()>/sounds/raw (layout legacy ab3d2-tkg-java, PCM brut)
logger.lifecycle('convertSounds source: {}', soundSrc) ajoute pour faciliter
le diagnostic. Message d’erreur ameliore quand aucune source n’est trouvee.
Tests : FibSoundDecoderTest.java (15 tests)
Nouveau dossier src/test/java/com/ab3d2/tools/convert/. Couvre :
– detection magic (positifs + 6 cas negatifs)
– rejets : magic invalide, fichier tronque (< 9 bytes), taille zero, taille
negative (high bit set), taille absurde (>16 MB)
– decode nominal : 1 sample, 2 samples (un seul delta utilise), 5 samples (2
bytes compresses), nombre pair de samples (verifie qu’un nibble en surplus
est ignore conformement a l’ASM)
– clipping : positif vers +63, negatif vers -64, premier echantillon clippe
aussi (le .clip_loop ASM clip TOUTES les valeurs, pas seulement les deltas)
– table Fibonacci : verification byte-par-byte vs .fibonnaci_lookup_vb ASM
A verifier sur sortie reelle
Le vrai test sera de lancer ./gradlew convertSounds et d’ecouter les .wav
produits depuis original/samples/*.fib. Si tous les samples sortent corrects,
le port est valide. En cas de bruit/distorsion, suspects principaux :
1. L’ordre des nibbles (high/low). Verifie en test mais double check sur
sample reel.
2. La frequence d’echantillonnage par defaut (11025 Hz). L’ASM ne stocke pas
cette info ; les vrais .fib n’ont pas de header Hz. C’est une heuristique.
3. Le clipping [-64, 63] peut sembler agressif mais est fidele a l’ASM.
Si les sons sont OK mais avec saturation entendue, peut-etre l’ASM
compense ailleurs (modulation de volume Paula). A reverifier.
Limitations restantes (hors scope FIB)
- floortile decoder (B) : pas attaque cette session. Format chunky 8-bit
16x(64×64) confirme par taille (65536 bytes) ; reste a confirmer le layout
on-disk (row-major sequentiel vs interleaved a la newtexturemaps). - convertSounds + IFF/.dm : les fichiers IFF 8SVX continuent de fonctionner
inchanges. Les.dm(delta-mod Amiga) sont toujours skip.