Conoscere la durata in secondi del Tempo Delta fra due Eventi Midi

Da Gambas-it.org - Wikipedia.

Per conoscere la durata del Tempo Delta (TΔ) in secondi fra due Eventi Midi (ossia il tempo che separa un Evento Midi da quello immediatamente successivo), si dovrà adottare la seguente formula:

(((60000000 / bpm) / Risoluzione_TΔ) * tick_reali) / 1000000  =  secondi

Laddove:

  • bmp: è il tempo metronomico (battute per minuto);
  • Risoluzione_TΔ: è la risoluzione di clock per nota da 1/4 (PPQN), che nel file Midi è espressa in Big-Endian dal 13° e il 14* byte (gli ultimi due byte della traccia MThd;
  • tick_reali: è il reale valore in tick del TΔ, riportato nel file Midi fra un Evento Midi e quello immediatamente successivo. Insomma è il valore che si intende trasformare in secondi.


Per ottenere il numero di tick esatto del Tempo Delta dal valore rappresentato nella traccia del file Midi, bisogna tenere conto che nel file Midi standard:
- il valore del TΔ può variare da 1 a 4 byte (scritti sempre in Big-Endian);
- nel caso il valore sia espresso da 2 o più byte, il Tempo Delta è espresso in formato a lunghezza variabile, il quale rappresenta i numeri usando solo sette bit per byte, mentre il bit più significativo è impostato ad un valore tale da poterlo riconoscere. Se la rappresentazione contiene più byte per esprimere un numero, il bit più significativo dei primi byte sarà posto sempre ad 1, mentre il bit più significativo dell'ultimo byte sarà sempre posto a 0. Tale impostazione sta ad indicare che, quando il bit più significativo è posto ad 1, tale byte non è l'ultimo della rappresentazione esadecimale, ma che dopo di esso v'è un altro byte. Se il bit più significativo è invece posto a 0, allora vuol dire che il byte, al quale quel bit appartiene, è l'ultimo della rappresentazione.
Da ciò se ne deduce che, nel caso di un valore composto da 2 o più byte, bisognerà sottrarre dal valore di ogni byte più a sinistra del byte meno significativo (cioè - essendo l'ordine dei byte in Big-Endian - quello più a destra del gruppo rappresentativo del TΔ), il valore &80 (ossia porre a 0 quel bit più significativo del byte in questione). Al valore così ottenuto per differenza, si addizionerà in fine il semplice valore del byte meno significativo del gruppo.

Insomma, avendo ad esempio questo valore 81 40 del TΔ in rappresentazione a lunghezza variabile nel file, si procederà come segue:

(&h81 - &h80) + &h40 = 
&h0100 + &h40 = 
&hC0

ossia, convertito in rappresentazione decimale: 192 tick reali.

Possiamo usare questo codice:

Public Sub Main()
 
 Dim val_lun_var, vl As Integer
 Dim bpm, td, c As Short
 Dim f As Float
  
' Il TΔ nel file in rappresentazione a "lunghezza variabile" (come presente nel file Midi):
 val_lun_var = &8140&
' Il Tempo metronomico":
 bpm = 60
' La Risoluzione del TΔ (PPQN)":
 td = 384
 c = 3
 
 Repeat
   vl = Shl(vl, 7) Or (Shr(val_lun_var, c * 8) And 127)
   Dec c
 Until c < 0
 
 Print "Valore TΔ reale = "; vl; ", tick reali: "; Hex(vl, 8)

' Calcola la durata in secondi:
 f = (((60000000 / bpm) / td) * vl) / 1000000
 Print "Durata: "; f; " secondi", CStr(Time(0, 0, 0, f * 1000))
 
End


Note

[1] Vedere anche questa pagina: Conversione del Tempo Delta fra due eventi Midi dai secondi nel valore esadecimale in formato "a lunghezza variabile"