Section courante

A propos

Section administrative du site

Programmation des entrées/sorties du port MIDI

Cette page traite de la programmation du mode MIDI de la Sound Blaster (SB-MIDI) et du mode UART MPU-401. Le port SB-MIDI est disponible sur toutes les cartes Sound Blaster. Le mode UART MPU-401 est disponible uniquement sur la Sound Blaster 16.

Vous pouvez utiliser l'une ou l'autre des interfaces MIDI. Cependant, il est préférable d'utiliser le mode MPU-401 sur la Sound Blaster 16 car il dispose de ses propres ports d'entrées/sorties indépendants et d'un bit d'état d'interruption, ce qui signifie qu'il est possible d'avoir du son numérisé et des entrées/sorties MIDI fonctionnant ensemble. D'autre part, le mode SB-MIDI partage les mêmes ports d'entrées/sorties et le même bit d'état d'interruption associés au son numérisé.

Les discussions suivantes supposent que vous avez des connaissances en programmation DSP et en partage de gestion des interruptions.

Mode SB-MIDI

Le mode SB-MIDI fournit une interface pour les entrées/sorties MIDI en mode normal ainsi qu'en mode UART. Le mode UART nécessite un DSP avec une version minimale de 2.00. En mode normal, toutes les données de sortie MIDI doivent être précédées d'une commande de sortie MIDI, mais en mode UART, une écriture sur le DSP est considérée comme des données MIDI.

Les données MIDI entrantes peuvent être détectées à l'aide d'un mode d'interrogation ou d'interruption. Il est suggéré d'utiliser le mode d'interruption pour lire les données MIDI entrantes car le DSP génère une interruption pour signaler à l'application chaque fois qu'il y a des données MIDI entrantes. Cela élimine le temps nécessaire pour continuer à interroger les données MIDI entrantes en mode d'interrogation.

Le mode d'horodatage MIDI, conforme aux spécifications Microsoft Multimedia Extension Level 1, est également disponible sur les versions DSP 2.00 et supérieures. En mode d'horodatage MIDI, les données MIDI entrantes sont étiquetées avec un horodatage pouvant être utilisé par un séquenceur MIDI pour relire les données au bon tempo.

Adresses d'entrée/sortie

Le mode SB-MIDI partage les mêmes ports d'entrées/sorties et le même bit d'état d'interruption du mode DMA 8 bits associé au son numérisé. Cela signifie que vous pouvez accéder au port MIDI en écrivant et en lisant sur le DSP.

Envoi de données MIDI

Ce qui suit illustre la différence entre l'envoi de données MIDI en mode normal et en mode UART :

Mode normal

En mode MIDI normal, toutes les données de sortie MIDI doivent être précédées d'une commande de sortie MIDI. Le fragment de code assembleur suivant montre le processus d'envoi de données MIDI au DSP. Supposons que WriteDSP est une procédure écrivant des données dans le registre AL sur le DSP :

  1.   MOV  AL,38h       ; Commande de sortie de données MIDI
  2.   CALL WriteDSP     ; Envoyer la commande au DSP
  3.   MOV  AL,bMidiData ; Données MIDI à envoyer
  4.   CALL WriteDSP     ; Envoyer des données MIDI
  5. ;**** Répétez le processus pour envoyer plus de données MIDI

Mode UART mode

Pour envoyer des données MIDI en mode UART, les commandes DSP 34h, 35h, 36h ou 37h doivent d'abord être envoyées au DSP pour faire passer l'interface en mode UART. Une fois en mode UART, une lecture depuis le DSP lit les données MIDI et une écriture vers le DSP envoie les données MIDI.

Pour mettre fin au mode UART, envoyez une commande de réinitialisation du DSP. La commande de réinitialisation se comporte différemment lorsque le DSP est en mode MIDI UART. Elle met fin au mode MIDI UART et restaure tous les paramètres du DSP aux états antérieurs à l'entrée en mode MIDI UART. Si votre application a été exécutée en mode MIDI UART, il est important que vous envoyiez la commande de réinitialisation du DSP pour quitter le mode MIDI UART lorsque votre application se termine.

Lecture des données MIDI

Lorsque des données MIDI sont disponibles à partir d'un périphérique MIDI externe, elles peuvent être lues à partir du port de données DSP. Comme mentionné précédemment, il existe deux modes de fonctionnement pour détecter la disponibilité des données MIDI entrantes : le mode d'interrogation ou le mode d'interruption. En mode d'interrogation, les données MIDI entrantes sont disponibles lorsque le bit 7 du port d'état de la mémoire tampon de lecture DSP est défini. Inversement, lorsque le bit 7 est effacé, aucune donnée MIDI n'est disponible.

En mode d'interruption, une interruption se produit lorsque des données MIDI sont disponibles. Une routine de service d'interruption doit être configurée pour récupérer les données MIDI. Une lecture du port d'état de la mémoire tampon de lecture DSP effacera le signal d'interruption.

La séquence de lecture des données MIDI est identique dans les modes d'interrogation et d'interruption. Vous trouverez ci-dessous un fragment de code assembleur qui peut être utilisé dans une routine d'interrogation ou une routine de service d'interruption :

  1.   MOV DX,wSBCBaseAddx ; Adresse d'entrée/sortie de base SBC 2x0h
  2.   ADD DL,0Eh          ; Port d'état de lecture du tampon, 2xEh
  3. Busy: 
  4.   IN AL,DX            ; Port d'état de lecture du tampon de lecture
  5.   OR AL,AL            ; Données disponibles ?
  6.   JNS Busy            ; Bit 7 effacé, réessayez
  7.   SUB DL,4            ; Port de données de lecture, 2xAh
  8.   IN AL,DX            ; Lire les données DSP entrantes

Les données MIDI entrantes ne sont pas étiquetées avec des informations de synchronisation, sauf si le mode d'horodatage MIDI est utilisé. Par conséquent, il appartient à l'application de gérer la synchronisation des données MIDI.

En mode d'horodatage MIDI, les données MIDI entrantes sont étiquetées avec 3 octets d'informations de synchronisation. Par conséquent, 4 octets de données sont toujours disponibles chaque fois qu'il y a des données MIDI entrantes. La procédure de récupération des données MIDI avec les informations de synchronisation est la même, sauf que vous pouvez désormais lire 4 octets à la fois dans la routine de service d'interruption.

L'horodatage MIDI est une qualité de 3 octets mesurant le temps en unités de millisecondes. Le format de compression des données MIDI entrantes horodatées est le suivant :

  1. nTime.LowByte, nTime.MidByte, nTime.HighByte, bMidiData

Mode UART MPU-401

Seul le mode UART (ou pass-through) MPU-401 est pris en charge sur Sound Blaster 16. Dans ce mode, l'interface n'exécute aucun service, relayant littéralement tout ce qu'elle reçoit, sans modification ni interprétation, entre le PC et l'appareil MIDI connecté. Une fois le mode UART activé, la seule commande reconnue par l'interface est Reset.

Adresses d'entrées/sorties

L'interface MIDI en mode UART Sound Blaster 16 MPU-401 utilise une ligne IRQ et deux adresses d'entrées/sorties consécutives. Les lignes IRQ possibles sont 2, 5, 7 et 10, avec une valeur par défaut de 5. Les adresses d'entrées/sorties de base possibles sont 300h et 330h, avec une valeur par défaut de 330h. Deux adresses d'entrées/sorties consécutives, comptant à partir de l'adresse de base, sont utilisées pour accéder à l'interface MIDI MPU-401. Les deux adresses sont 300h et 301h, ou 330h et 331h.

Les deux adresses d'entrées/sorties peuvent être classées comme suit :

Port d'état 3x1h (lecture seule) Ce port indique si l'interface est prête à accepter un octet de données/commande ou si des données entrantes sont disponibles pour la lecture.

Bit 6 : Sortie prête
0 - L'interface est prête à recevoir un octet de données/commande
1 - L'interface n'est pas prête à recevoir un octet de données/commande
Bit 7 : Entrée prête
0 - Les données sont disponibles pour la lecture
1 - Aucune donnée n'est disponible pour la lecture
Port de commande 3x1h (écriture seule) Les commandes sont envoyées via ce port.
Port de données 3x0h (lecture/écriture) Il s'agit du port par lequel transitent les données entrantes ou sortantes.

Vérification de l'état

Avant d'écrire un octet de commande ou des données MIDI sur (ou de lire un octet de données ou des données MIDI depuis) ??l'interface MPU-401, le port d'état doit être vérifié pour voir si l'interface est prête.

Le bit 6, le bit de sortie prêt, indique si l'interface est prête à recevoir des données. S'il est à 1, l'interface est occupée. Sinon, l'octet de commande ou les données MIDI peuvent être envoyés.

Exemple de code :

  1.   MOV DX,wMpuBaseAddx  ; Adresse d'entrée/sortie de base du MPU-401
  2.   INC DX               ; Port d'état
  3. Busy: 
  4.   IN AL,DX             ; Lire le port d'état
  5.   TEST AL,40h          ; Prêt pour la sortie ?
  6.   JNZ Busy
  7. ;***
  8. ;*** Envoyez une commande ou des données MIDI ici

Le bit 7, le bit d'entrée prête, indique si les données sont disponibles pour la lecture. S'il est à 1, aucune donnée n'est disponible. Sinon, il y a des données à lire.

Exemple de code :

  1.   MOV DX,wMpuBaseAddx  ; Adresse d'entrée/sortie de base du MPU-401
  2.   INC DX               ; Port d'état
  3. Busy: 
  4.   IN AL,DX             ; Lire le port d'état
  5.   TEST AL,80h          ; Données d'entrée disponibles ?
  6.   JNZ Busy
  7.   ;***
  8.   ;*** Lire les données ici

Envoi d'une commande

Les commandes sont envoyées via le port de commande pour contrôler le fonctionnement de l'interface. Avant d'envoyer la commande, le port d'état doit être interrogé.

Exemple de code :

  1.   MOV DX,wMpuBaseAddx   ; Adresse d'entrée/sortie de base du MPU-401
  2.   INC DX                ; Port d'état
  3. Busy: 
  4.   IN AL,DX              ; Lire le port d'état
  5.   TEST AL,40h           ; Prêt pour la sortie ?
  6.   JNZ Busy
  7.   MOV AL,bCommand       ; Obtenir la commande
  8.   OUT DX,AL             ; Commande de sortie via le port de commande

Comme seul le mode UART est pris en charge, seules deux commandes sont reconnues. Ces deux commandes sont Reset et Enter UART mode.

Réinitialisation

L'octet de commande 0FFh est utilisé pour réinitialiser l'interface MPU-401. Après avoir réinitialisé l'interface, un octet d'accusé de réception de commande, 0FEh, doit être relu à partir du port de données.

Ce mécanisme peut également être utilisé pour détecter l'existence de l'interface MPU-401. Après une réinitialisation de l'interface, les données lues à partir du port de données doivent être vérifiées comme étant 0FEh. Si cela échoue, soit le MPU-401 n'est pas installé, soit il n'existe pas à cette adresse d'entrées/sorties.

Exemple de code :

  1.   MOV DX,wMpuBaseAddx  ; Adresse d'entrée/sortie de base du MPU-401
  2.   INC DX               ; Port d'état
  3. Busy: 
  4.   IN AL,DX             ; Lire le port d'état
  5.   TEST AL,40h          ; Prêt pour la sortie ?
  6.   JNZ Busy             ; Non
  7.   MOV AL,0FFh          ; Sortie de la commande « Réinitialiser »
  8.   OUT DX,AL            ; via le port de commande
  9.   SUB CX,CX            ; Maximum de 65536 essais
  10. Empty: 
  11.   IN AL,DX             ; Lire le port d'état
  12.   TEST AL,80h          ; Les données d'entrée sont-elles prêtes ?
  13.   JNZ NextLoop         ; Non
  14.   DEC DX               ; Port de données
  15.   IN AL,DX             ; Lire les données
  16.   CMP AL,0FEh          ; Réinitialisation réussie ?
  17.   JE ResetOK           ; SUCCÈS!
  18.   INC DX               ; Port d'état
  19. NextLoop:
  20.   LOOP Empty           ; Essayer à nouveau
  21. ;***
  22. ;*** Échec de la réinitialisation : MPU-401 non détecté

Passer en mode UART

Pour envoyer ou recevoir des données MIDI, l'octet de commande 3Fh doit d'abord être envoyé pour faire passer l'interface en mode UART. Un octet d'accusé de réception de commande de 0FEh sera mis à disposition sur le port de données si le changement de mode réussit.

En mode UART, les données MIDI sont envoyées et reçues depuis le port de données. La commande Reset est utilisée pour quitter le mode UART.

Exemple de code :

  1.   MOV DX,wMpuBaseAddx       ; Adresse d'entrée/sortie de base du MPU-401
  2.   INC DX                    ; Port d'état
  3. Busy: 
  4.   IN AL,DX                  ; Lire le port d'état
  5.   TEST AL,40h               ; Prêt pour la sortie ?
  6.   JNZ Busy                  ; Non
  7.   MOV AL,3Fh                ; Sortie « Entrer en mode UART »
  8.   OUT DX,AL                 ; commande via le port de commande
  9.   SUB CX,CX                 ; Maximum de 65536 essais
  10. Empty: 
  11.   IN AL,DX                  ; Lire le port d'état
  12.   TEST AL,80h               ; Les données d'entrée sont-elles prêtes ?
  13.   JNZ NextLoop              ; Non
  14.   DEC DX                    ; Port de données
  15.   IN AL,DX                  ; Lire les données
  16.   CMP AL,0FEh               ; Changement de mode réussi ?
  17.   JE InUartMode             ; SUCCÈS!
  18.   INC DX                    ; Port d'état
  19. NextLoop:
  20.   LOOP Empty                ; Essayer à nouveau
  21. ;***
  22. ;*** Impossible de passer en mode UART

Une interruption est générée lorsque l'interface est configurée en mode UART. Il n'est pas nécessaire de configurer une routine de service d'interruption pour gérer l'interruption, car la lecture à partir du port de données effacera le signal d'interruption.

Il est important que votre application envoie la commande de réinitialisation MPU-401 pour quitter le mode UART MIDI lorsque votre application se termine.

Envoi de données MIDI

Une fois en mode UART, les données MIDI peuvent être envoyées à un périphérique MIDI externe en écrivant sur le port de données.

Exemple de code :

  1.   MOV DX,wMpuBaseAddx  ; Adresse d'entrée/sortie de base du MPU-401
  2.   INC DX               ; Port d'état
  3. Busy: 
  4.   IN AL,DX             ; Lire le port d'état
  5.   TEST AL,40h          ; Prêt pour la sortie ?
  6.   JNZ Busy             ; Non
  7.   MOV AL,bMidiData     ; Obtenir des données MIDI
  8.   DEC DX               ; Port de données
  9.   OUT DX,AL            ; Données MIDI de sortie

Lecture des données MIDI

Lorsque des données MIDI sont disponibles à partir d'un périphérique MIDI externe, elles peuvent être lues à partir du port de données. Il existe deux modes utilisés pour détecter la disponibilité des données d'entrée : l'interrogation et l'interruption.

En mode d'interrogation, comme précédemment, les données d'entrée sont disponibles lorsque le bit 7 du port d'état est à zéro. Inversement, lorsque le bit 7 est à un, aucune donnée MIDI n'est disponible.

En mode d'interruption, une interruption se produit lorsqu'un code MIDI est prêt. Une routine de service d'interruption doit être configurée pour récupérer le code MIDI. La lecture à partir du port de données effacera le signal d'interruption.

La séquence de lecture des données MIDI est identique dans les modes d'interrogation et d'interruption. Vous trouverez ci-dessous un fragment de code pouvant être utilisé dans la routine d'interrogation ou la routine de service d'interruption :

  1.   MOV DX,wMpuBaseAddx  ; Adresse d'entrée/sortie de base du MPU-401
  2.   INC DX               ; Port d'état
  3. Busy: 
  4.   IN AL,DX             ; Lire le port d'état
  5.   TEST AL,80h          ; Données MIDI disponibles ?
  6.   JNZ Busy             ; Non
  7.   DEC DX               ; Port de données
  8.   IN AL,DX             ; Lire les données MIDI et effacer les interruptions

En mode UART MPU-401, aucune information de synchronisation n'est disponible. Il appartient à l'application de gérer la synchronisation des données MIDI.



Dernière mise à jour : Dimanche, le 15 septembre 2024