Suite de l'aventure de construction de l'émulateur...
Arrivé à ce stade de l'écriture de l'émulateur, la partie vidéo (GA et CRTC) étant à peu près opérationnelle pour un premier usage basique, la partie gestion des fichiers K7 étant écrite, il me restait donc 2 gros morceaux à terminer avant de commencer les tests de fonctionnement de l’émulateur : L'émulation du PSG (pour le son) et celui du processeur. .
Il s’agit à mon sens des éléments minimum pour émuler le CPC 464. D'autres "modules" non essentiels mais indispensables à l'usage viendront s'ajouter un peu plus tard mais chaque chose en son temps. Un émulateur se construisant brique par brique, j'ai préféré pour ma part me focaliser sur un seul sujet à la fois, quitte à y passer plusieurs semaines/mois. Je me répète mais c'est peu de dire que la patience reste une vraie vertu sur ce type de chantier.
J’ai donc choisi de m'atteler à l'émulation de la puce sonore. Le processeur attendra encore un peu.
Sans surprise, vous l'aurez deviné, la première étape a consisté à récupérer toute la documentation disponible et notamment le dataSheet de la puce sonore équipant toute la gamme CPC, le Yamaha AY-3-8912, afin de mieux comprendre son fonctionnement interne. J'ai de la chance, il existe de nombreuses documentations techniques sur cette puce.
Comme toujours sur le papier ça n'a l'air pas trop compliqué : Le AY est doté de 14 registres qui peuvent être adressés afin de générer un son et/ou bruit sur 3 voies indépendantes, sur 15 niveaux de volume fixe ou via une enveloppe de volume prédéfinie. En plus, le son généré n'est pas une une onde sinusoïdale mais une bête onde carré. La fréquence du son dépend tout simplement d'une simple impulsion de période fixe. Cette fréquence sonore est produite par division de la fréquence d'horloge d'entrée à 1 Mhz, la fréquence allant de 62.5 kHz (1/16 Mhz, inaudible bien sûr), jusqu'à un minimum de 15 Hz env (1/16/4095, très peu audible aussi). Même si les fréquences disponibles couvrent le spectre d'audition de l'oreille humaine, elles ont l’inconvénient d'être très peu présentes dans les aigus, un peu dans les médiums et beaucoup dans les graves. Bon, pas top mais on va faire avec alors. C'est ce que a le CPC dans le ventre.
Mais vous l'aurez compris, comme toujours en émulation, si la théorie semble simple, la mise en œuvre est beaucoup moins aisée car 2 obstacles se sont rapidement présentés à moi : comment générer l'onde sonore en temps réel et comment l'envoyer vers les haut-parleurs de mon PC ?
Je me suis retrouvé exactement dans la même situation qu'avec la partie de l'affichage vidéo : Il est impossible d'adresser directement les informations à la puce sonore équipant tout PC. Pour pouvoir sortir du son, il faut encore et toujours en passer par les API système. Et sous Windows, c'est galère car il existe un gros paquets d'API sonores cohabitant ensemble et qui semblent n'être là que pour gérer la compatibilité avec les différentes versions de Windows. Entre les "Core Audio API", "DirectSound", "WASAPI" , "XAudio2" et les autres API "externes" disponibles, le choix ne manque pas. C'est un peu le bordel à vrai dire.
Au final, mon choix s'est porté sur XAudio2 qui est l'API la plus récente disponible, de bas-niveau et à faible latence, tout ce dont j'ai besoin pour produire mon onde sonore émulée. En plus cette API sait gérer de nombreux effets, comme l’ajout de filtres de fréquence qui me permettront plus tard d’affiner la qualité de l’émulation du PSG.
Je suis donc repassé d'une lecture de doc technique à la lecture des nombreux tutoriaux pour exploiter cette API...
En aparté, vous l'aurez compris, n'utilisant que des API Windows pour cet émulateur, celui-ci ne sera donc compatible que.. Windows ...et en version 10 je pense (XAudio2 n'est pas présent sur les versions antérieures il me semble)...
Reste maintenant la question de la génération en temps réel de l'onde sonore. En vérité, ça n'a pas été aussi compliqué que cela puisque j'avais déjà l'expérience de la lecture des fichiers K7 en .WAV qui contiennent également des ondes sonores "carrés".
Sur le principe, pour chacune des 3 voies, j'ai réservé une zone mémoire correspondant à la partie DATA d'un fichier virtuel WAV au format PCM (comme pour un fichier K7 en vérité), avec un baudrate de 125 kHz (nécessaire pour pouvoir gérer toutes les fréquences sonore produite par le AY).
Chacune des voies est programmée pour lire en boucle, et en tâche de fond, dans ces zones mémoires dédiées. Dès lors qu'un son doit être généré, il me suffit d'y écrire une fois toutes les 1/125.000 de seconde les impulsions correspondant à la fréquence sonore désirée et ..c'est tout. ça ne prend quasiment rien en ressource CPU et le résultat marche plutôt pas mal... voire même très bien sur les derniers tests que j'ai faits.
En vérité, j'ai quand même buté sur 2-3 trucs énervants lors de la mise au point de l'émulation de la puce sonore dont un pas encore complètement résolu à ce jour.
- Le premier point est l'apparition de temps en temps d'un grésillement sur le son produit. Un son pas propre. J'ai mis longtemps à comprendre que cela était dû au fait que l'API lisait les données à l’endroit approximatif où je les écrivais à ce même moment. Le son étant joué en continue, la lecture et écriture du son étant à la même vitesse, l'API jouait un son en cours de construction et générait un son bizarre.
- Le deuxième point a été la génération de l'onde pseudo-aléatoire du générateur de bruit du AY. Tout comme pour le calcul du CRC des fichiers K7, la recherche de l'algorithme mathématique permettant de générer ce "bruit" a été fastidieuse et au final, sachant que cela dépassait mes compétences mathématiques, j'ai repris un bout de code de 5-6 lignes trouvé sur internet (celui de l'Atari ST je crois, les puces sont similaires). Je ne sais pas si le son produit est exactement celui du CPC mais à l'oreille il n'en semble pas loin.
- Le troisième point n'est pas encore parfaitement résolu : le AY a la particularité de laisser le volume à un niveau constant lorsqu'une des voies sonores est éteinte. Un problème gênant apparait lorsque le niveau du volume varie dans ces conditions, un "claquement" sonore est émis lors de la transition, traduisant ce brusque changement de volume...Sur certaines démos jouant de la musique en exploitant cette propriété, on entend distinctement ces claquements à intervalles réguliers...J’arrive à les atténuer en lissant les transitions mais ce n’est pas parfait encore. Sujet en cours donc. Wait & See.
Enfin dernier point galère pour les tests : comment savoir si le son restitué est identique à celui produit par un vrai CPC... car il est beaucoup plus dur de comparer un son qu'une image. Dans ce cas, j'ai fait de l'empirique : J'ai écouté des sons simples sur YouTube produits par un vrai CPC et comparé à l'oreille ceux produits par l'émulateur.. Fastidieux mais nécessaire pour être sûr que le son de l'émulateur ressemble au vrai son d'un CPC.
Enfin, tout bon ouvrier devant avoir de bons outils, pour m'aider à accélérer la mise au point de l'émulation du PSG , j'ai crée un petit outil de test sur mesure qui m’a bien facilité les choses.

Petit bonus, j’ai ajouté la gestion de la stéréo : je ne sais si c’est exploité en vrai mais c’est géré...
Ainsi se termine ce long post consacré à l'émulation de la partie sonore du CPC. Une bonne chose de faite.
Dans le prochain post j'aborderai le plus gros morceau : l'émulation du CPU...Plusieurs milliers de ligne de code. Le coding en mode T-States se paye très cher !!!
