PROGRAMMATION D'UNE CARTE COMPATIBLE SOUND BLASTER


Sommaire

I.Généralités

II.Le DSP

III.Le DMA

IV.L'IRQ

V.La table de mixage

VI.Remerciements

 

Retour au sommaire

I.Généralités

Comment programmer la sound blaster ? Bonne question. Assez vaste, d'ailleurs. Ici, on ne va s'occuper que des sons digitaux, c'est-à-dire l'échantillonage, et pas la synthèse FM (comme les fichiers MIDI ou MOD &), ni l'utilisation du lecteur CD à travers la carte son. Toutes les commandes décrites sont tout à fait compatibles Sound Blaster. Je ne parlerais pas d'autres cartes ici, comme la Gravis Ultra Sound, qui se programme différemment. Il vaut donc mieux que vous lanciez le programme de test qui se trouve sur le site pour tester la compaptibilité de votre carte son si vous n'êtes pas sûr d'elle.

Autre chose : les cartes Sound Blaster n'en sont pas restées au même point depuis leur création, et à chaque version correspond un DSP différent. Il y a eu les Sound Blaster (DSP version 1.xx), les Sound Blaster 2 (DSP v. 2.xx), les Sound Blaster Pro (DSP v.3.xx) et les Sound Blaster 16 (DSP v.4.xx). Les Sound Blaster 32 et plus récentes changent surtout au niveau de la qualité, des fonctions Windows ou autres modes Dolby Digital, et se programme donc de la même façon qu'une Sound Blaster 16. Les DSP 1 et 2 n'ont pas beaucoup de différences, mais la version 3 inclut le mode High Speed, qui permet une fréquence d'échantillonage plus importante, et une table de mixage plus évoluée. Quand à la version 4, et inclut une table de mixage évoluée et la gestion de tous les modes (8/16 bits, 5000-48000 Hz, mono/stéréo), en seulement deux commandes, ce qui rend donc le mode High Speed obsolète, ce qui fait que ce mode n'est en fait présent que dans la version 3. Vous avez donc 2 solutions pour gérer la carte son : soit vous faire chier à supporter chaque version avec ses limites, soit ne supporter que la version 4, qui est après tout répandue partout et beaucoup plus simple. Vous devinerez évidemment quel parti j'ai pris. Néanmoins, pour les plus puristes (ou pour ceux qui n'ont qu'une vieille SB Pro, n'est-ce pas Kéké ?), je mettrais en annexe la liste de toutes les vieilles fonctions des précédentes versions.

Bon, revenons à nos moutons : comment programme-t-on cette putain de carte son ?
Pour synthétiser des sons, la carte utilise un processeur, le DSP (Digital Sound Processing), le gros boss de la carte son. C'est lui qui s'occupe de tous les transfert et les conversions. Et c'est lui que l'on programme pour enregistrer ou lire un son, via les ports. Globalement, c'est pas très dur : on dispose de 2 commandes, une qui sort un échantillon 8 bits sur les haut-parleurs, et l'autre qui en renvoie 1 à partir du micro. Donc pour lire ou écrire un son, il suffit de répéter un certain nombre de fois ces fonctions. Mais pour lire un son de 44KHz, il faudrait répéter la fonction de lecture 44000 fois par seconde, ce qui est impossible, même si votre processeur tourne à 500MHz, puisque la vitesse du bus et de la carte son ne le permet pas. Et en plus, il faudrait tout le temps faire une boucle pour jouer un son, ce qui est un peu con dans un jeu.

On ne peut donc avec ces fonctions que lire ou écrire des échantillons de piètre définition. Pour opérer correctement, on est donc obligé de passer par le DMA (Direct Memory Access), qui s'occupera tout seul de la lecture (ou l'écriture) des échantillons dans la mémoire à la demande du DSP, ce qui permet d'atteindre une résolution de 48KHz stéréo 16 bits, et en plus de libérer le processeur pour faire d'autres choses, puisqu'il suffit de lancer le DMA et ensuite il se débrouille tout seul. Ce document est donc divisé en plusieurs parties :

Hein ? Pourquoi l'IRQ ? Hé ben tu verras bien, on n'est pas pressé !

Retour au sommaire

II.Le DSP

Le DSP se contrôle via les ports. Communément, la carte se trouve sur le port 220h. Mais son adresse peut varier entre 210h et 280h. Ici, nous prendrons donc toujours comme addresse de base 2x0h, où x représente un chiffre variable, et puis en plus tout le monde fait pareil.
Le DSP possède 5 registres :

Adresse

Nom

Lecture

Ecriture

Description

2x4h

Port d 'adresse de la table de mixage

 

X

Envoyer ici le numéro de port de la table de mixage à lire ou écrire

2x5h

Port de données de la table de mixage

X

X

Ici on entre ou on lit les données du port

2x6h

Reset

 

X

Réinitialise le DSP

2xAh

Read Data

X

 

Pour lire les données envoyées par le DSP

2xCh

Write Command

 

X

Pour envoyer des commandes au DSP

Write Data

et lui transmettre des données

Etat du registre Write

X

 

Pour savoir si le DSP est au bout du fil

2xEh

Etat du registre Read

X

 

Pour savoir si le DSP a envoyé des données

IRQ 8 bits

ou pour lui dire que l'IRQ 8 bits est bien arrivé

2xFh

IRQ 16 bits

X

 

Pour lui dire que l'IRQ 16 bits est bien arrivé

Principe du contrôle du DSP :

Envoi de données :

On envoie la commande (ou fonction) désirée au DSP via le port Write Command. Mais il faut d'abord savoir s'il est prêt à recevoir la commande en testant ce même port (puisque registre Write Status=registre Write Data) : tant que le bit 7 est à 1, le DSP est occupé, en train de traiter la commande précédente. Sinon, il est prêt à écouter ce que vous avez à lui dire. Sinon, hé ben on recommence à tester le port Write Command ! Si on doit aussi lui transmettre des données, on envoie d'abord le code sur le port Write Command, puis les données sur ce même port (puisque Write Data=Write Command), dans l'ordre définit par la fonction, en vérifiant toujours que le DSP est prêt à les recevoir. On résume :

Tant que bit 7 du Port[2xCh]=1 : Attendre ;
Dès que bit 7 du Port[2xCh]=0 : Port[2xCh] = commande ;
Si données à envoyer en plus, refaire la même chose depuis le début mais en remplaçant la commande par les données à envoyer.

Lecture de données :

Le principe est exactement le même, sauf qu'on teste si le DSP a envoyé les données avec le port Read Data Status 2xEh et on les lit sur le port Read Data 2xAh. Attention : ici, c'est lorsque le bit 7 du port 2xEh est à 1 que les données ont été envoyées !

Les fonctions du DSP :

Après avoir vu comment on envoyait des commandes au DSP, voyons quelles sont ces commandes :

Reset du DSP :

On doit toujours commencer par initialiser le DSP avant de la programmer. On procède de la manière suivante :

Port[2x6h] =1 ;
Attendre env. 3 microsecondes ;
Port[2x6h] =0 ;
Si Port[2xAh]==0AAh (ne pas oublier d'attendre que le DSP ait envoyé les données, via le port 2xEh), le DSP est correctement initialisé.

Un truc : on peut comme ça tester le port de base de la Sound Blaster, mais y a un problème : si le canal est mauvais, on risque d'attendre plutôt longtemps que le registre Read Data Status dise que la réponse est disponible. Il faut donc faire une petite boucle limitée du genre (au hasard) LOOPNE et comme ça on sait tout de suite si le port choisi est bon.

Connaître le n° de version du DSP :

C'est pratique de savoir si la version du DSP est bien conforme à celle qu'on est sensé utiliser. Pour le savoir, on exécute la commande E1h, qui renvoie sur le regsitre Read Data le numéro de version principal, puis le numéro secondaire

Fréquence d'échantillonnage :

Avant la version 4, il fallait faire un calcul savant pour savoir quoi dire au DSP, via la fonction 40h. Maintenant, on envoie directement la fréquence en Hz à la fonction 41h (sortie) ou 42h (entrée), en envoyant d'abord l'octet de poids fort puis l'octet de poids faible. Les valeurs sont comprises entre 5000 et 44100 Hz.

Activer / désactiver les haut-parleurs :

Il vaut mieux vérifier que le lien entre la carte son et les haut-parleurs est présent avant de jouer un son sinon on risque fortement de s'arracher les cheveux en se demandant pourquoi ça marche pas. La fonction D1h active le lien Carte son-HP tandis que la D3h le désactive. Pour tester le lien, on peut utiliser la fonction D8h qui renvoie sur le Read Data un octet qui vaut 0FFh si le lien est présent, ou 00h s'il n'y en a pas.

Déclenchement du transfert :

Enfin, quand vous avez bien tout paramétré tout ça, préparé le DMA et détourné l'IRQ, vous pouvez lancer le transfert en envoyant au DSP la commande Byh ou Cyh. y varie suivant le mode d'échantillonnage (j'ai mis y au lieu de x pour pas qu'il y ait de confusion avec le port de base). Ces fonctions sont beaucoup plus pratiques que la vingtaine de fonctions différentes selon que l'on est en 16 ou bits, stéréo ou mono, entrée ou sortie & Ici, on utilise juste Bxh pour un transfert 16 bits, et Cxh pour 8 bits. La structure des deux commandes est la même et se présente comme ceci :

Structure du premier octet de commande

Bits

7

6

5

4

3

2

1

0

 

Valeurs

 

 

 

 

 

 

 

0

 

 

 

 

 

 

 

1 = FIFO activé / 0 = FIFO désactivé

 

1 = Auto-Init / 0 = pas d'Auto-Init

 

1 = Entrée (enregistre) / 0 = sortie (joue)

 

B = 16 bits / C = 8 bits

Après la commande, le DSP réclame un deuxième octet, déterminant si le transfert est codé en nombres signés ou pas :

Structure du deuxième octet de commande

Bits

7

6

5

4

3

2

1

0

 

Valeurs

0

0

 

 

0

0

0

0

 

 

 

 

 

1 = signé

 

1 = non signé

On envoie enfin une troisième valeur qui détermine le nombre d'échantillons (16 bits pour Byh, 8 bits pour Cyh) à jouer au format word, en envoyant en premier l'octet de poids faible. Et voilà, normalement ça joue le son. N'oubliez pas de paramétrer d'abord le DMA et le gestionnaire d'interruption.

 

Retour au sommaire

III.Le DMA

Sur les PC/AT (c 'est-à-dire les nôtres), il y a deux contrôleurs DMA : un maître et un esclave. Le maître contrôle les canaux 5 à 7 et l 'esclave les canaux 0 à 3. Le canal 4 est utilisé par le maître pour transmettre les commandes aux canaux inférieurs à 4 à l 'esclave par un procédé appelé "cascade". On contrôle l 'esclave via les ports 08h à 0Fh et le maître via les ports 0D0h à 0DEh.

Description des canaux DMA :

Canal

Contrôleur

N°DMA

Utilisation habituelle

0

Esclave

0 (00)

RAM-Refresh

1

Esclave

1 (01)

Lecteur disquettes

2

Esclave

2 (10)

Libre, souvent SB

3

Esclave

3 (11)

Lecteur disque dur

4

Maître

0 (00)

Cascade Maître è Esclave

5

Maître

1 (01)

Libre, souvent SB

6

Maître

2 (10)

Libre

7

Maître

3 (11)

Libre

Les registres du DMA sont les suivants :

Registre

Port (maitre)

Port(Esclave)

Accès

Status

D0h

08h

Read

Commande

D0h

08h

Write

Requête

D2h

09h

Write

Masque 1

D4h

0Ah

Write

Mode

D6h

0Bh

Write

FlipFlop

D8h

0Ch

Write

Mem temp

DAh

0Dh

Read

Reset

DAh

0Dh

Write

Reset de masque

DCh

0Eh

Write

Masque 2

DEh

0Fh

Write

Description des registres :

Le registre Status permet de savoir quels requêtes et quels TC (Terminal Count = fin de transfert) sont activés. Il ne nous intéresse pas ici.

Le registre Commande permet de paramétrer de quelle façon se font les requêtes. Toutes les valeurs doivent être laissées par défaut, donc on n 'y touche pas. De plus, il a l 'inconvénient de ne pas être lisible (si on le lit on récupère le status), donc on ne connaît pas les paramètres effectifs.

Le registre Requête permet de simuler une requête matérielle par logiciel. On ne s'en sert pas non plus.

Le registre Masque 1 nous sert parce qu 'on doit inhiber le canal sur lequel on va travailler avant d 'y toucher pour éviter de mettre les couilles dans l 'engrenage. Après toutes les opérations, on devra ensuite bien sûr le démasquer, pour qu'il soit opérationnel.

Structure du registre Masque 1

Bits

7

6

5

4

3

2

1

0

 

 

Valeurs

0

0

0

0

0

 

 

 

 

 

 

 

N° DMA

 

1 = Masquer le canal / 0 = Démasquer

Le registre Mode est aussi important car il permet de déterminer le sens du transfert, l 'auto-init, le mode &

Structure du registre Mode

 

Bits

7

6

5

4

3

2

1

0

 

 

 

Valeurs

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

N° DMA

 

 

Type de transfert :
00 = vérifier (utilisé pour le RAM-Refresh)
01 = écrire (périphérique vers mémoire)
10 = lire (mémoire vers périphérique)

 

 

1 = Auto-Init / 0 = pas Auto-Init

 

 

Sens de lecture : 0 = Incrémeter l'adresse / 1 = Décr.

 

 

Mode de transfert :
00 = à la demande
01 = unique
10 = en bloc
11 = en cascade

Quelques précisions sur le mode Auto-init :

Pout mettre au point clairement les choses, on va prendre un petit exemple : imaginez que vous programmez un jeu en utilisant la carte son, puisque vous venez de tout apprendre dans ce merveilleux et complet document (restons modestes) : vous décidez donc d'y incorporer des sons 16 bits stéréos à 44100 Hz, histoire de faire bien. Ca fait donc 4 octet par bloc, à 44100 blocs par seconde, c'est-à-dire environ 172 Ko par seconde de son.
Outre que ça prend un peu de place, il y a un autre problème, plutôt gros : le DMA étant une relique de l'antiquité, il ne travaille que sur des blocs de 64Ko max, ce qui fait un peu juste pour y mettre 170Ko : même en serrant très fort, ça va avoir du mal à rentrer. Alors, la solution ? Hé bien je suis sûr que vous vous êtes dit, en programmeur averti : "pas compliqué : je place les 64 premiers Ko dans un buffer, que je fait jouer par la carte, et ensuite, dès qu'elle a finit, j'y met les 64 Ko suivants, je réinitialise le DMA et je refais jouer le DSP, etc...".
C'est bien ! vous êtes très fort ! Mais seulement, il y a plus simple : il suffit de programmer le DMA et le DSP en mode Auto-Init. Dans ce mode, le DMA se réinitialise automatiquement dès qu'il arrive à la fin du bloc, tandis que le DSP joue continuellement le son : en gros, le son est répété indéfiniment. On peut donc utiliser ce système en raifraichissant le buffer à chaque fois qu'il a été lu. La seule question est de savoir comment il a finit d'être lu. Et la réponse se trouve au chapitre suivant, sur l'IRQ

Quelques précisions sur le mode de transfert :

Le DMA transmet (ou écrit) les données dans la mémoire à la demande du périphérique qui lui est relié, via la ligne DREQ. Il y a donc plusieurs façon de lui envoyer ces données : soit elles sont envoyées tant que cette ligne est à 1 (mode "à la demande"), soit le DMA envoie un octet à chaque fois que cette ligne passe à 1, c'est-à-dire est activée sur front montant (mode "unique"), soit le DMA balance carrément tout le bloc lorsque DREQ passe à 1 (mode "en bloc"). Dans le cas de la carte son, c'est la carte qui demande au DMA un octet chaque fois qu'elle en a besoin : on utilise donc toujours le mode unique.

Nous allons voir l'utilité du registre Flip-Flop un peu plus bas

Le registre Mem Temp ne nous sert à rien, tout comme les registres Reset et Reset de Masque, qui ne doivent pas être utilisés. Quant au registre Masque 2, il a la même fonctionnalité que le registre Masque 1, mais est programmé différemment. Comme on sait programmer le 1, on n'a pas besoin du 2.

Transmission de la taille et de l'adresse du bloc au contrôleur DMA :

En effet, même s 'il sait par où et de quelle façon transférer les données, le DMA ne sait toujours pas leur taille et leur emplacement. Il faut donc le lui dire. Pour cela, on envoie ces informations aux ports suivant ce tableau :

Canal DMA

Addresse de début

Longueur du bloc

Lower Page

Upper Page

0

00h

01h

87h

487h

1

02h

03h

83h

483h

2

04h

05h

81h

481h

3

06h

07h

82h

482h

4

C0h

C2h

8Fh

???

5

C4h

C6h

8Bh

48Bh

6

C8h

CAh

89h

489h

7

CCh

Ceh

8Ah

48Ah

 L 'adresse du bloc est un nombre de 28 bits qui permet d 'adresser jusqu 'à 256Mo. Elle est divisée en deux parties : l 'offset (16 bits inférieurs) et la page (12 bits supérieurs). Sa valeur est aisément calculable par 16*seg(adresse) + ofs(adresse).
Mais un port ne peut recevoir qu 'une valeur 8 bits, et l 'adresse est une valeur 28 bits ! Il faut donc encore passer par une astuce conne, à savoir mettre à zéro le Filp-Flop, puis envoyer l 'octet de poids faible puis l 'octet de poids fort de l 'offset dans le registre d 'adresse de début correct (voir tableau ci-dessus). Quand à la page, il faut l 'envoyer dans d 'autres ports : on envoie d 'abord au registre Lower Page les 8 bits inférieurs de la page, puis au Upper Page les 4 derniers bits (ouf !).
Note : après expérimentation, il s'avère que le registre Upper Page ne sert apparemment à rien, et il n'est d'ailleurs pas mentionné dans toutes les docs. Le DMA ne va donc que jusqu'à des adresses de 16 Mo max.

On a enfin donné l 'adresse au DMA. Reste maintenant à lui donner la taille du bloc, qui n 'est codée que sur 16 bits (ce qui limite malheureusement à 64Ko la taille du buffer). Ici, il suffit de mettre à zéro le Flip-Flop, puis d 'envoyer l 'octet de poids faible, puis l 'octet de poids fort au registre aquédat (voir plus haut).

Petite précision sur l'utilité du registre Flip-Flop :
Ce registre sert à initialiser une bascule interne pour séléctionner l'octet de poid faible / octet de poid fort des registre 16 bits (adresse de début,longueur ...). En effet on ne peut pas lire ou ecrire directement des valeurs de 16 bits dans ces registres. Il faut écrire d'abord 0 dans le registre Flip-Flop pour indiquer qu'on va écrire le poid faible du mot (16 bits) : on écrit ensuite l'octet de poid faible (8 bits inferieurs) dans le registre. A ce moment le registre Flip-Flop bascule automatiquement pour permettre d'écrire le poid fort. On inscrit donc l'octet de poid fort dans ce registre. Remarque : le Flip-Flop bascule sur le pois faible à nouveau, ce qui permet d'écrire l'adresse puis la longueur (ou vice-versa) à la suite en ne l'utilisant qu'une fois.

Attention :
Certains contrôleurs DMA, ayant été fabriqués par des pines, ne peuvent pas sauter les segments, c'est-à-dire que s'ils arrivent à 000C:FFFF, ils ne passeront pas à 000D:0000, mais à 000C:0000. Chez moi, ça ne le fait pas, mais il parait que c'est aussi influencé par la présence d'un driver EMS. Bref, l'info est à vérifier. Soyez vigilant.

Voilà, vous savez tout comment faire. Rapellons qu' il faut :

Masquer le canal DMA - registre Masque 1 ;
Spécificer le mode de transfert - registre Mode ;
Donner l 'adresse du buffer (offset + page) - registre Flip-Flop ;
Donner la taille du buffer - registre Flip-Flop ;
Libérer le canal DMA - registre Masque 1.

Remarque : vous n'êtes pas du tout obligé de suivre cet ordre (mis à part le masquage, bien sûr). L'essentiel est d'avoir fourni toutes les infos au DMA.

Effectuer un transfert 16 bits

Pour les sons codés sur 16 bits, on procède exactement de la même manière que pour les sons 8 bits. Les canaux DMA 16 bits sont ceux du maitre (4 à 7), tandis que les canaux 8 bits sont les canaux 0 à 3. La carte son dispose d'un canal 16 bits et d'un canal 8 bits : il suffit donc de preogrammer le bon canal pour avoir une sortie 16 ou 8 bits. En fait, la grosse différence est que l'adresse et la taille des données sont codées en words pour le transfert 16 bits et en octet pour le transfert 8 bits. Pensez donc à diviser par 2 ces 2 valeurs avant de les envoyer au controleur DMA.

Remarque : sur certaines cartes, il faut initialiser les deux canaux pour avoir un transfert 16 bits.

 

Retour au sommaire

IV.L'IRQ

L'IRQ : quoi qu'est-ce ?

Comme vous devez le savoir, les programmes sur PC sont composés d'instructions et d'interruptions. Les interruptions qui composent les programmes sont en fait les interruptions logicielles, car il existe aussi des interruptions matérielles, qui sont, comme leur nom l'indique, générées par le matériel. La plus connue est l'interruption clavier, qui informe le PC qu'une touche a été enfoncée, ce qui évite au processeur d'aller tout le temps voir ce qui s'y est passé (d'autant plus qu'il ne s'y passe presque jamais rien). Pour gérer ces interruptions, les PC sont équipés de 2 contrôleurs d'interruptions, ou PICs (Programmable Interrupt Controller), gérant chacun 8 interruptions. On ne peut donc avoir que 16 interruptions max. En général, le PIC sert à déclencher l'interruption logicielle associée à l'IRQ activée (IRQ = Interrupt Request = interruption matérielle).Bon d'accord, mais qu'est-ce que cette connerie d'IRQ vient foutre là ? Hé bien elle sert à nous simplifier la vie, puisque lorsque le DSP a terminé le bloc que vous lui avez soumis, elle vous le dit en activant l'IRQ déterminé par la config.

Voici les correspondances entre n°IRQ et interruption :

IRQ

Interruption

0

08h

1

09h

2

0Ah

3

0Bh

4

0Ch

5

0Dh

6

0Eh

7

0Fh

8

70h

9

71h

10

72h

11

73h

12

74h

13

75h

14

76h

15

77h

Si je vous dit ça, c 'est pas pour des prunes. En effet, si cette interruption est bien pratique pour le mode Auto-Init lorsqu 'on a plus de 64Ko à jouer, elle ne sert pas à grand chose en mode Single Cycle. Mais elle doit obligatoirement être gérée, même en mode Single Cycle. Pourquoi ? Hé bien tout simplement parce que lorsque le DSP a balancé l 'interruption, il attend un accusé de réception ' : il faut donc toujours lui envoyer son accusé de réception, même si on s 'en fout.

Nous devons donc détourner l 'interruption concernée, et inclure dans la nouvelle interruption l 'envoi de l 'accusé, avec en plus la gestion du mode auto-init si on veut gérer les sons de plus de 64Ko.

Bon, en clair, comment on l 'envoie ce putain d 'accusé ? Hé ben tout connement en effectuant une lecture du regsitre IRQ (voir tableau du DSP) 8 bits si c 'est la fin d 'un transfert 8 bits, et du registre IRQ 16 bits si c 'est la fin d 'un transfert 16 bits.

Note : IRQ 16 bits ne veut pas dire que ce registre est un registre de 16 bits, mais qu 'il sert à gérer l 'IRQ pour les transfert 16 bits.

Normalement, vous savez si vous avez déclenché un transfert 16 bits ou 8 bits, donc ça ne pose pas de problèmes. Mais si vous ne savez pas, il existe une technique pour connaître le mode de transfert : il faut lire le registre 82h de la table de mixage. Si le bit 0 de ce registre est posé, c 'est qu 'il s 'agit d 'un transfert 8 bits. Si c 'est le bit 1 qui est posé, alors c 'est un transfert 16 bits :

Bits

7

6

5

4

3

2

1

0

 

 

1 = transfert 8 bits
1 = transfert 16 bits

 

0

0

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Bon, tant qu 'à faire, je vais aussi vous parler de comment gérer les sons > 64Ko. Il existe deux technique : la première, le double-buffering, consiste à séparer le buffer en 2 zones de 32Ko, et pendant que l 'une est lue par le DMA et la carte son, l 'autre est remplie par le programme. Elle a l 'avantage de ne provoquer aucune coupure, mais occupe un tout petit peu plus le processeur. La seconde méthode consiste tout simplement à placer la suite du son dans le buffer lorsque celui-ci a été lu. Elle ne provoque en fait pas de coupure même si l 'ordinateur est assez lent, du moment qu 'on s 'y prend bien. De toute façon, la différence au niveau programmation est minime et si on sait faire la deuxième méthode, passer au double-buffering est très facile.

Dans les deux cas, on initialise au début le DMA en mode auto-init, comme ça il reviendra automatiquement au début dès qu 'il arrivera à la fin. Et pour la dernière tranche de l 'échantillon, on le réinitialise en mode single cycle pour ce qui reste.

Un dernier point : à la fin du gestionnaire d 'interruption, il faut envoyer la commande EOI (End Of Interrupt) à l 'IRQ pour lui dire qu 'on a fini. Concrètement, il suffit d 'envoyer la commande 20h au port 20h. Si ce n'est pas fait, l'échantillonage s'arrêtera au prochain bloc.

 

Retour au sommaire

V.La table de mixage

Elle permet de gérer la sortie du son tout comme une table de mixage normale, ou comme la fenêtre 'contrôle du volume' de Windows. On peut régler notemment la balance, le volume général, le volume wave, midi, line-in, etc... Pour lire ou écrire dans un registre de la table de mixage, on envoie son numéro dans le port d'adresse de la table de mixage (2x4h - voir tableau DSP) et on lit (ou écrit) sa valeur dans le port de données (2x5h).
Les registres présentés ici ne valent que pour des DSP de version 4.00 ou plus. Tous les registres ci-dessous peuvent à la fois être lus et modifiés.

Voici donc les différents registres utiles de la table de mixage :

Nom

Registre

Infos

Volume master - gauche

30h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume master - droit

31h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume voice - gauche

32h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume voice - droit

33h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume CD - gauche

36h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume CD - droit

37h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume line-in - gauche

38h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume line-in- droit

39h

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume micro

3Ah

Codé sur 5 bits (bits 3 à 7). Le volume varie de -62db à 0 db par pas de 2db.

Volume line-in- droit

3Bh

Codé sur 2 bits (bits 6 à 7).

Sélection sorties

3Ch

Structure du registre 3Ch

Bits

7

6

5

4

3

2

1

0

 

Valeurs

0

0

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Microphone : 1 = ON / 0 = OFF ??

 

CD droite : 1 = ON / 0 = OFF

 

CD gauche : 1 = ON / 0 = OFF

 

Line-in droite : 1 = ON / 0 = OFF ??

 

Line-in gauche : 1 = ON / 0 = OFF ??

 

Sélection entrées

3Dh

Structure du registre 3Dh

Bits

7

6

5

4

3

2

1

0

 

Valeurs

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Microphone : 1 = ON / 0 = OFF

 

CD droite : 1 = ON / 0 = OFF ??

 

CD gauche : 1 = ON / 0 = OFF ??

 

Line-in droite : 1 = ON / 0 = OFF

 

Line-in gauche : 1 = ON / 0 = OFF

 

FM droite : 1 = ON / 0 = OFF

 

FM gauche : 1 = ON / 0 = OFF

 

 

Retour au sommaire

VI.Remerciements

Document écrit par Antoche – Antoche@altern.org - #ICQ : 38 08 99 43

Libre reproduction et diffusion autorisée - modifications interdites sans autorisation de l'auteur.

Je remercie La Bible du programmeur, qui contient pas mal d'infos sur la SB, et Ethan Brodsky (si vous avez besoin d'une unité SoundBlaster performante en Pascal, il en a fait une vraiment excellente librement diffusée sur le net).

Retour à la rubrique programmation.