Estrarre i dati degli eventi Midi da un file Midi

Da Gambas-it.org - Wikipedia.

Mostreremo di seguito un codice per estrarre tutti i dati degli eventi Midi significativi da un file Midi, e in particolare:

  • Messaggi Midi;
  • byte del tempo;
  • Meta-Eventi;
  • Messaggi SysEx.


Public Sub Main()
 
 Dim fl As File
 Dim fileMidi, s As String
 Dim td, c As Short
 Dim tr, b, n As Byte
 Dim cmd, tipocmd, ultimo As Byte
 
 fileMidi = "/percorso/del/file.mid"
 Print "File Midi:         "; fileMidi
 
 fl = Open fileMidi For Read
 If IsNull(fl) Then Error.Raise("Impossibile aprire il file !")
 
 Read #fl, s, 4
 If s <> "MThd" Then Error.Raise("Il file non è uno standard Midi !")
 Print "Dimensione:    "; Lof(fl); " byte"
 Seek #fl, 9
 Read #fl, b
 Print "Tipo Midi:         "; b
 Seek #fl, 11
 Read #fl, tr
 Print "Numero tracce:   "; Format(tr, "###")
 Read #fl, td
 td = Rol(td, 8)
 Print "Risoluzione TΔ:  "; Format(td, "###")
 Seek #fl, Seek(fl) + 8
 
 Repeat
   Inc n
   Print "\n=== TRACCIA n. "; n; " ==="
   Sleep 1
   Do
     Legge_var(fl)
     Read #fl, b
     If b And 128 Then       ' Status running
       cmd = b
       ultimo = cmd
     Else
       cmd = ultimo
       Seek #fl, Seek(fl) - 1
     Endif
     tipocmd = Shr(cmd, 4)
     Select Case tipocmd
       Case 8 To 11
         Write "Messaggio:    " & Hex(cmd, 2) & " "
         Stampa_Valori(fl, 2)
       Case 12 To 13 
         Write "Messaggio:    " & Hex(cmd, 2) & " "
         Stampa_Valori(fl, 1)
       Case 14
         Write "Messaggio:    " & Hex(cmd, 2) & " "
         Stampa_Valori(fl, 2)
       Case 15
         If b = &F0 Then                              ' Evento SysEx
           Write "Evento SysEx: F0 "
           Repeat
             b = Read #fl As Byte
             Write Hex(b, 2) & " "
           Until b = &F7
           Print
         Else                                         ' Meta-Evento
           Read #fl, b
           Select Case b
             Case &2F                                 ' Termine Traccia
               Seek #fl, Seek(fl) + 9
               Exit
             Case Else                                ' gli altri tipi di eventi "Meta"
               Write "Meta-Evento:  FF "
               c = Read #fl As Byte
               Write Hex(b, 2) & " " & Hex(c, 2) & " "
               Stampa_Valori(fl, c)
           End Select
         Endif
     End Select
     Sleep 0.2
   Loop
   Dec tr
 Until tr = 0
 
 fl.Close
   
 Print "\n\e[31mTermine file Midi\e[0m"
 
End


Private Procedure Stampa_Valori(mf As File, av As Byte)

 Dim b, n As Byte
 
  For b = 1 To av
    Read #mf, n
    Write Hex(n, 2) & " "
  Next
  Print
  
End

Private Procedure Legge_var(mf As File)   ' Legge un numero a lunghezza-variabile (Tempo Delta)
 
 Dim c As Byte
  
  Write "Tempo Delta:  "
  Repeat
    Read #mf, c
    Write Hex(c, 2) & " "
  Until Not (c And 128)
  Print
  
End