Catégories
Liens
Synthé qui marche avec la lumiere : Plusieurs pistes sont possible, notamment en changeant les fréquences des pwm avec library Tone et Mozzi
Voici quelques codes pas mal… Certains utilisent les libraries Tone et Mozzi pour transformer l'arduino en petit synthé !
On capte le son emis en lumiere par des leds, via un panneau solaire. Ca donne ceci :
Le troisieme synth de la video est l'exemple de la librarie mozzi : Sensor/lighttemperature…
On fait clignoter 3 led a la noire, croche triolet, et on controle le temp avec un potentiometre et une photoresistance…
// 3 led a jouant a la noire, croche et triolet // un potentiometre 10k en A0 : controle le tempo général... // une photo resistance en A1 : controle un effet de delay #define led1 5 #define led2 9 #define led3 10 #define factor 6 //factor for pwm tone ! unsigned long previousMillis[3]; //[x] = number of leds void setup() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); Serial.begin(9600); } void loop() { int sensorValue = analogRead(A0); sensorValue = map(sensorValue, 0, 1023, 0, 2000); if(sensorValue > 1990) { sensorValue == 10000; } int sensorValueB = analogRead(A1); sensorValueB = map(sensorValueB, 0, 1023, 1023, 0); if(sensorValueB > 800) { BlinkLedSimple(led1, sensorValue, 0,sensorValueB); //BlinkLed( which led, interval, one of the stored prevMillis BlinkLedSimple(led2, sensorValue/3, 1,sensorValueB); //last parameters must be different for each led BlinkLedSimple(led3, sensorValue/2, 2,sensorValueB); } if(sensorValueB > 400 && sensorValueB < 800 ) { BlinkLed(led1, sensorValue, 0,sensorValueB); //BlinkLed( which led, interval, one of the stored prevMillis BlinkLed(led2, sensorValue/3, 1,sensorValueB); //last parameters must be different for each led BlinkLed(led3, sensorValue/2, 2,sensorValueB); } if(sensorValueB < 400) { BlinkLedSuper(led1, sensorValue, 0,sensorValueB); //BlinkLed( which led, interval, one of the stored prevMillis BlinkLedSuper(led2, sensorValue/3, 1,sensorValueB); //last parameters must be different for each led BlinkLedSuper(led3, sensorValue/2, 2,sensorValueB); } Serial.print("potentiometre"); Serial.println(sensorValue); Serial.print("ldr"); Serial.println(sensorValueB); delay(1); } ///Simple blink void BlinkLedSimple (int led, int interval, int array, int pwm){ if (((long)millis() - previousMillis[array]) >= interval){ previousMillis[array]= millis(); //stores the millis value in the selected array digitalWrite(led, !digitalRead(led)); //changes led state }} ///delayyyy blink void BlinkLed (int led, int interval, int array, int pwm){ if (((long)millis() - previousMillis[array]) >= interval){ previousMillis[array]= millis(); //stores the millis value in the selected array digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state } } ///super delayyyy blink void BlinkLedSuper (int led, int interval, int array, int pwm){ if (((long)millis() - previousMillis[array]) >= interval){ previousMillis[array]= millis(); //stores the millis value in the selected array digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state delay (pwm/factor); digitalWrite(led, !digitalRead(led)); //changes led state } }
On controle un synthe fm avec 5 potards, le son passe par la led en pin 9…
/* Use 5 Analogic inputs to control fm synth (A0 - ... - A4 ) Output Pin 9 - led ... */ #include <MozziGuts.h> #include <Oscil.h> // oscillator #include <tables/cos2048_int8.h> // table for Oscils to play #include <Smooth.h> #include <AutoMap.h> // maps unpredictable inputs to a range // int freqVal; // desired carrier frequency max and min, for AutoMap const int MIN_CARRIER_FREQ = 22; const int MAX_CARRIER_FREQ = 440; const int MIN = 1; const int MAX = 10; const int MIN_2 = 1; const int MAX_2 = 15; // desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics const int MIN_INTENSITY = 700; const int MAX_INTENSITY = 10; // desired mod speed max and min, for AutoMap, note they're inverted for reverse dynamics const int MIN_MOD_SPEED = 10000; const int MAX_MOD_SPEED = 1; AutoMap kMapCarrierFreq(0,1023,MIN_CARRIER_FREQ,MAX_CARRIER_FREQ); AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY); AutoMap kMapModSpeed(0,1023,MIN_MOD_SPEED,MAX_MOD_SPEED); AutoMap mapThis(0,1023,MIN,MAX); AutoMap mapThisToo(0,1023,MIN_2,MAX_2); const int KNOB_PIN = 0; // set the input for the knob to analog pin 0 const int LDR1_PIN=1; // set the analog input for fm_intensity to pin 1 const int LDR2_PIN=2; // set the analog input for mod rate to pin 2 const int LDR3_PIN=3; const int LDR4_PIN=4; Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCarrier(COS2048_DATA); Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aModulator(COS2048_DATA); Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kIntensityMod(COS2048_DATA); int mod_ratio = 5; // brightness (harmonics) long fm_intensity; // carries control info from updateControl to updateAudio // smoothing for intensity to remove clicks on transitions float smoothness = 0.95f; Smooth <long> aSmoothIntensity(smoothness); void setup(){ Serial.begin(115200); // set up the Serial output so we can look at the light level startMozzi(); // :)) } void updateControl(){ // freqVal = map(LDR3_PIN, 0, 1023, 1, 100); int freqVal = mozziAnalogRead(LDR3_PIN); // value is 0-1023 int FRQ = mapThis(freqVal); int knob2 = mozziAnalogRead(LDR4_PIN); // value is 0-1023 int knob2Val = mapThis(knob2); // read the knob int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023 // map the knob to carrier frequency int carrier_freq = kMapCarrierFreq(knob_value); //calculate the modulation frequency to stay in ratio int mod_freq = carrier_freq * mod_ratio * FRQ; // set the FM oscillator frequencies aCarrier.setFreq(carrier_freq); aModulator.setFreq(mod_freq); // read the light dependent resistor on the width Analog input pin int LDR1_value= mozziAnalogRead(LDR1_PIN); // value is 0-1023 // print the value to the Serial monitor for debugging int LDR1_calibrated = kMapIntensity(LDR1_value); // calculate the fm_intensity fm_intensity = ((long)LDR1_calibrated * knob2Val * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply // read the light dependent resistor on the speed Analog input pin int LDR2_value= mozziAnalogRead(LDR2_PIN); // value is 0-1023 Serial.print("LDR0 = "); Serial.print(knob_value); Serial.print("\t"); // prints a tab Serial.print("LDR1 = "); Serial.print(LDR1_value); Serial.print("\t"); // prints a tab Serial.print("LDR2 = "); Serial.print(LDR2_value); Serial.print("\t"); // prints a tab Serial.print("LDR3 = "); Serial.print(freqVal); Serial.print("\t"); // prints a tab Serial.print("LDR4 = "); Serial.print(knob2); Serial.print("\t"); // prints a tab // use a float here for low frequencies float mod_speed = (float)kMapModSpeed(LDR2_value)/1000; kIntensityMod.setFreq(mod_speed); Serial.println(); // finally, print a carraige return for the next line of debugging info } int updateAudio(){ long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next(); return aCarrier.phMod(modulation); } void loop(){ audioHook(); }
On controle ainsi deux pins avec tone depuis Pure Data…
Patch PureData : voir fichier 4 dans la page ressource http://reso-nance.org/wiki/logiciels/serial/accueil?s[]=puredata&s[]=serial
String inputString = ""; // chaine de caractères pour contenir les données boolean stringComplete = false; // pour savoir si la chaine est complète String fct =""; String arg=""; int index; #include <Tone.h> Tone freq1; Tone freq2; void setup() { Serial.begin(9600); // port série freq1.begin(9); freq2.begin(10); } void loop() { if (stringComplete) { //Serial.println(inputString); index = inputString.indexOf(' '); // on récupère la position du séparateur (l'espace " ") fct = inputString.substring(0,index); // on coupe la chaine en deux : la fonction et l'argument arg = inputString.substring(index,inputString.length()); if (fct == "LED10") { freq2.play(arg.toInt(),300); } else if (fct == "LED9") { freq1.play(arg.toInt(),300); } inputString = ""; // vide la chaine stringComplete = false; } } /* SerialEvent est déclenché quand de nouvelles données sont reçues. Cett routine tourne entre chaque loop(), donc utiliser un delay la fait aussi attendre */ void serialEvent() { while (Serial.available()) { char inChar = (char)Serial.read(); // Récupérer le prochain octet (byte ou char) inputString += inChar; // concaténation des octets if (inChar == '\n') { // caractère de fin pour notre chaine stringComplete = true; } } }
2 pot volume et pitch
#include <MozziGuts.h> #include <Oscil.h> // oscillator template #include <tables/sin2048_int8.h> // sine table for oscillator const char KNOB_PIN = 0; // set the input for the knob to analog pin 0 const char LDR_PIN = 1; // set the input for the LDR to analog pin 1 // use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA); byte volume; void setup(){ startMozzi(); // :)) } void updateControl(){ // read the potentiometer int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023 // map it to an 8 bit volume range for efficient calculations in updateAudio volume = knob_value >> 2; // 10 bits (0->1023) shifted right by 2 bits to give 8 bits (0->255) // read the light dependent resistor int light_level = mozziAnalogRead(LDR_PIN); // value is 0-1023 light_level = map(light_level,0,1023,0,12); light_level = light_level*100 + 200; // set the frequency aSin.setFreq( light_level); } int updateAudio(){ // cast char output from aSin.next() to int to make room for multiplication return ((int)aSin.next() * volume) >> 8; // shift back into range after multiplying by 8 bit value } void loop(){ audioHook(); // required here delay(100); }
2 pot (selecteur si pot ou ldr pour controler le pitch, pitch ) un ldr (pitch)….
/* */ #include <MozziGuts.h> #include <Oscil.h> // oscillator template #include <tables/sin2048_int8.h> // sine table for oscillator #include <RollingAverage.h> #include <ControlDelay.h> #define INPUT_PIN 0 // analog control input #define INPUT_PINA 2 // analog control input #define MIX_PIN 3 // analog control input unsigned int echo_cells_1 = 32; unsigned int echo_cells_2 = 60; unsigned int echo_cells_3 = 127; int bumpy_input = 12; #define CONTROL_RATE 64 ControlDelay <128, int> kDelay; // 2seconds // oscils to compare bumpy to averaged control input Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin0(SIN2048_DATA); Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin1(SIN2048_DATA); Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin2(SIN2048_DATA); Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin3(SIN2048_DATA); // use: RollingAverage <number_type, how_many_to_average> myThing RollingAverage <int, 32> kAverage; // how_many_to_average has to be power of 2 int averaged; void setup(){ kDelay.set(echo_cells_1); startMozzi(); } void updateControl(){ int mix = mozziAnalogRead(MIX_PIN); int pot = mozziAnalogRead(INPUT_PINA) ; int ldr = mozziAnalogRead(INPUT_PIN) ; if (mix > 500) { bumpy_input = ldr; } else { bumpy_input = pot; } averaged = kAverage.next(bumpy_input); aSin0.setFreq(averaged); aSin1.setFreq(kDelay.next(averaged)); aSin2.setFreq(kDelay.read(echo_cells_2)); aSin3.setFreq(kDelay.read(echo_cells_3)); } int updateAudio(){ return 3*((int)aSin0.next()+aSin1.next()+(aSin2.next()>>1) +(aSin3.next()>>2)) >>3; } void loop(){ audioHook(); }
Liste de matériel et outils nécessaires.
Code pour afficher les images du projet :
{{gallery>?&crop&lightbox}}