Alsa e Gambas - Invio dati con l'uso di un vettore di tipo Byte

Da Gambas-it.org - Wikipedia.

Per inviare gli eventi Midi ad ALSA, è possibile utilizzare anche vettori di tipo Byte[].

In particolare si creerà un vettore composto da 28 elementi e si assegneranno i valori necessari a tali elementi in base alla posizione di tali valori all'interno dell'aera di memoria modello di ciascun evento Midi di ALSA, come rappresentata dalla Struttura snd_seq_event_t.

Va però precisato che, però, questa soluzione non è ottimale: può andare bene soltanto per accogliere i valori corrispondenti al tipo di dato "BYTE" di Gambas o comunque, se superiore ("Integer"), valori ovviamente compresi comunque tra 0 e 255.

Mostriamo un esempio pratico:

Private midi As Pointer
Private evento As New Byte[28]


Library "libasound:2"

Private Const SND_SEQ_OPEN_OUTPUT As Integer = 1
Private Const SND_SEQ_QUEUE_DIRECT As Byte = 253
Private Enum SND_SEQ_EVENT_NOTEON = 6, SND_SEQ_EVENT_NOTEOFF

' int snd_seq_open (snd_seq_t **handle, const char * name, int streams, int mode)
' Open the ALSA sequencer.
Private Extern snd_seq_open(handle As Pointer, name As String, streams As Integer, mode As Integer) As Integer

 ' const char * snd_strerror (int errnum)
' Returns the message for an error code.
Private Extern snd_strerror(err As Integer) As String
  
' int snd_seq_event_output (snd_seq_t *handle, snd_seq_event_t *ev)
' Output an event.
Private Extern snd_seq_event_output(handle As Pointer, ev As Byte[])

' int snd_seq_drain_output (snd_seq_t * seq)
' Drain output buffer to sequencer.
Private Extern snd_seq_drain_output(seq As Pointer) As Integer

' int snd_seq_close (snd_seq_t *handle)
' Close the sequencer.
Private Extern snd_seq_close(handle As Pointer) As Integer


Public Sub Form_Open()

 SpinBox1.MaxValue = 127
 SpinBox1.Value = 64

End


Public Sub Button1_MouseDown()

 Dim rit As Integer

 rit = snd_seq_open(VarPtr(midi), "default", SND_SEQ_OPEN_OUTPUT, 0)
 If rit < 0 Then Error.Raise("Impossibile aprire il subsistema 'seq' di ALSA: " & snd_strerror(rit))

' Imposta il Messaggio Midi "Note-ON":
 evento[0] = SND_SEQ_EVENT_NOTEON
 evento[3] = SND_SEQ_QUEUE_DIRECT
 evento[14] = 128
 evento[17] = SpinBox1.Value
 evento[18] = 100

 Messaggio(evento)

End


Public Sub Button1_MouseUp()

' Imposta il Messaggio Midi "Note-OFF":
 evento[0] = SND_SEQ_EVENT_NOTEOFF
 evento[18] = 0

 Messaggio(evento)

 snd_seq_close(midi)

End


Private Procedure Messaggio(ev As Byte[])

' Inserisce l'Evento di ALSA nel buffer:
 snd_seq_event_output(midi, ev)

' Invia l'Evento:
 snd_seq_drain_output(midi)

End