Differenze tra le versioni di "ALSA e Gambas - L'accodamento degli eventi"

Da Gambas-it.org - Wikipedia.
 
(4 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
ALSA, per processare uno o più eventi, ha bisogno che sia creata una ''coda'' di eventi temporizzati. Come sappiamo, la temporizzazione degli eventi avviene mediante l'assegnazione per ciascun evento da parte dell'applicazione Midi di una <span style= "text-decoration:underline">marcatura temporale</span>: il ''Timestamp''. Una coda di eventi riceverà messaggi di temporizzazione, con i quali cercherà di adattare l'invio degli eventi Midi a questa temporizzazione.
+
ALSA, per processare uno o più ''Eventi Midi'', ha bisogno che sia creata una '''''Coda''''' di ''Eventi Midi'' <span style= "text-decoration:underline">temporizzati</span>.
<BR>L'evento, temporizzato con il proprio valore ''timestamp'', viene innanzitutto inserito nella coda di priorità, ed indirizzato al proprio client di destinazione subito o successivamente a seconda di quanto stabilito dal ''timestamp''.
+
<BR>Come sappiamo, la temporizzazione degli ''Eventi Midi'' avviene mediante l'assegnazione per ciascun Evento da parte dell'applicazione Midi di una <span style= "text-decoration:underline">marcatura temporale</span>: il ''[[ALSA_e_Gambas_-_La_marcatura_temporale_degli_eventi:_il_Timestamp|Timestamp]]''.
<P>Per creare una coda bisognerà utilizzare la funzione di ALSA:
+
<BR>Una ''Coda'' di ''Eventi Midi ALSA'' riceverà messaggi di temporizzazione, con i quali cercherà di adattare l'invio degli ''Eventi Midi'' a questa temporizzazione.
int snd_seq_alloc_queue(snd_seq_t * seq)
+
<BR>L'<I>Evento Midi</i>, temporizzato con il proprio valore ''timestamp'', viene innanzitutto inserito nella coda di priorità, ed indirizzato al proprio client di destinazione subito o successivamente a seconda di quanto stabilito dal ''timestamp''.
La funzione ritorna il valore identificativo della coda, che potrà essere uguale o superiore a zero. Se la funzione, però, ritorna un valore minore di zero, riporterà un errore. L'identificativo della coda sarà utilizzato nella successiva funzione per far partire o arrestare la coda medesima.</p>
 
<P>Questa funzione, come ormai ben sappiamo, andrà richiamata in Gambas con la consueta voce ''Extern''. Tenendo conto delle dichiarazioni assunte nel nostro codice nei capitoli iniziali di questa guida, inseriremo detta funzione nella routine ''alsa_open()'' presente in CAlsa.class, e così scriveremo:</p>
 
  
  PRIVATE Extern snd_seq_alloc_queue(seq As Pointer) As Integer
+
===Creare e allocare la Coda degli Eventi Midi di ALSA===
+
Per creare una ''Coda'' bisognerà utilizzare la funzione di ALSA:
'''Public''' Sub alsa_open(myname As string)
+
  int [https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html#ga036e62b321b56bee2e8d2e8280a6416a snd_seq_alloc_queue()]
  Dim err As Integer
+
La funzione ritorna il valore identificativo della ''Coda'', che potrà essere uguale o superiore a zero. Se la funzione, però, ritorna un valore minore di zero, riporterà un errore.
......
+
<BR>L'identificativo della ''Coda'' sarà poi utilizzato sia nella Struttura costitutiva di ciascun ''Evento Midi ALSA'', sia nella funzione esterna  "snd_seq_control_queue()" per far partire o arrestare la coda medesima.
   
+
 
err = snd_seq_alloc_queue(handle)
+
Questa funzione, come ormai ben sappiamo, andrà dichiarata in Gambas con la consueta parola-chiave ''Extern'':
printerr("Creazione della coda", err)
+
  Private Extern snd_seq_alloc_queue(seq As Pointer) As Integer
  IF err < 0 then error.Raise("Errore nella creazione di una coda")
+
E' possibile dare anche un nome alla ''Coda'' sostituendo la suddetta funzione con la seguente funzione esterna di ALSA:
outqueue = err
+
  err = [https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html#ga8efa821e0fc96fd05460306808e8fb7d snd_seq_alloc_named_queue()]
   
+
che sarà così dichiarata con ''Extern'':
......
+
  Private Extern snd_seq_alloc_named_queue(seq as Pointer, nome_coda As String) As Integer
  
E' possibile dare anche un nome alla coda sostituendo la funzione di prima con la seguente funzione esterna di ALSA:
+
===Avvio ed arresto della Coda degli Eventi Midi di ALSA===
err = snd_seq_alloc_named_queue(snd_seq_t * seq, const char * name)
+
<SPAN Style="text-decoration:underline">Dopo aver allocato la ''Coda'' di ''Eventi Midi'' temporizzati, sarà necessario avviarla</span>.
che sarà così richiamata con Extern ed utilizzata:
+
<BR>Se quest'azione non avviene, non vi sarà il processo di sequenziazione degli ''Eventi Midi'' temporizzati e, quindi, non vi sarà esecuzione audio.
PRIVATE Extern snd_seq_alloc_named_queue(seq as Pointer, nome_coda As String) As Integer
+
<BR>Ciò sarà compiuto mediante la funzione esterna di ALSA:
+
  [https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_middle.html#ga36dee7982baa47ad22ab8437541ea5ef snd_seq_control_queue(seq, q, type, value, 0, ev)]
...... ''<Font Color= #006400>' ''come sopra''</font>
+
Laddove:
err = snd_seq_alloc_named_queue(handle, "coda_eventi")
 
...... ''<Font Color= #006400>' ''come sopra''</font>
 
<SPAN Style="text-decoration:underline">Dopo aver allocato la coda di eventi temporizzati, sarà necessario avviarla</span>.
 
<BR>Ciò sarà compiuto mediante la funzione:
 
  snd_seq_control_queue(seq, q, type, value, 0, ev)
 
<BR>Laddove:
 
 
* ''seq'' è l'handle del sequencer ALSA;
 
* ''seq'' è l'handle del sequencer ALSA;
 
* ''q'' è l'identificativo della coda da avviare (o da fermare);
 
* ''q'' è l'identificativo della coda da avviare (o da fermare);
Riga 37: Riga 29:
 
* ''ev'' è un istanza dell'evento.
 
* ''ev'' è un istanza dell'evento.
 
In particolare per avviare la coda, si imposterà nel parametro "type" la Costante di ALSA:
 
In particolare per avviare la coda, si imposterà nel parametro "type" la Costante di ALSA:
  SND_SEQ_EVENT_START
+
  SND_SEQ_EVENT_START = 30
 
Se, invece, intendiamo fermare la coda utilizzeremo la medesima funzione cambiando, però il terzo parametro con la Costante:
 
Se, invece, intendiamo fermare la coda utilizzeremo la medesima funzione cambiando, però il terzo parametro con la Costante:
  SND_SEQ_EVENT_STOP.
+
  SND_SEQ_EVENT_STOP = 32
Nel codice se poniamo due button, con i quali poter scatenare queste funzioni, avremo in CAlsa.class:
+
In Gambas dichiareremo le suddette Costanti come segue:
 
 
 
  Private Const SND_SEQ_EVENT_START As Integer = 30
 
  Private Const SND_SEQ_EVENT_START As Integer = 30
 
  Private Const SND_SEQ_EVENT_STOP As Integer = 32
 
  Private Const SND_SEQ_EVENT_STOP As Integer = 32
 +
e saranno ad esempio così utilizzate:
 +
Private Extern snd_seq_control_queue(seq As Pointer, id_queue As integer, type_queue As Integer, val_queue As Integer, ev_queue As Integer) As Integer
 
   
 
   
PRIVATE Extern snd_seq_control_queue(seq As Pointer, id_queue As integer, type_queue As Integer, val_queue As Integer, ev_queue As Integer) As Integer
+
  '''Public''' Sub Avvia_la_Coda()
 
  '''Public''' Sub start_queue()
 
 
   
 
   
 
   Dim err As Integer
 
   Dim err As Integer
 
   
 
   
   err = snd_seq_control_queue(handle, outqueue, <FONT Color=#006400><B>SND_SEQ_EVENT_START</b></font>, 0, 0)
+
   err = snd_seq_control_queue(handle, id_coda, <FONT Color=#006400><B>SND_SEQ_EVENT_START</b></font>, 0, 0)
 
   
 
   
 
  '''End'''
 
  '''End'''
 
   
 
   
 
   
 
   
  '''Public''' Sub stop_queue()
+
  '''Public''' Sub Arresta_la_Coda()
 
+
 
   Dim err As Integer
 
   Dim err As Integer
 
   
 
   
   err = snd_seq_control_queue(handle, outqueue, <FONT Color=#B22222><B>SND_SEQ_EVENT_STOP</b></font>, 0, 0)
+
   err = snd_seq_control_queue(handle, id_coda, <FONT Color=#B22222><B>SND_SEQ_EVENT_STOP</b></font>, 0, 0)
 
+
 
  '''End'''
 
  '''End'''
 +
 +
 +
==Fasi successive alla creazione della coda==
 +
Dopo la creazione sia della ''Coda'' che degli ''Eventi Midi ALSA'', come esposto nelle pagine precedenti del presente Capitolo [[La_gestione_dei_dati_Midi_con_il_subsistema_Seq#ALSA_e_Gambas_-_Gestione_dei_Messaggi_Midi_standard|ALSA e Gambas - Gestione dei Messaggi Midi standard]], gli ''Eventi Midi'' devono essere accodati nel buffer di ALSA.
 +
<BR>Ciò deve avvire subito dopo la impostazione di tutti i parametri necessari alla definizione dell'<I>Evento Midi ALSA</i>, previsti nella Struttura [[Alsa_e_Gambas_-_Dai_Messaggi_Midi_standard_all'Evento_Midi_di_ALSA|snd_seq_event_t]], a mezzo della funzione esterna:
 +
[https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html#ga41be1e09173957944352c50067a686ea snd_seq_event_output_buffer()]
 +
L'invio finale ad ALSA della ''Coda'' degli ''Eventi Midi'', memorizzati nel buffer predetto, avviene attraverso la funzione esterna:
 +
[https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html#ga64a0ed5488504ef91b5b6b92172bc0aa snd_seq_drain_output()]
 +
Quest'ultimo atto determina il processamento degli ''Eventi Midi'' da parte del sistema ALSA e l'esecuzione musicale.
 +
 +
L'arresto della ''Coda'' degli ''Eventi Midi'', e quindi del loro processamento, avviene nella modalità già vista sopra, mediante l'uso della funzione esterna:
 +
snd_seq_control_queue()
 +
alla quale va passata al suo 3° argomento la Costante "SND_SEQ_EVENT_STOP".

Versione attuale delle 16:28, 24 gen 2022

ALSA, per processare uno o più Eventi Midi, ha bisogno che sia creata una Coda di Eventi Midi temporizzati.
Come sappiamo, la temporizzazione degli Eventi Midi avviene mediante l'assegnazione per ciascun Evento da parte dell'applicazione Midi di una marcatura temporale: il Timestamp.
Una Coda di Eventi Midi ALSA riceverà messaggi di temporizzazione, con i quali cercherà di adattare l'invio degli Eventi Midi a questa temporizzazione.
L'Evento Midi, temporizzato con il proprio valore timestamp, viene innanzitutto inserito nella coda di priorità, ed indirizzato al proprio client di destinazione subito o successivamente a seconda di quanto stabilito dal timestamp.

Creare e allocare la Coda degli Eventi Midi di ALSA

Per creare una Coda bisognerà utilizzare la funzione di ALSA:

int snd_seq_alloc_queue()

La funzione ritorna il valore identificativo della Coda, che potrà essere uguale o superiore a zero. Se la funzione, però, ritorna un valore minore di zero, riporterà un errore.
L'identificativo della Coda sarà poi utilizzato sia nella Struttura costitutiva di ciascun Evento Midi ALSA, sia nella funzione esterna "snd_seq_control_queue()" per far partire o arrestare la coda medesima.

Questa funzione, come ormai ben sappiamo, andrà dichiarata in Gambas con la consueta parola-chiave Extern:

Private Extern snd_seq_alloc_queue(seq As Pointer) As Integer

E' possibile dare anche un nome alla Coda sostituendo la suddetta funzione con la seguente funzione esterna di ALSA:

err = snd_seq_alloc_named_queue()

che sarà così dichiarata con Extern:

Private Extern snd_seq_alloc_named_queue(seq as Pointer, nome_coda As String) As Integer

Avvio ed arresto della Coda degli Eventi Midi di ALSA

Dopo aver allocato la Coda di Eventi Midi temporizzati, sarà necessario avviarla.
Se quest'azione non avviene, non vi sarà il processo di sequenziazione degli Eventi Midi temporizzati e, quindi, non vi sarà esecuzione audio.
Ciò sarà compiuto mediante la funzione esterna di ALSA:

snd_seq_control_queue(seq, q, type, value, 0, ev)

Laddove:

  • seq è l'handle del sequencer ALSA;
  • q è l'identificativo della coda da avviare (o da fermare);
  • type è il tipo di evento (Start, Stop oppure Continue);
  • value è il valore relativo all'evento;
  • ev è un istanza dell'evento.

In particolare per avviare la coda, si imposterà nel parametro "type" la Costante di ALSA:

SND_SEQ_EVENT_START = 30

Se, invece, intendiamo fermare la coda utilizzeremo la medesima funzione cambiando, però il terzo parametro con la Costante:

SND_SEQ_EVENT_STOP = 32

In Gambas dichiareremo le suddette Costanti come segue:

Private Const SND_SEQ_EVENT_START As Integer = 30
Private Const SND_SEQ_EVENT_STOP As Integer = 32

e saranno ad esempio così utilizzate:

Private Extern snd_seq_control_queue(seq As Pointer, id_queue As integer, type_queue As Integer, val_queue As Integer, ev_queue As Integer) As Integer

Public Sub Avvia_la_Coda()

 Dim err As Integer

 err = snd_seq_control_queue(handle, id_coda, SND_SEQ_EVENT_START, 0, 0)

End


Public Sub Arresta_la_Coda()

 Dim err As Integer

 err = snd_seq_control_queue(handle, id_coda, SND_SEQ_EVENT_STOP, 0, 0)

End


Fasi successive alla creazione della coda

Dopo la creazione sia della Coda che degli Eventi Midi ALSA, come esposto nelle pagine precedenti del presente Capitolo ALSA e Gambas - Gestione dei Messaggi Midi standard, gli Eventi Midi devono essere accodati nel buffer di ALSA.
Ciò deve avvire subito dopo la impostazione di tutti i parametri necessari alla definizione dell'Evento Midi ALSA, previsti nella Struttura snd_seq_event_t, a mezzo della funzione esterna:

snd_seq_event_output_buffer()

L'invio finale ad ALSA della Coda degli Eventi Midi, memorizzati nel buffer predetto, avviene attraverso la funzione esterna:

snd_seq_drain_output()

Quest'ultimo atto determina il processamento degli Eventi Midi da parte del sistema ALSA e l'esecuzione musicale.

L'arresto della Coda degli Eventi Midi, e quindi del loro processamento, avviene nella modalità già vista sopra, mediante l'uso della funzione esterna:

snd_seq_control_queue()

alla quale va passata al suo 3° argomento la Costante "SND_SEQ_EVENT_STOP".