Devices

Se vogliamo controllare i parametri di un Synth interagendo fisicamente con devices esterni come prima cosa dobbiamo cercare nelle specifiche tecniche dello strumento o del controller se ha o meno bisogno di essere connesso al computer con un cavo o se utilizza una qualche connessione Wi-fi.

In secondo luogo dobbiamo verificare quale protocollo di comunicazione utilizza per parlare con il mondo esterno ovvero che "lingua" utilizza.

Il protocollo di comunicazione più recente (anche se non recentissimo) che ha in parte soppiantato il protocollo Midi è l' OSC (Open Sound Control) che necessita di una connessione LAN (Local Area Network) o internet.

image not found

N.B. Ricordiamo che il protocollo OSC è anche quelllo utilizzato da SuperCollider per far comunicare tra loro Interprete e Server e la principale differenza con il protocollo Midi consiste proprio nel fatto che i valori MIDI devono "passare" obbligatoriamente dall'Interprete, mentre quello OSC possono essere inviati direttamente al Server.

Touchosc

Al giorno d'oggi esistono in commercio numerose interfacce touch screen e app attraverso le quali possiamo controllare dinamicamente con le dita diversi parametri di uno o più Synth tramite messaggi OSC.

La app più conosciuta è Touchosc che è multipiattaforma, funziona con i più comuni smartphone e tablet, possiede tutte le icone grafiche che possono servire a controllare parametri musicali ed è di facile programmazione. Vediamo brevemente le principali operazioni da compiere per rendere operativo il collegamento:

  1. Scarichiamo ed installiamo sul computer l’applicazione: TouchOSC Editor. (Un'applicazione per creare e mappare i controlli grafici sullo schermo del tablet o smartphone).

  2. Scarichiamo ed installiamo sul computer l’applicazione: TouchOSC Bridge (Un'applicazione per utilizzare controlli Midi via OSC)

  3. Scarichiamo ed installiamo sul tablet o smartphone l’applicazione: TouchOSC

  4. Verifichiamo se i due devices sono collegati in modalità Wi-Fi alla stessa rete altrimenti si rende necessario creare una rete locale tra loro (le modalità dipendono dai diversi sistemi operativi).

  5. Lanciamo TouchOSC Editor sul computer:

    image not found

  6. Selezioniamo il size (tipo di device) oppure specifichiamo la superficie dello schermo in pixels.

  7. Nell'area che simula lo schermo --> tasto destro per selezionare il tipo di controller da posizionare nell'area:

    image not found

  8. Togliamo la spunta auto

  9. Specifichiamo un nome /qualchecosa/... (oppure annotarsi il nome assegnato automaticamente alle singole icone).

  10. Diamo un nome al patch e salvarlo.

  11. Clicchiamo su Sync in alto a destra.

    image not found

  12. Lanciamo TouchOSC sul tablet o smartphone

  13. Specifichiamo l'indirizzo IP del computer con il quale vogliamo comunicare.

  14. Specifichiamo un valore numerico per la porta di trasmissione dei messaggi in uscita (outgoing) e un altro valore per i messaggi in entrata (incoming).

  15. Selezioniamo il nome del patch che abbiamo creato in precedenza tra quelli della lista presente in LAYOUT.

  16. Clicchiamo su Done in alto a destra e comparirà la nostra interfaccia sullo schermo del device.

Comandi

Ricevere messaggi OSC

Ora che i devices sono collegati tra loro vediamo quali sono le righe di codice necessarie per ricevere e inviare messaggi OSC dall'Interprete di Supercollider al device di controllo esterno.

  1. Eseguiamo il boot del Server.
  2. Per verificare la connessione tra i due devices possiamo monitorare tutti i messaggi OSC in ingresso eseguendo il codice seguente:

    OSCFunc.trace(true);  // legge tutti i messaggi OSC in ingresso e riporta i dati nella Post window
    OSCFunc.trace(false); // Termina il monitoraggio 
    

    Appena eseguiamo la prima riga nella Post window cominceranno ad apparire messaggi di questo tipo:

    OSC Message Received:
    	time: 7584.166923327
    	address: a NetAddr(127.0.0.1, 57110)
    	recvPort: 57120
    	msg: [ /status.reply, 1, 0, 0, 2, 114, 0.047717072069645, 0.06623613089323, 44100.0, 44099.990623509 ]
    
    A questo punto se vogliamo vedere anche i messaggi in ingresso dal device, dovremo sostituire su questo il numero di porta in uscita (ongoing) con quello che leggiamo in recvPort: (in questo caso 57120). Compiuta questa operazione leggeremo anche i messaggi generati dalla nostra interazione sul device:
    OSC Message Received:
    	time: 7932.805195529
    	address: a NetAddr(192.168.100.2, 9001) // IP e porta in entrata del Device
    	recvPort: 57120
    	msg: [ /1/fader1, 0.64645624160767 ]	// Array contenente il messaggio OSC ricevuto
    	                                        // [path, valore1, valore2, etc.]
    

  3. Volendo possiamo saltare il punto precedente e utilizzare direttamente la Classe OSCdef.new() specificando i seguenti argomenti:

    • un nome sotto forma di simbolo.
    • una funzione che sarà valutata ogni volta che arriva un messaggio OSC indirizzato all'istanza di OSCdef.new().
    • un indirizzo (path) sotto forma di simbolo che comincia con uno slash: ( /1/fader1 ) che corrisponde ai nomi assegnati automaticamente alle icone dei controlli oppure che abbiamo specificato noi nel programmare l'interfaccia con TouchOsc Edit (punto 9 del Paragrafo precedente).
    • la porta dalla quale ascoltare i messaggi (la stessa che abbiamo specificato come (outgoing) in TouchOsc sul Device.
    //            nome,    funzione,            indirizzo  porta
    OSCdef.new(\criccio, {arg msg; msg.postln}, '/x',       recvPort:8001)
    OSCdef.new(\ciaccio, {arg msg; msg.postln}, '/y',       recvPort:8001)
    OSCdef.new(\ciuccio, {arg msg; msg.postln}, '/z',       recvPort:8001)
    OSCdef.new(\cieccio, {arg msg; msg.postln}, '/1/fader1',recvPort:8000)
    

    Il contenuto del messaggio è un'Array che ha come primo item l'indirizzo al quale è inviato sotto forma di simbolo, seguito dalla lista di valori inviata, nel nostro caso:

    [ /1/fader1, 0.71172297000885 ]

    Possiamo ora isolare i singoli parametri nel modo usuale ([].at(id)) e assegnarli ad una variabile per utilizzarli nel codice.

  4. Se infine vogliamo eliminare la singola OSCdef o tutte:

    OSCdef(\criccio).free; // Cancella una specifica OSCdef
    OSCdef.freeAll;        // Cancella tutte le OSCdef
    

Il codice successivo sintetizza i diversi controlli di un Synth:

(
SynthDef(\osc,
              {arg gain=0;
               var sig;
                   sig = SinOsc.ar;    
               Out.ar(0,sig*gain.lag(0.2))
               }
          ).add;

{~synth = Synth(\osc)}.defer(0.1);
	
OSCdef.new(\master, {arg msg;
                     ~synth.set(\gain,msg[1]) },         // master out tra 0 e 1
                     '/1/fader1', recvPort:8000);
)

Inviare messaggi OSC

Se invece vogliamo inviare messaggi OSC ad altri devices dobbiamo specificare IP del device al quale vogliamo inviare i messaggi e porta del ricevente (in questo caso è la stessa che abbiamo settato in TouchOSC come incoming attraverso la Classe NetAddr("ID", porta)

c = NetAddr("192.168.100.2",  9001); 				

Per poi inviare i singoli messaggi con il metodo .sendMsg():

c.sendMsg("/1/fader1", rand(1.0));

Nel caso il singolo indirizzo accetti più valori non dobbiamo includerli in un Array ma semplicemente separarli da una virgola come negli esempi successivi.

127.0.0.1

Attraverso il protocollo Osc possiamo far comunicare tra loro non solo differenti devices ma anche differenti applicazioni installate sullo stesso computer.

Dobbiamo semplicemente specificare in entrambe le applicazioni un indirizzo IP speciale: 127.0.0.1. Come esempio vediamo come far cominicare tra loro uno script di SuperCollider e un patch di Max.

  1. Scarichiamo e lanciamo il patch di Max

  2. Eseguiamo il codice seguente

    //---------------- Riceve da Max
    
    (
    OSCdef.new(\criccio, {arg msg; msg.postln}, '/x', recvPort:12002);
    OSCdef.new(\ciaccio, {arg msg; msg.postln}, '/y', recvPort:12002);
    OSCdef.new(\ciuccio, {arg msg; msg.postln}, '/z', recvPort:12002);
    )
    
    //---------------- Invia a Max
    
    b = NetAddr("127.0.0.1",  9002);         
    
    b.sendMsg("/x", rand(127));               
    b.sendMsg("/y", rand(127));
    b.sendMsg("/z", rand(127), rand(127)); // nel caso di liste basta la vigola tra gli items
    

Server ---> Client

Se vogliamo inviare valori di segnali dal Server all'Interprete dobbiamo sottocampionarli attraverso un segnale impulsivo e utilizzare il codice seguente.

s.boot;

// -------------------------------> Un solo segnale

(
SynthDef(\inviaM, {var sig;
                       sig = LFNoise0.kr(3);   // Segnale da campionare
	
                   SendReply.kr(Impulse.kr(2), // Rata di sottocampionamento
                                '/posa',       // Etichetta
                                sig);          // Segnale da inviare	
                  }).add;

OSCdef.freeAll;
OSCdef.new(\ricevi, {arg val; val.postln},'/posa');
// val = [Etichetta, Nodo, -1, valore]
)

a = Synth(\inviaM);
a.free;

// -------------------------------> Più segnali dallo stesso Synth

(
SynthDef(\inviaP, {var sig1,sig2;
                       sig1 = LFNoise0.kr(3); // Primo segnale
                       sig2 = SinOsc.kr(5);   // Secondo segnale
	
                   SendReply.kr(Impulse.kr(2), 
                                '/posa',        
                                [sig1,sig2]); // Array di segnali da inviare	
                  }).add;

OSCdef.freeAll;
OSCdef.new(\ricevi, {arg val; val.postln},'/posa');
)

a = Synth(\inviaP);
a.free;