Paso 2: Cargar el código para el Arduino
Ahora tienes que subir el siguiente código a su Arduino. También puede descargar el sketch de Arduino desde el enlace en la parte inferior de la página. Antes de subir el código, correctamente debe instalar las bibliotecas de servidor BitVoicer en el IDE de Arduino (importar un .zip biblioteca).
#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); }
Este bosquejo tiene siete partes principales:
- Referencias de la biblioteca y declaración de variables: las cuatro primeras líneas incluyen referencias a las bibliotecas BVSP, BVSMic, BVSSpeaker y DAC. Estas bibliotecas son proporcionadas por BitSophia y pueden encontrarse en la carpeta de instalación de servidor BitVoicer. La biblioteca CAD se incluye automáticamente cuando se agrega una referencia a la biblioteca de BVSSpeaker. Las otras líneas declaran constantes y variables utilizadas en el dibujo. La clase BVSP se utiliza para comunicarse con el servidor de BitVoicer, la clase BVSMic se utiliza para capturar y almacenar muestras de audio y la clase BVSSpeaker se utiliza para reproducir audio con la debida DAC.
- Configuración de función: esta función realiza las siguientes acciones: configura los modos de patillas y su estado inicial; Inicializa la comunicación serial; e inicializa las clases BVSP, BVSMic y BVSSpeaker. También establece "los controladores de eventos" (son realmente funcionan punteros) para los eventos frameReceived, modeChanged y streamReceived de la clase BVSP.
- Función Loop: esta función realiza cinco acciones importantes: solicita información de estado al servidor (función keepAlive()); comprueba si el servidor ha enviado todos los datos y procesa los datos recibidos (receive() función); controla la grabación y envío de flujos de audio (isSREAvailable(), startRecording(), funciones stopRecording() y sendStream()); Juegos de las muestras de audio en cola en la clase de BVSSpeaker (la función play()); y llamadas de la playNextLEDNote() de la función controla cómo el LED debe parpadear después se recibe la orden de playLEDNotes.
- Función BVSP_frameReceived: esta función es llamada cada vez que la función receive() identifica que un marco de completa ha sido recibida. Aquí ejecutar los comandos enviados desde el servidor de BitVoicer. Comandos que controla los LEDs contiene 2 bytes. El primer byte indica el pin y el segundo byte indica el valor del pin. Utilizar la función analogWrite() para establecer el valor apropiado en el pasador. También verificar si el comando playLEDNotes, que es de tipo Byte, ha sido recibido. Si se ha recibido, me puse playLEDNotes en true y marque la hora actual. Esta vez se utilizará la función playNextLEDNote para sincronizar los LEDs con la canción.
- Función BVSP_modeChanged: esta función es llamada cada vez que la función receive() identifica un cambio de modo en la dirección saliente (servidor--> Arduino). ¡ WOW!!!!!! ¡¿Qué es eso?! BitVoicer servidor puede enviar datos enmarcados o flujos de audio a Arduino. Antes de la comunicación de un modo a otro, BitVoicer el servidor envía una señal. La clase BVSP identifica esta señal y provoca el evento modeChanged. En la función de BVSP_modeChanged, si detecta que la comunicación va del modo de secuencia a modo de enmarcado, sé que el audio ha terminado por lo que te puedo decir la clase BVSSpeaker para detener la reproducción de muestras de audio.
- Función BVSP_streamReceived: esta función es llamada cada vez que la función receive() identifica que se han recibido muestras de audio. Simplemente recuperar las muestras y cola en la clase de BVSSpeaker tan la función play() puede reproducirlos.
- función playNextLEDNote: esta función sólo funciona si la función de BVSP_frameReceived identifica el comando playLEDNotes. Controla y sincroniza los LEDs con el audio enviado desde el servidor de BitVoicer. Para sincronizar los LEDs con el audio y saber el momento correcto, usé Sonic Visualizer. Este software libre me ha permitido ver que el audio ondas así que me di cuenta fácilmente cuando se presiona una tecla del piano. También muestra una línea de tiempo y es como conseguí el utilizado en esta función de milisegundos. Suena como un truco tonto y es. Creo que sería posible analizar la reproducción de audio y enciende el LED correspondiente, pero que está fuera de mi alcance.