Conception électronique: MIDI in et micro-contrôleur (arduino)
- 23 réponses
- 6 participants
- 1 413 vues
- 7 followers
Anonyme
1096
Sujet de la discussion Posté le 15/12/2018 à 20:41:25Conception électronique: MIDI in et micro-contrôleur (arduino)
Salut à tous.
Ca fait quelques années que je pratique l'électronique en tant qu'amateur: réalisation de quelques mini synthés analogiques et numériques.
Je bloque néanmoins sur la conception d'un MIDI in.
Je m'explique: j'ai déjà réalisé des circuits qui pouvaient se synchroniser sur une horloge MIDI, ou pouvaient recevoir des notes MIDI. (6n138 + résistances + diode + micro-contrôleur.)
Cependant ça ne fonctionnait pas toujours très bien... il y avait des notes pas toujours jouées par exemple.
Côté micro-contrôleur j'utilise la gamme Arduino, comme la Uno qui tourne à 16Mhz ou la Due qui tourne à 84MHz. En ce qui concerne la programmation j'ai tendance à bien charger la mule et je pousse souvent ces cartes dans leurs retranchements.
Au final ma question est très simple.
Dans un synthétiseur numérique, vous semble t'il judicieux de dédier un micro-contrôleur à la réception et au filtrage des données MIDI ?
Les arduinos sont capables de lire les données MIDI grâce aux commandes "serial" (qui tournent ici à 31250 bauds). Cependant j'ai l'impression que cette tâche peut être polluée par les autres interruptions de mes programmes, provoquant des pertes de données MIDI.
Quelle solution est habituellement utilisée par les fabricants? un uc dédié ou pas?
Après je suis complètement autodidacte, je ne saisis pas toutes les subtilités de la programmation ...
Merci à ceux qui pourront m'éclairer.
Ca fait quelques années que je pratique l'électronique en tant qu'amateur: réalisation de quelques mini synthés analogiques et numériques.
Je bloque néanmoins sur la conception d'un MIDI in.
Je m'explique: j'ai déjà réalisé des circuits qui pouvaient se synchroniser sur une horloge MIDI, ou pouvaient recevoir des notes MIDI. (6n138 + résistances + diode + micro-contrôleur.)
Cependant ça ne fonctionnait pas toujours très bien... il y avait des notes pas toujours jouées par exemple.
Côté micro-contrôleur j'utilise la gamme Arduino, comme la Uno qui tourne à 16Mhz ou la Due qui tourne à 84MHz. En ce qui concerne la programmation j'ai tendance à bien charger la mule et je pousse souvent ces cartes dans leurs retranchements.
Au final ma question est très simple.
Dans un synthétiseur numérique, vous semble t'il judicieux de dédier un micro-contrôleur à la réception et au filtrage des données MIDI ?
Les arduinos sont capables de lire les données MIDI grâce aux commandes "serial" (qui tournent ici à 31250 bauds). Cependant j'ai l'impression que cette tâche peut être polluée par les autres interruptions de mes programmes, provoquant des pertes de données MIDI.
Quelle solution est habituellement utilisée par les fabricants? un uc dédié ou pas?
Après je suis complètement autodidacte, je ne saisis pas toutes les subtilités de la programmation ...
Merci à ceux qui pourront m'éclairer.
[ Dernière édition du message le 15/12/2018 à 20:52:08 ]
Anonyme
1096
11 Posté le 21/12/2018 à 20:10:18
Bon, bon, bon...
Déjà je n'avais pas tilté qu'Atmel s'était fait racheter il y a quelques années.
Sinon côté library DMA j'ai bien trouvé quelque chose pour l'Arduino Due.
Sauf que c'est destiné aux DACs de la carte qui sont réputés pour être pollués (mauvais développement/routing ), j'utilise donc des DACS externes qui communiquent en SPI (des MCP-4922). Bref la library n'est pas très utile ici.
Côté SAM3X8E j'ai commencé à voir tout ça, on dirait bien que l'appNote "DMA-Controller-DMAC_ApplicationNote_AT07892.pdf" est mon amie.
Je comprends grosso modo les commandes mais je suis encore à mille lieux de saisir comment organiser tout ça.
Je posterai quelques bouts de codes et détaillerai mon projet dans les jours à venir. Je vous souhaite un joyeux Noël d'ici là.
Déjà je n'avais pas tilté qu'Atmel s'était fait racheter il y a quelques années.
Sinon côté library DMA j'ai bien trouvé quelque chose pour l'Arduino Due.
Sauf que c'est destiné aux DACs de la carte qui sont réputés pour être pollués (mauvais développement/routing ), j'utilise donc des DACS externes qui communiquent en SPI (des MCP-4922). Bref la library n'est pas très utile ici.
Côté SAM3X8E j'ai commencé à voir tout ça, on dirait bien que l'appNote "DMA-Controller-DMAC_ApplicationNote_AT07892.pdf" est mon amie.
Je comprends grosso modo les commandes mais je suis encore à mille lieux de saisir comment organiser tout ça.
Je posterai quelques bouts de codes et détaillerai mon projet dans les jours à venir. Je vous souhaite un joyeux Noël d'ici là.
[ Dernière édition du message le 21/12/2018 à 20:15:48 ]
Obiwan78
169
Posteur·euse AFfiné·e
Membre depuis 10 ans
12 Posté le 21/12/2018 à 22:16:25
Salut à tous.
J'ai comme l'impression d'être tombé sur le bon topic
Je suis votre discussion car je suis actuellement en réflexion pour me faire un afficheur avec 4 led ou plus pour le tempo et les noires de chaque mesure.
Est-ce que vous sauriez m'aider sachant que j'ai commander des prises midi femelles et que j'ai un arduino (ancien) par lequel je voudrais recevoir le midi pour envoyer un signal sur mes leds ?
D'avance merci.
J'ai comme l'impression d'être tombé sur le bon topic
Je suis votre discussion car je suis actuellement en réflexion pour me faire un afficheur avec 4 led ou plus pour le tempo et les noires de chaque mesure.
Est-ce que vous sauriez m'aider sachant que j'ai commander des prises midi femelles et que j'ai un arduino (ancien) par lequel je voudrais recevoir le midi pour envoyer un signal sur mes leds ?
D'avance merci.
Consultez mes ventes : https://fr.audiofanzine.com/membres/992137/classifieds/published-products/
Rémy M. (chimimic)
14200
Modérateur·trice thématique
Membre depuis 22 ans
13 Posté le 21/12/2018 à 22:25:03
Citation de Obiwan78 :
je suis actuellement en réflexion pour me faire un afficheur avec 4 led ou plus pour le tempo et les noires de chaque mesure.
Est-ce que vous sauriez m'aider sachant que j'ai commander des prises midi femelles et que j'ai un arduino (ancien) par lequel je voudrais recevoir le midi pour envoyer un signal sur mes leds ?
Connais-tu déjà les grandes lignes de la normes MIDI ?
Formateur en techniques sonores ; électronicien ; auteur @ sonelec-musique.com
Anonyme
1096
14 Posté le 21/12/2018 à 23:36:56
x
Hors sujet :Citation de Obiwan78 :Est-ce que vous sauriez m'aider sachant que j'ai commander des prises midi femelles et que j'ai un arduino (ancien) par lequel je voudrais recevoir le midi pour envoyer un signal sur mes leds ?
Tu parles bien d'un système qui est esclave sur une horloge MIDI externe?
Déjà il te faut le bon circuit qui ne se limite pas à des prises:
https://sandsoftwaresound.net/wp-content/uploads/2016/05/schematic_midi_in.jpg
- 1 prise DIN 5 pins
- 2 résistances 220 Ohms
- 1 diode 1N4148
- 1 optocoupleur 6N138
Obiwan78
169
Posteur·euse AFfiné·e
Membre depuis 10 ans
15 Posté le 22/12/2018 à 14:37:25
Je ne connais pas à proprement parlé la norme midi même si je j’utilise dans mon setup Home Studio avec mes synthés.
La c’est pour avoir un retour les au click (tempo) histoire de bien voir ou j’en suis.
Il y a plein d’appli sur IPad mais aucun ne gère le midi In sauf si vous savez laquelle ?
La c’est pour avoir un retour les au click (tempo) histoire de bien voir ou j’en suis.
Il y a plein d’appli sur IPad mais aucun ne gère le midi In sauf si vous savez laquelle ?
Consultez mes ventes : https://fr.audiofanzine.com/membres/992137/classifieds/published-products/
pfeuh
104
Posteur·euse AFfiné·e
Membre depuis 19 ans
16 Posté le 24/12/2018 à 15:27:59
Hello,
Je réponds à la question Dans un synthétiseur numérique, vous semble t'il judicieux de dédier un micro-contrôleur à la réception et au filtrage des données MIDI ?
Dans l'absolu, non. Un buffer de réception bien conçu prend un temps de traitement négligeable.
Ça m’étonnerait que tu aies un tampon d'entrée plein. Pour info tu as à la louche 300 microsecondes entre chaque réception d'octet complet... On peut en faire des choses, en 300 microsecondes. Pour ton histoire de notes qui ne démarrent pas ou ne s'arrêtent pas, je pense que l'erreur vient de là:
if ( MidiInput == 240 ) {
240 = 0xf0 = 0b11110000 = début de message exclusif.
Du coup, je ne vois pas trop ce que fait cet exemple.
Pour gérer les notes le standard midi autorise les messages 1 octet noteon/noteoff + 1 octet note + 1 octet vélocité mais aussi 1 octet noteon/noteoff et autant de couples 1 octet note + 1 octet vélocité. Autrement dit un seul noteon/noteoff et un nombre de notes non prédictible.
De plus les messages temps réel (taille 1 octet unique) peuvent s'intercaler n'importe où dans ton flot d'entrée, causant un bordel monstre si tu ne le gère pas.
J'ai vu quelqu'un te conseiller une machine d'état, c'est une très bonne idée. Saches juste qu'il existe déjà de nombreux drivers de réception midi en C et d'autres langages. Ils sont bien sûrs conçus autour d'une machine d'état et d'une réception bufferisée sous interruption, mais au delà du plaisir de le refaire soi-même, ils ont étés testés sous toutes les coutures. Ça et le fait qu'il y ait une communauté autour sont deux aspects non négligeables.
https://www.midi.org/
A+
Pfeuh
Je réponds à la question Dans un synthétiseur numérique, vous semble t'il judicieux de dédier un micro-contrôleur à la réception et au filtrage des données MIDI ?
Dans l'absolu, non. Un buffer de réception bien conçu prend un temps de traitement négligeable.
Ça m’étonnerait que tu aies un tampon d'entrée plein. Pour info tu as à la louche 300 microsecondes entre chaque réception d'octet complet... On peut en faire des choses, en 300 microsecondes. Pour ton histoire de notes qui ne démarrent pas ou ne s'arrêtent pas, je pense que l'erreur vient de là:
if ( MidiInput == 240 ) {
240 = 0xf0 = 0b11110000 = début de message exclusif.
Du coup, je ne vois pas trop ce que fait cet exemple.
Pour gérer les notes le standard midi autorise les messages 1 octet noteon/noteoff + 1 octet note + 1 octet vélocité mais aussi 1 octet noteon/noteoff et autant de couples 1 octet note + 1 octet vélocité. Autrement dit un seul noteon/noteoff et un nombre de notes non prédictible.
De plus les messages temps réel (taille 1 octet unique) peuvent s'intercaler n'importe où dans ton flot d'entrée, causant un bordel monstre si tu ne le gère pas.
J'ai vu quelqu'un te conseiller une machine d'état, c'est une très bonne idée. Saches juste qu'il existe déjà de nombreux drivers de réception midi en C et d'autres langages. Ils sont bien sûrs conçus autour d'une machine d'état et d'une réception bufferisée sous interruption, mais au delà du plaisir de le refaire soi-même, ils ont étés testés sous toutes les coutures. Ça et le fait qu'il y ait une communauté autour sont deux aspects non négligeables.
https://www.midi.org/
A+
Pfeuh
Anonyme
1096
17 Posté le 25/12/2018 à 21:27:11
Salut à tous.
Par rapport au commentaire de Pfeuh:
Bien vu! cet exemple était ancien et faux. L'idée ici était de lire l'horloge MIDI, la valeur aurait donc dû être 248 qui correspond 11111000.
J'ai remis les mains dans la programmation ces derniers jours, en ce moment je bosse sur un synthé polyphonique, je commence avec trois voix pour déblayer le terrain.
Malgré l'erreur que tu as repéré je n'ai pas trop de soucis avec le traitement du MIDI: note On et Off, etc... je ne sais pas si les choses sont faites dans les règles de l'art mais disons qu'elles fonctionnent.
Le code récemment pondu qui permet de piloter 3 voix (hauteur et trigger):
Voilà , je me sens surtout handicapé face à ces histoires de DMA pour l'audio. Je vais avoir un peu de temps ces jours-ci pour m'y plonger.
A défaut de DMA, j'ai traficoté un système de buffer avec une "array" disponible depuis ma Loop principale et mon ISR. J'imagine que c'est pas vraiment la meilleure formule mais les premiers tests semblaient fonctionner. Je ne sais pas si c'est une bonne idée.
Par rapport au commentaire de Pfeuh:
Bien vu! cet exemple était ancien et faux. L'idée ici était de lire l'horloge MIDI, la valeur aurait donc dû être 248 qui correspond 11111000.
J'ai remis les mains dans la programmation ces derniers jours, en ce moment je bosse sur un synthé polyphonique, je commence avec trois voix pour déblayer le terrain.
Malgré l'erreur que tu as repéré je n'ai pas trop de soucis avec le traitement du MIDI: note On et Off, etc... je ne sais pas si les choses sont faites dans les règles de l'art mais disons qu'elles fonctionnent.
Le code récemment pondu qui permet de piloter 3 voix (hauteur et trigger):
Spoiler - Cliquer ici pour lire la suite
/************ Scan MIDI in ************/
void scan_MIDI() {
incoming_MIDI_Byte = Serial1.read ();
if ( incoming_MIDI_Byte > 127 ) {
MIDI_Swap_Byte = 0;
switch (incoming_MIDI_Byte - MIDI_Channel_Select ) {
case 128:
MIDI_Note_On = 0;
MIDI_Note_Off = 1;
break;
case 144:
MIDI_Note_On = 1;
MIDI_Note_Off = 0;
break;
default:
MIDI_Note_On = 0;
MIDI_Note_Off = 0;
}
} else {
if ( incoming_MIDI_Byte != -1 ) {
if ( MIDI_Swap_Byte == 0 ) {
if ( MIDI_Note_On == 1 ) { // Note On
if ( incoming_MIDI_Byte != note_Voice_1 && incoming_MIDI_Byte != note_Voice_2 && incoming_MIDI_Byte != note_Voice_3 ) {
voice_Counter = voice_Counter + 1;
if ( voice_Counter == 4)
voice_Counter = 1;
switch (voice_Counter ) {
case 1:
note_Voice_1 = incoming_MIDI_Byte ;
break;
case 2:
note_Voice_2 = incoming_MIDI_Byte ;
break;
case 3:
note_Voice_3 = incoming_MIDI_Byte ;
break;
}
}
if ( incoming_MIDI_Byte == note_Voice_1 )
trig_Voice_1 = 1;
if ( incoming_MIDI_Byte == note_Voice_2 )
trig_Voice_2 = 1;
if ( incoming_MIDI_Byte == note_Voice_3 )
trig_Voice_3 = 1;
}
if ( MIDI_Note_Off == 1 ) {
if ( incoming_MIDI_Byte == note_Voice_1 )
trig_Voice_1 = 0;
if ( incoming_MIDI_Byte == note_Voice_2 )
trig_Voice_2 = 0;
if ( incoming_MIDI_Byte == note_Voice_3 )
trig_Voice_3 = 0;
}
}
MIDI_Swap_Byte = !MIDI_Swap_Byte;
}
}
}
/************ Scan MIDI in ************/
void scan_MIDI() {
incoming_MIDI_Byte = Serial1.read ();
if ( incoming_MIDI_Byte > 127 ) {
MIDI_Swap_Byte = 0;
switch (incoming_MIDI_Byte - MIDI_Channel_Select ) {
case 128:
MIDI_Note_On = 0;
MIDI_Note_Off = 1;
break;
case 144:
MIDI_Note_On = 1;
MIDI_Note_Off = 0;
break;
default:
MIDI_Note_On = 0;
MIDI_Note_Off = 0;
}
} else {
if ( incoming_MIDI_Byte != -1 ) {
if ( MIDI_Swap_Byte == 0 ) {
if ( MIDI_Note_On == 1 ) { // Note On
if ( incoming_MIDI_Byte != note_Voice_1 && incoming_MIDI_Byte != note_Voice_2 && incoming_MIDI_Byte != note_Voice_3 ) {
voice_Counter = voice_Counter + 1;
if ( voice_Counter == 4)
voice_Counter = 1;
switch (voice_Counter ) {
case 1:
note_Voice_1 = incoming_MIDI_Byte ;
break;
case 2:
note_Voice_2 = incoming_MIDI_Byte ;
break;
case 3:
note_Voice_3 = incoming_MIDI_Byte ;
break;
}
}
if ( incoming_MIDI_Byte == note_Voice_1 )
trig_Voice_1 = 1;
if ( incoming_MIDI_Byte == note_Voice_2 )
trig_Voice_2 = 1;
if ( incoming_MIDI_Byte == note_Voice_3 )
trig_Voice_3 = 1;
}
if ( MIDI_Note_Off == 1 ) {
if ( incoming_MIDI_Byte == note_Voice_1 )
trig_Voice_1 = 0;
if ( incoming_MIDI_Byte == note_Voice_2 )
trig_Voice_2 = 0;
if ( incoming_MIDI_Byte == note_Voice_3 )
trig_Voice_3 = 0;
}
}
MIDI_Swap_Byte = !MIDI_Swap_Byte;
}
}
}
Voilà , je me sens surtout handicapé face à ces histoires de DMA pour l'audio. Je vais avoir un peu de temps ces jours-ci pour m'y plonger.
A défaut de DMA, j'ai traficoté un système de buffer avec une "array" disponible depuis ma Loop principale et mon ISR. J'imagine que c'est pas vraiment la meilleure formule mais les premiers tests semblaient fonctionner. Je ne sais pas si c'est une bonne idée.
[ Dernière édition du message le 25/12/2018 à 21:51:10 ]
Anonyme
1096
18 Posté le 30/01/2019 à 19:48:20
Bon, je reviens sur ce sujet. Reprenons depuis le début.
Déjà, pour lire les messages MIDI entrant, j'utilise la commande serial. En gros je l'utilise ainsi:
( J'ai fait un effort sur le mise en page )
Voilà c'est tout bête mais je me demande déjà si c'est une bonne idée d'utiliser cette commande serial... car il me semble que c'est une commande Arduino qui n'est pas forcément optimisée... pour vous est-ce à priori quelque chose dont je dois me soucier pour le moment ? (Je suis presque débutant).
Aab tu avais parlé d'une machine à état , de FIFO... ça s'utilise comment dans ce cas là? Je crains que ça dépasse largement le cap de mes compétences.
Ensuite je me demande si une interruption doit être liée à la réception d'un message MIDI. Je sais coder une interruption pour un bouton par exemple mais je ne vois pas trop comment m'y prendre pour la réception d'un message MIDI....
Déjà, pour lire les messages MIDI entrant, j'utilise la commande serial. En gros je l'utilise ainsi:
int incoming_MIDI_Byte;
void setup() {
Serial1.begin(31250); // prépare à la communication MIDI sur le port série 1.
}
void loop() {
incoming_MIDI_Byte = Serial1.read (); // lit le message sur le port série 1
}
( J'ai fait un effort sur le mise en page )
Voilà c'est tout bête mais je me demande déjà si c'est une bonne idée d'utiliser cette commande serial... car il me semble que c'est une commande Arduino qui n'est pas forcément optimisée... pour vous est-ce à priori quelque chose dont je dois me soucier pour le moment ? (Je suis presque débutant).
Aab tu avais parlé d'une machine à état , de FIFO... ça s'utilise comment dans ce cas là? Je crains que ça dépasse largement le cap de mes compétences.
Ensuite je me demande si une interruption doit être liée à la réception d'un message MIDI. Je sais coder une interruption pour un bouton par exemple mais je ne vois pas trop comment m'y prendre pour la réception d'un message MIDI....
[ Dernière édition du message le 30/01/2019 à 19:59:30 ]
pfeuh
104
Posteur·euse AFfiné·e
Membre depuis 19 ans
19 Posté le 30/01/2019 à 20:32:20
Hello,
Sur un arduino, tu n'as pas le choix, le seul driver série (donc capable de transporter des messages midi) est Serial (Serial2, Serial3 et Serial4 aussi si tu as un gros arduino)
Ce driver marche déjà sous interruption. Quand un caractère est reçu, il est mis dans un tampon circulaire. Quand tu appelles la méthode Serial.available(), c'est le nombre de caractères en attente dans ce tampon circulaire qui t'es retourné. Quand tu lis un caractère, ce nombre est décrementé sans que tu ne t'occupes de rien. C'est ça, une gestion des interruptions.
Toi, tu commences ton programme par Serial.read(), ce qui a pour effet... De totalement bloquer le processeur (sauf les interruptions et le DMA jusqu'à ce qu'un caractère arrive... Pas très efficace...
Pour faire plusieurs tâches à la fois, il faut diviser chaque tâche en étapes et en transitions. Tu as ta boucle principale qui appelle toutes les machines d'état les unes après les autres et qui recommence indéfiniment.
Je suis tombé sur cet exemple, il a l'air d'être assez pédagogique.
https://forum.arduino.cc/index.php?topic=470879.0
A vue de nez, tu aurais les états suivants:
etat attente
etat premier octet recu attente du deuxieme
etat deuxieme octet recu attente du troisieme (on traite le message et on revient a l'etat attente)
etat octet clock (on traite l'octet et on revient à l'etat precedent)
C'est le cas le plus simple. Comme dit, il y a déjà d'excellent drivers midi tous faits qui intègrent tout ça et bien plus.
A+
Pfeuh
Sur un arduino, tu n'as pas le choix, le seul driver série (donc capable de transporter des messages midi) est Serial (Serial2, Serial3 et Serial4 aussi si tu as un gros arduino)
Ce driver marche déjà sous interruption. Quand un caractère est reçu, il est mis dans un tampon circulaire. Quand tu appelles la méthode Serial.available(), c'est le nombre de caractères en attente dans ce tampon circulaire qui t'es retourné. Quand tu lis un caractère, ce nombre est décrementé sans que tu ne t'occupes de rien. C'est ça, une gestion des interruptions.
Toi, tu commences ton programme par Serial.read(), ce qui a pour effet... De totalement bloquer le processeur (sauf les interruptions et le DMA jusqu'à ce qu'un caractère arrive... Pas très efficace...
Pour faire plusieurs tâches à la fois, il faut diviser chaque tâche en étapes et en transitions. Tu as ta boucle principale qui appelle toutes les machines d'état les unes après les autres et qui recommence indéfiniment.
Je suis tombé sur cet exemple, il a l'air d'être assez pédagogique.
https://forum.arduino.cc/index.php?topic=470879.0
A vue de nez, tu aurais les états suivants:
etat attente
etat premier octet recu attente du deuxieme
etat deuxieme octet recu attente du troisieme (on traite le message et on revient a l'etat attente)
etat octet clock (on traite l'octet et on revient à l'etat precedent)
C'est le cas le plus simple. Comme dit, il y a déjà d'excellent drivers midi tous faits qui intègrent tout ça et bien plus.
A+
Pfeuh
static volatile
1793
AFicionado·a
Membre depuis 7 ans
20 Posté le 31/01/2019 à 11:00:30
D'accord avec ce que dit pfeuh.
Pour la lib Serial, s'il existe effectivement un call qui te renvoie le nombre de bytes dans le buffer, c'est ce qu'il faut utiliser et n'appeler read() que lorsque le buffer n'est pas vide.
Pour les machines à états, le lien est pas mal, un peu confus peut-être à mon goût.
Ce qu'il faut retenir, c'est que c'est juste une abstraction.
C'est quelque chose que tu peux dessiner sur un papier pour représenter ton système et ainsi construire ta pensée avant de commencer à écrire du code.
En ce sens, l'exemple du lien avec les lumières est bon.
Pour le MIDI, ça sera plus complexe, selon si tu décides d'implémenter toute la spec ou juste la partie qui t'intéresse, mais tu peux tout à fait représenter les actions nécessaires au décodage d'un flux MIDI avec ce genre d'abstraction.
Dans tous les cas, il te faudra construire, sur papier, ta machine à états en te référant à la spec, et ensuite imaginer comment la représenter en C.
Effectivement, la manière naive (pas au sens péjoratif, mais au sens où c'est la correspondance la plus directe entre le dessin et le code) sera un switch():
Pour la lib Serial, s'il existe effectivement un call qui te renvoie le nombre de bytes dans le buffer, c'est ce qu'il faut utiliser et n'appeler read() que lorsque le buffer n'est pas vide.
Pour les machines à états, le lien est pas mal, un peu confus peut-être à mon goût.
Ce qu'il faut retenir, c'est que c'est juste une abstraction.
C'est quelque chose que tu peux dessiner sur un papier pour représenter ton système et ainsi construire ta pensée avant de commencer à écrire du code.
En ce sens, l'exemple du lien avec les lumières est bon.
Pour le MIDI, ça sera plus complexe, selon si tu décides d'implémenter toute la spec ou juste la partie qui t'intéresse, mais tu peux tout à fait représenter les actions nécessaires au décodage d'un flux MIDI avec ce genre d'abstraction.
Dans tous les cas, il te faudra construire, sur papier, ta machine à états en te référant à la spec, et ensuite imaginer comment la représenter en C.
Effectivement, la manière naive (pas au sens péjoratif, mais au sens où c'est la correspondance la plus directe entre le dessin et le code) sera un switch():
enum {
IDLE,
STATE_1,
STATE_2,
} state;
for ( ; ; ) {
switch (state) {
default:
case IDLE:
if (condition) {
do_something();
state = STATE_1;
}
break;
case STATE_1:
/* do something else */
if (reset_detected()) {
state = IDLE;
} else if (something_happens()) {
state = STATE_2;
}
break;
/* and so on and so forth */
}
}
Resistance is not futile... it's voltage divided by current
- < Liste des sujets
- Charte