Theremin

Theremin

Damien Girod – Sébastien Juchs – Pierre-Yves Pouilleul – Pierre-François Tachon

 

Présentation

Le but de notre projet était de construire une sorte de Theremin (http://fr.wikipedia.org/wiki/Th%C3%A9r%C3%A9mine) à l’aide d’Arduino, Processing et deux télémètres à ultrasons (sonars), l’un contrôlant le volume et l’autre la fréquence de l’onde. Nous avons par la suite ajouté un bouton afin de pouvoir changer le type d’onde émise par Processing et donc le timbre du son entendu.

Nous avons utilisé la libraire Minim (http://code.compartmental.net/tools/minim/) pour l’émission et le traitement de l’audio. Dans l’idéal, nous aurions voulu faire communiquer l’Arduino avec Max/MSP mais nous n’avons pas eu le temps de nous y atteler. En effet, nous avons rencontré quelques problèmes au niveau des sonars qui agissaient parfois plutôt… bizarrement, peut-être du fait de leur proximité dans l’espace.

 

Vidéo

(le son est assez faible)

Schéma 

theremin_bb

 

 

Code Arduino

int sonar1Value = 0;
int sonar2Value = 0;
int buttonValue = 0;

void setup() {
// On démarre la communication série
Serial.begin(2400);

// le bouton
pinMode(3, INPUT);
}

void loop() {
// On lit la valeur du sonar 1 (fréquence) dans l’entrée analogique
sonar1Value = analogRead(3);
//On l’envoie à Processing
Serial.print(« F »);
Serial.print(« , »);
Serial.print(sonar1Value);
Serial.print(« , »);
Serial.println();
//On lit la valeur du sonar 2 (volume)
sonar2Value = analogRead(2);
//On l’envoie à Processing
Serial.print(« V »);
Serial.print(« , »);
Serial.print(sonar2Value);
Serial.print(« , »);
Serial.println();
//On lit la valeur du bouton
buttonValue = digitalRead(3);
//On l’envoie à Processing
Serial.print(« B »);
Serial.print(« , »);
Serial.print(buttonValue);
Serial.print(« , »);
Serial.println();

delay(100);
}

 

Code Processing

// On importe les librairies nécessaires
import processing.serial.*;
import ddf.minim.*;
import ddf.minim.signals.*;
import ddf.minim.effects.*;

Minim minim;
AudioOutput out;

// on utilise la superclasse Oscillator pour pouvoir faire des PulseWave, SawWave, SineWave etc.
Oscillator wave;
Oscillator wave2;

Serial myPort; // On créé une instance de la classe Serial
short LF = 10; // « Fin de ligne »
char HEADERSONAR1 = ‘F'; // C’est le caractère que l’on a inséré avant la valeur du sonar1
char HEADERSONAR2 = ‘V'; // C’est le caractère que l’on a inséré avant la valeur du sonar2
char HEADERBUTTON = ‘B'; // C’est le caractère que l’on a inséré avant la valeur du bouton
int sonar1Value =0; // Une variable pour stocker la valeur du switch
int sonar2Value= 0; // Une variable pour stocker la valeur du potentiomètre
int buttonValue =0; // Une variable pour stocker la valeur du bouton

int freq1 = 440; // fréquence 1
int freq2 = 450; // fréquence 2
float amplitude = 1.0; // amplitude du signal

int waveType = 2;
// 0 = PulseWave, 1 = SawWave, 2 = SineWave, 3 = SquareWave, 4 = TriangleWave

void setup()
{
size(400, 400);
println(Serial.list());
// on utilise le port COM3
String portName = Serial.list()[1];
// On initialise la communication série, à la même vitesse qu’Arduino
myPort = new Serial(this, portName, 2400);

minim = new Minim(this);

// on récupère le flux de sortie
out = minim.getLineOut(Minim.STEREO, 512);

// on crée deux ondes sinusoidales (pour un effet de trémolo on ne met pas exactement
// la même fréquence)
wave = new SineWave(freq1,amplitude, 44100);
wave2 = new SineWave(freq2, amplitude, 44100);

// on ajoute les ondes au flux de sortie
out.addSignal(wave);
out.addSignal(wave2);

}

// Un message est reçu depuis l’Arduino
void serialEvent(Serial p) {
String message = myPort.readStringUntil(LF); // On lit le message reçu, jusqu’au saut de ligne
if (message != null)
{
print(« Message » + message);
// On découpe le message à chaque virgule, on le stocke dans un tableau
String [] data = message.split(« , »);

//Message reçu du sonar 1(fréquence)
if (data[0].charAt(0) == HEADERSONAR1)
{
// On convertit la valeur (String -> Int)
int sonar1Raw = Integer.parseInt(data[1]);
sonar1Value = sonar1Raw;
}
//Message reçu du sonar 2 (volume)
else if (data[0].charAt(0) == HEADERSONAR2)
{
// On convertit la valeur (String -> Int)
int sonar2Raw = Integer.parseInt(data[1]);
sonar2Value = sonar2Raw;
}
// message reçu du bouton (changement de type d’onde)
else if(data[0].charAt(0) == HEADERBUTTON)
{
// On convertit la valeur (String -> Int)
int buttonRaw = Integer.parseInt(data[1]);
buttonValue = buttonRaw;
}
}
}

void draw() {
// on change la valeur de la fréquence selon l’entrée du sonar
// (on multiplie par 5 pour que le changement soit plus flagrant)
freq1 = 440 + sonar1Value * 5;
freq2 = 450 + sonar1Value * 5;

// on change la fréquence des ondes
wave.setFreq(freq1);
wave2.setFreq(freq2);

// l’amplitude doit être entre 0 et 1 et la valeur min envoyée par le sonar est 11
amplitude = (sonar2Value – 11)/ 30.0;

// on change l’amplitude des ondes
wave.setAmp(amplitude);
wave2.setAmp(amplitude);

// si le bouton est pressé, on change le type d’onde
if(buttonValue == 1) {
// il y a 5 types d’ondes différents, le compteur va de 0 à 4
waveType = (waveType + 1)%5;

// on efface le signal actuel du flux
out.clearSignals();

switch(waveType) {

case 0 :
wave = new PulseWave(freq1,amplitude, 44100);
wave2 = new PulseWave(freq2, amplitude, 44100);
break;

case 1 :
wave = new SawWave(freq1,amplitude, 44100);
wave2 = new SawWave(freq2, amplitude, 44100);
break;

case 2 :
wave = new SineWave(freq1,amplitude, 44100);
wave2 = new SineWave(freq2, amplitude, 44100);
break;

case 3 :
wave = new SquareWave(freq1,amplitude, 44100);
wave2 = new SquareWave(freq2, amplitude, 44100);
break;

case 4 :
wave = new TriangleWave(freq1,amplitude, 44100);
wave2 = new TriangleWave(freq2, amplitude, 44100);
break;

default:
break;

}

// on attend pour ne pas que l’onde change plein de fois comme le bouton va
// renvoyer 1 plusieurs fois
delay(50);

// on ajoute les nouveaux signaux au flux audio
out.addSignal(wave);
out.addSignal(wave2);
}
}

Laisser un commentaire

Votre e-mail ne sera jamais publié ni communiqué.

Vous pouvez utiliser ces balises et attributs HTML <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>