MIDI RPN & NRPN – Capiamoci qualcosa

Written by Antonio Antetomaso on . Posted in Tutorial

Dopo una serie di appuntamenti di carattere prettamente recensivo, vorrei “rompere un po’ le righe” proponendovi una chiacchierata dal sapore più squisitamente didattico (mamma mia che parolona…) incentrata su di un tema che abbiamo già affrontato in passato, ovvero il protocollo MIDI.
COPERTINA
Di Antonio Antetomaso

Nel dettaglio, durante lo scorso appuntamento, si è discusso brevemente della storia e delle caratteristiche del protocollo MIDI e si è spostato decisamente il focus sullo standard GENERAL MIDI, che ha provato a fare un po’ di ordine nell’universo delle possibili implementazioni della specifica da parte dei costruttori di strumenti musicali.


Orbene, mi piacerebbe riprendere il discorso iniziato la volta scorsa andando ad analizzare uno degli aspetti forse meno chiari del protocollo, i messaggi RPN ed NRPN con la promessa di essere il più lapalissiano e meno noioso possibile. Prima di entrare nei dettagli della tematica, oltre a suggerirvi di dare una scorsa veloce alla precedente puntata, vorrei ripassare brevemente con voi qualcosa relativamente alla struttura dei messaggi midi e alla loro tipologia, per poi orientare le vele verso la nostra meta.

A me gli occhi allora: iniziamo con il ricordare che il MIDI è la specifica di una interfaccia di comunicazione tra strumenti musicali, nel senso che definisce precisamente come interconnettere tra loro due o più di essi e cosa può essere inviato da uno strumento ad un altro. In merito al cosa, ovvio che stiamo parlando di messaggi e, considerato che la D della parola MIDI sta per “DIGITAL”, va da sè che si tratta di UNO e ZERO che transitano.

FIGURA1

E difatti un messaggio MIDI altro non è che una sequenza di uno o più byte (8 bit…non fucilatemi per la precisazione), costruiti secondo la tipologia di messaggio con cui si ha a che fare. Ciascun byte identifica precisamente una parte del messaggio e, scendendo ancora di più con la lente di ingrandimento, ciascun bit del byte in questione ha un preciso e definito ruolo.

Iniziamo dal bit più a sinistra che, per gli amici, è definito bit “più significativo” (MSB); esso definisce univocamente il tipo di messaggio midi con il quale abbiamo a che fare, inducendo la suddivisione di tutti i byte che compongono i messaggi midi in due grandi categorie: status bytes e data bytes.

I primi hanno il bit più significativo pari a 1, i secondi pari a 0. In figura seguente è mostrata la struttura di uno status byte.

c

Come si nota, in uno status byte gli 8 bit possono essere divisi in due nibbles (gruppi di 4 bit), uno più significativo e l’altro meno significativo, da sinistra verso destra. Tolto il bit che identifica il tipo di byte che stiamo trasmettendo, i seguenti 3 bit che formano il nibble più significativo identificano il tipo di messaggio midi che si sta trasmettendo o, in altre parole, il comando che si vuole dare allo strumento ricevente.

Se la matematica non è una opinione, 2 alla 3 fa 8 per altrettante tipologie di messaggi MIDI previste dalla specifica.

FIGURA3

I primi sette tipi di messaggi sono definiti channel voice messages perchè richiedono l’impostazione del canale midi sul quale essi vengono trasmessi, mentre l’ottavo tipo di messaggio prende il nome di system message: trattasi di una categoria di messaggi che prescindono dal canale su cui essi sono inviati e che impattano su parametri globali dell’apparecchiatura MIDI a cui sono destinati.

Il nibble meno significativo di uno status byte identifica univocamente il canale su cui il messaggio viene trasmesso. Ancora, con 4 bit a disposizione si hanno 16 possibili valori…ed ecco perchè i canali midi sono 16, vi torna?

a

In un system message, tale gruppo di 4 bit non viene utilizzato per specificare il canale, bensì il tipo di parametro globale che si vuole toccare.
La struttura di un data byte invece è molto più semplice perchè è contraddistinta dal primo bit pari sempre a 0 e da 7 bit che rappresentano il valore numerico assegnato al parametro MIDI su cui si sta intervenendo ed univocamente identificato dallo status byte, mi spiego?
Conticino alla mano, con 7 bit ho 128 valori possibili, da 0 a 127…ecco spiegato ancora perchè ciascun parametro MIDI assume al massimo un valore pari a 127. Questo è inoltre il limite che ha portato all’introduzione dei messaggi RPN e NRPN….ma portate ancora un po’ di pazienza.
Prima di andare avanti, facciamo un esempio concreto: proviamo ad inviare un messaggio “note on” al nostro ipotetico sintetizzatore. Abbiamo detto che devo costruire delle sequenze di bytes no? Bene, la sequenza in oggetto, da specifica midi, è costituita da ben 3 bytes, uno di stato e gli altri due di dati. Il primo serve a dire che stiamo mandando un messaggio di note on, il secondo identifica la nota da riprodurre, il terzo la dinamica da adottare. Tabella MIDI alla mano, ecco i tre bytes pronti per essere inviati:

b

Abbastanza chiaro no? Orbene, se la risposta è si, siamo pronti per capire qualcosa dei protagonisti del nostro appuntamento. Iniziamo con il dire che si tratta di un caso particolare di messaggi di control change, quindi quelli che hanno come nibble più significativo 1011.
Inviare un byte di stato relativo ad un control change, significa di fatto dire all’apparecchiatura destinataria del messaggio:” ehi amico, preparati perchè devo intervenire su uno dei 128 parametri di espressione che mi metti a disposizione, ma il parametro che mi serve di controllare te lo dico con il prossimo byte”.

d

Ecco infatti la lista di tutti e 128 i parametri di control change inviabili ad una apparecchiatura midi, ciascuno associato ad un numero ben preciso:

FIGURA7

Come per ogni altro parametro, anche per ciascuno di essi è possibile specificare un valore che va da 0 a 127. Uhm….e che succede se devo operare su di un parametro per il quale mi servono più di 128 valori? Semplice, anzichè usare un solo byte di CC ne uso due e assegno a ciascuno di essi un valore, considerando il primo numero come la cifra più significativa e il secondo come la cifra meno significativa. Ho quindi la possibilità di specificare 128*128=16384 valori possibili, da 0 a 16383. Chiamo il byte che rappresenta la cifra più significativa MSB (Most Significative Byte) e quello che rappresenta la cifra meno significativa LSB (Less Significative Byte).

Come li costruisco sti MSB ed LSB? OK, un esempio porterà la giusta luce. Ricordate il modulo Roland JV-1080?

FIGURA8

Orbene, tale modulo offre 640 timbri organizzati in 5 banchi da 128….mi dite voi come faccio a selezionarli via midi avendo solo un messaggio di program change per il quale è possibile specificare solo 128 valori?
Semplice, non devo costruire un messaggio di program change classico, ma devo affiancarlo ad un messaggio di bank select. Orbene, se guardate la tabella di tutti i messaggi di CC disponibili notate che per costruire un messaggio di bank select devo inviare due control change, il primo di tipo MSB corrispondente al numero 0, il secondo, LSB, al numero 32, ciascuno con il suo data byte, a specificarne il valore che si desidera impostare. Supponiamo di voler selezionare il timbro di “piano acustico” che corrisponde alla prima posizione del banco A. Andiamo a consultare l’implementazione MIDI del JV-1080 per scoprire quale valore inviare per CC0 e CC32 per selezionare il banco A e quale valore di program change inviare per il timbro di piano.

Scopriamo che dobbiamo inviare la sequenza:

* CC0=81
* CC32=0
* Pr.Change=1
Questo si traduce di fatto in:

* status byte relativo ad un messaggio di CC
* data byte con il valore 0 (il numero del CC MSB)
* data byte con il valore 81
* status byte relativo ad un messaggio di CC
* data byte con il valore 32 (il numero del CC LSB)
* data byte con il valore 0
* status byte relativo ad un messaggio di program change
* data byte relativo al valore di program change da impostare
per un totale di 8 bytes.

Se avete capito tutto, passo senza indugio a definire i messaggi RPN (Registered Parameter Number) e NRPN (Non Registered Parameter Number) come particolari messaggi di control change di tipo MSB/LSB, che servono ad intervenire su di un sottoinsieme di parametri della nostra apparecchiatura midi, ciascuno dei quali è identificato da altri due bytes MSB/LSB, per un totale (teorico) di 16384 parametri. Per la specifica del valore di ciascuno di essi ancora un’altra coppia MSB/LSB.

Essi sono stati concepiti, ancora, per superare il limite dei 128 tipi di messaggi di control change, usando appunto come tecnica quella dell’ annidamento. In pratica è come avere un cassetto dentro un altro: scelgo una coppia MSB/LSB per segnalare l’intervento su una delle due categorie di parametri (RPN o NRPN), un’altra coppia MSB/LSB per selezionare il tipo di parametro e poi mando il valore per quel parametro utilizzando un’altra coppia MSB/LSB.

Con maggiore precisione, i parametri NRPN sono identificati da un CC di tipo MSB pari a 99 e un CC di tipo LSB pari a 98, mentre gli RPN da un MSB pari a 101 e un LSB pari a 100.
Il particolare parametro RPN o NRPN su cui si va ad intervenire è identificato mediante un CC65 come MSB e un CC64 come LSB. Infine, per specificare il valore del parametro selezionato bisogna usare il CC6 come MSB (data entry MSB) e il CC38 (data entry LSB), assegnando ad entrambi un valore.
La differenza tra RPN e NRPN è nel fatto che i primi sono definiti dalla specifica MIDI, i secondi sono a discrezione del costruttore dello strumento (qualche grado di libertà bisogna pur darlo no?).
In merito ai parametri RPN essi sono, allo stato attuale, i seguenti:

Schermata 03-2457105 alle 10.01.49

Facciamo un esempio…
Supponiamo che io voglia alterare l’intonazione del mio strumento via MIDI, portandola al valore midi di 76 (442 HZ).

Devo mandare un messaggio RPN, non ci son santi. Bene, l’RPN associato all’intonazione è identificato da CC65 pari a 0 e CC64 pari a 2.
Prima però devo dichiarare che sto per inviare un RPN, quindi devo inviare CC101 e CC100. Ecco dunque la nostra sequenza:

 

* status byte relativo ad un control change
* data byte contenente il valore 101
* status byte relativo ad un control change
* data byte contenente il valore 65
* data byte contenente il valore 0
* status byte relativo ad un control change
* data byte contenente il valore 100
* status byte relativo ad un control change
* data byte contenente il valore 65
* data byte contenente il valore 2
* status byte relativo ad un control change
* data byte contenente il valore 6
* data entry MSB contenente il valore 76 (in questo caso 76 è minore di 128 e la specifica mi dice che devo usare solo il data entry MSB)

Dai che non è difficile….(disse asciugandosi il sudore sulla fronte).
Permettetemi un consiglio: se veramente volete capire a fondo questa roba, non c’è niente di meglio che prendere la scheda relativa all’implementazione MIDI del vostro strumento ed iniziare a costruire, magari mediante la vostra DAW preferita, qualche messaggio RPN o NRPN e ad inviarlo. Logic ad esempio offre un ottimo editor di eventi midi, con il quale costruire facilmente messaggi midi ed inviarli.
Provate: vi si aprirà un mondo tutto nuovo, credete a me.
Alla prossima, ragazzi.

Tags: ,

Comments (6)

  • synthy

    |

    grazie Antonio, hai colmato il mio gap…

    Reply

  • Antonio Antetomaso

    |

    Piccola errata corrige: nella sequenza finale relativa al messaggio di RPN c’è un piccolo refuso dovuto al copia e incolla. Tanto per essere precisi, gli ultimi 5 bytes sono:

    .
    .
    * data byte contenente il valore 64 (e non 65)
    * data byte contenente il valore 2
    * status byte relativo ad un control change
    * data byte contenente il valore 6
    * data entry MSB contenente il valore 76 (in questo caso 76 è minore di 128 e la specifica mi dice che devo usare solo il data entry MSB).

    Non chiamatemi “pignolo” 😀

    Reply

  • Massimiliano

    |

    Articolo chiaro ed esaustivo. Grazie mille.

    Reply

  • massimo

    |

    ciao Antonio, e grazie per l’articolo , molto utile e chiaro.
    avrei una domanda , spero di non uscire troppo dal tracciato.
    conosci i valori msb e lsb per poter accedere alle banche suoni dell alpha juno 2? ho cercato nella implementation page del manuale ma non li ho trovati. forse è troppo vecchia per gestire il program change in questo modo? grazie mille

    Reply

  • Bozzy

    |

    Grazie, articolo chiaro ed esaustivo. Tuttavia non mi trovo con la parte relativa agli RPN/NRPN.
    A quanto so (e vari articoli in rete mi darebbero ragione), i CC 65 e 64 non c’entrano un cavolo in questo contesto.
    Un messaggio CC è sempre formato da 3 bytes: lo status byte di control change, un data byte per definire quale control e un data byte per definirne il valore.
    Per inviare un NRPN, ad esempio, dovrò inviare un CC 99 xx dove xx è l’MSB di quell’NRPN, poi un CC 98 yy dove yy è l’LSB di quell’NRPN: fin qua ho identificato quale fra i 16384 NRPN voglio modificare (non servono i CC65 e 64 per stabilirlo!). Infine invierò un CC6 ed eventualmente un CC38 per definire il valore dell’NRPN prima selezionato.
    La sequenza corretta del tuo esempio (RPN) dovrebbe essere questa:
    * status byte relativo ad un control change
    * data byte contenente il valore 101
    * data byte contenente il valore 0
    * status byte relativo ad un control change
    * data byte contenente il valore 100
    * data byte contenente il valore 2
    * status byte relativo ad un control change
    * data byte contenente il valore 6
    * data entry MSB contenente il valore 76 (in questo caso 76 è minore di 128 e la specifica mi dice che devo usare solo il data entry MSB)
    Giusto?

    Reply

Leave a comment

Inserisci il numero mancante: *

ga('send', 'pageview');