Differenze tra le versioni di "Individuare i nomi e le rispettive posizioni degli strumenti musicali in un file sf2 con le sole risorse di Gambas"

Da Gambas-it.org - Wikipedia.
 
(Una versione intermedia di uno stesso utente non è mostrata)
Riga 25: Riga 25:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
      
 
      
 
   Dim fl As File
 
   Dim fl As File
Riga 34: Riga 34:
 
   Dim sfPH As SfPresetHeader
 
   Dim sfPH As SfPresetHeader
 
          
 
          
  sf2 = "<FONT Color=gray>''/percorso/del/file.sf2''</font>"
+
  sf2 = "<FONT Color=darkgreen>''/percorso/del/file.sf2''</font>"
 
      
 
      
  fl = Open sf2 For Read
+
  fl = Open sf2 For Read
  If IsNull(fl) Then Error.Raise("Impossibile caricare il file '" & sf2 & " ' !")
 
 
      
 
      
  With bb = New Byte[Lof(fl)]
+
  With bb = New Byte[Lof(fl)]
    .Read(fl, 0, Lof(fl))
+
    .Read(fl, 0, Lof(fl))
    s = .ToString(0, bb.Count)
+
    s = .ToString(0, bb.Count)
    If IsNull(s) then Error.Raise("Il file caricato non contiene dati !")
+
    If IsNull(s) then Error.Raise("Il file caricato non contiene dati !")
  End With
+
  End With
  bb.Clear
+
  bb.Clear
 
        
 
        
 
  <FONT Color=gray>' ''Individua la posizione del Blocco 'pdtaphdr':''</font>
 
  <FONT Color=gray>' ''Individua la posizione del Blocco 'pdtaphdr':''</font>
  i = InStr(s, "pdtaphdr")
+
  i = InStr(s, "pdtaphdr")
  If i = 0 Then Error.Raise("Impossibile trovare il TAG 'pdtaphdr' !")
+
  If i = 0 Then Error.Raise("Impossibile trovare il TAG 'pdtaphdr' !")
 
      
 
      
 
  <FONT Color=gray>' ''Individua la quantità di byte che compongono l'intero blocco 'pdtaphdr':''</font>
 
  <FONT Color=gray>' ''Individua la quantità di byte che compongono l'intero blocco 'pdtaphdr':''</font>
  Seek #fl, i + 7
+
  Seek #fl, i + 7
  j = Read #fl As Integer
+
  j = Read #fl As Integer
 
    
 
    
 
  <FONT Color=gray>' ''Raccoglie ad ogni ciclo 38 byte contenenti i vari elementi dello strumento musicale rappresentati dai membri della "Struttura".''
 
  <FONT Color=gray>' ''Raccoglie ad ogni ciclo 38 byte contenenti i vari elementi dello strumento musicale rappresentati dai membri della "Struttura".''
 
  ' ''In particolare serviranno in seguito i primi tre membri: nome dello strumento musicale, preset (sua posizione all'interno del Banco) e numero del Banco di appartenenza.''</font>
 
  ' ''In particolare serviranno in seguito i primi tre membri: nome dello strumento musicale, preset (sua posizione all'interno del Banco) e numero del Banco di appartenenza.''</font>
  pphh1 = New SfPresetHeader[]
+
  pphh1 = New SfPresetHeader[]
 
   
 
   
  While Seek(fl) < j + i
+
  While Seek(fl) < j + i
      
+
     sfPH = New SfPresetHeader
    sfPH = New SfPresetHeader
+
     With sfPH
      
+
      .achPresetName.Read(fl, 0, 20)
    With sfPH
+
      .wPreset = Read #fl As Short
      .achPresetName.Read(fl, 0, 20)
+
      .wBank = Read #fl As Short
      .wPreset = Read #fl As Short
+
      .wPresetBagNdx = Read #fl As Short
      .wBank = Read #fl As Short
+
      .dwLibrary = Read #fl As Integer
      .wPresetBagNdx = Read #fl As Short
+
      .dwGenre = Read #fl As Integer
      .dwLibrary = Read #fl As Integer
+
      .dwMorphology = Read #fl As Integer
      .dwGenre = Read #fl As Integer
+
    End With
      .dwMorphology = Read #fl As Integer
+
    pphh1.Add(sfph)
    End With
+
  Wend
   
 
    pphh1.Add(sfph)
 
   
 
  Wend
 
 
    
 
    
  fl.Close
+
  fl.Close
 
   
 
   
 
  <FONT Color=gray>' ''Elimina l'ultima variabile di tipo "Struttura", poiché contenente i dati terminale del blocco 'pdtaphdr' che sono non significativi:''</font>
 
  <FONT Color=gray>' ''Elimina l'ultima variabile di tipo "Struttura", poiché contenente i dati terminale del blocco 'pdtaphdr' che sono non significativi:''</font>
  pphh1.Remove(pphh1.Max)
+
  pphh1.Remove(pphh1.Max)
 
 
   
 
   
  <FONT Color=gray>' ''Vengono scritti in console i suoni degli strumenti musicali, secondo la loro posizione all'interno del blocco 'pdtaphdr',''
+
  <FONT Color=gray>' ''Vengono scritti in console i suoni degli strumenti musicali, secondo la loro posizione all'interno del blocco 'pdtaphdr', e in particolare: il Banco dei suoni, il preset ed il nome dello strumento musicale:''</font>
' ''ed in particolare: il Banco dei suoni, il preset ed il nome dello strumento musicale:''</font>
+
  Print "Strumenti compresi nel file banco: "; File.Name(sf2)
  Print "Strumenti compresi nel file banco: "; File.Name(sf2)
+
  Print "\nBanco  Preset    Nome strumento\n"
  Print "\nBanco  Preset    Nome strumento\n"
 
 
    
 
    
  For j = 0 To pphh1.Max
+
  For j = 0 To pphh1.Max
    With pphh1[j]
+
    With pphh1[j]
      Print .wBank; "        ";
+
      Print .wBank; "        ";
      Print .wPreset; "        ";
+
      Print .wPreset; "        ";
      Print .achPresetName.ToString()
+
      Print .achPresetName.ToString()
    End With
+
    End With
  Next
+
  Next
 
   
 
   
 
  <FONT Color=gray>' ''Fornisce alcune informazioni generali sul blocco 'pdtaphdr' del file .sf2:''</font>
 
  <FONT Color=gray>' ''Fornisce alcune informazioni generali sul blocco 'pdtaphdr' del file .sf2:''</font>
  Print "\n\nFile soundbank: "; sf2
+
  Print "\n\nFile soundbank: "; sf2
  Print "Dimensione totale suoni campionati: "; i; " byte"
+
  Print "Dimensione totale suoni campionati: "; i; " byte"
  Print "Durata totale dei suoni campionati: "; Time(0, 0, 0, (i \ 176400) * 1000)
+
  Print "Durata totale dei suoni campionati: "; Time(0, 0, 0, (i \ 176400) * 1000)
 
    
 
    
  '''End'''
+
  End
  
  
Riga 116: Riga 109:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
      
 
      
 
   Dim fl As File
 
   Dim fl As File
Riga 125: Riga 118:
 
   Dim sfPH As SfPresetHeader
 
   Dim sfPH As SfPresetHeader
 
        
 
        
  sf2 = "<FONT Color=gray>''/percorso/del/file.sf2''</font>"
+
  sf2 = "<FONT Color=darkgreen>''/percorso/del/file.sf2''</font>"
 
    
 
    
  fl = Open sf2 For Read
+
  fl = Open sf2 For Read
  If IsNull(fl) Then Error.Raise("Impossibile caricare il file '" & sf2 & " ' !")
 
 
    
 
    
  With bb = New Byte[Lof(fl)]
+
  With bb = New Byte[Lof(fl)]
    .Read(fl, 0, Lof(fl))
+
    .Read(fl, 0, Lof(fl))
    s = .ToString(0, bb.Count)
+
    s = .ToString(0, bb.Count)
    If IsNull(s) Then Error.Raise("Il file caricato non contiene dati !")
+
    If IsNull(s) Then Error.Raise("Il file caricato non contiene dati !")
  End With
+
  End With
 
    
 
    
 
  <FONT Color=gray>' ''Individua la posizione del Blocco 'pdtaphdr':''</font>
 
  <FONT Color=gray>' ''Individua la posizione del Blocco 'pdtaphdr':''</font>
  i = InStr(s, "pdtaphdr")
+
  i = InStr(s, "pdtaphdr")
  If i = 0 Then Error.Raise("Impossibile trovare il TAG 'pdtaphdr' !")
+
  If i == 0 Then Error.Raise("Impossibile trovare il TAG 'pdtaphdr' !")
 
    
 
    
 
  <FONT Color=gray>' ''Individua la quantità di byte che compongono l'intero blocco 'pdtaphdr':''</font>
 
  <FONT Color=gray>' ''Individua la quantità di byte che compongono l'intero blocco 'pdtaphdr':''</font>
  Seek #fl, i + 7
+
  Seek #fl, i + 7
  j = Read #fl As Integer
+
  j = Read #fl As Integer
 
   
 
   
 
  <FONT Color=gray>' ''Raccoglie ad ogni ciclo 38 byte contenenti i vari elementi dello strumento musicale rappresentati dai membri della "Struttura".''
 
  <FONT Color=gray>' ''Raccoglie ad ogni ciclo 38 byte contenenti i vari elementi dello strumento musicale rappresentati dai membri della "Struttura".''
 
  ' ''In particolare serviranno in seguito i primi tre membri: nome dello strumento musicale, preset (sua posizione all'interno del Banco) e numero del Banco di appartenenza.''</font>
 
  ' ''In particolare serviranno in seguito i primi tre membri: nome dello strumento musicale, preset (sua posizione all'interno del Banco) e numero del Banco di appartenenza.''</font>
  pphh1 = New SfPresetHeader[]
+
  pphh1 = New SfPresetHeader[]
 
   
 
   
  While Seek(fl) < j + i
+
  While Seek(fl) < j + i
 
+
    sfPH = New SfPresetHeader
    sfPH = New SfPresetHeader
+
    With sfPH
 
+
      .achPresetName.Read(fl, 0, 20)
    With sfPH
+
      .wPreset = Read #fl As Short
      .achPresetName.Read(fl, 0, 20)
+
      .wBank = Read #fl As Short
      .wPreset = Read #fl As Short
+
      .wPresetBagNdx = Read #fl As Short
      .wBank = Read #fl As Short
+
      .dwLibrary = Read #fl As Integer
      .wPresetBagNdx = Read #fl As Short
+
      .dwGenre = Read #fl As Integer
      .dwLibrary = Read #fl As Integer
+
      .dwMorphology = Read #fl As Integer
      .dwGenre = Read #fl As Integer
+
    End With
      .dwMorphology = Read #fl As Integer
+
    pphh1.Add(sfph)
    End With
+
  Wend
   
 
    pphh1.Add(sfph)
 
   
 
  Wend
 
 
    
 
    
  fl.Close
+
  fl.Close
 
   
 
   
 
  <FONT Color=gray>' ''Elimina l'ultima variabile di tipo "Struttura", poiché contenente i dati terminale del blocco 'pdtaphdr' che sono non significativi:''</font>
 
  <FONT Color=gray>' ''Elimina l'ultima variabile di tipo "Struttura", poiché contenente i dati terminale del blocco 'pdtaphdr' che sono non significativi:''</font>
  pphh1.Remove(pphh1.Max)
+
  pphh1.Remove(pphh1.Max)
 
   
 
   
 
  <FONT Color=gray>' ''Individua i banchi di suoni presenti nel file sf2:''</font>
 
  <FONT Color=gray>' ''Individua i banchi di suoni presenti nel file sf2:''</font>
  bc = New Byte[]
+
  bc = New Byte[]
 
    
 
    
  For j = 0 To pphh1.Max
+
  For j = 0 To pphh1.Max
    If bc.Find(pphh1[j].wBank) = -1 Then bc.Push(pphh1[j].wBank)
+
    If bc.Find(pphh1[j].wBank) = -1 Then bc.Push(pphh1[j].wBank)
  Next
+
  Next
 
    
 
    
 
  <FONT Color=gray>' ''Ordina in modo ascendente i numeri dei banchi dei suoni:''</font>
 
  <FONT Color=gray>' ''Ordina in modo ascendente i numeri dei banchi dei suoni:''</font>
  bc.Sort(gb.Ascent)
+
  bc.Sort(gb.Ascent)
 
   
 
   
  pphh3 = New SfPresetHeader[]
+
  pphh3 = New SfPresetHeader[]
 
   
 
   
  For i = 0 To bc.Max
+
  For i = 0 To bc.Max
    pphh2 = New SfPresetHeader[128]
+
    pphh2 = New SfPresetHeader[128]
   
 
 
  <FONT Color=gray>' ''Per ordinare in modo ascendente gli strumenti, si selezionano solo quelli appartenenti ad uno dei Banchi presenti nell vettore "bc".''
 
  <FONT Color=gray>' ''Per ordinare in modo ascendente gli strumenti, si selezionano solo quelli appartenenti ad uno dei Banchi presenti nell vettore "bc".''
  ' ''Quindi, per ordinarli in modo ascendente secondo il proprio "preset", si assegna ciascuna variabile di tipo "Struttura", contenuta nel vettore "pphh1",
+
  ' ''Quindi, per ordinarli in modo ascendente secondo il proprio "preset", si assegna ciascuna variabile di tipo "Struttura", contenuta nel vettore "pphh1", all'elemento del vettore "pphh2" avente indice corrispondente al valore del membro "wPreset" della variabile vettoriale che si sta assegnando:''</font>
' '' all'elemento del vettore "pphh2" avente indice corrispondente al valore del membro "wPreset" della variabile vettoriale che si sta assegnando:''</font>
+
    For j = 0 To pphh1.Max
    For j = 0 To pphh1.Max
+
      If pphh1[j].wBank = bc[i] Then pphh2[pphh1[j].wPreset] = pphh1[j]
      If pphh1[j].wBank = bc[i] Then pphh2[pphh1[j].wPreset] = pphh1[j]
+
    Next
    Next
 
 
 
  <FONT Color=gray>' ''Il vettore "pphh2", così riempito in modo ordinato ascendente, viene inserito nella variabile vettoriale "pph3" in coda all'ultimo elemento già presente:''</font>
 
  <FONT Color=gray>' ''Il vettore "pphh2", così riempito in modo ordinato ascendente, viene inserito nella variabile vettoriale "pph3" in coda all'ultimo elemento già presente:''</font>
    pphh3.Insert(pphh2)
+
    pphh3.Insert(pphh2)
    pphh2.Clear
+
    pphh2.Clear
   
+
  Next
  Next
 
 
   
 
   
 
  <FONT Color=gray>' ''Vengono eliminati gli eventuali elementi nulli della variabile vettoriale "pphh3":''</font>
 
  <FONT Color=gray>' ''Vengono eliminati gli eventuali elementi nulli della variabile vettoriale "pphh3":''</font>
  i = pphh3.Count
+
  i = pphh3.Count
  j = 0
+
  j = 0
 
   
 
   
  While j < i
+
  While j < i
    If IsNull(pphh3[j]) Then
+
    If IsNull(pphh3[j]) Then
      pphh3.Remove(j)
+
      pphh3.Remove(j)
      Dec i
+
      Dec i
      Dec j
+
      Dec j
    Endif
+
    Endif
    Inc j
+
    Inc j
  Wend
+
  Wend
 
   
 
   
  Print "Strumenti compresi nel file banco: "; File.Name(sf2)
+
  Print "Strumenti compresi nel file banco: "; File.Name(sf2)
  Print "\nPreset  Banco    Nome strumento\n"
+
  Print "\nPreset  Banco    Nome strumento\n"
 
+
 
 
  <FONT Color=gray>' ''Vengono scritti in console il preset ed i nomi degli strumenti musicali, nonché il Banco degli strumenti di appartenenza:''</font>
 
  <FONT Color=gray>' ''Vengono scritti in console il preset ed i nomi degli strumenti musicali, nonché il Banco degli strumenti di appartenenza:''</font>
  For j = 0 To pphh3.Max
+
  For j = 0 To pphh3.Max
    If j > 0 Then
+
    If j > 0 Then
      If (pphh3[j].wBank <> pphh3[j - 1].wBank) Then Print "--------------------------------------------"
+
      If (pphh3[j].wBank <> pphh3[j - 1].wBank) Then Print "--------------------------------------------"
    Endif
+
    Endif
     
+
    With pphh3[j]
    With pphh3[j]
+
      Print .wBank; "        ";
      Print .wBank; "        ";
+
      Print .wPreset; "        ";
      Print .wPreset; "        ";
+
      Print .achPresetName.ToString()
      Print .achPresetName.ToString()
+
    End With
    End With
+
  Next
  Next
 
 
    
 
    
  '''End'''
+
  End
  
  

Versione attuale delle 16:15, 10 giu 2024

Un file banco di suoni di formato sf2 è semplicemente una libreria di suoni per la riproduzione di dati Midi che si basa su tabelle di suoni campionati (wavetable).

Il file contiene, dunque, dati audio di suoni campionati che possono essere successivamente manipolati dal calcolatore per generare le restanti frequenze sonore appartenenti a quel timbro originario.

Il file .sf2 è costituito, fra l'altro, da diversi blocchi comprendenti specifiche informazioni di carattere generale sul file stesso. In particolare il blocco denominato "pdtaphdr" contiene i nomi degli strumenti musicali e le rispettive posizioni all'interno del banco di suoni come vengono visualizzati dagli appositi programmi di gestione del file soundfont .sf2 .

L'esempio seguente mostra un possibile codice, con il quale estrarre dal blocco del blocco pdtaphdr i nomi e le rispettive posizioni degli strumenti musicali presenti nel file sf2.

Per ottenere questo risultato, bisognerà;

  • individuare il blocco pdtaphdr;
  • estrarre la dimensione del blocco pdtaphdr, che è rappresentata in Little-Endian dai 4 byte immediatamente successivi all'identificativo pdtaphdr (la dimensione è la quantità di byte dal primo byte successivo ai predetti 4 byte della dimensione del blocco fino all'identificativo del blocco pdag);
  • estrarre mediante apposita Struttura i valori del blocco pdtaphdr, ed in partciolare: il nome di ciascuno strumento musicale, il Banco dei suoni di appartenenza e la rispettiva posizione all'interno del banco di suoni del file sf2, tenendo presente che immediatamente dopo i 4 byte della dimensione del blocco pdtaphdr, vi sono uno o più gruppi di 38 byte, contenenti i predetti elementi da estrarre.


Il seguente codice mostrerà secondo la sequenza degli strumenti musicali all'interno del blocco pdtaphdr del file sf2: il numero di banco dei suoni, il preset ed il nome di ciascuno strumento.

Public Struct sfPresetHeader
  achPresetName[20] As Byte
  wPreset As Short
  wBank As Short
  wPresetBagNdx As Short
  dwLibrary As Integer
  dwGenre As Integer
  dwMorphology As Integer
End Struct


Public Sub Main()
    
 Dim fl As File
 Dim sf2, s As String
 Dim bb As Byte[]
 Dim i, j As Integer
 Dim pphh1 As SfPresetHeader[]
 Dim sfPH As SfPresetHeader
       
 sf2 = "/percorso/del/file.sf2"
   
 fl = Open sf2 For Read
   
 With bb = New Byte[Lof(fl)]
   .Read(fl, 0, Lof(fl))
   s = .ToString(0, bb.Count)
   If IsNull(s) then Error.Raise("Il file caricato non contiene dati !")
 End With
 bb.Clear
     
' Individua la posizione del Blocco 'pdtaphdr':
 i = InStr(s, "pdtaphdr")
 If i = 0 Then Error.Raise("Impossibile trovare il TAG 'pdtaphdr' !")
   
' Individua la quantità di byte che compongono l'intero blocco 'pdtaphdr':
 Seek #fl, i + 7
 j = Read #fl As Integer
 
' Raccoglie ad ogni ciclo 38 byte contenenti i vari elementi dello strumento musicale rappresentati dai membri della "Struttura".
' In particolare serviranno in seguito i primi tre membri: nome dello strumento musicale, preset (sua posizione all'interno del Banco) e numero del Banco di appartenenza.
 pphh1 = New SfPresetHeader[]

 While Seek(fl) < j + i
   sfPH = New SfPresetHeader
   With sfPH
     .achPresetName.Read(fl, 0, 20)
     .wPreset = Read #fl As Short
     .wBank = Read #fl As Short
     .wPresetBagNdx = Read #fl As Short
     .dwLibrary = Read #fl As Integer
     .dwGenre = Read #fl As Integer
     .dwMorphology = Read #fl As Integer
   End With
   pphh1.Add(sfph)
 Wend
  
 fl.Close

' Elimina l'ultima variabile di tipo "Struttura", poiché contenente i dati terminale del blocco 'pdtaphdr' che sono non significativi:
 pphh1.Remove(pphh1.Max)

' Vengono scritti in console i suoni degli strumenti musicali, secondo la loro posizione all'interno del blocco 'pdtaphdr', e in particolare: il Banco dei suoni, il preset ed il nome dello strumento musicale:
 Print "Strumenti compresi nel file banco: "; File.Name(sf2)
 Print "\nBanco   Preset     Nome strumento\n"
  
 For j = 0 To pphh1.Max
   With pphh1[j]
     Print .wBank; "        ";
     Print .wPreset; "         ";
     Print .achPresetName.ToString()
   End With
 Next

' Fornisce alcune informazioni generali sul blocco 'pdtaphdr' del file .sf2:
 Print "\n\nFile soundbank: "; sf2
 Print "Dimensione totale suoni campionati: "; i; " byte"
 Print "Durata totale dei suoni campionati: "; Time(0, 0, 0, (i \ 176400) * 1000)
  
End


Il seguente codice mostrerà gli strumenti musicali secondo il rispettivo ordine ascendente del numero di banco di appartenenza e del loro preset:

Public Struct sfPresetHeader
  achPresetName[20] As Byte
  wPreset As Short
  wBank As Short
  wPresetBagNdx As Short
  dwLibrary As Integer
  dwGenre As Integer
  dwMorphology As Integer
End Struct


Public Sub Main()
   
 Dim fl As File
 Dim sf2, s As String
 Dim bb, bc As Byte[]
 Dim i, j As Integer
 Dim pphh1, pphh2, pphh3 As SfPresetHeader[]
 Dim sfPH As SfPresetHeader
      
 sf2 = "/percorso/del/file.sf2"
  
 fl = Open sf2 For Read
  
 With bb = New Byte[Lof(fl)]
   .Read(fl, 0, Lof(fl))
   s = .ToString(0, bb.Count)
   If IsNull(s) Then Error.Raise("Il file caricato non contiene dati !")
 End With
  
' Individua la posizione del Blocco 'pdtaphdr':
 i = InStr(s, "pdtaphdr")
 If i == 0 Then Error.Raise("Impossibile trovare il TAG 'pdtaphdr' !")
  
' Individua la quantità di byte che compongono l'intero blocco 'pdtaphdr':
 Seek #fl, i + 7
 j = Read #fl As Integer

' Raccoglie ad ogni ciclo 38 byte contenenti i vari elementi dello strumento musicale rappresentati dai membri della "Struttura".
' In particolare serviranno in seguito i primi tre membri: nome dello strumento musicale, preset (sua posizione all'interno del Banco) e numero del Banco di appartenenza.
 pphh1 = New SfPresetHeader[]

 While Seek(fl) < j + i
   sfPH = New SfPresetHeader
   With sfPH
     .achPresetName.Read(fl, 0, 20)
     .wPreset = Read #fl As Short
     .wBank = Read #fl As Short
     .wPresetBagNdx = Read #fl As Short
     .dwLibrary = Read #fl As Integer
     .dwGenre = Read #fl As Integer
     .dwMorphology = Read #fl As Integer
   End With
   pphh1.Add(sfph)
 Wend
 
 fl.Close

' Elimina l'ultima variabile di tipo "Struttura", poiché contenente i dati terminale del blocco 'pdtaphdr' che sono non significativi:
 pphh1.Remove(pphh1.Max)

' Individua i banchi di suoni presenti nel file sf2:
 bc = New Byte[]
  
 For j = 0 To pphh1.Max
   If bc.Find(pphh1[j].wBank) = -1 Then bc.Push(pphh1[j].wBank)
 Next
  
' Ordina in modo ascendente i numeri dei banchi dei suoni:
 bc.Sort(gb.Ascent)

 pphh3 = New SfPresetHeader[]

 For i = 0 To bc.Max
   pphh2 = New SfPresetHeader[128]
' Per ordinare in modo ascendente gli strumenti, si selezionano solo quelli appartenenti ad uno dei Banchi presenti nell vettore "bc".
' Quindi, per ordinarli in modo ascendente secondo il proprio "preset", si assegna ciascuna variabile di tipo "Struttura", contenuta nel vettore "pphh1", all'elemento del vettore "pphh2" avente indice corrispondente al valore del membro "wPreset" della variabile vettoriale che si sta assegnando:
   For j = 0 To pphh1.Max
     If pphh1[j].wBank = bc[i] Then pphh2[pphh1[j].wPreset] = pphh1[j]
   Next
' Il vettore "pphh2", così riempito in modo ordinato ascendente, viene inserito nella variabile vettoriale "pph3" in coda all'ultimo elemento già presente:
   pphh3.Insert(pphh2)
   pphh2.Clear
 Next

' Vengono eliminati gli eventuali elementi nulli della variabile vettoriale "pphh3":
 i = pphh3.Count
 j = 0

 While j < i
   If IsNull(pphh3[j]) Then
     pphh3.Remove(j)
     Dec i
     Dec j
   Endif
   Inc j
 Wend

 Print "Strumenti compresi nel file banco: "; File.Name(sf2)
 Print "\nPreset   Banco     Nome strumento\n"
 
' Vengono scritti in console il preset ed i nomi degli strumenti musicali, nonché il Banco degli strumenti di appartenenza:
 For j = 0 To pphh3.Max
   If j > 0 Then
     If (pphh3[j].wBank <> pphh3[j - 1].wBank) Then Print "--------------------------------------------"
   Endif
   With pphh3[j]
     Print .wBank; "        ";
     Print .wPreset; "         ";
     Print .achPresetName.ToString()
   End With
 Next
  
End


Riferimenti