Inviare dati grezzi Midi attraverso il subsistema RawMidi
Premessa
Il sistema Alsa consente di inviare dati Midi grezzi ad un dispositivo Midi esterno mediante il suo subsistema RawMidi.
Nella elaborazione del codice bisognerà, ovviamente, richiamare la libreria estrena di Alsa, attualmente libasound.so.2.0.0, che in Gambas richiameremo così:
Library "libasound:2"
e conseguentemente dichiarare attraverso la parola Extern le funzioni di Alsa necessarie.
Per scrivere dati MIDI, è necessario innanzitutto aprire la connessione con l'interfaccia RawMidi chiamando la funzione
int snd_rawmidi_open (snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi, const char *name, int mode)
passandogli così il nome dell'hardware della scheda, del dispositivo e del sub-dispositivo desiderato. Quella funzione restituirà un handle (maniglia) che è possibile utilizzare per chiamare le successive funzioni esterne necessarie di Alsa.
Detta funzione in Gambas sarà così dichiarata:
Private Extern snd_rawmidi_open(in_rmidi As Pointer, out_rmidi As Pointer, name As String, mode As Integer) As Integer
laddove il parametro in_rmidi, trattandosi in questo caso di inviare dati Midi, sarà posto a zero.
L'altra funzione esterna essenziale è quella che consentirà di inviare i dati grezzi ad un dispositivo Midi esterno:
ssize_t snd_rawmidi_write(snd_rawmidi_t * rawmidi, const void * buffer, size_t size)
che in Gambas sarà dichiarata così:
Private Extern snd_rawmidi_write(out_rmidi As Pointer, buffer As Pointer, size As Integer) As Integer
A questa funzione esterna si passa l'handle, ricevuto dalla funzione snd_rawmidi_open (), l'indirizzo di un buffer contenente alcuni dati MIDI, e la quantità di dati da inviare ogni volta.
Potrebbe sussitere un limite alla quantità di dati che questa funzione è capace di inviare. È possibile determinare quale sia la dimensione dell'output del buffer del driver chiamando la funzione esterna
size_t snd_rawmidi_params_get_buffer_size (const snd_rawmidi_params_t * params)
la quale ritorna apputno la dimensione in byte disponibile del buffer di entrata e di uscita del subsistema RawMidi. Volendo, sarà possibile cambiare quella quantità di byte, chiamando la funzione
int snd_rawmidi_params_set_buffer_size (snd_rawmidi_t * rawmidi, snd_rawmidi_params_t * params, size_t val)
Modalità Blocking e Non-Blocking
Di norma, un uscita Midi viene aperta in modalità bloccante (Blocking). Ciò significa che, quando vengono passati dei dati Midi alla funzione esterna snd_rawmidi_write(), la stessa non ritornerà alcun valore sino a che quei dati non saranno stati inviati attraverso la porta output.
In alternativa è possibile impostare la modalità di apertura non bloccante (Non-Blocking) attraverso la funzione:
int snd_rawmidi_nonblock (snd_rawmidi_t *rmidi, int nonblock)
che in Gambas dichiareremo così:
Private Extern snd_rawmidi_nonblock(midiOut As Pointer, nonblock As Integer) as Integer
e che in codice richiameremo così:
err = snd_rawmidi_nonblock(handleOut, 1)
Nella modalità non bloccante la funzione snd_rawmidi_write() scrive nel driver output i dati presenti nel buffer imediatamente, consentendo così al programma di svolgere altre funzioni.
Una cosa da tener presente, quando si imposta la modalità Non-Blocking, è che se viene chiamata la funzione snd_rawmidi_close () per chiudere una porta output del subsitema RawMidi, immediatamente dopo aver utilizzato la funzione snd_rawmidi_write (), potrebbero perdersi alcuni dati ancora presenti nel driver.
Per ovviare a questo problema è opportuno chiamare la funzione esterna:
int snd_rawmidi_drain (snd_rawmidi_t *rmidi)
Chiudere il dispositivo Output
Per chiudere la porta di uscita dell'interfaccia RawMidi, si utilizza semplicemente la funzione esterna
int snd_rawmidi_close (snd_rawmidi_t *rmidi)
che in Gambas dichiareremo così:
Private Extern snd_rawmidi_close(midiOut As Pointer) as Integer
e che in codice richiameremo così:
err = snd_rawmidi_close(handleOut)
Esempio
Pagina in costruzione