11.1 MIDI In

# MIDI In

In questa sezione impareremo a collegare un controller MIDI per mandare eventi a Sonic Pi per controllare i nostri synths e suoni. Procurati un controller MIDI come una tastiera o una superficie di controllo e andiamo sul fisico!


## Collegamento a un controller MIDI

Per poter ricevere informazioni da un dispositivo MIDI esterno in Sonic Pi dobbiamo innanzitutto collegarlo al nostro computer. Tipicamente questo avviene via USB anche se dispositivi più vecchi possono avere il connettore DIN a 5 pin, per il quale servirà hardware specifico (ad esempio una scheda audio con connettori MIDI DIN). Una volta collegato il dispositivo, lancia Sonic Pi e controlla la sezione IO nel pannello preferenze. Dovresti vedere il tuo dispositivo elencato qui. Se non è così, prova a premere il tasto 'Reset MIDI' e controlla se compare. Se ancora non vedi la periferica, la prossima cosa da fare è controllare la configurazione MIDI del tuo sistema operativo e controllare se rileva il tuo dispositivo. Se nessuna di queste cose funziona, sentiti libero di chiedere aiuto nel nostro forum https://in-thread.sonic-pi.net

## Ricevere eventi MIDI

Una volta che il tuo dispositivo è connesso, Sonic Pi riceverà automaticamente gli eventi. Puoi vederlo da te manipolando il tuo dispositivo MIDI e controllando il cue logger nella sezione inferiore destra della finestra applicazione sotto il registro eventi (se non fosse visibile vai su Preferenze->Editor->Show & Hide e abilita 'Show cue log'). Vedrai un flusso di eventi come:

```
/midi:nanokey2_keyboard:0:1/note_off  [55, 64]
/midi:nanokey2_keyboard:0:1/note_on   [53, 102]
/midi:nanokey2_keyboard:0:1/note_off  [57, 64]
/midi:nanokey2_keyboard:0:1/note_off  [53, 64]
/midi:nanokey2_keyboard:0:1/note_on   [57, 87]
/midi:nanokey2_keyboard:0:1/note_on   [55, 81]
/midi:nanokey2_keyboard:0:1/note_on   [53, 96]
/midi:nanokey2_keyboard:0:1/note_off  [55, 64]
```

Una volta che riesci a vedere un flusso di dati come questo significa che hai collegato correttamente la tua periferica MIDI. Congratulazioni, ora vediamo cosa ci puoi fare!

## Stato del MIDI Time

Questi eventi si dividono in due sezioni. Prima c'è il nome dell'evento come ad esempio `/midi:nanokey2_keyboard:0:1/note_on` seguito dal valore degli eventi come ad esempio `[18, 62]`. Nota interessante, queste sono le 2 cose di cui abbiamo bisogno per salvare le informazioni nel Time State. *Sonic Pi inserisce automaticamente gli eventi MIDI in ingresso nel Time State*. Questo significa che puoi ottenere il valore dell'ultimo evento MIDI e allo stesso tempo aspettare l'evento successivo usando quanto imparato nella sezione 10 di questo tutorial.

## Controllare gli effetti

Ora che abbiamo connesso un dispositivo MIDI, visto gli eventi nel cue log e scoperto che la conoscenza del Time State è tutto ciò che ci serve per lavorare con gli eventi, possiamo ora cominciare a divertirci. Costruiamo un piano MIDI semplice:

```
live_loop :midi_piano do
  note, velocity = sync "/midi:nanokey2_keyboard:0:1/note_on"
  synth :piano, note: note
end
```

Ci sono alcune cose che succedono nel codice riportato sopra, inclusi alcuni problemi. Innanzitutto abbiamo un semplice `live_loop` che si ripete all'infinito eseguendo il codice fra i blocchi `do`/`end`. Questo è stato introdotto nella sezione 9.2. Secondariamente, stiamo chiamando `sync` per attendere il prossimo evento Time State corrispondente. Usiamo una stringa che rappresenta il messaggio MIDI che stiamo cercando (che è lo stesso mostrato nel cue logger). Nota che questa lunga stringa è fornita dal sistema di auto completamento di Sonic Pi, quindi non è necessario digitarla tutta a mano. Nel registro abbiamo visto che c'erano due valori per ogni evento MIDI note, quindi assegnamo il risultato a due diverse variabili `note` e `velocity`. Infine triggeriamo il synth `:piano` passandogli la nostra nota.

Ora prova tu. Modifica il codice sopra, sostituisci la chiave sync con una stringa che corrisponda alla tua specifica periferica MIDI e premi Run. Hey presto, hai un piano funzionante! Tuttavia, probabilmente noterai un paio di problemi: primo, tutte le note escono allo stesso volume indipendentemente dalla forza applicata sulla tastiera. Questo può essere sistemato facilmente usando il valore MIDI velocity e convertendolo in amplitude. Dato che MIDI ha un intervallo di 0->127, per convertire questo numero in un valore compreso fra 0->1 dobbiamo dividerlo per 127:

```
live_loop :midi_piano do
  note, velocity = sync "/midi:nanokey2_keyboard:0:1/note_on"
  synth :piano, note: note, amp: velocity / 127.0
end
```

Aggiorna il codice e premi Run di nuovo. Ora la velocity della tastiera dovrebbe essere rispettata. Ora, liberiamoci di quella fastidiosa latenza.

## Rimuovere la latenza

Prima di poter rimuovere la latenza, dobbiamo capire da cosa è causata. Al fine di mantenere tutti i synth e gli effetti ben sincronizzati su tutte le possibili CPU e relative capacità, Sonic Pi programma l'audio *in anticipo* di 0.5 secondi come valore predefinito. (Notare che questa latenza aggiuntiva può essere configurata attraverso le funzioni `set_sched_ahead_time!` e `use_sched_ahead_time`). Questa latenza di 0.5s viene aggiunta al nostro synth `:piano` perchè viene aggiunta a tutti i synth triggerati da Sonic Pi. Tipicamente desideriamo questa latenza perchè significa avere tutti i synth ben sincronizzati. Tuttavia questo ha senso solo per i synth gestiti a codice usando `play` e `sleep`. In questo caso stiamo triggerando il synth `:piano` con un dispositivo MIDI esterno e di conseguenza non vogliamo che Sonic Pi controlli la sincronizzazione per noi. Possiamo spegnere questa latenza usando il comando `use_real_time` che disabilita la latenza per il thread corrente. Questo significa che puoi usare il modo real time per i live loop che hanno la loro sincronizzazione controllata dai `sync` con i dispositivi esterni e mantenere la latenza predefinita per tutti gli altri live loop. Vediamo:

```
live_loop :midi_piano do
  use_real_time
  note, velocity = sync "/midi:nanokey2_keyboard:0:1/note_on"
  synth :piano, note: note, amp: velocity / 127.0
end
```

Aggiorna il tuo codice per allinearlo al codice sopra e premi Run di nuovo. Ora abbiamo un piano a bassa latenza con velocity variabile codificato in appena 5 righe. Facile vero!

## Ottenere i valori

Finalmente, ora che i nostri eventi MIDI vanno dritti nel Time State, possiamo anche usare la funziona `get` per recuperare l'ultimo messaggio passato. Questo non blocca il thread corrente e restituisce `nil` se nessun valore viene trovato (cosa che può essere superata passando un valore di default - vedi la documentazione per `get`). Ricorda che puoi chiamare `get` in qualunque thread in qualunque momento per vedere l'ultimo evento corrispondente al valore nel Time State. Puoi anche usare `time_warp` per tornare indietro nel tempo e chiamare `get` per vedere gli eventi passati...


## Ora hai tu il controllo

choose (scegli)
