FIXME Page à compléter.

Export de la musique

L'export de la musique se fait uniquement sous la forme d'un flux (stream du même genre que le format YM ST-Sound de Leonard), il n'est pas fourni de player externe qui décode les données d'instrument, pattern, etc.

Le flux de sortie donne pour chaque trame (frame) les valeurs à programmer dans les registres du AY, les informations qui permettent de gérer le SID, le sample et les options “Entry” et “Signal”.

Deux formats d'export sont proposés :

  • full stream : donne la valeur de tous les flux pour chaque trame
  • delta stream : donne uniquement les valeurs modifiées par rapport à la trame précédente, il s'agit d'une forme de compression, le fichier généré est facilement trois fois plus petit

Les deux formats utilisent la même extension de nom de fichier SDS.

Données des trames

Chaque trame contient 16 flux d'un octet chacun qui représentent dans l'ordre, les valeurs calculées à envoyer dans les registres AY 0 à 13, la période SID (codée sur 9 bits) et l'information Signal/Entry (combinée en un octet).

Les valeurs des registres de période (0, 1, 2, 3, 4, 5, 11, 12) et de bruit (6) sont stockées directement telles qu'elles doivent être envoyées à l'AY. Par conséquent, le quartet de poids fort des flux des registres 1, 2 et 5 sera toujours à 0, les 3 bits de poids fort du flux du registre 6 seront toujours à 0.

Pour le registre 13, la valeur spéciale &ff indique que le registre ne doit pas être écrit pour cette trame.

Les flux des registres 7, 8, 9 et 10 ont des bits ajoutés par rapport aux registres AY qui servent à coder l'information pour SID et sample.

Flux Bits utiles [7:0] Signification
0 n n n n n n n n Valeur du registre 0 du AY (LSB de la période du canal A)
1 . . . . n n n n Valeur du registre 1 du AY (MSB de la période du canal A)
2 n n n n n n n n Valeur du registre 2 du AY (LSB de la période du canal B)
3 . . . . n n n n Valeur du registre 3 du AY (MSB de la période du canal B)
4 n n n n n n n n Valeur du registre 4 du AY (LSB de la période du canal C)
5 . . . . n n n n Valeur du registre 5 du AY (MSB de la période du canal C)
6 . . . n n n n n Valeur du registre 6 du AY (période du bruit)
7 s . n n n n n n n = valeur du registre 7 du AY (mixeur)
s = bit de poids fort de la période SID
8 n n n n n n n n Pour le canal A, selon la valeur des bit[7:5]
= %1xx, sample. Les bit[6:0] donnent le numéro du sample, sauf 0 qui indique qu'un sample est en cours
= %01m, SID de type m (utilise les bit[4:0])
= %00x, bit[4:0] est la valeur à placer dans le registre 8 du AY (volume du canal A)
9 n n n n n n n n Comme le flux 8 pour le canal B
10 n n n n n n n n Comme le flux 8 pour le canal C
11 n n n n n n n n Valeur du registre 11 du AY (LSB de la période d'enveloppe)
12 n n n n n n n n Valeur du registre 12 du AY (MSB de la période d'enveloppe)
13 n n n n n n n n Si 255, indique que le registre 13 ne doit pas être écrit
Sinon, valeur à écrire dans le registre 13 du AY (courbe d'enveloppe 8 à 15)
14 n n n n n n n n LSB de la période SID
15 n n n n n n n n Signal/Entry :
Si &00 à &7F, c'est un signal (affiché S.00 à S.7F dans la pattern)
Si &80 à &BF, c'est un point d'entrée (affiché E.00 à E.3F dans la pattern)
Si &FF, pas de signal ni entry

Pour le dernier flux “Signal/Entry” au traitement de l'export, l'idée est plutôt de ne pas garder ce flux dans les données compressées. Il est plus avantageux à la place de générer deux tables de pointeur/valeurs à part, une pour les signaux et l'autre pour pouvoir forcer des trames complètes et ainsi avoir plusieurs points d'entrée dans la musique (dont le “loop to”).

Format de fichier

Un fichier stream est composé de :

  • une signature de fichier de 5 octets : “SDST” suivi d'un octet &1A
  • 1 octet à &00 (numéro de version de format)
  • 1 octet à &20 (version du logiciel qui a créé le fichier, en BCD)
  • un chunk MHDR qui contient les informations sur le module
  • un chunk d'entête STHD
  • un chunk qui contient les données des flux : STF pour un stream full ou STD pour un stream delta
  • le cas écheant, des chunks AYL et/ou AYLA pour les samples et alias utilisés dans la musique
  • un octet &1A qui marque la fin du fichier

Un chunk commence toujours par son nom sur 4 caractères, suivi de la taille des données du chunk en 32 bits. Les valeurs sont stockées en little-endian.

Chunk "Module header"

Nom Description Contenu
MHDR Module header
Informations sur le module
4 octets : longueur du chunk
Titre de la musique (chaîne de caractères terminée par 0, taille maximum de 14+1)
Auteur (chaîne de caractères terminée par 0, taille maximum de 30+1)
Commentaire 1 (chaîne de caractères terminée par 0, taille maximum de 30+1)
Commentaire 2 (chaîne de caractères terminée par 0, taille maximum de 30+1)

Chunk "Stream header"

Nom Description Contenu
STHD Stream header
Entête
4 octets : longueur du chunk
1 octet : nombre de flux par trame (permet de déduire la taille d'une trame STF et la taille du bitmask STD)
4 octets : nombre de trames (0 si inconnu)
4 octets : numéro de la trame “loop to” (0 pour la première trame)
2 octets à 0 (réservés)

Chunk "Full stream"

Nom Description Contenu
STF Stream Full
Données des flux pour chaque trame
(tous les flux à chaque trame)
4 octets : longueur du chunk (0 si inconnu)
16 octets pour chaque trame : 1 octet par flux, en commençant par le flux 0
4 octets à &FF : marqueur de fin de stream

Chunk "Delta stream"

Nom Description Contenu
STD Stream Delta
Données des flux pour chaque trame
(uniquement les flux dont la valeur change)
4 octets : longueur du chunk (0 si inconnu)
<données des trames>
4 octets à &FF : marqueur de fin de stream

Dans un chunk STD , sont stockés uniquement les flux dont la valeur change par rapport à la trame précédente. Un bitmask indique quels flux sont renseignés dans les octets qui suivent.

Une trame est donc codée comme suit :

  • 2 octets de bitmask : 1 bit par flux (0=flux inactif ; 1=flux actif). Par convention, le bit15 correspond au flux 0
  • n octets : octet de chaque flux actif (flux 0 en premier)

La première trame (trame 0) est toujours complète.

Chunk "AY-List"

Nom Description Contenu
AYL AY-List
Sample sous forme d'AY-List
4 octets : longueur du chunk
1 octet : numéro du sample (1 à 127)
12 octets : nom du sample (chaîne de caractères de taille fixe)
<données au format AY-List>

Les samples utilisés dans la musique sont sauvés dans des chunks AYL . L'AY-List du sample doit être terminée par une instruction STOP.

Chunk "AY-List alias"

Nom Description Contenu
AYLA Alias d'AY-List
Alias de sample (offset dans un sample parent)
4 octets : longueur du chunk
1 octet : numéro de l'alias de sample (1 à 127)
12 octets : nom de l'alias de sample (chaîne de caractères de taille fixe)
1 octet : numéro du sample parent (1 à 127)
2 octets : offset dans le sample parent (valeur paire)

Les alias de samples utilisés dans la musique sont sauvés dans des chunks AYLA. Le chunk AYL du sample parent de l'alias doit avoir été rencontré précédemment.

Utiliser une musique exportée

Une fois la musique exportée, le fichier SDS créé contient toutes les données nécessaires pour rejouer la musique dans votre application. Mais avant cela une étape supplémentaire est nécessaire, il s'agit d'appliquer un algorithme de compression à la partie flux des données pour réduire sa taille. Je propose ici plusieurs méthodes.

Méthode Kit AY

Le Kit AY de Madram est prévu à l'origine pour convertir et compresser un fichier YM. Une version modifiée adaptée au format SDS “Stream Full” du Soundtracker DMA est disponible dans la section Téléchargements.

C'est un outil qui tourne sur CPC et je vous préviens, c'est très lent, soyez patient.

Lancez le fichier Basic et donnez lui le fichier SDS à traiter. Il générera :

  • un fichier OUT.AYC qui contient les flux compressés au format AYC
  • un fichier OUT.ASM qui définit la table d'adresse des AY-listes (samples)
  • un fichier OUT.AYL qui contient les AY-Listes des samples

Le source assembleur stkdma_ayc_player.asm contient le code du décompresseur et du player, il utilise les trois fichiers précédents.

Le Kit AY atteint un très bon taux de compression et la routine de décompression est très rapide, mais elle nécessite un buffer de 256 octets pour chaque flux. La quantité de RAM nécessaire à ces buffers est l'inconvénient de cette méthode.

FIXME à compléter (autre méthode)