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.
(Creata pagina con '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''). ...')
 
Riga 12: Riga 12:
 
* estrarre il nome di ciascuno strumento musicale 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 all'inizio di ciascun gruppo il nome dello strumento musicale, nonché al 21° byte del gruppo la posizione dello strumento nel banco del file.
 
* estrarre il nome di ciascuno strumento musicale 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 all'inizio di ciascun gruppo il nome dello strumento musicale, nonché al 21° byte del gruppo la posizione dello strumento nel banco del file.
  
 
+
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()
 
  '''Public''' Sub Main()
 
      
 
      
Riga 18: Riga 28:
 
   Dim sf2, s As String
 
   Dim sf2, s As String
 
   Dim bb As Byte[]
 
   Dim bb As Byte[]
   Dim i, j As Integer
+
   Dim i, j, n As Integer
   Dim ss, ss2 As New String[]
+
   Dim pphh1, pphh2 As SfPresetHeader[]
   Dim p As Pointer
+
   Dim sfPH As SfPresetHeader
     
+
       
 
   sf2 = "''/percorso/del/file.sf2''"
 
   sf2 = "''/percorso/del/file.sf2''"
 
      
 
      
Riga 34: Riga 44:
 
   bb.Clear
 
   bb.Clear
 
        
 
        
  <FONT Color=gray>' ''Individua la posizione del TAG '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 del TAG '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".''
 +
' ''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[]
 
   
 
   
   j += i
+
   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
 
   
 
   
  <FONT Color=gray>' ''Raccoglie ad ogni ciclo 38 byte contenenti il nome dello strumento musicale (a cominciare dal primo di quei 38 byte),''
+
  <FONT Color=gray>' ''Elimina l'ultima variabile di tipo "Struttura", poiché contenente i dati terminale del blocco 'pdtaphdr' che sono non significativi:''</font>
' ''nonché la sua reale posizione nel banco degli strumenti (il numero della posizione è rintracciabile al 21° byte):''</font>
+
   pphh1.Remove(pphh1.Max)
   While i < j
 
    With bb = New Byte[38]
 
      .Read(fl, 0, bb.Count)
 
      ss.Add(.ToString(0, bb.Count))
 
    End With
 
    i += 38
 
  Wend
 
 
   
 
   
   fl.Close
+
<FONT Color=gray>' ''Si procede a ordinare i nomi degli strumenti tenendo conto del valore rappresentato dal membro ".wPreset" della Struttura:''</font>
   
+
   n = pphh1.Count
   ss.Remove(ss.Max)
+
   If n < 128 Then n = 128
 
   
 
   
<FONT Color=gray>' ''Si procede a ordinare i nomi degli strumenti tenendo conto del valore rappresentato dal 21° byte del gruppo dei 38:''</font>
+
   pphh2 = New SfPresetHeader[n]
   ss2 = New String[ss.Count]
+
   For j = 0 To pphh1.Max
   For j = 0 To ss2.Max
+
    If pphh1[j].wBank > 0 Then pphh2.Add(pphh1[j])
      ss2[Asc(ss[j], 21)] = ss[j]
+
    pphh2[pphh1[j].wPreset] = pphh1[j]
 
   Next
 
   Next
 +
 +
  i = pphh2.Max
 +
 +
  j = 0
 +
  While j < i
 +
    If IsNull(pphh2[j]) Then
 +
      pphh2.Remove(j)
 +
      Dec j
 +
      Dec i
 +
    Endif
 +
    Inc j
 +
  Wend
 
   
 
   
 
   Print "Strumenti compresi nel file banco: "; File.Name(sf2)
 
   Print "Strumenti compresi nel file banco: "; File.Name(sf2)
   Print
+
   Print "\nPreset  Banco    Nome strumento\n"
 
      
 
      
  <FONT Color=gray>' ''Vengono scritti in console i nomi degli strumenti e la loro posizione, utilizzando il Puntatore ai dati del vettore di tipo Stringa[].''
+
  <FONT Color=gray>' ''Vengono scritti in console il preset ed i nomi degli strumenti musicali, nonché il Banco degli strumenti di appartenenza:''</font>
' ''Si usa questa modalità per eliminare i dati non stampabili posti dopo il nome di ciascuno strumento.''</font>
+
   For j = 0 To pphh2.Max
  p = ss2.Data
+
     If (j > 0) Then
       
+
      If (pphh2[j].wBank <> pphh2[j - 1].wBank) Then Print
   For j = 0 To ss2.Max
+
    Endif
     s = String@(Pointer@(p))
+
   
    If IsNull(s) = False Then Print j;; s
+
    With pphh2[j]
     p = p + 8
+
      Print .wPreset; "        ";
 +
      Print .wBank; "        ";
 +
      Print .achPresetName.ToString()
 +
     End With
 
   Next
 
   Next
   
+
 
 
  '''End'''
 
  '''End'''
  

Versione delle 12:15, 23 mag 2015

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 è costituita, fra l'altro, da diversi blocchi comprendenti specifiche informazioni di carattere generale sul file stesso. In particolare il TAG 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 il nome di ciascuno strumento musicale 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 all'inizio di ciascun gruppo il nome dello strumento musicale, nonché al 21° byte del gruppo la posizione dello strumento nel banco del file.
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, n As Integer
 Dim pphh1, pphh2 As SfPresetHeader[]
 Dim sfPH As SfPresetHeader
       
  sf2 = "/percorso/del/file.sf2"
   
  fl = Open sf2 For Read
  If IsNull(fl) Then Error.Raise("Impossibile caricare il file '" & sf2 & " ' !")
   
  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)

' Si procede a ordinare i nomi degli strumenti tenendo conto del valore rappresentato dal membro ".wPreset" della Struttura:
  n = pphh1.Count
  If n < 128 Then n = 128

  pphh2 = New SfPresetHeader[n]
  For j = 0 To pphh1.Max
    If pphh1[j].wBank > 0 Then pphh2.Add(pphh1[j])
    pphh2[pphh1[j].wPreset] = pphh1[j]
  Next

  i = pphh2.Max

  j = 0
  While j < i
    If IsNull(pphh2[j]) Then
      pphh2.Remove(j)
      Dec j
      Dec i
    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 pphh2.Max
    If (j > 0) Then
      If (pphh2[j].wBank <> pphh2[j - 1].wBank) Then Print
    Endif
    
    With pphh2[j]
      Print .wPreset; "        ";
      Print .wBank; "         ";
      Print .achPresetName.ToString()
    End With
  Next
  
End



Riferimenti