Aller au contenu principal

Session 132duodecimus (suite) — Port FIB / CSFX (samples sonores AB3D2)

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)

  • tryExtractPCM detecte maintenant le magic CSFX en premier (avant FORM/IFF)
    et delegue a FibSoundDecoder.decode(). Donc un fichier raw qui commencerait
    par CSFX serait aussi decompresse correctement.
  • main() scanne en plus du RAW_SFX_FILES un 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) ET BOOM.fib existent dans le meme
    dossier, le raw est traite en premier et le .fib est skip pour ne pas
    produire un doublon boom.wav.
  • Default arg srcDir mis 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.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *