Hello everyone!
I come to implore your help for my project ...
Let me explain THE PROBLEM:
I am making an analog synthesizer totally controllable in MIDI.
For the management of ADSR envellope I use the OZOE module (https://www.ozoe.fr/), the Ozoe envellope is based on an arduino, the code is available on its site. However, the ozoe envelope is designed to be driven in analog (4 pot and 3 switches).
The idea is basically relatively simple:
1- Remove all that is not useful to me in the code (EOC management)
2- implement MIDI listening in the code
3-replace the control of the 4potentiometers and the 3 switches by MIDI CC commands
4-Replace / Implement the management of an MCP4922 DAC
I am new to coding, however I want to learn.
I spent my last day trying to get the module to work ... In the end it was a total failure ... Probably my code is messed up ... But where?
thanks again
ps: sorry for my english (i'm french) ... i admit i use google trad
The ozoe code
the modified code
I come to implore your help for my project ...
Let me explain THE PROBLEM:
I am making an analog synthesizer totally controllable in MIDI.
For the management of ADSR envellope I use the OZOE module (https://www.ozoe.fr/), the Ozoe envellope is based on an arduino, the code is available on its site. However, the ozoe envelope is designed to be driven in analog (4 pot and 3 switches).
The idea is basically relatively simple:
1- Remove all that is not useful to me in the code (EOC management)
2- implement MIDI listening in the code
3-replace the control of the 4potentiometers and the 3 switches by MIDI CC commands
4-Replace / Implement the management of an MCP4922 DAC
I am new to coding, however I want to learn.
I spent my last day trying to get the module to work ... In the end it was a total failure ... Probably my code is messed up ... But where?
thanks again
ps: sorry for my english (i'm french) ... i admit i use google trad
The ozoe code
Code:
//----------------------------------------------
// CHARGEMENT DES LIBRAIRIES
//----------------------------------------------
#include <SPI.h>
#include <math.h>
//----------------------------------------------
// CONSTANTES harware
//----------------------------------------------
// --- PORTC ---
const int POT_A = A4;
const int POT_D = A3;
const int POT_S = A2;
const int POT_R = A1;
// --- PORTB ---
// SPI : 13=CLOCK 11=MOSI
const int FORM01 = 12;
const int CS = 10; //Chip Select du MCP4822
const int FORM10 = 9;
const int TIME10 = 8;
// --- PORTD ---
const int TIME01 = 7;
const int MODE10 = 6;
const int MODE01 = 5;
const int GATE_IN = 2;
//----------------------------------------------
// VARIABLES GLOBALES
//----------------------------------------------
// Possibilitee d adapter le temps maxi des entrees TIMExx
// +-------------+--------+--------+-------+
// + VALEUR | 5s | 0.5 | 60s |
// + UNITE | s | 1/10s | s |
// + Choix_timer | 0 | 1 | 2 |
// + Choix_timer | MIDLE | SHORT | LONG |
// + | | | |
byte DureeRef[3]= { 5 , 10 , 60 }; // MODIFIABLE
// + | | | |
// + MAXI | 128 | | 128 |
// +-------------+--------+--------+-------+
float k_timer = 0.00; //
byte klog =4; // Courbure equivalente à celles des condensateurs
unsigned long TimerStartTop = 0; // instant en microsecondes du dernier evenement start ou stop
unsigned long TimerIHM = 0; // Intervalle de temps en milliseconde du scan IHM
unsigned long TimeRefA = 0; // Duree en microsecondes de l'Attack
unsigned long TimeRefD = 0; // Duree en microsecondes du Decay
unsigned long TimeRefR = 0; // Duree en microsecondes du Release
unsigned long tempsreel; // Differentiel du Temps en microseconde entre l'evenement et le temps absolu
unsigned long TimerEOC = 0; // Debut du Temps en microsecondes de l'impulse de l'OEC
unsigned long Offset = 0; // Amortissement des montees et descente du MCP
int tension = 0; // Tension courante en millivolts
int tensionlin = 0; // Tension courante en millivolts
int tensionlog = 0; // Tension courante en millivolts
int memo_tension = 0; // Tension boucle-1 en millivolts
unsigned int TensionRefS = 0; // Tension (mV) de reference du SUSTAIN
unsigned int TensionStartTop = 0; // Tension (mV) du dernier evenement start ou stop
unsigned int DureeEOC = 0; // Duree de l'impulse de l'OEC
byte Etat_module = 0; // 0=NOP 1=A 2=D 3=S 4=R
byte Choix_forme = 0; // 0=LIN 1=LOG 2=EXP
byte Choix_timer = 0; // 0=x1 1=x0.1 2=x10
byte Choix_gate_in = 0; // 0=GATE_IN 1=TRIG_IN 2=LOOP
byte ihm_i = 0; // temporaire
boolean Etat_gate_in = 0; // Copie de l'etat de l'entree gate (1=on 0=off)
boolean FlagEOC = 0; // etat de la sortie End Of Cycle (1=on 0=off)
boolean StartTop = 0; // Flag fugitif sur l'Etat_gate_in (1=actif 0=deactive)
boolean PatchV2 = 0; // 0=organisation V3 - 1=Organisation V2 || Organise les inverseurs selon l'ordre de la V2 MODIFIABLE
//----------------------------------------------
// INITIALISATION
//----------------------------------------------
void setup() {
//Serial.begin(9600); // Seulement pour la mise au point
analogReference(DEFAULT);
pinMode(CS, OUTPUT);
pinMode(FORM01, INPUT_PULLUP);
pinMode(FORM10, INPUT_PULLUP);
pinMode(TIME01, INPUT_PULLUP);
pinMode(TIME10, INPUT_PULLUP);
pinMode(MODE01, INPUT_PULLUP);
pinMode(MODE10, INPUT_PULLUP);
pinMode(GATE_IN,INPUT_PULLUP);
// INITIALISATION INTERRUPTION (0=INT 0 = Gate_In = Pin 2 )
attachInterrupt(0, Gate_In_Up, FALLING); // O:INT0:GATE_IN
// GESTION MCP4822 sur le bus SPI
SPI.begin();
SPI.setClockDivider(32); // defaut : 4. peut être 2,4,8,16,32,64,128
SPI.setDataMode(SPI_MODE0); // mode: SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3
PORTB |=(1<<CS-8); // HIGH Desactive le chip
ECRIREDAC();
// INITIALISATION VALEURS IHM
for (byte i=0;i<8;i++){
TimerIHM= millis()+100;
IHM();
}
// Fin INITIALISATION
TimerStartTop=micros();
TimerIHM= millis()+100;
}
//----------------------------------------------
// BOUCLE PRINCIPALE
//----------------------------------------------
void loop() {
IHM(); // GESTION DES INVERSEURS ET POTENTIOMETRES
AUTOMATE(); // GESTION DE L'ENCHAINEMENT DES TACHES
CALCUL(); // DETERMINATION DE LA TENSION DE SORTIE
ECRIREDAC(); // ENVOIE DE LA TENSION DE SORTIE SUR LE DAC
}
//----------------------------------------------
// ENVOI DE LA TENSION DE SORTIE AU DAC
//----------------------------------------------
void ECRIREDAC(){
if (memo_tension!=tension){
memo_tension=tension;
noInterrupts(); // Ne pas deranger
PORTB &=~(1<<CS-8); // LOW
SPDR=highByte(tension)| B00010000; while (!(SPSR&(1<<SPIF))); // Gainx2
SPDR=lowByte(tension); while (!(SPSR&(1<<SPIF)));
PORTB |=(1<<CS-8); // HIGH
interrupts();
}
}
//----------------------------------------------
// CALCUL DE LA TENSION DE SORTIE (0->4095mV)
//----------------------------------------------
void CALCUL(){
//----------------------------------------------------------------------ATTACK--
if (Etat_module==1){
tempsreel=(micros()-TimerStartTop);
tension=4095-TensionStartTop;
tension*=float(tempsreel*k_timer/(TimeRefA*(4095.00-TensionStartTop)/4095.00));
tension+=TensionStartTop;
if (Choix_forme==1){ // LOG
tension+=512;// V3.01
float k=(4095-TensionStartTop)/3.61;
tension=(log10(tension-TensionStartTop)*k*klog)+(4095-(log10(4095-TensionStartTop)*k*klog));
}
if (Choix_forme==2){ // EXP
//float k=log(4095.00-TensionStartTop); // V3.01 Suppress
//k=k*float(tempsreel*k_timer/(TimeRefA*(4095.00-TensionStartTop)/4095.00));
//if (k>16){tension=4095;}else{tension=exp(k)+TensionStartTop;}
tensionlin=tension;
tension=4095-TensionStartTop;
float k=tension/3.61;
tension*=float((TimeRefA-(tempsreel*k_timer))/(TimeRefA*(4095.00-TensionStartTop)/4095.00));
tensionlog=(log10(tension-TensionStartTop)*k*klog)+(4095-(log10(4095-TensionStartTop)*k*klog));
tension=tensionlin-tensionlog+tension;
}
tension=constrain(tension,TensionStartTop,4095);
}
//----------------------------------------------------------------------DECAY--
else if (Etat_module==2){
tempsreel=(micros()-TimerStartTop);
tension=TensionStartTop-((TensionStartTop-TensionRefS)*(k_timer*tempsreel/TimeRefD*2)); // V3.01 "*2" = contraction
if (Choix_forme==1){//LOG => EXP en descente
float k=log(TensionStartTop-TensionRefS)*(1-(k_timer*tempsreel/TimeRefD));
if (k>16){tension=4095;}else{tension=exp(k)+TensionRefS-1;}
}
else if (Choix_forme==2){ // EXP => LOG en descente
// V3.01 "*2" = contraction
tension=TensionRefS+((log10((TensionStartTop-(TensionStartTop*(k_timer*tempsreel/TimeRefD*2)))/(klog*100)))*((TensionStartTop-TensionRefS)/log10(TensionStartTop/(klog*100))));
}
tension=constrain(tension,TensionRefS-1,4095);
}
//----------------------------------------------------------------------SUSTAIN--
else if (Etat_module==3){tension=TensionRefS;}
//----------------------------------------------------------------------RELEASE--
else if (Etat_module==4){
tempsreel=(micros()-TimerStartTop);
tension=TensionStartTop-(k_timer*tempsreel*float(4095.00/TimeRefR*2)); // LIN // V3.01 "*2" = contraction
if (Choix_forme==1){ // LOG
float k=log(TensionStartTop)*(1-(k_timer*tempsreel/TimeRefR));
if (k>16){tension=4095;}else{tension=exp(k);tension-=50;} // V3.01 pour l'offset
}
else if (Choix_forme==2){ // EXP
// V3.01 "*2" = contraction
tension=(log10((TensionStartTop-(TensionStartTop*(k_timer*tempsreel/TimeRefR*2)))/(klog*50)))*((TensionStartTop)/log10(TensionStartTop/(klog*50)));
}
tension=constrain(tension,0,TensionRefS);
}
}
//----------------------------------------------
// ENCHAINEMENT DES PHASES ENTRE ELLES
// ET GESTION EOC
//----------------------------------------------
void AUTOMATE(){
byte mem1=Etat_module;
float mem2=k_timer;
byte k=1; // V3.01
if (Choix_forme==1){k=2;}// V3.01
//------------------------------------------------------------------------------
if (Etat_module==0 && ((Etat_gate_in==1)+(Choix_gate_in==1)>0) ){Etat_module=1;}
else if (Etat_module==1 && Etat_gate_in==0 && Choix_gate_in==0 ){
if (tension>TensionRefS){Etat_module=2;}else{Etat_module=4;}
}
else if (Etat_module==1 && tension>=4095){Etat_module=2;}
else if (Etat_module==2 && (tension<=TensionRefS || k_timer*tempsreel>TimeRefD/k )){ // V3.01 "/k"
if (Etat_gate_in==1){Etat_module=3;}else{Etat_module=4;}
}
else if (Etat_module==2 && StartTop==1){
Etat_module=1;
StartTop=0;
}
else if (Etat_module==3 && Etat_gate_in==0){Etat_module=4;}
else if (Etat_module==4 && Etat_gate_in==1 ){Etat_module=1;}
StartTop=0;
if (Etat_module!=mem1 || k_timer!=mem2){// INITIALISATION DE L'INSTANT DE BASCULE ENTRE PHASE
TimerStartTop=micros();
TensionStartTop=constrain(tension,0,4095);
}
}
//----------------------------------------------
// CALCUL DE LA DUREE DE LA PHASE (ADR) ASSOCIEE AU POTENTIOMETRE
//----------------------------------------------
unsigned long RefTime(unsigned int potar){
unsigned long k=word(potar*(DureeRef[Choix_timer]));;
k*=float(100000.00/1023.00);
k+=Offset+100;
return k;
}
//----------------------------------------------
// PATCH DES INVERSEURS SELON L'ORGANISATION DE LA V2
//----------------------------------------------
void patch_inverseur(){
//---------------------------------------------------
// PATCH
// CABLAGE SELON V3 SUR UNE FACADE V2 et AJOUT d'un INVERSEUR 3 Positions sur la Forme
//
// +-------------+---------+------------+----------+--------- V2 FROM V3 ----------+
// INVERSEUR FORME MODE GATE TIME FORME MODE GATE TIME
// +-------------+---------+------------+----------+----------+-------------+--------+
// UP =1 LOG LOOP x.1 LIN GATE_IN x10
// ZERO =0 LIN GATE_IN x1 EXP LOOP x1
// DOWN =2 EXP TRIG_IN x10 LOG TRIG_IN x.1
// +-------------+---------+------------+----------+----------+-------------+--------+
byte i=Choix_gate_in;
if (i==0){Choix_gate_in=1;}else if(i==1){Choix_gate_in=0;}else if(i==2){Choix_gate_in=2;}
i=Choix_forme;
if (i==0){Choix_forme=2;}else if(i==1){Choix_forme=0;}else if(i==2){Choix_forme=1;} // Avec inverseur ON-OFF-ON
// if (i==0){Choix_forme=1;}else if(i==1){Choix_forme=0;} // Avec inverseur ON-OFF (en V2 pas de forme EXP)
i=Choix_timer;
if (i==0){Choix_timer=0;}else if(i==1){Choix_timer=2;}else if(i==2){Choix_timer=1;}
//---------------------------------------------------
}
//----------------------------------------------
// LECTURE PERIODIQUE DES INVERSEURS ET POTENTIOMETRES
//----------------------------------------------
void IHM(){
if (millis()-TimerIHM>10){ // scan inverseurs ou d'un potard toutes les 60 ms maxi
TimerIHM= millis();
ihm_i++;
if (ihm_i==1){
byte pb=PINB;
byte pd=PIND;
Choix_gate_in = !bitRead(pd,MODE01) +!bitRead(pd,MODE10)*2;
Choix_forme = !bitRead(pb,FORM01-8)+!bitRead(pb,FORM10-8)*2;
Choix_timer = !bitRead(pd,TIME01) +!bitRead(pb,TIME10-8)*2;
if (PatchV2){patch_inverseur();}
// if (Choix_timer==2){k_timer=0.100;}else{k_timer=1.00;}
if (Choix_timer==1){k_timer=1.00;}else{k_timer=0.05;} // V3.01
Offset=word(DureeRef[Choix_timer]*500);
}
else if (ihm_i==2){TimeRefA = RefTime(analogRead(POT_A));TimeRefA/=2;} // V3.01 pour div/2
else if (ihm_i==3){TimeRefD = RefTime(analogRead(POT_D));}
else if (ihm_i==4){TimeRefR = RefTime(analogRead(POT_R));}
else if (ihm_i==5){TensionRefS = map(analogRead(POT_S),0,1023,1,4095);}
else if (ihm_i==6){DureeEOC = min(((TimeRefA/1000)+(TimeRefD/1000)+(TimeRefR/1000))/4 , 40 );} // 40ms pour une utilisation habituelle.
else if (ihm_i>7){ihm_i=0;}
}
}
//----------------------------------------------
// Gestion du Gate_In par interruption sur INT0
// (le gate_in est inverse par le bc547)
//----------------------------------------------
void Gate_In_Up(){
Etat_gate_in=1;
StartTop=1;
attachInterrupt(0, Gate_In_Down, RISING );
}
void Gate_In_Down(){
Etat_gate_in=0;
attachInterrupt(0, Gate_In_Up, FALLING);
}
void AffValeurs(){
Serial.println();
}
the modified code
Code:
//----------------------------------------------
// CHARGEMENT DES LIBRAIRIES
//----------------------------------------------
#include <math.h>
#include <MCP4922.h>
#include <SPI.h>
MCP4922 DAC(11,13,10,14);
//----------------------------------------------
// VARIABLES GLOBALES
//----------------------------------------------
// Possibilitee d adapter le temps maxi des entrees TIMExx
// +-------------+--------+--------+-------+
// + VALEUR | 5s | 0.5 | 60s |
// + UNITE | s | 1/10s | s |
// + Choix_timer | 0 | 1 | 2 |
// + Choix_timer | MIDLE | SHORT | LONG |
// + | | | |
byte DureeRef[3]= { 5 , 10 , 60 }; // MODIFIABLE
// + | | | |
// + MAXI | 128 | | 128 |
// +-------------+--------+--------+-------+
float k_timer = 0.00; //
byte klog =4; // Courbure equivalente à celles des condensateurs
unsigned long TimerStartTop = 0; // instant en microsecondes du dernier evenement start ou stop
unsigned long TimerIHM = 0; // Intervalle de temps en milliseconde du scan IHM
unsigned long TimeRefA = 112; // Duree en microsecondes de l'Attack
unsigned long TimeRefD = 560; // Duree en microsecondes du Decay
unsigned long TimeRefR = 560; // Duree en microsecondes du Release
unsigned long tempsreel; // Differentiel du Temps en microseconde entre l'evenement et le temps absolu
unsigned long Offset = 0; // Amortissement des montees et descente du MCP
int tension = 0; // Tension courante en millivolts
int tensionlin = 0; // Tension courante en millivolts
int tensionlog = 0; // Tension courante en millivolts
int memo_tension = 0; // Tension boucle-1 en millivolts
unsigned int TensionRefS = 560; // Tension (mV) de reference du SUSTAIN
unsigned int TensionStartTop = 0; // Tension (mV) du dernier evenement start ou stop
byte Etat_module = 0; // 0=NOP 1=A 2=D 3=S 4=R
byte Choix_forme = 0; // 0=LIN 1=LOG 2=EXP
byte Choix_timer = 0; // 0=x1 1=x0.1 2=x10
byte Choix_gate_in = 0; // 0=GATE_IN 1=TRIG_IN 2=LOOP
boolean Etat_gate_in = 0; // Copie de l'etat de l'entree gate (1=on 0=off)
boolean StartTop = 0; // Flag fugitif sur l'Etat_gate_in (1=actif 0=deactive)
//----------------------------------------------
// INITIALISATION
//----------------------------------------------
void setup() {
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleControlChange(OnControlChange);
SPI.begin();
ECRIREDAC();
// INITIALISATION VALEURS IHM
for (byte i=0;i<8;i++){
TimerIHM= millis()+100;
}
// Fin INITIALISATION
TimerStartTop=micros();
TimerIHM= millis()+100;
}
//----------------------------------------------
// BOUCLE PRINCIPALE
//----------------------------------------------
void loop() {
usbMIDI.read();
AUTOMATE(); // GESTION DE L'ENCHAINEMENT DES TACHES
CALCUL(); // DETERMINATION DE LA TENSION DE SORTIE
ECRIREDAC(); // ENVOIE DE LA TENSION DE SORTIE SUR LE DAC
}
//----------------------------------------------
// Gestion du Gate_In par MIDI
//----------------------------------------------
void OnNoteOn(byte channel, byte pitch, byte velocity) {
if(velocity > 0) {
Etat_gate_in = 1;
StartTop=1;
}
else {
Etat_gate_in = 0;
}
}
void OnNoteOff(byte channel, byte pitch, byte velocity) {
Etat_gate_in = 0;
}
void AffValeurs(){
Serial.println();
}
//----------------------------------------------
// ENVOI DE LA TENSION DE SORTIE AU DAC
//----------------------------------------------
void ECRIREDAC(){
if (memo_tension!=tension){
memo_tension=tension;
DAC.Set(tension,tension);
}
}
//----------------------------------------------
// CALCUL DE LA TENSION DE SORTIE (0->4095mV)
//----------------------------------------------
void CALCUL(){
//----------------------------------------------------------------------ATTACK--
if (Etat_module==1){
tempsreel=(micros()-TimerStartTop);
tension=4095-TensionStartTop;
tension*=float(tempsreel*k_timer/(TimeRefA*(4095.00-TensionStartTop)/4095.00));
tension+=TensionStartTop;
if (Choix_forme==1){
tension+=512;
float k=(4095-TensionStartTop)/3.61;
tension=(log10(tension-TensionStartTop)*k*klog)+(4095-(log10(4095-TensionStartTop)*k*klog));
}
if (Choix_forme==2){
tensionlin=tension;
tension=4095-TensionStartTop;
float k=tension/3.61;
tension*=float((TimeRefA-(tempsreel*k_timer))/(TimeRefA*(4095.00-TensionStartTop)/4095.00));
tensionlog=(log10(tension-TensionStartTop)*k*klog)+(4095-(log10(4095-TensionStartTop)*k*klog));
tension=tensionlin-tensionlog+tension;
}
tension=constrain(tension,TensionStartTop,4095);
}
//----------------------------------------------------------------------DECAY--
else if (Etat_module==2){
tempsreel=(micros()-TimerStartTop);
tension=TensionStartTop-((TensionStartTop-TensionRefS)*(k_timer*tempsreel/TimeRefD*2)); // V3.01 "*2" = contraction
if (Choix_forme==1){//LOG => EXP en descente
float k=log(TensionStartTop-TensionRefS)*(1-(k_timer*tempsreel/TimeRefD));
if (k>16){tension=4095;}else{tension=exp(k)+TensionRefS-1;}
}
else if (Choix_forme==2){ // EXP => LOG en descente
// V3.01 "*2" = contraction
tension=TensionRefS+((log10((TensionStartTop-(TensionStartTop*(k_timer*tempsreel/TimeRefD*2)))/(klog*100)))*((TensionStartTop-TensionRefS)/log10(TensionStartTop/(klog*100))));
}
tension=constrain(tension,TensionRefS-1,4095);
}
//----------------------------------------------------------------------SUSTAIN--
else if (Etat_module==3){tension=TensionRefS;}
//----------------------------------------------------------------------RELEASE--
else if (Etat_module==4){
tempsreel=(micros()-TimerStartTop);
tension=TensionStartTop-(k_timer*tempsreel*float(4095.00/TimeRefR*2)); // LIN // V3.01 "*2" = contraction
if (Choix_forme==1){ // LOG
float k=log(TensionStartTop)*(1-(k_timer*tempsreel/TimeRefR));
if (k>16){tension=4095;}else{tension=exp(k);tension-=50;} // V3.01 pour l'offset
}
else if (Choix_forme==2){ // EXP
// V3.01 "*2" = contraction
tension=(log10((TensionStartTop-(TensionStartTop*(k_timer*tempsreel/TimeRefR*2)))/(klog*50)))*((TensionStartTop)/log10(TensionStartTop/(klog*50)));
}
tension=constrain(tension,0,TensionRefS);
}
}
//----------------------------------------------
// ENCHAINEMENT DES PHASES ENTRE ELLES
//
//----------------------------------------------
void AUTOMATE(){
byte mem1=Etat_module;
float mem2=k_timer;
byte k=1; // V3.01
if (Choix_forme==1){k=2;}// V3.01
//------------------------------------------------------------------------------
if (Etat_module==0 && ((Etat_gate_in==1)+(Choix_gate_in==1)>0) ){Etat_module=1;}
else if (Etat_module==1 && Etat_gate_in==0 && Choix_gate_in==0 ){
if (tension>TensionRefS){Etat_module=2;}else{Etat_module=4;}
}
else if (Etat_module==1 && tension>=4095){Etat_module=2;}
else if (Etat_module==2 && (tension<=TensionRefS || k_timer*tempsreel>TimeRefD/k )){ // V3.01 "/k"
if (Etat_gate_in==1){Etat_module=3;}else{Etat_module=4;}
}
else if (Etat_module==2 && StartTop==1){
Etat_module=1;
StartTop=0;
}
else if (Etat_module==3 && Etat_gate_in==0){Etat_module=4;}
else if (Etat_module==4 && Etat_gate_in==1 ){Etat_module=1;}
StartTop=0;
if (Etat_module!=mem1 || k_timer!=mem2){// INITIALISATION DE L'INSTANT DE BASCULE ENTRE PHASE
TimerStartTop=micros();
TensionStartTop=constrain(tension,0,4095);
}
}
//----------------------------------------------
// CALCUL DE LA DUREE DE LA PHASE (ADR) ASSOCIEE AU POTENTIOMETRE
//----------------------------------------------
unsigned long RefTime(unsigned int potar){
unsigned long k=word(potar*(DureeRef[Choix_timer]));;
k*=float(100000.00/1023.00);
k+=Offset+100;
return k;
}
//----------------------------------------------
// GESTION DES CONTROLES MIDI
//----------------------------------------------
void OnControlChange (byte channel, byte control, byte value) {
if ( control == 1) {
TimeRefA = map(value, 0, 127, 0, 1023);TimeRefA/=2;
}
if ( control == 2) {
TimeRefD = map(value, 0, 127, 0, 1023);
}
if ( control == 3) {
TensionRefS = map(value, 0, 127, 0, 4095);
}
if ( control == 4) {
TimeRefR = map(value, 0, 127, 0, 1023);
}
if ( control == 5) {
Choix_forme = map(value, 0, 127, 0, 2);
}
if ( control == 6) {
Choix_timer = map(value, 0, 127, 0, 2);
}
if (channel == 1 && control == 7) {
Choix_gate_in = map(value, 0, 127, 0, 2);
}
}