Génération Audio par expression mathématiques

Je suis récemment tombé sur ces deux vidéos, qui consistent à générer du son/de la musique à partir d’expressions mathématiques somme toute simples, en regard du résultat obtenu. Je vous laisse juger:

Ce n’est pas une technique nouvelle, elle est utilisée par exemple par des démomakers pour des productions de taille très réduite. Quelques références pour commencer. Tout d’abord ce site qui permet d’essayer interactivement ses propres formules: http://entropedia.co.uk/generative_music/

Ensuite un guide pour comprendre comment façonner ses formules, en procédant par étapes: http://canonical.org/~kragen/bytebeat/

Enfin, un site qui référence des librairies et projets autour de ce principe: https://wiki.shackspace.de/doku.php?id=project:algorithmicsoundscapes

Et sur Amstrad CPC?

Il se trouve que cette méthode n’a pas particulièrement été mise en oeuvre sur Amstrad CPC. Je propose ici une expérimentation simple et rapide, pour évaluer la possibilité d’utiliser ce type de formules sur ces machines. Nous allons utiliser RASM pour assembler le code, mais aussi et surtout pour effectuer l’évaluation des formules.

Mais au préalable, il faut se remémorer le fonctionnement du composant audio sur le CPC, le AY8912. Pour cela, rien de tel que la page dédiée sur le site du quasar. Ce que l’on va faire ici, c’est faire varier le volume de l’un des trois canaux (le A) en envoyant des données en permanence, à intervalle régulier. Pour manipuler les registres, on va se munir d’une macro:

Ensuite on va activer le canal A, en utilisant le registre 7 du PSG, et ensuite envoyer en continu les données contenues dans un buffer (ici situé de #4000 à #7FFF) et écrivant dans le registre 8 du dit composant:

Il reste a remplir le buffer, et c’est la que l’on va pouvoir utiliser des expressions mathématiques. Elle seront interprétées par RASM. Rappelons que les volumes sont exprimés par des valeurs sur 4 bits, donc de 0 à 15. Il faut donc veiller a rester dans cet intervalle quand on écrit dans les registre 8,9 et 10.

Et c’est tout! Bien que le code soit très court, le binaire produit sera assez gros au final (environ 20Kb). Mais il permet de tester assez rapidement des expressions mathématiques si on utilise un émulateur. On pourra par exemple ex&cuter ce programme une première fois, et ensuite de changer l’expression mathématique, recompiler et glisser le binaire sur la fenêtre de l’émulateur (comme winCPC ou javaCPC) et cela modifiera le son produit, puisque seul le buffer audio aura été modifié, le programme restant identique.

Exemples

Quelques sons en guise d’exemple, produits avec cette méthode, enregistrés sur émulateur:

Evolutions

Bien sûr, dans la pratique si on veut faire un programme très court, il faudra écrire l’expression mathématique en assembleur de façon a générer le buffer audio durant le runtime.

De plus, une spécificité du chipset audio est que l’échelle du volume audio n’est pas linéaire mais logarithmique. En conséquence, les différences entre les volumes faibles sont tres subtiles, alors que les valeurs élevées sont plus tranchées. Donc on peut simplifier le signal en se limitant aux valeurs 0, 13, 14 et 15, ce qui peut s’encoder sur 2 bits. On gagne ainsi un facteur 4 dans le stockage des données, ce qui est loin d’être négligeable.

Enfin, il est a noter que l’on peut jouer sur la fréquence du son émis en modifiant la durée de la temporisation dans la boucle principale. Ici il y a 65 nops, de facon a ce que la boucle prenne 2 lignes de balayage écran. On pourra en guise d’exercice moduler cette durer de facon à jouer des notes. Et bien sur, il reste deux autres canaux, ainsi qu’un générateur de bruit qui ne demandent qu’à être utilisés!

Un merci a Roudoudou et Tronic pour m’avoir aiguillé pour l’écriture de ce billet.