Differenze tra le versioni di "Alsa e Gambas: Ricevere dati da smf"

Da Gambas-it.org - Wikipedia.
Riga 4: Riga 4:
 
<BR>La prima specifica [RP-001] dello ''Standard Midi File'' fu rilasciata nel 1990 dalla "''MIDI Manufacturers Association''" (MMA) per consentire lo scambio di file e di informazioni fra i sequencer Midi.
 
<BR>La prima specifica [RP-001] dello ''Standard Midi File'' fu rilasciata nel 1990 dalla "''MIDI Manufacturers Association''" (MMA) per consentire lo scambio di file e di informazioni fra i sequencer Midi.
 
<P>Il file MIDI è composto da complesse strutture, tecnicamente chiamate: ''Chunk'' (Blocco), formate da un certo numero di byte, ossia di istruzioni conformi al protocollo Midi. Il primo blocco, posto sempre all'inizio del file, è quello relativo all'intestazione del file, ed è chiamato perciò: ''Header Chunk''. E' facilmente riconoscibile perché ha il suo identificativo (''MThd'') posto proprio all'inizio. Il blocco d'intestazione contiene notizie generali, ma essenziali, per la definizio del file Midi medesimo.
 
<P>Il file MIDI è composto da complesse strutture, tecnicamente chiamate: ''Chunk'' (Blocco), formate da un certo numero di byte, ossia di istruzioni conformi al protocollo Midi. Il primo blocco, posto sempre all'inizio del file, è quello relativo all'intestazione del file, ed è chiamato perciò: ''Header Chunk''. E' facilmente riconoscibile perché ha il suo identificativo (''MThd'') posto proprio all'inizio. Il blocco d'intestazione contiene notizie generali, ma essenziali, per la definizio del file Midi medesimo.
<BR>Oltre al blocco d'intestazione il file è costituito da almeno un blocco traccia, chiamato ''Track Chunk'', e riconoscibile dal suo identificativo: ''MTrk''. Questo blocco contiene i dati veri e propri che definiscono la struttura e le modalità di esecuzione di un brano musicale.{[[#Note|1]]}</p>
+
<BR>Oltre al blocco d'intestazione il file è costituito da almeno un blocco traccia, chiamato ''Track Chunk'', e riconoscibile dal suo identificativo: ''MTrk''. Questo blocco contiene i dati veri e propri che definiscono la struttura e le modalità di esecuzione di un brano musicale.|[[#Note|1]]|
 +
<BR>Di seguito eviteremo di esporre codice esemplificativo, ritenendo che ciascun programmatore possa e debba scegliere le soluzioni algoritmiche che riterrà più oppurtune e migliori. Ci limiteremo soltanto a mostrare il codice a scopo esplicativo di quelle parti più delicate relative a particolari concetti.</p>
  
  
 
===Acquisizione dei dati Midi===
 
===Acquisizione dei dati Midi===
Si dovranno ovviamente acquisire i dati dal file ''.mid'':
+
Si dovranno ovviamente acquisire i dati dal file ''.mid'', avendo cura in particolare di:
 
+
* lunghezza dell'intero file Midi, ossia la quantità di byte che lo costituiscono;
flMid As File
+
* il numero delle tracce ''Mtrk'' esistenti, e la lunghezza di ciascuna traccia;
ndt As Integer  ''<Font Color= #006400>' la variabile " n " contiene la quantità totale di dati presenti nel file Midi''</font>
+
* individuare la risoluzione PPQN del Tempo Delta del file Midi, con la quale successivamente determinare i valori decimali dei Midi ''tick'';
b[1000000] As Byte  ''<Font Color= #006400>' la variabile " b " contiene <SPAN Style="text-decoration:underline">tutti</span> i dati raccolti dal file Midi''</font>
+
* distinguere i Messaggi Midi dai Meta-eventi;
ris As Integer  ''<Font Color= #006400>' la variabile " ris " contienela risoluzione del Tempo Delta del file Midi''</font>
+
* individuare i valori del Tempo Delta.
n As Integer  ''<Font Color= #006400>' la variabile " n " contiene la quantità di byte che costituiscono la rappresentazione esadecimale dei Midi ''tick''</font>
 
g[1000000, 4] As Byte  ''<Font Color= #006400>' la variabile " g " è un array che contiene i valori esadecimali costituenti la rappresentazione esadecimale dei Midi ''tick''</font>
 
preTick As Integer  ''<Font Color= #006400>' contiene il valore <SPAN Style="text-decoration:underline">reale</span> della durata in "'''tick'''" dei Tempi Delta''</font>
 
tick_nota As Integer  ''<Font Color= #006400>' contiene il valore della durata in "tick" dei Tempi Delta, adattati alla "risoluzione" indicata nel file Midi''</font>
 
'--
 
w[255] As Integer  ''<Font Color= #006400>' lunghezza di una traccia''</font>
 
a[255, 1000000] As Integer
 
progrTr[255] As Integer
 
numTr As Byte  ''<Font Color= #006400>' numero delle tracce esistenti''</font>
 
y As Byte  ''<Font Color= #006400>' numero di byte costituenti i valori della "rappresentazione" esadecimale del Tempo Delta''</font>
 
 
 
 
'''Public''' Sub Button1_Click()
 
 
Dim a As Byte
 
 
flMid = Open "/percorso.../mioFileMidi.mid" For Read
 
 
 
While Not Eof(flMid)
 
  ndt = ndt + 1
 
  Read #flMid, a
 
  b[ndt] = a
 
Wend
 
 
Close #flMid
 
 
'''End'''
 
  
  
Riga 67: Riga 39:
  
  
===Ricavare la lunghezza della traccia MTrk contenente i dati Midi===
+
===Individuazione della lunghezza della traccia MTrk contenente i dati Midi===
Successivamente ricaveremo la lunghezza della traccia MTrk{[[#Note|5]]}, ed in particolare della parte contenente i dati relativi ai Messaggi Midi ed ai relativi Tempi Delta:
+
Successivamente provvederemo a ricavare la lunghezza della traccia MTrk |[[#Note|5]]|, ed in particolare della parte contenente i dati relativi ai Messaggi Midi ed ai relativi Tempi Delta.
 
 
'''Public''' Sub Button3_Click()
 
 
Dim j As Integer
 
Dim lngTr As Long
 
 
For j = 0 To ndt
 
 
  If Chr(b[j]) & Chr(b[j + 1]) & Chr(b[j + 2]) & Chr(b[j + 3]) = "MTrk" Then
 
    Inc numTr            ''<Font Color= #006400>' numera progressivamente ciascuna traccia trovata...''</font>
 
    progrTr[numTr] = j  ''<Font Color= #006400>' alla quale viene attribuito il numero progessivo del byte, dal quale ha inizio (con la prima lettera "M" Trk)''</font>
 
   
 
  ''<Font Color= #006400>' ricava la lunghezza di una traccia:''</font>
 
      w[numTr] = (b[j + 4] * 256 ^ 3) + (b[j + 5] * 256 ^ 2) + (b[j + 6] * 256) + b[j + 7]
 
      Print "lunghezza = "; w[numTr]; " = "; b[j + 4], b[j + 5], b[j + 6], b[j + 7]  ''<Font Color= #006400>' a soli fini didattici ne vediamo il risultato''</font>
 
  Endif
 
 
Next
 
 
''<Font Color= #006400>' ricava la lunghezza di una traccia (quantità di byte dei dati e dei TD).
 
' Si sottrae 3 al risultato per non tener conto appunto dei 3 byte di fine traccia:''</font>
 
  lngTr = ((b[19] * 256 ^ 3) + (b[20] * 256 ^ 2) + (b[21] * 256) + b[22]) - 3
 
 
 
  Print lngTr  ''<Font Color= #006400>' a soli fini didattici ne vediamo il risultato''</font>
 
 
'''End'''
 
  
  
 
===Estrazione dei dati relativi ai ''Messaggi Midi'' e dei dati relativi al ''Tempo Delta''===
 
===Estrazione dei dati relativi ai ''Messaggi Midi'' e dei dati relativi al ''Tempo Delta''===
Si procederà quindi ad estrarre dai dati raccolti dal file Midi: quelli relativi ai Messaggi Midi e quelli appartenti al ''Tempo Delta'' che separano ciascun evento Midi. Come sappiamo, gli eventi Midi, compresi i valori relativi al Tempo Delta, sono contenuti nel cuore di ciascun blocco Traccia "''MTrk''". Pertanto è da lì che dovremo estrarli. Procediamo con il seguente possibile algoritmo che mira a distinguere tra loro i vari eventi e tra i dati appartenenti al Tempo Delta:
+
Si procederà quindi ad estrarre dai dati raccolti dal file Midi: quelli relativi ai Messaggi Midi e quelli appartenti al ''Tempo Delta'' che separano ciascun evento Midi. Come sappiamo, gli eventi Midi, compresi i valori relativi al Tempo Delta, sono contenuti nel cuore di ciascun blocco Traccia "''MTrk''". Pertanto è da lì che dovremo estrarli. Procederemo quindi a distinguere tra loro i vari eventi e tra i dati appartenenti al Tempo Delta, tenendo conto che dopo un Tempo Delta v'è <SPAN style="text-decoration:underline">sempre</span> un ''evento Midi'' (''Messaggio Midi'' oppure ''Meta-evento''), e dopo un evento Midi v'è <SPAN style="text-decoration:underline">sempre</span> un ''Tempo Delta'' che li separa.
 
 
'''Public''' Sub Button4_Click()
 
 
Dim j, c, cc, e, f, t, numPr As Byte
 
Dim r, k, x, y, d As Integer
 
Dim leggeMeta As String              ''<Font Color= #006400>' dovrà in vero essere posto all'esterno come globale''</font>
 
Dim fuTempoDelta As Boolean
 
 
For j = 1 To numTr    ''<Font Color= #006400>' impostiamo ciascuna traccia esistente per il suo numero''</font>
 
 
  fuTempoDelta = False
 
 
  x = (progrTr[j] + 8)  ''<Font Color= #006400>' cominciamo dal 1° byte successivo alla definizione della lunghezza della traccia''</font>
 
 
  r = (progrTr[j] + 7) + (w[j] - 2)
 
 
  ''<Font Color= #006400>'''' individua ogni byte di evento Midi o TD in ciascuna traccia:'''''</font>
 
    While x < r    ''<Font Color= #006400>' finché x è minore della lunghezza -2 byte della traccia n° j...''</font>
 
 
    ''<Font Color= #006400>' verifichiamo il marcatore di dati, il quale segnala se il precedente dato analizzato e processato
 
    ' era un Tempo Delta oppure un evento Midi (Messaggio Midi o Meta-evento):''</font>
 
      If fuTempoDelta = True Then
 
        fuTempoDelta = False
 
 
        Select Case b[x]    ''<Font Color= #006400>' verifichiamo il valore del byte attuale''</font>
 
 
          Case 240          ''<Font Color= #006400>''''----Individuazione dei SysEx:'''''</font>
 
            While b[x] < 247
 
                x = x + 1      ''<Font Color= #006400>' salta al byte successivo fino alla fine del SysEx''</font>
 
              Wend
 
              x = x + 1
 
 
            Case 255        ''<Font Color= #006400>''''----Individuazione dei Meta-Eventi:'''''</font>
 
              Select Case b[x + 1]
 
                Case 1, 2, 3, 4, 5, 6, 7, 127
 
                  For k = 3 To 2 + b[x + 2]        ''<Font Color= #006400>' legge il contenuto del Meta-evento''</font>
 
                    leggeMeta = leggeMeta & b[x + k]
 
                    Print "leggeMeta "; leggeMeta  ''<Font Color= #006400>' a fini qui didattici ci limitiamo a mostrare il contenuto del Meta-Evento''</font>
 
                  Next
 
                  x = x + 3 + b[x + 2]            ''<Font Color= #006400>' calcola il salto per passare al byte del Tempo Delta successivo all'attuale Meta-Evento''</font>
 
                Case 32, 33, 81, 84, 88, 89
 
                  Select Case b[x + 2]
 
                    Case 2
 
                      For k = 3 To 2 + b[x + 2]    ''<Font Color= #006400>' legge il contenuto del Meta-evento''</font>
 
                        leggeMeta = leggeMeta & b[x + k]
 
                        Print "leggeMeta "; leggeMeta  ''<Font Color= #006400>' a fini qui didattici ci limitiamo a mostrare il contenuto del Meta-Evento''</font>
 
                      Next
 
                      x = x + 5
 
                    Case 3
 
                      For k = 3 To 2 + b[x + 2]    ''<Font Color= #006400>' legge il contenuto del Meta-evento''</font>
 
                        leggeMeta = leggeMeta & b[x + k]
 
                        Print "leggeMeta "; leggeMeta  ''<Font Color= #006400>' a fini qui didattici ci limitiamo a mostrare il contenuto del Meta-Evento''</font>
 
                        leggeMeta = Null
 
                      Next
 
                      x = x + 6
 
                    Case 4
 
                      For k = 3 To 2 + b[x + 2]    ''<Font Color= #006400>' legge il contenuto del Meta-evento''</font>
 
                        leggeMeta = leggeMeta & b[x + k]
 
                        Print "leggeMeta "; leggeMeta  ''<Font Color= #006400>' a fini qui didattici ci limitiamo a mostrare il contenuto del Meta-Evento''</font>
 
                        leggeMeta = Null
 
                      Next
 
                      x = x + 7
 
                    Case 5
 
                      For k = 3 To 2 + b[x + 2]    ''<Font Color= #006400>' legge il contenuto del Meta-evento''</font>
 
                        leggeMeta = leggeMeta & b[x + k]
 
                        Print "leggeMeta "; leggeMeta  ''<Font Color= #006400>' a fini qui didattici ci limitiamo a mostrare il contenuto del Meta-Evento''</font>
 
                        leggeMeta = Null
 
                      Next
 
                      x = x + 8
 
                  End Select
 
             
 
              End Select
 
 
 
          Case Else      ''<Font Color= #006400>''''----se non è un Meta-evento, allora... è un Messaggio Midi:'''''</font>
 
 
            a[j, d] = b[x]
 
 
            If (a[j, d] > 127 And a[j, d] < 192) Or a[j, d] > 223 Then
 
              numPr = 2
 
            Endif
 
            If a[j, d] > 191 And a[j, d] < 224 Then
 
              numPr = 1
 
            Endif
 
 
            For f = 1 To numPr    ''<Font Color= #006400>' legge i singoli dati del Messaggio Midi''</font>
 
              x = x + 1
 
              Inc d
 
              a[j, d] = b[x]
 
              Print Hex$(a[j, d])  ''<Font Color= #006400>' a fini qui didattici ci limitiamo a mostrare i singoli dati del Messaggio Midi''</font>
 
              If f = numPr Then
 
                x = x + 1
 
                fuTempoDelta = False    ''<Font Color= #006400>' questa impostazione determinerà il passaggio all'analisi del TD''</font>
 
              Endif
 
            Next
 
 
       
 
          End Select      ''<Font Color= #006400>' termine del: Select Case b[x]''</font>
 
 
 
 
        Else              ''<Font Color= #006400>''''----altrimenti è un Tempo Delta'''''</font>
 
          For y = 0 To 3  ''<Font Color= #006400>'' cerchiamo di capire quanti byte (da 1 a 4) compongono il valore del Tempo Delta in questione''</font>
 
            If b[x + y] < 128 Then
 
                For t = 0 To y      ''<Font Color= #006400>' raccogliamo i byte (da 1 a 4) che compongono il valore del Tempo Delta''</font>
 
                  Print Hex$(b[x + t])  ''<Font Color= #006400>' a fini qui didattici mostriamo anche i singoli dati della "rappresentazione" del Tempo Delta''</font>
 
                  tickReali()          ''<Font Color= #006400>' chiamiamo questa sub-routine per ottenere i valori '''reali''' del Tempo Delta''</font>
 
                Next
 
              x = x + y + 1      ''<Font Color= #006400>' calcola il salto per passare al byte dell'Evento Midi successivo all'attuale Tempo Delta''</font>
 
              fuTempoDelta = True    ''<Font Color= #006400>' questa impostazione determinerà il passaggio successivamente all'analisi degli eventi Midi e non del Tempo Delta''</font>
 
              Exit                ''<Font Color= #006400>' esce dal ciclo For''</font>
 
            Endif
 
          Next
 
         
 
        Endif
 
 
    Wend
 
 
 
  Next      '' <Font Color= #006400>'fine del FOR principale, iniziale''</font>
 
 
 
'''End'''
 
  
  

Versione delle 16:44, 16 lug 2012

Introduzione

Uno Standard Midi File (.smf) è un archivio di informazioni contenente dati Midi nel loro formato standard.
La prima specifica [RP-001] dello Standard Midi File fu rilasciata nel 1990 dalla "MIDI Manufacturers Association" (MMA) per consentire lo scambio di file e di informazioni fra i sequencer Midi.

Il file MIDI è composto da complesse strutture, tecnicamente chiamate: Chunk (Blocco), formate da un certo numero di byte, ossia di istruzioni conformi al protocollo Midi. Il primo blocco, posto sempre all'inizio del file, è quello relativo all'intestazione del file, ed è chiamato perciò: Header Chunk. E' facilmente riconoscibile perché ha il suo identificativo (MThd) posto proprio all'inizio. Il blocco d'intestazione contiene notizie generali, ma essenziali, per la definizio del file Midi medesimo.
Oltre al blocco d'intestazione il file è costituito da almeno un blocco traccia, chiamato Track Chunk, e riconoscibile dal suo identificativo: MTrk. Questo blocco contiene i dati veri e propri che definiscono la struttura e le modalità di esecuzione di un brano musicale.|1|
Di seguito eviteremo di esporre codice esemplificativo, ritenendo che ciascun programmatore possa e debba scegliere le soluzioni algoritmiche che riterrà più oppurtune e migliori. Ci limiteremo soltanto a mostrare il codice a scopo esplicativo di quelle parti più delicate relative a particolari concetti.


Acquisizione dei dati Midi

Si dovranno ovviamente acquisire i dati dal file .mid, avendo cura in particolare di:

  • lunghezza dell'intero file Midi, ossia la quantità di byte che lo costituiscono;
  • il numero delle tracce Mtrk esistenti, e la lunghezza di ciascuna traccia;
  • individuare la risoluzione PPQN del Tempo Delta del file Midi, con la quale successivamente determinare i valori decimali dei Midi tick;
  • distinguere i Messaggi Midi dai Meta-eventi;
  • individuare i valori del Tempo Delta.


Il Tempo Delta: l'anima degli eventi Midi

I dati contenuti nel Blocco Traccia possono essere eventi oppure meta-eventi Midi.
Gli eventi Midi sono dei messaggi Midi "temporizzati", nel senso che definiscono dei fenomeni Midi nel tempo; e per questo sono sostanzialmente composti da due elementi: il tempo ed il messaggio in sé.
I Meta-eventi, invece, sono dati Midi che non rappresentano "fenomeni" sonori o di dinamica sonora{2}.
Gli elementi essenziali dell'esecuzione di un brano musicale si esplicano ovviamente nel tempo (una nota dopo l'altra); cosicché il file Midi non fa altro che riprodurre in byte questa sequenza temporale di fenomeni sonori. Tali fenomeni sono divisi l'uno dall'altro da uno spazio temporale, che nel caso di contemporaneità di esecusione di note (polifonia) è ovviamente pari a zero, e che rappresenta la differenza tra il tempo trascorso dall'inizio del brano sino al dato in questione. Tale differenza, che separa i due dati, è chiamata Tempo Delta (Delta Time). Il Tempo Delta è il tempo (in clock{3}) che separa un fenomeno sonoro Midi dall'altro, ossia sta ad indicare dopo quanto tempo un dato accadrà rispetto a quello immeditamente precedente.
Come è facilmente comprensibile, il Tempo Delta non è un evento Midi, ma semplicemente un dato Midi, che rende Eventi i dati ai quali si applica. Poiché in particolare il Tempo Delta distanzia temporalmente ai messaggi Midi, e quindi a questi si applica, esso risulta fondamentale per la durata dell'evento, per esempio di una nota o di una pausa. {4}


Determinazione del Tempo Delta

Gli ultimi due byte dell'Header Chunk di un file Midi stabiliscono il metro di definizione dei valori del Tempo Delta presenti all'interno del file medesimo. In particolare essi rappresentano il numero di tick del Tempo Delta per una nota da 1/4. Ci dicono, cioè, quanti tick sono presenti all'interno di una nota da un quarto. Pertanto, possiamo dire che essi rappresentano il valore della risoluzione del Tempo Delta.

Andiamo a ricavare detta risoluzione dal file Midi così:

Public Sub Button2_Click()    ' per ricavare la risoluzione del Tempo Delta del file Midi

 'ricava la risoluzione del Tempo Delta del file Midi:
   ris = CInt((b[13] * 256) + b[14])

 Print ris   ' a soli fini didattici vediamo il risultato

End


Individuazione della lunghezza della traccia MTrk contenente i dati Midi

Successivamente provvederemo a ricavare la lunghezza della traccia MTrk |5|, ed in particolare della parte contenente i dati relativi ai Messaggi Midi ed ai relativi Tempi Delta.


Estrazione dei dati relativi ai Messaggi Midi e dei dati relativi al Tempo Delta

Si procederà quindi ad estrarre dai dati raccolti dal file Midi: quelli relativi ai Messaggi Midi e quelli appartenti al Tempo Delta che separano ciascun evento Midi. Come sappiamo, gli eventi Midi, compresi i valori relativi al Tempo Delta, sono contenuti nel cuore di ciascun blocco Traccia "MTrk". Pertanto è da lì che dovremo estrarli. Procederemo quindi a distinguere tra loro i vari eventi e tra i dati appartenenti al Tempo Delta, tenendo conto che dopo un Tempo Delta v'è sempre un evento Midi (Messaggio Midi oppure Meta-evento), e dopo un evento Midi v'è sempre un Tempo Delta che li separa.


Il Tempo Delta come dato a lunghezza variabile

Il Tempo Delta è un valore codificato a lunghezza variabile. Bisogna innanzitutto precisare che di ciascun byte, appartenente al Tempo Telta, soltanto gli ultimi sette bit sono utili alla definizione del valore del Tempo Delta medesimo. Il primo bit è semplicemente un "flag", un segno di riconoscimento, che dice se dopo (ossia alla destra) quel byte c'è o meno un altro byte. Se tale bit-flag è = 0, vuol dire che il byte è solo, è unico; se invece il bit è = 1, vorrà dire che dopo il byte, al quale quel bit 1 appartiene, c'è un altro byte che concorre a comporre il valore del Tempo Delta.

Esempio:

  • 01111111 = 7F : non c'è nessun altro byte alla sua destra.

Il numero successivo che ci si aspetterebbe è: 10000000, cioè l'esadecimale 80. Tale numero, però in binario è così determinato: 10000000. Poiché il primo bit è sempre un flag particolare, essendo in questo caso pari ad 1, vuol dire che dopo il byte al quale appartiene c'è un altro byte !

Dal che si può facilmente notare che siamo costretti dopo il numero 7F ad aggiungere un altro byte per rappresentare il valore superiore del Tempo Delta. Si procede aggiungendo a destra uno zero, causando così uno spostamento a sinistra dei precedenti bit esistenti:

1 <--- 0000000 <--- 0

Da ciò avremo in prima battuta: 00000001 00000000; ma, da come sappiamo, questa rappresentazione non è corretta, poiché il primo byte a sinistra per indicare che esiste un ulteriore byte (componente la rappresentazione del valore del Tempo Delta) ha bisogno che il suo MSB sia uguale a 1.

Così si dovrà aggiungere nella rappresentazione del valore temporale un bit pari a 1: 1 --> 0000001 00000000; e pertanto avremo che, per esempio, dopo 7F ci sarà uno slittamento del conteggio a 81 00.

Concludiamo precisando che un dato di lunghezza variabile non può essere maggiore di quattro byte, il cui valore massimo è rappresentato da: 0xFF, 0xFF, 0xFF, 0x7F.


Trasformazione della rappresentazione esadecimale in tick reali

E' dunque chiaro che i valori del Tempo delta, contenuti in un file Midi, non sono i valori reali, bensì - come abbiamo visto nel paragrafo precedente - la loro rappresentazione. E', altresì, ovvio che ad ALSA dovremo passare i valori reali in tick; e pertanto dovremo trasformare i valori del tempo Delta, raccolti dal file Midi, in valori reali decimali espressi in appunto in tick tenuto conto della risoluzione del Tempo Delta presente nell'Header Chunk. Otterremo questo risultato mediante il seguente algoritmo:

Public Sub tickReali()

Dim h, rob As Integer
Dim ciclo As Byte 

h = x + y

 ciclo = b[h]
 
 While ciclo > 127
   ciclo = ciclo And 127
    rob = (rob + ciclo) * 128
    Dec h
   ciclo = b[h]
 Wend

' Restituisce il valore decimale reale della durata in tick del Tempo Delta.
' A soli fini didattici vediamo il risultato:
   preTick = rob + ciclo

' Poiché il valore del Tempo Delta non è assoluto, bensì relativo al valore della "risoluzione"
' indicata alla fine del blocco "MThd" del file Midi, sarà necessario adeguare il valore dei tick, ottenuto dalla conversione
' del valore esadecimale "a lunghezza variabile", alla risoluzione dei valori del tempo Delta presente nel file Midi.
' Questo è il valore in "tick" che sarà inviato ad Alsa:
   tick_nota = preTick / (ris / 96)
 
End



Note

[1] Per un'analisi interna dettagliata del file Midi (.mid) rinviamo alla seguente lettura: Struttura del file MIDI.

[2] Anche i Meta-eventi sono sostanzialmente posti nel tempo. Si prenda come esempio un cambio di tonalità o di tempo metronomico che avviene dopo un certo numero di misure dall'inizio del brano musicale.

[3] Una istruzione temporale è determinata dalla risoluzione del Tempo Delta in PPNQ impostata negli ultimi due byte dell'Header Chunk.

[4] Infatti, la durata di una nota nel protocollo Midi è così definita: NoteON -> TempoDelta -> NoteOFF. La nota comincia a suonare, e si spegnerà dopo il lasso di tempo definito dal dato Tempo Delta.

[5] Ricordiamo che per mero esempio abbiamo previsto la presenza di una sola traccia all'interno del file Midi.