Implementación de una Armónica con Processing
Camilo Ernesto Montes Navarro
Control 1 y Laboratorio
Resumen:
Básicamente el objetivo de la practica es aprovechar las ventajas de programación del Sofware Procesing 2.0 de la pagina oficial. Este es un entorno programable que posee mucha versatilidad, y que por medio del cual podemos hacer múltiples tareas dejando volar la imaginación. En este trabajo se pretende hacer control de una interfaz que simule una especie de instrumento virtual, específicamente una armónica. Consta de una sintetización de sonido por teclado, selección de activación manual o programación de melodías con su respectivo control de velocidad por Hardware(pulsadores).
Al final del documento se encuentra escrito el código primario usado temporalmente.
Implementación:
El primer paso para el proyecto fue la captación de sonido por medio de un sintetizador y un programa de grabación.
Para esto se hizo uso de la pagina:
Pulse aquí, aquí se encuentran disponibles las notas de una armónica en una aplicación de Android.
Luego de la adquisición, se procede a la creación del proyecto en procesing. Para poder implementar audio es necesario cargar una libreria en el procesing que permita su lectura y reproducción, en este caso se usa la libreria Maxim, lista en la pagina del Processing¨.
A continuación se muestra una imagen de una porción de la ventana en la cual se encuentra escrito el programa:
![]() |
| Imagen de Armónica |
1. En la primera parte se carga la libreria Maxim, para el propósito descrito anteriormente.
Se declara: AudioPlayer junto con el nombre del archivo de audio que se va a usar en reproducción (lar archivos de audio en formato .wav). Añadido cargamos los datos para montar imágenes y trabajar con variables booleanas. Estas variables se explicarán mas adelante.
Lo anterior corresponde a la declaración de datos a utilizar. Posteriormente formamos la estructura para el Setup del Procesing:
1. Cargamos una imagen para agregar estética el entorno visual del trabajo con:
img = loadImage("armonica1.jpg");
Nota: el tamaño esta programado para quedar igual al de la interfaz toma el tamaño de la imagen.
2. Carga de registro de audio:
TurkishMarch22= maxim.loadFile("TurkishMarch22.wav");
MattArmonica22= maxim.loadFile("MattArmonica22.wav");
Titanic22= maxim.loadFile("Titanic22.wav");
(Sonidos que se reproducirán)
maxim = new Maxim(this);
G1 = maxim.loadFile("G1.wav");
G2 = maxim.loadFile("G2.wav");...
.
.
.
(Notas de la armonica)
3. Al escribir lo siguiente en el Setup podemos hacer que la reproduccion no sea continua luego de una activación:
G1.setLooping(false);
G2.setLooping(false);
G3.setLooping(false);
G4.setLooping(false); ...
.
.
.
G10.set.Looping(false);
G10.set.Looping(false);
4. En la tercera parte del programa se comienza a armar el funcionamiento como tal:
Se decide activar las notas del instrumento en cuestión a través de las teclas del computador (teclas de la a--ñ para mayor facilidad y sencillez). Con cada presión se reproduce la nota asignada.
Para esto se usa el Keypressed. Dentro de esta estructura de Processing nos permite leer si fue presionada una tecla o no. Ejemplo:
if(key=='a'){
Acciones...
} //// Si se ha presionado la tecla a se ejecuta lo que este dentro de la sentencia.
De esta forma se logra la reproducción individual de cada nota.
5. Como ya es posible tocar una nota, se adiciona un control que nos permita decidir si se quiere escuchar una melodía activada por tecla o tonos asignados.
En este caso la tecla que gobierna sera la 'm'. Se programa la interfaz de modo tal que cuando se presione esta tecla podamos hacer una transición en la modalidad de funcionamiento, es decir si estamos tocando notas individuales, se cambie a toque de melodía y visceversa.
Ademas de la tecla m, usamos una variable auxiliar booleana para hacer uso de sus dos estados, esta variable es la que aparece en el programa como 'value'. Explícitamente, si esta variable es 'true' entonces se anula función de escuchar alguna melodía, y tenemos la oportunidad de hacer música con nuestras manos.
De lo contrario podemos escuchar un extracto de música de varios estilos.
Se tiene algo como se muestra a continuación:
...
Si value==false entonces:
modo Tonos con teclado....
Si value==true entonces:
se activa modo de Música con teclas...
Control de velocidad en modo melodía....
....
5. Sobre esta funcionalidad se añade un control de velocidad de reproducción, el cual consiste en que cuando se este en este estado, el usuario cuenta con 4 niveles de velocidad sobre los cuales quiere oir la musicalización ofrecida, los cuales también se activan por teclado (teclas a--f, específicamente en modo melodía).
Cuando se este este modo con las teclas del PC, esta a disposición la posibilidad de aumentar la velocidad de reproducción:
Por ejemplo:
if(key=='a'){
//////Si esta tecla se presiona el sonido se reproduce en velocidad normal
Titanic22.speed(1.00);
TurkishMarch22.speed(1.00);
MattArmonica22.speed(1.0);}
if(key=='s'){
Titanic22.speed(1.12);
TurkishMarch22.speed(1.12);
MattArmonica22.speed(1.12);}
...Esto para cuando se este jugando con la música.
..SPEED(K): nos permite acelerar o desacelerar un archivo de audio. Es usada en el ejemplo anterior.
Para lo que concierne a la hora de escuchar los sonidos guardados cuando se haya presionado la tecla 'm', estos se activaran con las teclas 'v','b', y 'n'.
Al presionar 'v' se activa el archivo especificado por "TurkishMarch22.wav", la cual es unas de las mas reconocidas obras de Mozart.
Cuando es 'b' el presionada entonces se escucha "MattArmonica22.wav"una melodía infantil de caricaturas.
y cuando es 'n' se escucha "Titanic22.wav"segmento de la banda sonora de Titanic.
(Nota: La música se toca al compás de la armónica).
![]() |
| Ubicación de Pixeles. |
6. Luego de tener todo este repertorio de acciones, se procede a 'maquillar' el entorno de la interfaz. Para lo anterior,ubicamos la posición de los pixeles que marquen en la imagen de la armónica los orificios por los que se tocan las notas del instrumento. (Los orificios rectangulares distribuidos verticalmente en la imagen señalados con rojo).
![]() |
| Sonidos que se reproducen con el teclado (tecla a hasta ñ) . |
![]() |
| Cada recuadro se ilumina al presionar determinada nota. |
Para adornar el programa, se crea una función que tenga la facultad de iluminar cada recuadro que represente la correspondiente.
En las figuras anteriores, se muestra que nota se activa y que recuadro se ilumina.
Asuntos finales:
Otra opcion para hacer mejoras al diseño es hacer uso de la librería Minim, la cual nos permite mayor volumen y fidelidad de audio.
Otra opcion para hacer mejoras al diseño es hacer uso de la librería Minim, la cual nos permite mayor volumen y fidelidad de audio.
La idea es continuar con las mejoras en cuanto a la presentación del trabajo, la implementación en Arduino arrojo una serie de inconvenientes que no permitieron su descripción en este apartado, sin embargo aun esta en pie su realización . Se puede hacer el control de reproducción de audio através de cuatro botones o pulsadores, esto como parte del la integración de Hardware para el trabajo. En el proyecto están las librerías Arduino y la asignación de variables para leer el Arduino. Pero se dejaron como comentarios.
Se puede modificar la interfaz al gusto jugando con nuevas imágenes, audio, solo es dejar volar la imaginación...
Paginas de Interés:
//import processing.serial.*;
//import cc.arduino.*;
//Arduino arduino;
//int ledPin9=9;
//int ledPin8=8; ///Pines para la lectura del arduino(pines)
//int ledPin7=7;
//int ledPin=7;
Maxim maxim;
AudioPlayer G1;
AudioPlayer G2;
AudioPlayer G3;
AudioPlayer G4;
AudioPlayer G5;
AudioPlayer G6;
AudioPlayer G7;
AudioPlayer G8;
AudioPlayer G9;
AudioPlayer G10;
AudioPlayer TurkishMarch22;
AudioPlayer MattArmonica22;
AudioPlayer Titanic22;
// The Setup function that we'll be called only once
PImage img;
boolean value=false;
boolean vel1=false;
//Arduino arduino;
void setup(){
// println(Arduino.list()); // Mostramos los puertos detectados
//arduino = new Arduino(this, Arduino.list()[], 57600);
//arduino.pinMode(ledPin7, Arduino.INPUT);
//arduino.pinMode(ledPin8, Arduino.INPUT);
//arduino.pinMode(ledPin9, Arduino.INPUT);
img = loadImage("armonica1.jpg");
//size(875, 275);
size(img.width,img.height);
background(255);
maxim = new Maxim(this);
G1 = maxim.loadFile("G1.wav");
G2 = maxim.loadFile("G2.wav");
G3 = maxim.loadFile("G3.wav");
G4 = maxim.loadFile("G4.wav");
G5 = maxim.loadFile("G5.wav");
G6 = maxim.loadFile("G6.wav");
G7 = maxim.loadFile("G7.wav");
G8 = maxim.loadFile("G8.wav");
G9 = maxim.loadFile("G9.wav");
G10 = maxim.loadFile("G10.wav");
TurkishMarch22= maxim.loadFile("TurkishMarch22.wav");
MattArmonica22= maxim.loadFile("MattArmonica22.wav");
Titanic22= maxim.loadFile("Titanic22.wav");
G1.setLooping(false);
G2.setLooping(false);
G3.setLooping(false);
G4.setLooping(false);
G5.setLooping(false);
G6.setLooping(false);
G7.setLooping(false);
G8.setLooping(false);
G9.setLooping(false);
G10.setLooping(false);
TurkishMarch22.setLooping(false);
MattArmonica22.setLooping(false);
Titanic22.setLooping(false);
//arduino=new Arduino(this.Arduino.list()[1].57600);
}
int c1=0;
void keyPressed(){
if(key=='m'){ //si es presionada la m
value=!value; /// el estado de la variable booleana pasa
} //de 1 a 0, y 0 a 1.
if(value==false){
TurkishMarch22.stop(); ///
Titanic22.stop(); ////Se detiene la reproduccion
MattArmonica22.stop(); //// d estos sonidos
if(key=='a'){
c1=1;
G1.play();primera nota
G1.cue(0);}
if(key=='s'){
c1=2;
G2.play();2da nota
G2.cue(0);}
if(key=='d'){
c1=3;
G3.play(); //3ra nota
G3.cue(0);
}
if(key=='f'){
c1=4;
G4.play();
G4.cue(0); //4ta nota
}
if(key=='g'){
c1=5;
G5.play();
G5.cue(0); //5ta nota
}
if(key=='h'){
c1=6;
G6.play();
G6.cue(0); } //6ta nota
if(key=='j'){
c1=7;
G7.play();
G7.cue(0); //7ma nota
}
if(key=='k'){
c1=8;
G8.play();
G8.cue(0); //8va nota
}
if(key=='l'){
c1=9;
G9.play();
G9.cue(0); //9naa nota
}
if(key=='ñ'){
c1=10;
G10.play(); //dcima nota
}
}
///// si value=true entonces se abre la posibilidad de escuchar la musica //////incluida
else{
int cont=0;
//if(key=='z'){
// vel1=!vel1;}
if(key=='v'){
cont=1;
MattArmonica22.stop();
Titanic22.stop();
maxim = new Maxim(this);
TurkishMarch22.play();
TurkishMarch22.cue(0);}
if(key=='b'){
cont=2;;/// se reproduce la musica de Mattarmonica deteniendo las //otras 2 melodias
TurkishMarch22.stop();
Titanic22.stop();
maxim = new Maxim(this);
MattArmonica22.play();
MattArmonica22.cue(0);}
if(key=='n'){
cont=3;/// se reproduce la musica de titanic deteniendo las otras 2 ////melodias
TurkishMarch22.stop();
MattArmonica22.stop();
maxim = new Maxim(this);
Titanic22.play();
Titanic22.cue(0);}
if(key=='a'){
//////Si esta tecla se presiona el sonido se reproduce esn velocidad //normal
Titanic22.speed(1.00);
TurkishMarch22.speed(1.00);
MattArmonica22.speed(1.0);}
if(key=='s'){
//////Si esta tecla se presiona se acelera el sonido que se este
//reproduciendo con el valor 1.12
Titanic22.speed(1.12);
TurkishMarch22.speed(1.12);
MattArmonica22.speed(1.12);}
if(key=='d'){
//////Si esta tecla se presiona se acelera el sonido que se este
//reproduciendo con el valor 1.16
Titanic22.speed(1.16);
TurkishMarch22.speed(1.16);
MattArmonica22.speed(1.16);}
if(key=='f'){
//////Si esta tecla se presiona se acelera el sonido que se este
//reproduciendo con el valor 1.21
Titanic22.speed(1.21);
TurkishMarch22.speed(1.21);
MattArmonica22.speed(1.21);}
}
}
void draw(){
////////////////////////////////////////////////////////////////////////////////////
//if(value==true){
//if (arduino.digitalRead(9) == Arduino.HIGH){
//TurkishMarch22.stop();
// MattArmonica22.stop();
//maxim = new Maxim(this);
//Titanic22.play();
//Titanic22.cue(0); }
//if (arduino.digitalRead(8) == Arduino.HIGH){
//Titanic22.stop();
//MattArmonica22.stop();
//maxim = new Maxim(this);
//TurkishMarch22.play();
//TurkishMarch22.cue(0); }
//}
//if (arduino.digitalRead(7) == Arduino.HIGH){
//Titanic22.stop();
//TurkishMarch22.stop();
//maxim = new Maxim(this);
//MattArmonica22.play();
//MattArmonica22.cue(0);
//} Lectura de los pines para reproducir el audio
//Esta parteomitida es la correspondiente a la implementacion del arduino //como integracion de hardware
////////////////////////////////////////////////////////////////////////////////
image(img,0,0);
if(c1 == 1){
fill(50,205,100);
// fill(0); Relleno del primer recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(170,200,30,42,5);
if(c1==2){
fill(100,50,255);
// fill(0); Relleno del segundo recuadro con color
}else{
//fill(255)
stroke(255,255,255);
fill(0);}
rect(226,200,30,42,5);
if(c1==3){
fill(255,75,150);
//fill(0); Relleno del 3er recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(284,200,30,42,5);
if(c1==4){
fill(125,170,235);
//fill(0); Relleno del 4to recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(339,200,30,42,5);
if(c1==5){
fill(200,225,0);
// fill(0); Relleno del 5to recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(395,200,30,42,5);
if(c1==6){
fill(150,150,175);
//fill(0); Relleno del 6mo recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(452,200,30,42,5);
if(c1==7){
fill(175,100,0);
//fill(0); Relleno del 7mo recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(509,200,30,42,5);
if(c1==8){
fill(175,20,200);
//fill(0); Relleno del 8vo recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(566,200,30,42,5);
if(c1==9){
fill(100,205,25);
//fill(0); Relleno del 9no recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(621,200,30,42,5);
if(c1==10){
fill(15,250,250);
//fill(0); Relleno del 10mo recuadro con color
}else{//fill(255);
stroke(255,255,255);
fill(0);}
rect(679,200,30,42,5);
}








No hay comentarios:
Publicar un comentario