Effets sonores sur la brique EV3 en Python

La brique EV3 du Lego MindStorm est dotée d'un haut-parleur à partir duquel on peut entendre des sons générés par programmation. Ce haut-parleur est assez rudimentaire et de qualité médiocre. Mais il permet de générer quelques effets sonores intéressants. 
La programmation du son sur la brique EV3 passe par la classe Sound de la bibliothèque ev3dev2. Cette classe doit être instanciée et les sons sont émis par l'invocation des méthodes de cette classe. La documentation de cette classe est disponible « ici ».

Jouer des sons sur la brique EV3

Le logiciel de programmation par briques graphiques livré avec le kit du robot Lego MindStorm propose une brique Action pour les effets sonores. En fonction des données à jouer, cette brique est déclinée de plusieurs façons.

En Python, la classe Sound expose les méthodes correspondantes.

La classe Sound

La classe Sound se trouve dans le module ev3dev2.sound et doit être instanciée une fois pour être utilisée. En général, l'instance unique créée est affectée à une constante qui peut être utilisée dans le programme pour y invoquer les méthodes des effets sonores.
from ev3dev2.sound import Sound

HP = Sound()

Le paramètre play_type

Les méthodes de la classe Sound à invoquer pour émettre des effets sonores possèdent toutes un paramètre particulier pour indiquer la manière dont le son est joué. En effet, jouer un son peut prendre un certain temps. Ce paramètre indique ce que le programme doit faire pendant ce temps. La classe Sound expose les trois valeurs de ce paramètres sous forme de constantes de classe :
  • Sound.PLAY_WAIT_FOR_COMPLETE (valeur numérique 0) indique que le programme doit attendre que le son soit complètement joué avant d'exécuter l'instruction suivante.
  • Sound.PLAY_NO_WAIT_FOR_COMPLETE (valeur numérique 1) indique que le son est joué dans une tâche en parallèle. Le programme donne la main immédiatement à l'instruction suivant sans attendre que le son soit terminé.
  • Sound.PLAY_LOOP (valeur numérique 2) indique que le son doit être joué en boucle dans une tâche en parallèle. Le programme donne la main immédiatement à l'instruction suivant  et continue à s'exécuter pendant ce temps là.

Méthode beep()

Cette méthode n'a pas d'équivalent en programmation graphique. Elle effectue un appel à l'instruction beep du système Linux. Elle est déclarée comme ceci :
beep(args='', play_type=PLAY_WAIT_FOR_COMPLETE)

  • args est un paramètre de type chaîne de caractères permet de passer les options de la ligne de commande de l'instruction beep. L'exemple ci-dessous émet trois bips d'une demi seconde avec une fréquence de 880hz.  
from ev3dev2.sound import Sound

HP = Sound()

HP.beep("-l 500 -r 3 -f 880")

Méthode play_file()

Cette méthode est équivalente à la brique graphique ci-dessus. Elle est déclarée comme ci-dessous.
play_file(wav_file, volume=100, play_type=PLAY_WAIT_FOR_COMPLETE)
Les paramètres passé sont les mêmes que pour la brique graphique :
  • wave_file est le nom du fichier contenant le son.
  • volume est exprimé en % et permet de régler le volume du son.
  • play_type définit ce que fait le programme pendant que le son est joué.
L'article « Jouer un fichier .wav en Python sur la brique EV3» présente un exemple de l'utilisation de cette méthode.

Méthode play_tone()

Cette méthode est équivalente à la brique graphique ci-dessus. Elle est déclarée comme ci-dessous.
play_tone(frequency, duration, delay=0.0, volume=100, play_type=0)
Les paramètres passé sont les mêmes que pour la brique graphique :
  • frequency est la fréquence du son exprimée en Hertz.
  • duration est la durée du son exprimée en secondes.
  • delay est le délai exprimé en secondes après le son.
  • volume est exprimé en % et permet de régler le volume du son.
  • play_type définit ce que fait le programme pendant que le son est joué.
L'exemple ci dessous utilise la méthode play_tone() pour jouer la gamme en Do majeur, chaque note étant tenue pendant une seconde :
from ev3dev2.sound import Sound

HP = Sound()

GAMME = [261.6, 293.7, 329.6, 349.2, 392.0, 440.0, 493.9, 523.2]

for note in GAMME:
    HP.play_tone(note, 1)

Méthode play_note()

Cette méthode est équivalente à la brique graphique ci-dessus. Elle est déclarée comme ci-dessous.
play_note(note, duration, volume=100, play_type=PLAY_WAIT_FOR_COMPLETE)
Les paramètres passé sont les mêmes que pour la brique graphique :
  • note est une chaîne de caractères exprimant le symbole musical de la note.
  • duration est la durée du son exprimée en secondes.
  • volume est exprimé en % et permet de régler le volume du son.
  • play_type définit ce que fait le programme pendant que le son est joué.
L'exemple ci dessous utilise la méthode play_note() pour jouer la gamme chromatique en Do majeur, chaque note étant tenue pendant une demi seconde :
from ev3dev2.sound import Sound

HP = Sound()

GAMME_CHROMATIQUE = ["C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", "C5"]

for note in GAMME_CHROMATIQUE:
    HP.play_note(note, 1)

Méthodes musicales tone() et play_song()

Pour jouer un morceau de musique, il est possible d'utilise les méthodes play_tone() ou play_note() à l'intérieur d'une boucle. Cependant, cette pratique présente quelques inconvénients :
  • A chaque itération dans la boucle, donc entre chaque note, il y a un temps non contrôlable, généré par l'interpréteur Python, qui donne un effet saccadé à la musique.
  • L'usage du paramètre play_type avec la valeur  Sound.PLAY_NO_WAIT_FOR_COMPLETE  ne concerne que la note sur laquelle il est utilisé. Autrement dit, l'usage de cette valeur va provoquer l'exécution de toutes les notes en même temps, chacune d'elle effaçant la précédente. Il est donc impossible de jouer un morceau de musique complet en mode parallèle.
Pour lever ces inconvénients, la classe Sound expose deux méthodes — tone() et play_song() — auxquelles on peut passer un morceau de musique entier sous forme de tableau. Ces méthodes permettent de jouer de la musique sur la brique EV3. Elles n'ont pas d'équivalent dans les briques graphiques Lego. Mais elles facilitent l’émission de morceaux de musique. Elles sont déclarées comme suit :
tone(tone_sequence, play_type=PLAY_WAIT_FOR_COMPLETE)
  • tone_sequence est un tableau de tuples, un tuple par note. Chaque tuple est composé de trois valeurs : la fréquence en Hertz, la durée en millisecondes, le délai après la note en millisecondes.
  • play_type définit ce que fait le programme pendant que le son est joué.
play_song(song, tempo=120, delay=0.05)
  • song est un tableau  de tuples, un tuple par note. Chaque tuple contient deux valeurs : le symbole musical de la  note, le symbole musical de la durée. 
  • tempo indique  le tempo en noires par secondes. La valeur par défaut est 120 ce qui correspond à Allegro en musique.
  • delay indique le délai entre chaque note. La valeur par défaut est cinq centièmes de secondes. Ce qui permet de couper les notes et de donner une attaque à chacune d'elles.
L'article « Jouer de la musique en Python sur la brique EV3» présente des exemples de l'utilisation de ces méthodes.

Méthode speak()

Cette méthode amusante interprète la chaîne de caractères text passée en paramètre pour faire parler la brique EV3. Elle effectue un appel à l'instruction espeak, le narrateur de Linux.  Elle est déclarée comme suit :
speak(text, espeak_opts='-a 200 -s 130', volume=100, play_type=0)
Les paramètres passés sont les suivants :
  • text est la chaîne de caractères à afficher.
  • espeak_opts est un paramètre de type chaîne de caractères qui permet de passer les options de la ligne de commande de l'instruction espeak
  • volume est exprimé en % et permet de régler le volume du son.
  • play_type définit ce que fait le programme pendant que le son est joué.
Le problème de cette méthode est que la langue utilisée par défaut est l'anglais. Ce qui fait que le texte français interprété et prononcé est souvent incohérent. L'article « Un robot EV3 qui parle» présente un exemple de l'utilisation de cette méthode paramétrée en langue française.

Commentaires

Posts les plus consultés de ce blog

Connecter ev3dev2 à Internet en WiFi

Connecter Visual Studio Code à un robot MindStorm EV3 avec ev3dev-browser

Installer les modules EV3DEV2 sur Python