Analyse Audio sur CPC: le Volume

Maintenant que nous savons utiliser un player audio, il est temps d’en venir à l’analyse de l’audio. Pour cela, nous allons aller lire à chaque trame vidéo l’état d’un ensemble de registres du PSG8912, le composant audio de l’Amstrad CPC. Je ne vais pas donner ici le détail de tous les registres,  je vous renvois vers des articles de MadRam qui est complet sur le sujet. Il y décrit comment récupérer les volumes des 3 voies audio, mais aussi la fréquence des notes jouées. Je vais largement m’en inspirer dans la suite.

Commençons par le Volume des 3 canaux. Je reproduis ici la fonction de lecture d’un registre du PSG de l’article d’AmsLive:

Cette fonction prend le numéro de registre à lire dans l’accumulateur, et renvoie la valeur du registre.

Les registres 8,9 et 10 du PSG correspondent au volume de chaque canal A,B et C, codé sur 4 bits. Voici un bout de code pour lire les 3 valeurs 4 bits (0-15), et en faire la somme, et stocker le tout dans un tableau pointé par IX:

Visualisation

Nous allons faire une macro très simple, qui affiche un segment en deux couleurs. Le code n’est pas particulierement optimisé, et utilise la encore IX pour récuperer les données:

Maintenant, pour afficher les 4 segments (A,B, C, A+B+C/4), on définit et utilise une macro DRAWVOL de la sorte:

Calcul des attaques

Le volume en tant que tel ne nous est pas tres utile pour une jeu de rythme. Ce qui va nous intéresser pour rythmer le jeu, ce sont les attaques,quand le volume augment rapidement. On va donc s’intéresser a la variation instantanée du volume de chacune des pistes. Pour cela on va faire la différence trame à trame des valeurs mesurées. Quand cette différence est positive, le volume à augmenté, on a affaire à une attaque.

Pour commencer, on  va définir quelques variables, apres notre section de code:

Nous pouvons maintenant initialiser IX, mais comme on a besoin de comparer les valeurs trames a trame, on va en profiter pour initialiser IY, de facon a ce que ce derniere pointe sur le buffer contenant les valeurs de la trame précédente. On met ainsi en place un double buffering, basé sur la parité du numéro de trame, que l’on a incrémenté au passage:

Maintenant que IX et IY pointent sur leurs buffers respectifs:

Ca manque de rasters

Mais on ne va pas s’arrêter en si bon chemin. Nous allons visualiser les donnés, en les affichant sur plusieurs trames, et en les faisant défiler verticalement. Le tout a l’aide de rasters, en commutant une couleur 3 fois par ligne vidéo, pour chaque canal audio.

Pour cela, on commence par définir quelques constantes, pour accéder au composant Gate Array, définir quelques couleurs et palettes.

Ensuite on se munit de 3 tableaux pour stocker l’historique des données, converti en couleur. Pour des raisons de commodité, les 3 tableaux seront de taille 256 (soit 256/50 = 5,12 secondes), et mis bout a bout (pas d’entrelacement), en veillant à bien aligner les buffers sur une adresse dont le poids faible est nul (ici 0x9000):

Apres chaque calcul des attaques, on injecte des données dans le buffer, après les avoir passé a travers une LUT (une palette).

Enfin, le raster a proprement parler. On attend deux interruptions (HALT) pour placer le raster au milieu de l’écran:

Pour animer le tout, on incrémente l’index général:

Le code source complet, ainsi que le binaire compilé se trouvent la. Le dsk pret a l’emploi se trouve ici. Le résultat en vidéo:

Dans les parties suivantes, nous allons réutiliser les données calculées pour synchroniser affichage et musique.

Références