Logo Mon Club Elec

Processing – Sons avec la librairie Minim : Jouer un son à partir d’un fichier à la réception d’une chaîne de caractères sur le Port Série.

La librairie Minim est un outil puissant pour le traitement du son. Elle permet aux développeurs de créer des applications audio interactives et de jouer des sons à partir de fichiers. Dans cet article, nous allons voir comment utiliser la librairie Minim pour jouer un son à partir d’un fichier à la réception d’une chaîne de caractères sur le Port Série. Nous verrons comment configurer le Port Série et comment utiliser la librairie Minim pour jouer le son.

Processing – Sons avec la librairie Minim : Jouer un son à partir d’un fichier à la réception d’une chaîne de caractères sur le Port Série.

Processing – Sons avec la librairie Minim : Jouer un son à partir d’un fichier à la réception d’une chaîne de caractères sur le Port Série.

Explication

  • Ce programme joue un son à la réception sur le port série d’une chaine de caractère correspondant au fichier son à jouer…
  • Ce programme pourra servir de base pour jouer des sons sur un robot avec eeePC embarqué à la demande de la carte Arduino qui n’aura qu’à envoyer le nom du fichier à jouer pour que le robot le fasse : prometteur ! Surtout qu’on peut utiliser tels quels des sons trouvés sur le net (r2d2, sabre laser, etc… ) ou des textes enregistrés dans Audacity. Un robot qui parle et fait des sons, c’est quand même top !
  • Pour plus d’info sur le concept de eeePC embarqué avec une carte Arduino, voir la page : « Symbiose numérique » Arduino / PC

Ressources utiles

  • Librairie GUI controlP5
  • Librairie sons Minim

Le programme Processing

Processing – Sons avec la librairie Minim : Jouer un son à partir d’un fichier à la réception d’une chaîne de caractères sur le Port Série.
  • Copier/coller ce programme dans une interface Processing et enregistrer-le
  • Mettre dans le répertoire du programme les fichiers sons utilisés. Les fichiers que j’ai utilisés sont ici
  • Une fois fait, lancer le programme.
  • Connecter une carte Arduino programmée avec le programme ci-dessous sur le port Série pour pouvoir saisir la chaine son de votre choix.
  • Saisissez des chaines correspondant au nom du fichier son à jouer présent dans le répertoire du programme et le programme jouera ce son.
// Programme processing
// généré avec le générateur de code Processing
// www.mon-club-elec.fr
// par X. HINAULT – Février 2011 – tous droits réservés

/////////////// Description du programme ////////////
// Utilise un/des objets String (chaîne de caractère)
// Utilise le port Serie
// Utilise la librairie GUI controlP5
// Utilise un/des bouton(s) simple(s) (Button)
// Utilise un/des champ(s) texte (Textfield)
// Ajoute un bouton et un champ pour chemin fichier

/*
Envoie vers Arduino une chaîne saisie dans un champ texte.
Reçoit la chaine renvoyée par Arduino et l’affiche dans la console.
Le fichier son voulu est joué en fonction de la chaine de caractères reçue.
*/

// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

import processing.serial.*; // importe la librairie série processing

import ddf.minim.*; // importe la librairie minim de gestion des sons sous Processing
// cette librairie doit être présente dans le répertoire /libraries du répertoire Processing
// voir ici : http://code.compartmental.net/tools/minim/

import controlP5.*; // importe la librairie GUI controlP5
// cette librairie doit être présente dans le répertoire /libraries du répertoire Processing
// voir ici : http://www.sojamo.de/libraries/controlP5/

// déclaration objets

String str1 = « machaine »; // déclare un objet String (chaine de caractère)
String chaineEnvoi = «  »; // déclare un objet String (chaine de caractère)

// — port Série —
Serial  myPort; // Création objet désignant le port série

// — sons —
Minim minim; // déclare un objet de type Minim de portée globale
AudioPlayer player; // déclare un objet Audioplayer pour lire les sons

// — interface GUI —
ControlP5 controlP5; // déclare un objet principal de la librairie GUI controlP5

Button envoiButton; // déclare objet Button  

Textfield chaineText; // déclare des objets Textfield

// déclaration variables globales

//—— déclaration des variables de couleur utiles —-
int jaune=color(255,255,0);
int vert=color(0,255,0);
int rouge=color(255,0,0);
int bleu=color(0,0,255);
int noir=color(0,0,0);
int blanc=color(255,255,255);
int bleuclair=color(0,255,255);
int violet=color(255,0,255);

// XXXXXXXXXXXXXXXXXXXXXX  Fonction SETUP XXXXXXXXXXXXXXXXXXXXXX

void setup(){ // fonction d’initialisation exécutée 1 fois au démarrage

        // —- initialisation paramètres graphiques utilisés
        colorMode(RGB, 255,255,255); // fixe format couleur R G B pour fill, stroke, etc…
        fill(0,0,255); // couleur remplissage RGB
        stroke (0,0,0); // couleur pourtour RGB
        rectMode(CORNER); // origine rectangle : CORNER = coin sup gauche | CENTER : centre
        imageMode(CORNER); // origine image : CORNER = coin sup gauche | CENTER : centre
        //strokeWeight(0); // largeur pourtour
        frameRate(30);// Images par seconde

        // — initialisation fenêtre de base —
        size(400, 130); // ouvre une fenêtre xpixels  x ypixels
        background(0,0,0); // couleur fond fenetre

// — initialisation des objets et fonctionnalités utilisées —

        //————- initialisation port série —-
        println(Serial.list()); // affiche dans la console la liste des ports séries
        // Vérifier que le numéro du port série utilisé est le meme que celui utilisé avec  Serial.list()[index]
        myPort = new Serial(this, Serial.list()[0], 115200); // Initialise une nouvelle instance du port Série
        //myPort = new Serial(this, « /dev/ttyUSB0 », 115200); // Initialise une nouvelle instance du port Série
        myPort.bufferUntil(\n); // attendre arrivée d’un saut de ligne pour générer évènement série

        //————- initialisation objets de la librairie Minim (sons) —-
        // initialise l’objet Minim déclaré – cet objet donne accès à Javasound
        minim = new Minim(this); // Initialise l’objet Minim – le parent utilisé est this par défaut

        //— chargement d’un fichier son —-
        player = minim.loadFile(« test_des_moteurs.mp3 »); // charge un fichier son dans l’objet Audioplayer
        // ajouter le fichier sons dans le répertoire du programme via Sketch > Add File
        // taille par défaut du buffer 1024

        //—- infos sur le fichier sons et objets sons Minim —
        println(« **** Infos Audio **** »);
        player.printControls(); // pour avoir info sur les paramètres sons disponibles et leurs grandeurs
        println(« Volume actuel= »+player.getVolume()); // affiche la valeur du volume actuel
        println(« Durée Totale= »+player.length()+« ms »); // affiche la taille du fichier
        println(« Taille Buffer= »+player.bufferSize()); // affiche la taille du buffer utilisé
        println(« Format Audio= »+player.getFormat()); // affiche le format du fichier audio
        println(« Taux Echantillonage= »+player.sampleRate()); // affiche le taux d’échantillonage du fichier audio
        println(« Type= »+player.type()); // affiche le type du fichier audio (Mono ou stéréo)
        println(« Position= »+player.position()); // affiche la position dans le fichier son
        println();

        //======== Initialisation Objets GUI ControlP5 =========

        controlP5 = new ControlP5(this); // initialise l’objet principal de la librairie GUI controlP5

        // typeObjet nomObjet=controlP5.addObjet(paramètres); // pour info : déclaration / initialisation possible en 1 ligne
        // Textfield field = controlP5.addTextfield(« myWindowTextfield »,70,130,100,20); // exemple

        //======== Initialisation Objets Button =========

        //—- le bouton envoi chaine
        envoiButton=controlP5.addButton(« envoiButton »,0,width60,height40,50,24); // initialise et ajoute un Button au ControlP5
        envoiButton.setLabelVisible(true); // affichage des labels
        envoiButton.setLabel(« ENVOI »); // fixe label du bouton
        envoiButton.setColorActive(color(255,0,0)); // fixe la couleur active
        envoiButton.setColorForeground(color(0,255,255)); // fixe couleur avant

        //======== Initialisation Objets Textfield =========

        //—- champ texte saisie chaine
        chaineText=controlP5.addTextfield(« cheminText »,10,height40,300,20); // initialise et ajoute un Textfield au ControlP5
        chaineText.setAutoClear(false); // autoeffacement après return
        chaineText.setValue(chaineEnvoi); // initialise Texte du champ
        chaineText.setLabelVisible(true); // affichage des labels
        chaineText.setLabel(« CHEMIN »); // fixe label
        chaineText.setColorActive(color(255,0,0)); // fixe la couleur active
        chaineText.setColorForeground(color(0,255,255)); // fixe couleur avant

} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

void  draw() { // fonction exécutée en boucle

// tout se passe dans Serial Event

} // fin de la fonction draw()

// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX

        //————- Fonction de gestion des évènements série —-
         void serialEvent (Serial myPort) { // fonction appelée lors de la survenue d’un évènement série

        // ******** Gestion de la valeur reçue sur le port série : **********

        String inString = myPort.readStringUntil(\n); // chaine stockant la chaîne reçue sur le port Série
        // saut de ligne en marque de fin

        if (inString != null) { // si la chaine recue n’est pas vide

                print (inString); // affichage brut de la chaine recue

        //———— analyse de la chaine reçue et sélection son ——–
        String nomFichier=«  »; // String pour nom fichier

        if (match(inString,« test_des_moteurs.mp3 »)!=null) nomFichier=« test_des_moteurs.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_moteur_gauche_avant.mp3 »)!=null) nomFichier=« test_moteur_gauche_avant.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_moteur_gauche_arriere.mp3 »)!=null) nomFichier=« test_moteur_gauche_arriere.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_moteur_droit_arriere.mp3 »)!=null) nomFichier=« test_moteur_droit_arriere.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_moteur_droit_avant.mp3 »)!=null) nomFichier=« test_moteur_droit_avant.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_moteur_droit_avant.mp3 »)!=null) nomFichier=« test_moteur_droit_avant.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_tourne_gauche.mp3 »)!=null) nomFichier=« test_tourne_gauche.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_tourne_droite.mp3 »)!=null) nomFichier=« test_tourne_droite.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_deux_moteurs_avant.mp3 »)!=null) nomFichier=« test_deux_moteurs_avant.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_deux_moteurs_arriere.mp3 »)!=null) nomFichier=« test_deux_moteurs_arriere.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« test_des_moteurs_fini.mp3 »)!=null) nomFichier=« test_des_moteurs_fini.mp3 »; // test la chaine reçue et définit nom fichier son associé

        if (match(inString,« r2d2_1.mp3 »)!=null) nomFichier=« r2d2_1.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« r2d2_2.mp3 »)!=null) nomFichier=« r2d2_2.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« r2d2_3.mp3 »)!=null) nomFichier=« r2d2_3.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« r2d2_4.mp3 »)!=null) nomFichier=« r2d2_4.mp3 »; // test la chaine reçue et définit nom fichier son associé
        if (match(inString,« r2d2_5.mp3 »)!=null) nomFichier=« r2d2_5.mp3 »; // test la chaine reçue et définit nom fichier son associé

         if (nomFichier!=«  ») { // si une chaine valide a été reçue
           //— chargement du fichier son —-
           //player = minim.loadFile(« test_des_moteurs.mp3 »); // charge un fichier son dans l’objet Audioplayer
           player = minim.loadFile(nomFichier); // charge un fichier son dans l’objet Audioplayer
            // ajouter le fichier sons dans le répertoire du programme via Sketch > Add File
            // taille par défaut du buffer 1024
           //player.setVolume(65535); // fixe le volume 0-65536

            player.play(); // lance la lecture du son
            delay (player.length()+500); // attend la durée du son + délai

           //— signale à Arduino fin son
           myPort.write(‘H’); // envoie le caractère H sur le port Série pour signaler fin son

         } // fin si chaine valide

        } // fin condition chaine recue pas vide

} // fin de la fonction de gestion des évènements Série

//————- Fonction d’arret de la librairie Minim —-

void stop(){ // fonction d’arrêt de la librairie Minim

        // toujours fermer les objets Minim
        player.close();
        minim.stop();
        super.stop();

}

// Gestion des évènements des objets GUI controlP5 —-

//—— fonction gestion globale des évènements GUI controlP5
public void controlEvent(ControlEvent theEvent) {
        //println(theEvent.controller().name());// affiche le nom de l’évènement
}

        //—- evenement bouton envoi chaine

void envoiButton(int theValue) { // fonction évènement Button de meme nom – reçoit la valeur

        println(« Evènement envoiButton »);

        myPort.write(chaineText.getText()+« \n« ); // envoie la chaine suivi saut ligne sur le port Série
        print(« Envoi de la chaine : »);
        print(chaineText.getText()+« \n« );
        chaineText.setValue(«  »); // vide le champ texte

} // fin evènement bouton envoi

// —— gestion évènement Textfield ——

        //—- evenement champ texte chemin fichier

public void chaineText(String theText) { // fonction évènement Textfield de meme nom – déclenché par return – reçoit la chaine

        //println(« Evènement CheminText avec valeur = « +theText);

        chaineEnvoi=theText; // mémorise le contenu du champ

        //println(« Le chemin est : »+chaineEnvoi);

} // fin evènement champ texte chemin fichier

//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX

 

Programme Arduino à utiliser

  • Ce programme très simple est un « miroir » qui renvoie uniquement la chaine reçue sur le port Série, ce qui permet de tester le résultat de chaines depuis Processing lui-même.
// — Programme Arduino —
// Trame de code générée par le générateur de code Arduino
// du site www.mon-club-elec.fr

// Auteur du Programme : X. HINAULT – Tous droits réservés
// Programme écrit le : 20/2/2011.

// ——- Licence du code de ce programme —–
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License,
//  or any later version.
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

// ////////////////////  PRESENTATION DU PROGRAMME ////////////////////

// ——– Que fait ce programme ? ———
 /* Ce programme reçoit une chaine saisie dans un champ texte d’une interface Processing via le port Série
 et renvoie cette chaine sur le port Série pour réafficher la chaîne reçue dans la console Processing */

// — Fonctionnalités utilisées —

// Utilise la connexion série vers le PC
// Utilise / fonctionne avec une interface Processing coté PC

// ——– Circuit à réaliser ———

// La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB)

// /////////////////////////////// 1. Entête déclarative ///////////////////////
// A ce niveau sont déclarées les librairies incluses, les constantes, les variables, les objets utiles…

// — Déclaration des constantes —

// — Inclusion des librairies —

// — Déclaration des constantes utiles —

// — Déclaration des constantes des broches E/S numériques —

// — Déclaration des constantes des broches analogiques —

// — Déclaration des variables globales —

 int octetReception=0; // variable de stockage des valeurs reçues sur le port Série
 long nombreReception=0; // variable de stockage du nombre  reçu sur le port Série
 long nombreReception0=0; // variable de stockage du dernier nombre  reçu sur le port Série
 String chaineReception=«  »; // déclare un objet String vide pour reception chaine

// — Déclaration des objets utiles pour les fonctionnalités utilisées —

// ////////////////////////// 2. FONCTION SETUP = Code d’initialisation //////////////////////////
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()

// — ici instructions à exécuter 1 seule fois au démarrage du programme —

// ——- Initialisation fonctionnalités utilisées ——-  

Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission

// ——- Broches en sorties numériques ——-  

// ——- Broches en entrées numériques ——-  

// ——- Activation si besoin du rappel au + (pullup) des broches en entrées numériques ——-  

// ——- Initialisation des variables utilisées ——-  

} // fin de la fonction setup()
// ********************************************************************************

////////////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////
// la fonction loop() s’exécute sans fin en boucle aussi longtemps que l’Arduino est sous tension

void loop(){ // debut de la fonction loop()

// — ici instructions à exécuter par le programme principal —

//—- code type réception chaine sur le port série —
while (Serial.available()>0) { // tant qu’un octet en réception
        octetReception=Serial.read(); // Lit le 1er octet reçu et le met dans la variable

        if (octetReception==10) { // si Octet reçu est le saut de ligne
                Serial.println (« Arduino a recu : »+chaineReception); // affiche la chaine recue
                chaineReception=«  »; //RAZ le String de réception
                break; // sort de la boucle while
        }
        else { // si le caractère reçu n’est pas un saut de ligne
                chaineReception=chaineReception+char(octetReception); // ajoute le caratère au String
        }

} // fin tant que  octet réception

//—– une fois que le saut de ligne est reçu, on sort du While et on se positionne ici

} // fin de la fonction loop() – le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

// ////////////////////////// FONCTIONS DE GESTION DES INTERRUPTIONS ////////////////////

// ////////////////////////// AUTRES FONCTIONS DU PROGRAMME ////////////////////

//—- fonction de réception valeur entière sur le port série —

// ////////////////////////// Fin du programme ////////////////////
 

Noter cet article

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Archive Mon Club Elec

Articles populaires

Newsletter

Inscrivez-vous maintenant et bénéficiez d'un soutien continu pour réaliser vos travaux électriques en toute sécurité.