This page is at least 8 years old !
Régler le volume
Une fois que la fréquence peut être choisie, on peut aussi vouloir régler le volume sonore.
Comme la sortie OSC de notre générateur de fréquence n'est qu'un signal binaire (0 ou 1), il n'est pour l'instant possible que d'avoir le silence absolu, ou le volume le plus élevé. Il faut donc transformer cette sortie en un bus, pour obtenir un réglage plus fin. Prenons un bus 4 bits, permettant 2^4 = 16 réglages de volume possibles.
Comme on souhaite rester dans le domaine numérique le plus longtemps possible, on n'a pas besoin de considérer le fait qu'un signal audio doit être (le plus souvent) centré sur 0, c'est à dire avoir -0.5/0.5 au lieu de 0/1. Le circuit analogique en dehors du soundchip s'occupera de ce centrage. Ceci nous permet de garder des nombres positifs et de simplifier encore la logique.
Pour ajouter le réglage du volume, on peut ajouter un nouveau registre 4 bits appelé "VOL" et utiliser un multiplexeur. Lorsque la sortie du diviseur de fréquence OSC (toujours binaire) est à 0, la nouvelle sortie OUT 4 bits est à 0 (silence), et lorsqu'elle est à 1, la valeur contenue dans VOL est donnée.
Le multiplexeur permet de basculer entre 0 et la valeur de VOL à la fréquence de OSC.
reg [2:0] CNT; reg [3:0] VOL; wire [3:0] OUT; assign OUT = OSC ? VOL : 4'b0000; always @(posedge MCLK) begin if (CNT) CNT <= CNT - 1'b1; // Decrementer si > 0 else begin CNT <= HPERIOD; // Reload OSC <= ~OSC; // Inversion sortie end end
On voit que OSC est toujours un signal binaire à la fréquence désirée, et que OUT est fixé à la valeur de VOL que lorsque OSC est à 1.
A noter que comme OUT est maintenant en logique combinatoire, si VOL change alors que OSC est à 1, OUT changera aussi instantanément.
VOL pourrait aussi être configuré par un CPU externe.
Le volume est ajusté "par le haut", mais comme indiqué, ça ne pose aucun problème pour l'équipement audio après centrage.
On en est là:
Volume et intensité sonore
Certains sourcilleront à propos du fait que le volume est ici réglé linéairement, alors que la perception humaine du volume sonore est plutôt exponentielle.
Beaucoup de soundchips primitifs ignoraient simplement ce fait, et produisaient en effet des variations de volume linéaires. Elles pouvaient cependant être adaptées par le CPU en utilisant une table qui "exponentialisait" la valeur avant de l'envoyer au soundchip, mais cela posait un problème de résolution dans les valeurs hautes, pour le coup similaire à celui de la fréquence.
En effet, une progression linéaire sur 4 bits donnerait: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 (16 valeurs).
Une progression exponentielle pourrait donner par contre 0, 1, 1, 2, 3, 5, 7, 10, 17, et au delà... Avec seulement 9 valeurs qui tiennent sur 4 bits, et deux petites valeurs indiques (1).
Les soundchips tout-numérique plus récents utilisaient une table interne sur un nombre de bits plus important, permettant de conserver un bus étroit avec le CPU tout en permettant d'ajuster le volume de façon plus naturelle. De nombreux soundchips avec une section analogique intégrée profitaient de la construction de leur DAC pour produire cette courbe sans besoin de table.
Une telle conversion par table peut se faire comme suit, avec par exemple un réglage du volume sur 3 bits ("VOL_LIN"), et une sortie exponentielle sur 4 bits ("VOL_EXP"):
wire [2:0] VOL_LIN; wire [3:0] VOL_EXP; assign VOL_EXP = (VOL_LIN == 3'd0) ? 4'd0 : (VOL_LIN == 3'd1) ? 4'd1 : (VOL_LIN == 3'd2) ? 4'd2 : (VOL_LIN == 3'd3) ? 4'd3 : (VOL_LIN == 3'd4) ? 4'd5 : (VOL_LIN == 3'd5) ? 4'd7 : (VOL_LIN == 3'd6) ? 4'd10 : 4'd15;
La différence s'entend:
Pour des tables bien plus grandes, on peut considérer l'utilisation de mémoire synthétisée. Il existe différentes options selon les marques.
On peut ignorer ce souci pour l'instant, intégrer la solution plus tard ne posera pas de problème (prévoir un peu de place dans le CPLD si besoin).