Differenze tra le versioni di "ALSA e Gambas - Inviarsi una Eco~ nel futuro"

Da Gambas-it.org - Wikipedia.
(Creata pagina con "Nella progettazione del nostro sequencer può risultare utile verificare il punto di esecuzione dell'applicativo, come ad esempio conoscere quando il programma sta eseguendo d...")
 
Riga 1: Riga 1:
 
Nella progettazione del nostro sequencer può risultare utile verificare il punto di esecuzione dell'applicativo, come ad esempio conoscere quando il programma sta eseguendo degli eventi Midi. Per sapere ciò che in quel momento sta facendo il nostro client-sequencer, dobbiamo inviare un particolare tipo di evento: l'''Eco''.
 
Nella progettazione del nostro sequencer può risultare utile verificare il punto di esecuzione dell'applicativo, come ad esempio conoscere quando il programma sta eseguendo degli eventi Midi. Per sapere ciò che in quel momento sta facendo il nostro client-sequencer, dobbiamo inviare un particolare tipo di evento: l'''Eco''.
<BR>Il sequencer riceve l'evento ''eco'' anch'esso temporizzato, e ce lo restituirà nel momento stabilito dal proprio ''timestamp''. Quando il programma ci ritorna l'''eco'', che noi abbiamo precedentemente inviato, siamo in grado di individuare il punto del processo in cui si trova il sequencer.
+
<BR>Il sequencer riceve l'Evento ''Eco'' anch'esso temporizzato, e ce lo restituirà nel momento stabilito dal proprio ''timestamp''. Quando il programma ci ritorna l'''Eco'', che noi abbiamo precedentemente inviato, siamo in grado di individuare il punto del processo in cui si trova il sequencer.
  
L'invio dell'evento "''Eco''" può essere una soluzione per poter inviare ad Alsa i dati Midi in maniera costante, ricorrente e nel momento opportuno. Infatti, Alsa non è in grado di gestire una quantità elevata di dati: non è possibile inviarle molte centinaia di dati relativi agli eventi Midi ed ai relativi Tempi Delta contenuti in un file Midi. Pertanto, se ne dovrà inviare una quantità adeguata,  e comunque tale che Alsa non ne rimanga mai priva, fintanto che l'esecuzione del file Midi non è terminata. Se avvenisse l'interruzione del flusso di dati, vi sarebbe irrimediabilmente una spiacevole interruzione dell'esecuzione del brano. Allora, il sequencer dovrà "sapere" il momento opportuno per inviare ad Alsa un altro gruppo di dati, perché siano gestiti. L'importante, per la corretta e coerente esecuzione del brano Midi, è non causare interruzioni nel flusso di dati Midi da inviare ad Alsa. Riportando quanto sottolineato da Clemens Ladisch all'interno del codice sorgente del suo programma ''Aplaymidi'', esistono tre possibilità su come far attendere il sequencer sino al momento del successivo invio di un altro gruppo di dati Midi ad Alsa. Esse sono:
+
L'invio dell'Evento ''Eco'' può essere una soluzione per poter inviare ad Alsa i dati Midi in maniera costante, ricorrente e nel momento opportuno. Infatti, Alsa non è in grado di gestire una quantità elevata di dati: non è possibile inviarle molte centinaia di dati relativi agli eventi Midi ed ai relativi Tempi Delta contenuti in un file Midi. Pertanto, se ne dovrà inviare una quantità adeguata,  e comunque tale che Alsa non ne rimanga mai priva, fintanto che l'esecuzione del file Midi non è terminata. Se avvenisse l'interruzione del flusso di dati, vi sarebbe irrimediabilmente una spiacevole interruzione dell'esecuzione del brano. Allora, il sequencer dovrà "sapere" il momento opportuno per inviare ad Alsa un altro gruppo di dati, perché siano gestiti. L'importante, per la corretta e coerente esecuzione del brano Midi, è non causare interruzioni nel flusso di dati Midi da inviare ad Alsa. Riportando quanto sottolineato da Clemens Ladisch all'interno del codice sorgente del suo programma ''Aplaymidi'', esistono tre possibilità su come far attendere il sequencer sino al momento del successivo invio di un altro gruppo di dati Midi ad Alsa. Esse sono:
 
* 1) inviare ad Alsa un evento ''Eco'', ed attendere che esso torni al sequencer;
 
* 1) inviare ad Alsa un evento ''Eco'', ed attendere che esso torni al sequencer;
 
* 2) attendere un avviso di EVENT_STOP per la ''coda'' degli eventi che viene inviato dalla porta Timer di sistema (questa richiederebbe una ''sottoscrizione'');
 
* 2) attendere un avviso di EVENT_STOP per la ''coda'' degli eventi che viene inviato dalla porta Timer di sistema (questa richiederebbe una ''sottoscrizione'');
Riga 10: Riga 10:
  
  
====Scrittura in Gambas====
+
===Scrittura in Gambas===
 
+
Poiché l'''Eco'' è un evento come qualsiasi altro, e tale è definito e riconosciuto da ALSA, in Gambas lo invieremo utilizzando le medesime modalità che noi conosciamo per inviare un qualsiasi tipo di evento. Avremo solo l'accortezza di indicare il sequencer stesso come <span style= "text-decoration:underline">destinatario</span> dell'evento ''Eco''.
Poiché l'''Eco'' è un evento come qualsiasi altro, e tale è definito e riconosciuto da ALSA, in Gambas lo invieremo utilizzando le medesime modalità (''Memory Stream'' oppure ''Strutture'') che noi conosciamo per inviare un qualsiasi tipo di evento. Avremo solo l'accortezza di indicare il sequencer stesso come <span style= "text-decoration:underline">destinatario</span> dell'evento ''Eco''. Per fare ciò, dopo aver individuato il numero identificativo e la porta del nostro sequencer-applicativo, dovremo inserire tali valori nella funzione esterna di ALSA: ''err = snd_seq_connect_to(handle, outport, '''dclient''', '''dport''')''.
 
<P>Dunque, tenendo conto del modello di codice riportato agli inizi della nostra guida, scriveremo così:</p>
 
  
 +
Dunque, il codice in astratto così:
 +
Private Const SND_SEQ_EVENT_ECHO As Integer = '''50'''  <Font Color=gray> ' ''Questa costante di ALSA individua il "tipo" di Evento "Echo"''</font>
 
   
 
   
Const SND_SEQ_EVENT_ECHO As Integer = 50    <Font Color= #006400> ' ''Questa costante di ALSA individua il "tipo" di evento: un'Eco.''</font>
+
  ......
 
   
 
   
 +
  Dim ev_Midi As snd_seq_event_t
 +
 
 +
  With ev_midi
 +
    .type = <B>SND_SEQ_EVENT_ECHO</b>
 +
    .flags = SND_SEQ_TIME_STAMP_TICK
 +
    .tag = 0
 +
    .queue = coda
 +
    .tick_o_tv_sec = <Font Color=gray>''timestamp_in_tick_midi''</font>
 +
    .tv_nsec = 0
 +
    .source_client = <Font Color=#B22222>id</font>
 +
    .source.port = <Font Color=#006400>s_port</font>
 +
    .dest_client = <Font Color=#B22222>id</font>      <Font Color=gray>' ''Invia l'Evento Midi "Echo" a se stesso''</font>
 +
    .dest_port = <Font Color=#006400>s_port</font>    <Font Color=gray>' ''Invia l'Evento Midi "Echo" alla sua porta quale Client di ALSA''</font>
 +
    .channel = 0
 +
    .note = 0
 +
    .velocity = 0
 +
    .off_velocity = 0
 +
    .param = 0
 +
    .value = 0
 +
  End With
 
   
 
   
'''Public''' Sub invioEco(timestamp As Integer)
 
 
  Dim err As Integer
 
 
  prepareev(SND_SEQ_EVENT_ECHO, timestamp)  <Font Color= #006400>    ' ''chiama la routine di preparazione di un evento.''</font>
 
 
  Seek #pStream, 16
 
  WRITE #pStream, 254 as Byte    <Font Color= #006400>              ' ''Identificativo del destinatario: il sequencer invia l'Eco a se stesso.''</font>
 
 
  WRITE #pStream, 253 as Byte    <Font Color= #006400>            ' ''Porta del destinatario.''</font>
 
 
  err = snd_seq_event_output_buffer(handle, ev)
 
 
  printerr("Eco", err)  <Font Color= #006400>                      ' ''Consueta gestione dell'errore.''</font>
 
 
 
 
  '''End'''
 
  '''End'''
 
+
L'evento ''Eco'' verrà, poi, intercettato come qualsiasi altro ''Evento Midi ALSA'' con le funzioni che già conosciamo per ricevere gli ''Eventi Midi''.
L'evento ''Eco'' verrà, poi, intercettato come qualsiasi altro evento con le funzioni che già conosciamo per ricevere gli eventi Midi.
 

Versione delle 20:36, 25 gen 2022

Nella progettazione del nostro sequencer può risultare utile verificare il punto di esecuzione dell'applicativo, come ad esempio conoscere quando il programma sta eseguendo degli eventi Midi. Per sapere ciò che in quel momento sta facendo il nostro client-sequencer, dobbiamo inviare un particolare tipo di evento: l'Eco.
Il sequencer riceve l'Evento Eco anch'esso temporizzato, e ce lo restituirà nel momento stabilito dal proprio timestamp. Quando il programma ci ritorna l'Eco, che noi abbiamo precedentemente inviato, siamo in grado di individuare il punto del processo in cui si trova il sequencer.

L'invio dell'Evento Eco può essere una soluzione per poter inviare ad Alsa i dati Midi in maniera costante, ricorrente e nel momento opportuno. Infatti, Alsa non è in grado di gestire una quantità elevata di dati: non è possibile inviarle molte centinaia di dati relativi agli eventi Midi ed ai relativi Tempi Delta contenuti in un file Midi. Pertanto, se ne dovrà inviare una quantità adeguata, e comunque tale che Alsa non ne rimanga mai priva, fintanto che l'esecuzione del file Midi non è terminata. Se avvenisse l'interruzione del flusso di dati, vi sarebbe irrimediabilmente una spiacevole interruzione dell'esecuzione del brano. Allora, il sequencer dovrà "sapere" il momento opportuno per inviare ad Alsa un altro gruppo di dati, perché siano gestiti. L'importante, per la corretta e coerente esecuzione del brano Midi, è non causare interruzioni nel flusso di dati Midi da inviare ad Alsa. Riportando quanto sottolineato da Clemens Ladisch all'interno del codice sorgente del suo programma Aplaymidi, esistono tre possibilità su come far attendere il sequencer sino al momento del successivo invio di un altro gruppo di dati Midi ad Alsa. Esse sono:

  • 1) inviare ad Alsa un evento Eco, ed attendere che esso torni al sequencer;
  • 2) attendere un avviso di EVENT_STOP per la coda degli eventi che viene inviato dalla porta Timer di sistema (questa richiederebbe una sottoscrizione);
  • 3) attendere che il pool di uscita sia vuoto (in questo caso si utilizzerebbe la funzione: snd_seq_sync_output_queue(snd_seq_t *seq, size_t size), la quale attende sino a che tutti gli eventi sono stati processati.

Fra le tre possibilità qui mostreremo la prima, quella dell'invio di un evento "Eco".


Scrittura in Gambas

Poiché l'Eco è un evento come qualsiasi altro, e tale è definito e riconosciuto da ALSA, in Gambas lo invieremo utilizzando le medesime modalità che noi conosciamo per inviare un qualsiasi tipo di evento. Avremo solo l'accortezza di indicare il sequencer stesso come destinatario dell'evento Eco.

Dunque, il codice in astratto così:

Private Const SND_SEQ_EVENT_ECHO As Integer = 50    ' Questa costante di ALSA individua il "tipo" di Evento "Echo"

 ......

 Dim ev_Midi As snd_seq_event_t
 
 With ev_midi
   .type = SND_SEQ_EVENT_ECHO
   .flags = SND_SEQ_TIME_STAMP_TICK
   .tag = 0
   .queue = coda
   .tick_o_tv_sec = timestamp_in_tick_midi
   .tv_nsec = 0
   .source_client = id
   .source.port = s_port
   .dest_client = id      ' Invia l'Evento Midi "Echo" a se stesso
   .dest_port = s_port    ' Invia l'Evento Midi "Echo" alla sua porta quale Client di ALSA
   .channel = 0
   .note = 0
   .velocity = 0
   .off_velocity = 0
   .param = 0
   .value = 0
 End With

End

L'evento Eco verrà, poi, intercettato come qualsiasi altro Evento Midi ALSA con le funzioni che già conosciamo per ricevere gli Eventi Midi.