Je me pose la question de l'encodage des instructions pour le player. Actuellement le player utilise le jeu d'instruction de longeur variable suivant:
Code:
0xxxxxxx xxxxxxxx : "appelle" la routine à l'adresse indiquée (en relatif par rapport au début du morceau)
00000000 : retour de l'appel précédent (cela sert dans la factorisation de bouts de musiques identiques)
10000000 tttttttt : positionne le tempo (nombre de tour de boucle par valeur de délais, typiquement 100)
1000xxxx : joue x*tempo tours de boucle (souvent x=1 pour les changements à chaque frame, sinon x=6 pour les changements à chaque row)
11ccvvvv : met le volume à v pour le canal c qui devient le canal courant
10100000 iiiiiiii : change l'instrument du canal courant pr positionne l'instrument "i" (forrmat long: 256 instruments)
101iiiii : change l'instrument du canal courant pr positionne l'instrument "i-1" (forrmat court: 31 instruments)
10010000 ffffffff ffffffff : change la fréquence du canal courant à "f" (format long: 16 bits, jamais utilisé)
1001ffff ffffffff : change la fréquence du canal courant à "f-256" (format court: 12 bits, le seul utilisé jusqu'à présent)
C'est pas mal compact et sa se décode en très peu de cycles par le player. Par exemple voici un extrait du module "corrpution" dans ce format.
Code:
* Row 48 : 32
* Unsupported effect 0x0E(1A) for Channel 1, Row 48, Pattern 32
fcb $81 ; d:1
fcb $cf ; c:1 v:15
fcb $a1 ; s:1
fcb $92,$f9 ; f:505
fcb $df ; c:2 v:15
fcb $ab ; s:11
fcb $92,$42 ; f:322
fcb $ef ; c:3 v:15
fcb $a0,$27 ; s:40
fcb $91,$fc ; f:252
fcb $ff ; c:4 v:15
fcb $a5 ; s:5
fcb $92,$1c ; f:284
fcb $81 ; d:1
fcb $de ; c:2 v:14
fcb $81 ; d:1
fcb $da ; c:2 v:10
fcb $81 ; d:1
fcb $d8 ; c:2 v:8
fcb $81 ; d:1
fcb $d6 ; c:2 v:6
* Row 49 : 32
fcb $81 ; d:1
fcb $d2 ; c:2 v:2
fcb $ee ; c:3 v:14
fcb $ff ; c:4 v:15
fcb $a4 ; s:4
fcb $92,$87 ; f:391
fcb $81 ; d:1
fcb $d0 ; c:2 v:0
fcb $ec ; c:3 v:12
fcb $81 ; d:1
fcb $ea ; c:3 v:10
fcb $81 ; d:1
fcb $e6 ; c:3 v:6
* Row 50 : 32
fcb $81 ; d:1
fcb $cf ; c:1 v:15
fcb $ae ; s:14
fcb $91,$80 ; f:128
fcb $df ; c:2 v:15
fcb $a0,$32 ; s:51
fcb $92,$66 ; f:358
fcb $ef ; c:3 v:15
fcb $a0,$35 ; s:54
fcb $91,$80 ; f:128
fcb $f2 ; c:4 v:2
fcb $a5 ; s:5
fcb $92,$1c ; f:284
On voit que sur ce morceau, un row occupe environ 20 octets, change 4 instruments, 4 volumes et 3 des fréquences. C'est un bout assez chargé qui dure 4 "delais" (somme des $8x) pour un total de 80ms. Donc tous les 80ms on consome 20 octets, soit exactement 15000 octets par minutes. Pas étonnant que ce morceau de 3-4 minutes soit super lourd même sans les instruments.
Aussi je réfléchis à un encodage plus compact et reprends l'idée du player 1 bit de l'an dernier qui écrit des rows et pas des instructions indépendantes du canal. C'est moins puissant, mais plus compact
Code:
1ccccddd VIFFvvvv [instru] [xxxxxxxx] [yyyyyyyy]
- Les cccc du début indiquent s'il faut changer le canal correspondant.
- Les ddd sont le delay-1 à attendre avant de passer au "row" suivant (000 = attente de 1).
- V = 1 si la partie volume "vvvv" est à changer. Si V=0, "vvvv" servira pour de futures extensions.
- I = 1 si l'octet "instru" est présent 0 sinon.
- FF=00 si pas de changement de frequence
- FF=01 fréquence = xxxxxxxxyyyyyyyy (0->65535)
- FF=10 frequence = 00000000xxxxxxxx (0->255)
- FF=11 fréquence = 00000001xxxxxxxx (256->511)
Avec ce format le "Row 50" devient
Code:
%11111001 %1011111 $0e $80 %1111111 $33 $66 %11011111 $36 $80 %11110010 $05 $1C
soit 13 octets au lieu de 19 (30% plus court). C'est bon, je prends
Ca me plait bien, surtout qu'il ya de la place pour des extensions (karaoké, changements de palette voir mini animations).
Ya plus qu'à... (tout casser et recoder avec ce nouveau format)