Étape 2: Télécharger le code sur l’Arduino
Maintenant, vous devrez télécharger le code ci-dessous sur votre Arduino. Vous pouvez également télécharger le sketch Arduino depuis le lien en bas de la page. Avant de télécharger le code, vous devez correctement installer les bibliothèques BitVoicer Server dans l’IDE Arduino (Importer un fichier zip bibliothèque).
#include <BVSP.h>#include <BVSMic.h> #include <BVSSpeaker.h> #include <DAC.h>// Defines the Arduino pin that will be used to capture audio #define BVSM_AUDIO_INPUT 7// Defines the LED pins #define RED_LED_PIN 6 #define YELLOW_LED_PIN 9 #define GREEN_LED_PIN 10// Defines the constants that will be passed as parameters to // the BVSP.begin function const unsigned long STATUS_REQUEST_TIMEOUT = 3000; const unsigned long STATUS_REQUEST_INTERVAL = 4000;// Defines the size of the mic audio buffer const int MIC_BUFFER_SIZE = 64;// Defines the size of the speaker audio buffer const int SPEAKER_BUFFER_SIZE = 128;// Defines the size of the receive buffer const int RECEIVE_BUFFER_SIZE = 2;// Initializes a new global instance of the BVSP class BVSP bvsp = BVSP();// Initializes a new global instance of the BVSMic class BVSMic bvsm = BVSMic();// Initializes a new global instance of the BVSSpeaker class BVSSpeaker bvss = BVSSpeaker();// Creates a buffer that will be used to read recorded samples // from the BVSMic class byte micBuffer[MIC_BUFFER_SIZE];// Creates a buffer that will be used to write audio samples // into the BVSSpeaker class byte speakerBuffer[SPEAKER_BUFFER_SIZE];// Creates a buffer that will be used to read the commands sent // from BitVoicer Server. // Byte 0 = pin number // Byte 1 = pin value byte receiveBuffer[RECEIVE_BUFFER_SIZE];// These variables are used to control when to play // "LED Notes". These notes will be played along with // the song streamed from BitVoicer Server. bool playLEDNotes = false; unsigned int playStartTime = 0;void setup() { // Sets up the pin modes pinMode(RED_LED_PIN, OUTPUT); pinMode(YELLOW_LED_PIN, OUTPUT); pinMode(GREEN_LED_PIN, OUTPUT); // Sets the initial state of all LEDs digitalWrite(RED_LED_PIN, LOW); digitalWrite(YELLOW_LED_PIN, LOW); digitalWrite(GREEN_LED_PIN, LOW); // Starts serial communication at 115200 bps Serial.begin(115200); // Sets the Arduino serial port that will be used for // communication, how long it will take before a status request // times out and how often status requests should be sent to // BitVoicer Server. bvsp.begin(Serial, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL); // Defines the function that will handle the frameReceived // event bvsp.frameReceived = BVSP_frameReceived; // Sets the function that will handle the modeChanged // event bvsp.modeChanged = BVSP_modeChanged; // Sets the function that will handle the streamReceived // event bvsp.streamReceived = BVSP_streamReceived; // Prepares the BVSMic class timer bvsm.begin(); // Sets the DAC that will be used by the BVSSpeaker class bvss.begin(DAC); }void loop() { // Checks if the status request interval has elapsed and if it // has, sends a status request to BitVoicer Server bvsp.keepAlive(); // Checks if there is data available at the serial port buffer // and processes its content according to the specifications // of the BitVoicer Server Protocol bvsp.receive(); // Checks if there is one SRE available. If there is one, // starts recording. if (bvsp.isSREAvailable()) { // If the BVSMic class is not recording, sets up the audio // input and starts recording if (!bvsm.isRecording) { bvsm.setAudioInput(BVSM_AUDIO_INPUT, DEFAULT); bvsm.startRecording(); } // Checks if the BVSMic class has available samples if (bvsm.available) { // Makes sure the inbound mode is STREAM_MODE before // transmitting the stream if (bvsp.inboundMode == FRAMED_MODE) bvsp.setInboundMode(STREAM_MODE); // Reads the audio samples from the BVSMic class int bytesRead = bvsm.read(micBuffer, MIC_BUFFER_SIZE); // Sends the audio stream to BitVoicer Server bvsp.sendStream(micBuffer, bytesRead); } } else { // No SRE is available. If the BVSMic class is recording, // stops it. if (bvsm.isRecording) bvsm.stopRecording(); } // Plays all audio samples available in the BVSSpeaker class // internal buffer. These samples are written in the // BVSP_streamReceived event handler. If no samples are // available in the internal buffer, nothing is played. bvss.play(); // If playLEDNotes has been set to true, // plays the "LED notes" along with the music. if (playLEDNotes) playNextLEDNote(); }// Handles the frameReceived event void BVSP_frameReceived(byte dataType, int payloadSize) { // Checks if the received frame contains binary data // 0x07 = Binary data (byte array) if (dataType == DATA_TYPE_BINARY) { // If 2 bytes were received, process the command. if (bvsp.getReceivedBytes(receiveBuffer, RECEIVE_BUFFER_SIZE) == RECEIVE_BUFFER_SIZE) { analogWrite(receiveBuffer[0], receiveBuffer[1]); } } // Checks if the received frame contains byte data type // 0x01 = Byte data type else if (dataType == DATA_TYPE_BYTE) { // If the received byte value is 255, sets playLEDNotes // and marks the current time. if (bvsp.getReceivedByte() == 255) { playLEDNotes = true; playStartTime = millis(); } } }// Handles the modeChanged event void BVSP_modeChanged() { // If the outboundMode (Server --> Device) has turned to // FRAMED_MODE, no audio stream is supposed to be received. // Tells the BVSSpeaker class to finish playing when its // internal buffer become empty. if (bvsp.outboundMode == FRAMED_MODE) bvss.finishPlaying(); } // Handles the streamReceived event void BVSP_streamReceived(int size) { // Gets the received stream from the BVSP class int bytesRead = bvsp.getReceivedStream(speakerBuffer, SPEAKER_BUFFER_SIZE); // Enqueues the received stream to play bvss.enqueue(speakerBuffer, bytesRead); }// Lights up the appropriate LED based on the time // the command to start playing LED notes was received. // The timings used here are syncronized with the music. void playNextLEDNote() { // Gets the elapsed time between playStartTime and the // current time. unsigned long elapsed = millis() - playStartTime; // Turns off all LEDs allLEDsOff(); // The last note has been played. // Turns off the last LED and stops playing LED notes. if (elapsed >= 11500) { analogWrite(RED_LED_PIN, 0); playLEDNotes = false; } else if (elapsed >= 9900) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 9370) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 8900) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 8610) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 8230) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 7970) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 7470) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 6760) analogWrite(GREEN_LED_PIN, 255); // E note else if (elapsed >= 6350) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 5880) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 5560) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 5180) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 4890) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 4420) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 3810) analogWrite(GREEN_LED_PIN, 255); // E note else if (elapsed >= 3420) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 2930) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 2560) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 2200) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 1930) analogWrite(YELLOW_LED_PIN, 255); // D note else if (elapsed >= 1470) analogWrite(RED_LED_PIN, 255); // C note else if (elapsed >= 1000) analogWrite(GREEN_LED_PIN, 255); // E note }// Turns off all LEDs. void allLEDsOff() { analogWrite(RED_LED_PIN, 0); analogWrite(YELLOW_LED_PIN, 0); analogWrite(GREEN_LED_PIN, 0); }
Ce croquis a sept grandes parties :
- Les références de bibliothèque et de la déclaration de variable: les quatre premières lignes incluent des références aux bibliothèques de DJESTOXX, BVSMic, BVSSpeaker et DAC. Ces bibliothèques sont fournis par BitSophia et se trouvent dans le dossier d’installation de serveur BitVoicer. La bibliothèque DAC est incluse automatiquement lorsque vous ajoutez une référence à la bibliothèque de BVSSpeaker. Les autres lignes déclarent les constantes et les variables utilisées tout au long de l’esquisse. La classe DJESTOXX est utilisée pour communiquer avec le serveur BitVoicer, la classe BVSMic est utilisée pour capturer et stocker les échantillons audio et de la classe BVSSpeaker est utilisée pour reproduire audio à l’aide de la raison DAC.
- Fonction de configuration: cette fonction effectue les actions suivantes : met en place les modes de pin et de leur état initial ; Initialise la communication série ; et initialise les classes DJESTOXX, BVSMic et BVSSpeaker. Il définit également des "gestionnaires d’événements" (ils sont en fait fonctionner les pointeurs) pour les événements modeChanged, frameReceived et streamReceived de la classe DJESTOXX.
- Fonction de boucle: cette fonction effectue cinq actions importantes : demande d’infos d’État sur le serveur (fonction keepAlive()) ; vérifie si le serveur a envoyé toutes les données et traite les données reçues (fonction receive()) ; contrôle de l’enregistrement et l’envoi de flux audio (isSREAvailable(), startRecording(), fonctions stopRecording() et sendStream()) ; fois les échantillons audio en file d’attente dans la classe BVSSpeaker (fonction play()) ; et appelle le playNextLEDNote() fonction qui contrôle comment les LEDs doivent clignoter après réception de la commande playLEDNotes.
- BVSP_frameReceived fonction: cette fonction est appelée chaque fois que la fonction receive() identifie qu’une trame complète a été reçue. Ici, je lance les commandes envoyées par le serveur BitVoicer. Commandes qui contrôle les LEDs contient 2 octets. Le premier octet indique le code pin et le deuxième octet indique la valeur de code pin. J’utilise la fonction analogWrite() pour définir la valeur appropriée à la broche. J’ai aussi vérifier si la commande playLEDNotes, qui est de type Byte, a été reçue. Si elle a été reçue, j’ai mis playLEDNotes à true et marquer l’heure actuelle. Cette fois-ci serviront par la fonction playNextLEDNote pour synchroniser les LEDs avec la chanson.
- BVSP_modeChanged fonction: cette fonction est appelée chaque fois que la fonction receive() identifie un changement de mode dans la direction sortante (serveur--> Arduino). WOW ! Qu'est-ce que c est?! BitVoicer serveur peut envoyer les données encadrées ou flux audio à l’Arduino. Avant que la communication passe d’un mode à l’autre, BitVoicer Server envoie un signal. La classe DJESTOXX identifie ce signal et déclenche l’événement modeChanged. Dans la fonction BVSP_modeChanged, si je détecte que la communication va de mode stream en mode encadrée, je sais que l’audio est terminée, je ne peux dire la classe BVSSpeaker pour arrêter la lecture des échantillons audio.
- BVSP_streamReceived fonction: cette fonction est appelée chaque fois que la fonction receive() identifie que les échantillons audio ont été reçus. J’ai simplement récupérer les échantillons et file d’attente dans la classe BVSSpeaker pour la fonction play() pouvez les reproduire.
- playNextLEDNote fonction: cette fonction ne fonctionne que si la fonction BVSP_frameReceived identifie la commande playLEDNotes. Il contrôle et synchronise les LEDs avec l’audio envoyée du serveur BitVoicer. Pour synchroniser les LEDs avec l’audio et connaître le bon timing, j’ai utilisé le Visualiseur de Sonic. Ce logiciel libre m’a permis de voir que l’audio agite donc je pourrais dire facilement lorsqu’une touche a été enfoncée. Il montre également une ligne de temps et c’est comment j’ai obtenu les millisecondes utilisés dans cette fonction. On dirait un truc stupide, et il est. Je pense qu’il serait possible d’analyser le flux audio et la LED correspondante s’allume, mais c’est hors de ma portée.