miércoles, 28 de marzo de 2012

Proyecto #3. Jugando con sonido/1

Hace tiempo descubrí la web CreativeApplications.net en la que varios artistas envueltos en el uso de tecnología muestran sus proyectos y prototipos. De entre ellos llamó poderosamente mi atención el trabajo de dos grupos de artistas que trabajan con Arduino y Processing:

1) El colectivo www.the-product.org y su obra Soundmachines, y
2) Bartholomäus Traubeck y su obra Years.

Ambos proyectos buscan convertir en sonido códigos de imágenes. El primero, Soundmachines, utiliza algo así como discos perforados que al iluminarse permiten la lectura de códigos de luz que generan loops de sonido, de forma que podemos crear música de baile de forma fácil e intuitiva. El segundo es más poético. Se trata de un giradiscos capaz de leer las líneas de tiempo de un troco de árbol. Las diferencias de intensidad en las líneas generan una música al piano en apariencia caótica, incluso aleatoria. Al final se percibe cierta armonía.

Digamos que me quedé un tanto boquiabierto ante piezas tan sugerentes y, actualmente, estoy intentando emular técnicamente lo que tales artistas han logrado, para luego crear mis propias piezas en las que imagen y sonido interactúen. Mi idea inicial, parecida a la de Soundmachines, consistiría en crear un giradiscos en el que cualquiera pudiera insertar su propio disco dibujado, al modo de los discos perforados de los organillos antiguos. 

Dichos dibujos serían leídos mediante un cabezal que tuviera diferentes sensores LDR que fueran sensibles a los cambios de luminosidad y convirtieran dichos cambios en señales para hacer saltar notas musicales, un archivo sonoro, etc. A su vez, tales cambios de luminosidad podrían convertirse de nuevo en imágenes a través de Processing. A continuación os muestro mi primer intento de hacer esta idea realidad. He utilizado un motorcito de microondas para hacer girar el disco, 2 LDR conectados a una placa Arduino Mega mediante resistencias de 10K y una bombilla para iluminar el disco y aumentar el contraste de la lectura. En cuanto al software, he usado la librería Firmata(StandardFirmata) de Arduino para controlar la microcontroladora directamente desde Processing. En Processing he utilizado un programa que utiliza la librería SoundCipher que permite utilizar diferentes sonidos de forma muy fácil. A lo anterior he añadido un sencillo dibujo mediante curveVertex(). A medida que vaya avanzando iré descargando más información. Más abajo os dejo un video y el código de este primer prototipo que iré complicando y puliendo a medida que vaya trabajando. Por cierto, se admiten sugerencias.


Código para Processing:

//Importar libreria SoundCipher para controlar sonidos con Processing

import arb.soundcipher.*;

SoundCipher sc1 = new SoundCipher(this);
SoundCipher sc2 = new SoundCipher(this);

//Importar libreria Serie para conectar Arduino con Processing
//(Hay que tener previamente descargada en la microcontroladora la libreria Firmata)

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;

//Pines analogicos de los sensores LDR

int potPin1=0;
int potPin2=1;

//Valores analogicos de los sensores LDR

int val1;
int val2;

//Declaramos los puntos del dibujo que variaran con los datos de los sensores LDR

float point_level_1, point_level_2, point_level_3;

void setup() {
 
size(400, 400);

//Elegimos puerto serie para la placa arduino

arduino = new Arduino(this, Arduino.list()[0], 57600);

smooth();

}

void draw() {
 
  background (255);
  noFill ();
 
//Reduce la lectura analogica de los ensores LDR a una cuarta parte

val1 = arduino.analogRead(potPin1)/4;
val2 = arduino.analogRead(potPin2)/4;

//Mapea los valores entrantes de los sensores LDR a valores adaptados a la ventana de Processing

float grey1= map(val1, 190, 240, 0, 400);
float grey2= map(val2, 190, 240, 0, 400);

//Escribe los valores de los sensores LDR que estan conectados a Arduino

println("val1");
println(val1);
println("val2");
println(val2);

 //Dibujo de la pantalla de Processing
 //1
  point_level_1=map(grey1, 0, width, 25, 50);
  fill (44, 215, 230, 255);
  curveTightness (map(grey1, 0, height, 20, -5));
  beginShape ();
  curveVertex (width/2-point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2-point_level_1);
  curveVertex (width/2-point_level_1, height/2-point_level_1);
  curveVertex (width/2-point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2-point_level_1);
  endShape ();
  //2
  point_level_2=map(grey2, 0, height, 30, 60);
  fill (255, 59, 142, 200);
  curveTightness (map(grey2, 0, width, -7, 25));
  beginShape ();
  curveVertex (width/2-point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2-point_level_2);
  curveVertex (width/2-point_level_2, height/2-point_level_2);
  curveVertex (width/2-point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2-point_level_2);
  endShape ();
  //3
  point_level_3=map(grey2, 0, height, -60, -10);
  fill (0, 0, 0, 20);
  curveTightness (map(grey2, 0, height, -5, 20) );
  beginShape ();
  curveVertex (width/2-point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2-point_level_3);
  curveVertex (width/2-point_level_3, height/2-point_level_3);
  curveVertex (width/2-point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2-point_level_3);
  endShape();

//A partir de un nivel de luz lanzar una nota musical

if(val1 > 230){
 
sc1.playNote(70, 500, 0.2);
delay(800);

}else if(val2 > 230){
sc2.playNote(40, 500, 0.2);

delay(600);

}

}

No hay comentarios:

Publicar un comentario