BIO Sound Machine

Il progetto didattico BIO-Sound machine è uno strumento che trasforma le variazioni della conduttività elettrica dei Bio-organismi, come le piante (ma non solo), in generazione di suoni secondo il protocollo MIDI (Musical Instruments Digital Interface).
Il progetto si avvale di una scheda elettronica progettata ad hoc e della tecnologia Arduino per ciò che concerne la manipolazione della grandezza rilevata attraverso i sensori e la generazione MIDI.

BIO Organismi: le Piante

Recenti studi scientifici hanno confermato il fatto che le piante possono comunicare tra loro e con altri esseri viventi, come gli insetti, e sono in grado di produrre ultrasuoni quando sono stressate.
Inoltre è studiato che i segnali elettrici che controllano il corpo umano sono presenti anche nelle piante, sebbene queste non abbiano neuroni. Come gli altri esseri viventi hanno una personalità, possiedono tutti i cinque sensi come noi, si scambiano informazioni e interagiscono, adottano strategie per la sopravvivenza, hanno una vita sociale, sfruttano al meglio le risorse energetiche. Sono capaci di scegliere, imparare e ricordare, sentono perfino la gravità (Greg Gage – Stefano Mancuso).
La vita segreta delle piante è probabilmente molto più ricca e complicata di quanto pensiamo e oggi siamo solo all’inizio dell’esplorazione scientifica di questo affascinante campo di studio.

Con un diverso approccio, come nel caso di BIO Sound Machine, è possibile dar loro voce utilizzando sensori che traducono alcuni dei loro propri processi biologici in musica tramite un sintetizzatore.
Processi biologici della fotosintesi e del movimento dei liquidi all’interno della pianta durante il processo di cavitazione in cui le bolle d’aria vengono aspirate attraverso il corpo della pianta, specialmente quando l’acqua è scarsa.
Come tutti gli organismi viventi, le piante subiscono variazioni di resistenza elettrica dovute a questi fattori, tra cui importantissimi stati fisiologici ed emozionali. Le piante sono delle grandi antenne, dei ricettori sensibilissimi, esse captano dall’ambiente moltissime variazioni energetiche fisiche (campi elettromagnetici statici e variabili..).

Naturalmente, le piante non producono direttamente la musica.
Il suono che sentiamo come musica da un sintetizzatore in un concerto di piante è dovuto alla associazione attraverso il coding informatico di queste variazioni captate, attraverso il circuito elettronico realizzato, con suoni artificiali.

Il Circuito Elettronico

Il circuito elettronico realizzato per il progetto è passato attraverso varie fasi di sviluppo con la creazione di successivi prototipi ai quali si sono aggiunte via via varie funzionalità.

La sezione di ingresso, realizzata con integrato Timer555, ha la funzione di convertire la conduttività elettrica tra foglia e foglia o tra terreno e foglia, rilevata attraverso sensori elettrici adesivi di uso medicale, in un segnale elettronico digitale di frequenza proporzionale ad essa.
Tale frequenza determina la lunghezza dell’impulso (semiperiodo alto) che viene letta in ingresso da Arduino utilizzando la funzione pulseIn(), che restituisce questo valore in mS.

Sulla base della variazione di questi valori rilevati attraverso i sensori collegati all’ingresso del circuito è stato impostato tutto il programma per la generazione del suono MIDI.

Nello schema circuitale sono stati inseriti in ingresso ad Arduino anche tre potenziometri ed un selettore a 12 posizioni, per poter manipolare da programma le modalità di generazione del suono.

Schema elettronico versione2

Il Programma Arduino

L’algoritmo legge il valore della durata dell’impulso generato dalla sezione di ingresso con Timer555, valore che è espresso in mS.
Questo valore che subisce continuamente piccole variazioni legate ai processi biologici viene memorizzato nei suoi valori minimi e massimi. Attraverso questi valori si effettua quindi una normalizzazione rispetto al valore minimo e massimo delle note che si vogliono riprodurre.
Questo significa che, sapendo che nel protocollo MIDI ogni nota delle ottave corrispondenti al campo audio è identificata da un numero che varia da 0 a 127, il range di variazione dell’impulso letto viene amplificato adattandolo a questi valori delle note. Quindi ogni variazione che genera un passaggio da una nota a quelle successive o precedenti può produrre la generazione di un valore MIDI.
Questo valore, insieme al valore della sua Velocity (intensità), viene quindi inviato sull’uscita MIDI con messaggi seriali secondo il protocollo.

Attraverso i potenziometri inseriti è possibile controllare i valori del Volume di uscita, della Soglia della variazione di generazione delle note e della Estensione delle ottave di generazione.
Il primo (colore Blu) imposta il valore della Velocity tra 0 e 127 determinando il volume di uscita.
Il controllo della Soglia (colore Bianco) imposta invece il valore oltre il quale la variazione del segnale prodotto in ingresso generi la nota.
Il valore prodotto dal potenziometro della Estensione delle ottave (colore Arancione) modifica i valori MIDI minimo e massimo nella normalizzazione per la generazione in base alle variazioni dovute al segnale di ingresso, modificando di fatto il numero di ottave entro il quale questa generazione avviene, da un massimo di 9 ad un minimo di una (quella centrale).

Con il pulsante BTN1 viene selezionata la produzione della nota singola o della sua triade maggiore, mentre con BTN2 si possono selezionare i modi Cromatico, Maggiore, Minore o Minore Diatonico entro i quali generare le note.

Il programma gestisce inoltre la visualizzazione di queste impostazioni attraverso una serie di led.
I quattro led da 5mm indicano il modo scelto, mentre quelli da 3mm la tonalità (da sinistra da DO a SI, il led verde l’eventuale #).

Volendo utilizzare direttamente la porta USB di Arduino, che nella versione2 è un MEGA 2560, come uscita MIDI da collegare direttamente al Sintetizzatore per la riproduzione dei suoni, occorre, una volta caricato lo scheck, sostituire il Firmware nel processore della seriale della scheda con quello MIDI.
Per farlo si deve installare una applicazione DFU (Device Firmware Update) come ATMEL Flip e fare l’upload del firmware Arduino_MIDI. Per utilizzare l’applicazione DFU occorre prima di tutto cortocircuitare l’ingresso Reset2 di Arduino a GND (Pulsante DFU della scheda BIO Sound) e quindi collegare ATMEL Flip alla scheda selezionando USB (Ctrl+U), caricare il file del firmware e lanciare RUN.
Nel caso dobbiate apportare modifiche al programma Arduino dovete ripristinare il firmware originale a seconda della scheda utilizzata (Arduino UNO Rev3, Arduino MEGA 2560).

Listato programma:

/* BIOSound - Generazione MIDI con le piante (e non solo :)
 *  
 * Versione v2 definitiva .- 13 Dicembre 2021
 * scheda: Arduino Mega 2560 
 * autore: Fabrizio Silvetti fabriziosilvetti.com
 * 
 * Il programma legge la durata impulso (proporzionale alla freq 
 * dell'astabile con 555) generato dalla variazione della impedenza in ingresso.
 * Normalizzato ai suoi valori Max e min, viene utilizzato per la creazione delle note.
 * Nella creazione note si tiene conto di:
 * - estensione ottave (scelto con pot Arancio, 1 - 9)
 * - tonalità (scelta con selettore Rosso, C, C#, D, D#, E, F, F#, G, G#, A, A#, B)
 * - modo (scelta con BTN2, Chromatic, Major, Minor, Minor Diatonic)
 * - histeresi (scelta con pot Bianco, 0 - 50, e utilizzata come variazione minima dalla nota precedente per creazione nota)
 * - volume (scelto con pot Blu, 0 - 127)
 * Le note vengono create in MIDI, dove nota==1 -> C0(16Hz) e nota==127 -> B9(8350Hz).
 * Con BTN1 vengono creati accordi Maggiori sulla nota.
*/
const byte btn1Pin = A0; //btn1 Polifonia
const byte btn2Pin = A1; //btn2 Scelta Modo (Chromatic, Major, Minor, Minor Diatonic)
const byte volPin = A4; //pin pot volume
const byte histPin = A5; //pin pot Histeresi
const byte octPin = A13; //pin pot Estensione Ottave
const byte in_555 = 2; //pin collegato all'Out del 555
//leds scala scelta
const byte led_blue_chrom = 13; //scala Chromatica 
const byte led_red_mag = 12; //scala Maggiore 
const byte led_yellow_min_dia = A2; //scala Minore Diatonica 
const byte led_green_min= A3; //scala Minore 
//leds tonalità
const byte led_diesis = 17; 
const byte led_C = A11;
const byte led_D = A12;
const byte led_E = 21;
const byte led_F = A10;
const byte led_G = 20;
const byte led_A = 19;
const byte led_B = 18;
/* Selettore tonalità
 * ton    seq_in_Ard
 * C      011111111111
 * C#     101111111111
 * D      110111111111
 * D#     111011111111
 * E      111101111111
 * F      111110111111
 * F#     111111011111
 * G      111111100111 anomalia sel
 * G#     111111110111
 * A      111111111011
 * A#     111111111101
 * B      111111111110
 */
const int C_pin = 11;
const int Cd_pin = 10;
const int D_pin = 9;
const int Dd_pin = 8;
const int E_pin = 7;
const int F_pin = 4;
const int Fd_pin = 3;
const int G_pin = 14;
const int Gd_pin = 15;
const int A_pin = 16;
const int Ad_pin = 5;
const int B_pin = 6;
//Generazione nota con elaborazione_segnale()
unsigned long _pulse;
unsigned long maxSignal = 0;
unsigned long minSignal = 1000000;
int mediaSignal, deltaSignal, notaSignal;
int nota, nota_temp;
unsigned long loopMillis = 0;
bool btn_isPressed = false;
//Impostazione note MIDI
byte _channel = 1;  //setting channel to 11 or 12 often helps simply computer midi routing setups
byte _velocity = 0; // 0 -> 127
int _estensione_ottave;
int noteMin; //C0  - keyboard note minimum
int noteMax; //C7  - keyboard note maximum
int tonalita; // 1->C, 2->C#, 3->D, 4-D#, 5->E, 6->F, 7->F#, 8->G, 9->G#, 10->A, 11->A#, 12->B
int tipo_scala = 0; //Maggiore
int indice_nota;
int nota_base_tonalita[13];
//int nota_base_tonalita[13] = {0,60,61,62,63,64,65,66,67,68,69,70,71};
int scale[4][13] = {                // scale[tipo][nota]
  {12, 1,2,3,4,5,6,7,8,9,10,11,12}, //Chromatic
  {7, 1, 3, 5, 6, 8, 10, 12},       //Major
  {7, 1, 3, 4, 6, 8, 9, 11},        //DiaMinor
  //{7, 1, 2, 2, 5, 6, 9, 11},        //Indian
  {7, 1, 3, 4, 6, 8, 9, 11}         //Minor
};
//per test Serial
int ottave[8] = {0,1,2,3,4,5,6,7};
String note_ottave[8][13] = { //A4 = 440 Hz
  {"0","C0","C0#","D0","D0#","E0","F0","F2#","G0","G0#","A0","A0#","B0"}, //12->C0(16Hz) a 107->B7(3951Hz)
  {"1","C1","C1#","D1","D1#","E1","F1","F1#","G1","G1#","A1","A1#","B1"},
  {"2","C2","C2#","D2","D2#","E2","F2","F2#","G2","G2#","A2","A2#","B2"},
  {"3","C3","C3#","D3","D3#","E3","F3","F3#","G3","G3#","A3","A3#","B3"},
  {"4","C4","C4#","D4","D4#","E4","F4","F4#","G4","G4#","A4","A4#","B4"},
  {"5","C5","C5#","D5","D5#","E5","F5","F5#","G5","G5#","A5","A5#","B5"},
  {"6","C6","C6#","D6","D6#","E6","F6","F6#","G6","G6#","A6","A6#","B6"},
  {"7","C7","C7#","D7","D7#","E7","F7","F7#","G7","G7#","A7","A7#","B7"}
};
// utilizzo potenziometro creazione Soglia generazione nota
int threshold; 
int threshMin = 0; 
int threshMax = 50; // valore max isteresi per esecuzione nota
int knobMin = 1;
int knobMax = 1023;
void setup()
{
  pinMode(btn1Pin, INPUT_PULLUP);
  pinMode(btn2Pin, INPUT_PULLUP);
  pinMode(histPin, INPUT);
  pinMode(volPin, INPUT);
  pinMode(in_555, INPUT);
  pinMode(C_pin, INPUT_PULLUP);
  pinMode(Cd_pin, INPUT_PULLUP);
  pinMode(D_pin, INPUT_PULLUP);
  pinMode(Dd_pin, INPUT_PULLUP);
  pinMode(E_pin, INPUT_PULLUP);
  pinMode(F_pin, INPUT_PULLUP);
  pinMode(Fd_pin, INPUT_PULLUP);
  pinMode(G_pin, INPUT_PULLUP);
  pinMode(Gd_pin, INPUT_PULLUP);
  pinMode(A_pin, INPUT_PULLUP);
  pinMode(Ad_pin, INPUT_PULLUP);
  pinMode(B_pin, INPUT_PULLUP);
  pinMode(led_blue_chrom, OUTPUT);
  pinMode(led_red_mag, OUTPUT);
  pinMode(led_yellow_min_dia, OUTPUT);
  pinMode(led_green_min, OUTPUT);
  pinMode(led_diesis, OUTPUT);
  pinMode(led_C, OUTPUT);
  pinMode(led_D, OUTPUT);
  pinMode(led_E, OUTPUT);
  pinMode(led_F, OUTPUT);
  pinMode(led_G, OUTPUT);
  pinMode(led_A, OUTPUT);
  pinMode(led_B, OUTPUT);
  Serial.begin(31250);  //initialize at MIDI rate
}
void loop()
{
  loopMillis = millis(); //controllo istante di ingresso loop
  //checkBattery(); //on low power, shutoff lightShow, continue MIDI operation
  while(millis() <= (loopMillis + 2000))
  {
    checkKnob(); // check isteresi potenziometro
    scelta_tonalita();
    //impostazione nota minima e massima (estensione ottave)//
    noteMin = nota_base_tonalita[1];                        //
    noteMax = noteMin + (12 * _estensione_ottave);          //
    elaborazione_segnale(); // elaborazione nota
    creazione_nota();
  }
  //Reset valori maxSignal e minSignal
  maxSignal = 0;
  minSignal = 1000000;
}
void elaborazione_segnale() {
  _pulse = pulseInLong(in_555,HIGH); //for TEST 555
  // determinazione delta SignalIn
  if(_pulse > maxSignal) maxSignal = _pulse;
  if(_pulse < minSignal) minSignal = _pulse;
  deltaSignal = maxSignal - minSignal;
  mediaSignal = (maxSignal + minSignal) / 2;
  notaSignal = _pulse - minSignal;
  nota =  map(notaSignal, 0, deltaSignal, noteMin, noteMax);
  if(nota < noteMin) nota = noteMin;
  if(nota > noteMax) nota = noteMax;
}
void creazione_nota()
{
  if(nota >= (nota_temp + threshold) || nota <= (nota_temp - threshold))  //Isteresi note
    {
      //Serial.print("NOTA = ");Serial.println(nota);
      int base = nota_base_tonalita[tonalita]; // nota iniziale ottave
      int ottava = nota/12 - 1; // 0->C0, 1->C1, 2->C2, 3->C3, 4->C4, 5->C5, 6->C6, 7->C7
      int nota_ottava = (nota%12) + 1; // determino la nota all'interno dell'ottava
      lettura_scelta_scala();
      for(int i=1; i<=scale[tipo_scala][0]; i++) 
      { 
        // Verifico se la nota è nella tonalità
        if(nota == ((scale[tipo_scala][i] - 1) + base)
        || nota == ((scale[tipo_scala][i] - 1) + base + 12) 
        || nota == ((scale[tipo_scala][i] - 1) + base + 24) 
        || nota == ((scale[tipo_scala][i] - 1) + base + 36) 
        || nota == ((scale[tipo_scala][i] - 1) + base + 48) 
        || nota == ((scale[tipo_scala][i] - 1) + base + 60) 
        || nota == ((scale[tipo_scala][i] - 1) + base + 72) 
        || nota == ((scale[tipo_scala][i] - 1) + base + 84)) 
        {
          // creazione note
          midiSerial(144, _channel, nota, _velocity);
          if(!digitalRead(btn1Pin))  //creazione polifonia con BTN1
          {
            midiSerial(144, _channel+1, nota+5, _velocity); // 3 maggiore
            midiSerial(144, _channel+2, nota+8, _velocity); // 5 
            midiSerial(144, _channel+3, nota+10, _velocity); // 7 minore
          }
          //interruzione note precedentemente create
          else 
          {
            midiSerial(144, _channel+1, nota_temp+5, 0);
            midiSerial(144, _channel+2, nota_temp+8, 0);
            midiSerial(144, _channel+3, nota_temp+10, 0);
          }
          midiSerial(144, _channel, nota_temp, 0);    
          nota_temp = nota; //memorizzo valore precedente nota
          delay(50); // ?
          //Serial.println(""); Serial.print("NOTA = "); Serial.print(nota); Serial.print(" - "); Serial.println(note_ottave[ottava][nota_ottava]); // for TEST 555
          break;
        }
        else 
        {
          midiSerial(144, _channel, nota, 0);
          if(!digitalRead(btn1Pin))  //creazione polifonia con BTN1
          {
            midiSerial(144, _channel+1, nota+5, 0); // 3 maggiore
            midiSerial(144, _channel+2, nota+8, 0); // 5 
            midiSerial(144, _channel+3, nota+10, 0); // 7 minore
          }
          else 
          {
            midiSerial(144, _channel+1, nota_temp+5, 0);
            midiSerial(144, _channel+2, nota_temp+8, 0);
            midiSerial(144, _channel+3, nota_temp+10, 0);
          }
        }
      }
    }
}
void scelta_tonalita()
{
  int _C = digitalRead(C_pin);
  int _Cd = digitalRead(Cd_pin);
  int _D = digitalRead(D_pin);
  int _Dd = digitalRead(Dd_pin);
  int _E = digitalRead(E_pin);
  int _F = digitalRead(F_pin);
  int _Fd = digitalRead(Fd_pin);
  int _G = digitalRead(G_pin);
  int _Gd = digitalRead(Gd_pin);
  int _A = digitalRead(A_pin);
  int _Ad = digitalRead(Ad_pin);
  int _B = digitalRead(B_pin);
  if(_C == 0) {
    tonalita = 1;
    digitalWrite(led_C, HIGH);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, LOW);
  }
  if(_Cd == 0) {
    tonalita = 2;
    digitalWrite(led_C, HIGH);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, HIGH);
  }
  if(_D == 0) {
    tonalita = 3;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, HIGH);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, LOW);
  }
  if(_Dd == 0) {
    tonalita = 4;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, HIGH);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, HIGH);
  }
  if(_E == 0) {
    tonalita = 5;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, HIGH);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, LOW);
  }
  if(_F == 0) {
    tonalita = 6;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, HIGH);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, LOW);
  }
  if(_Fd == 0) {
    tonalita = 7;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, HIGH);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, HIGH);
  }
  if(_G == 0 && _Gd == 0) {
    tonalita = 8;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, HIGH);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, LOW);
  }
  if(_G == 1 && _Gd == 0) {
    tonalita = 9;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, HIGH);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, HIGH);
  }
  if(_A == 0) {
    tonalita = 10;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, HIGH);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, LOW);
  }
  if(_Ad == 0) {
    tonalita = 11;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, HIGH);
    digitalWrite(led_B, LOW);
    digitalWrite(led_diesis, HIGH);
  }
  if(_B == 0) {
    tonalita = 12;
    digitalWrite(led_C, LOW);
    digitalWrite(led_D, LOW);
    digitalWrite(led_E, LOW);
    digitalWrite(led_F, LOW);
    digitalWrite(led_G, LOW);
    digitalWrite(led_A, LOW);
    digitalWrite(led_B, HIGH);
    digitalWrite(led_diesis, LOW);
  }
}
void lettura_scelta_scala() {
  //shift scala sul button release
  if(!digitalRead(btn2Pin)) btn_isPressed = true;
  if(digitalRead(btn2Pin) && btn_isPressed == true) 
  {
    btn_isPressed = false;
    tipo_scala ++;
    if(tipo_scala > 3) tipo_scala = 0;
  }
  if(tipo_scala == 0) 
  {
    digitalWrite(led_blue_chrom,HIGH);
    digitalWrite(led_red_mag,LOW);
    digitalWrite(led_yellow_min_dia,LOW);
    digitalWrite(led_green_min,LOW);
  }
  else if(tipo_scala == 1) 
  {
    digitalWrite(led_blue_chrom,LOW);
    digitalWrite(led_red_mag,HIGH);
    digitalWrite(led_yellow_min_dia,LOW);
    digitalWrite(led_green_min,LOW);
  }
  else if(tipo_scala == 2) 
  {
    digitalWrite(led_blue_chrom,LOW);
    digitalWrite(led_red_mag,LOW);
    digitalWrite(led_yellow_min_dia,HIGH);
    digitalWrite(led_green_min,LOW);
  }
  else if(tipo_scala == 3) 
  {
    digitalWrite(led_blue_chrom,LOW);
    digitalWrite(led_red_mag,LOW);
    digitalWrite(led_yellow_min_dia,LOW);
    digitalWrite(led_green_min,HIGH);
  }
  else 
  {
    digitalWrite(led_blue_chrom,LOW);
    digitalWrite(led_red_mag,LOW);
    digitalWrite(led_yellow_min_dia,LOW);
    digitalWrite(led_green_min,LOW);
  }
}
void checkKnob() {
  //funzione lettura potenziometri 
  _velocity = analogRead(volPin);
  threshold = analogRead(histPin);  
  _estensione_ottave = analogRead(octPin);
  //set estensione_ottave
  if(_estensione_ottave < 114) {
    _estensione_ottave = 1;
    nota_base_tonalita[0] = 0;
    for(int i=60; i<72; i++) nota_base_tonalita[i-59] = i; //0,C4,C4#,D4,D4#,E4,F4,F4#,G4,G4#,A4,A4#,B4
    /*Serial.print("nota_base_tonalita[] = ");
    Serial.print(nota_base_tonalita[1]);
    Serial.print(nota_base_tonalita[2]);
    Serial.print(nota_base_tonalita[3]);
    Serial.print(nota_base_tonalita[4]);
    Serial.print(nota_base_tonalita[5]);
    Serial.print(nota_base_tonalita[6]);
    Serial.print(nota_base_tonalita[7]);
    Serial.print(nota_base_tonalita[8]);
    Serial.print(nota_base_tonalita[9]);
    Serial.print(nota_base_tonalita[10]);
    Serial.print(nota_base_tonalita[11]);
    Serial.println(nota_base_tonalita[12]);*/
  }
  else if(_estensione_ottave >= 114 && _estensione_ottave < 228) {
    _estensione_ottave = 2;
    nota_base_tonalita[0] = 0;
    for(int i=54; i<66; i++) nota_base_tonalita[i-53] = i; //0,F3#,G3,G3#,A3,A3#,B3,C4,C4#,D4,D4#,E4,F4
  }
  else if(_estensione_ottave >= 228 && _estensione_ottave < 352) {
    _estensione_ottave = 3;
    nota_base_tonalita[0] = 0;
    for(int i=48; i<60; i++) nota_base_tonalita[i-47] = i; //0,C3,C3#,D3,D3#,E3,F3,F3#,G3,G3#,A3,A3#,B3
  }
  else if(_estensione_ottave >= 352 && _estensione_ottave < 446) {
    _estensione_ottave = 4;
    nota_base_tonalita[0] = 0;
    for(int i=42; i<54; i++) nota_base_tonalita[i-41] = i; //0,F2#,G2,G2#,A2,A2#,B2,C3,C3#,D3,D3#,E3,F3
  }
  else if(_estensione_ottave >= 466 && _estensione_ottave < 580) {
    _estensione_ottave = 5;
    nota_base_tonalita[0] = 0;
    for(int i=36; i<48; i++) nota_base_tonalita[i-35] = i; //0,C2,C2#,D2,D2#,E2,F2,F2#,G2,G2#,A2,A2#,B2
  }
  else if(_estensione_ottave >= 580 && _estensione_ottave < 694) {
    _estensione_ottave = 6;
    nota_base_tonalita[0] = 0;
    for(int i=30; i<42; i++) nota_base_tonalita[i-29] = i; //0,F1#,G1,G1#,A1,A1#,B1,C2,C2#,D2,D2#,E2,F2
  }
  else if(_estensione_ottave >= 694 && _estensione_ottave < 808) {
    _estensione_ottave = 7;
    nota_base_tonalita[0] = 0;
    for(int i=24; i<36; i++) nota_base_tonalita[i-23] = i; //0,C1,C1#,D1,D1#,E1,F1,F1#,G1,G1#,A1,A1#,B1
  }
  else if(_estensione_ottave >= 808 && _estensione_ottave < 922) {
    _estensione_ottave = 8;
    nota_base_tonalita[0] = 0;
    for(int i=18; i<30; i++) nota_base_tonalita[i-17] = i; //0,F0#,G0,G0#,A0,A0#,B0,C1,C1#,D1,D1#,E1,F1
  }
  else {
    _estensione_ottave = 9;
    nota_base_tonalita[0] = 0;
    for(int i=12; i<24; i++) nota_base_tonalita[i-11] = i; //0,C0,C0#,D0,D0#,E0,F0,F0#,G0,G0#,A0,A0#,B0
  }
  //set threshold to knobValue mapping
  _velocity = map(_velocity, 0, 255, 0, 127);
  threshold = map(threshold, knobMin, knobMax, threshMin, threshMax);
}
// ------------ MIDI Serial -------------
void midiSerial(int type, int channel, int data1, int data2) //Tipo, Canale, Nota, Velocità 
{ 
    //remove MSBs on data
    data1 &= 0x7F;  //number
    data2 &= 0x7F;  //velocity
    byte statusbyte = (type | ((channel-1) & 0x0F));
    Serial.write(statusbyte);
    Serial.write(data1);
    Serial.write(data2);
}
Risorse in rete:

Potrebbero interessarti anche...