Fondere insieme due file WAV: differenze tra le versioni

Da Gambas-it.org - Wikipedia.
Vai alla navigazione Vai alla ricerca
Nessun oggetto della modifica
Nessun oggetto della modifica
 
(11 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Per fondere (mischiare) due file audio di formato WAV con le sole funzioni di Gambas, bisognerà prestare cura ad almeno i seguenti aspetti:
Per fondere (mischiare) due file audio di formato '''WAV''' con le sole funzioni di Gambas, bisognerà prestare cura ad almeno i seguenti aspetti:


* i due file da fondere devono avere uguale frequenza e risoluzione di campionamento ed uguale numero di canali;
* i due file da fondere devono avere uguale frequenza, uguale risoluzione di campionamento ed uguale numero di canali;
* eliminare l'intero primo blocco di intestazione al file avente dimensione inferiore;
* il blocco d'intestazione del nuovo file wav ottenuto deve essere corrispondente a quello del file wav avente la maggiore quantità di dati audio fra i due file da fondere.
* impostare i nuovi corretti valori che indicano le dimensioni del file wav, presenti nei byte n. 4, 5, 6, 7 e nei byte n. 40, 41, 42, 43 dell'header del file wav finale.
Il risultato finale è una somma campione per campione, con eventuale normalizzazione per evitare ''clipping''.


 
Di seguito un possibile semplice codice supponendo che i due file wav siano di formato con risoluzione di campionamento a 16bit con segno:
Di seguito un possibile semplice codice supponendo che i due file wav siano a 2 canali e a 16bit:
  Public Sub Main()
  '''Public''' Sub Main()
   
   
   Dim fileWAV_1, fileWAV_2 As String
   Dim fileWAV_1, fileWAV_2, wav1, wav2 As String
   Dim fl As File
   Dim fl As File
   Dim ss1, ss2, ss3 As Short[]
   Dim ss1, ss2 As '''Short'''[]
   Dim i As Integer
   Dim i As Integer
  Dim he As Byte[]
   
   
   fileWav_1 = "<FONT Color=gray>''/percorso/del/primo/file.wav''</font>"
   fileWav_1 = "<FONT Color=darkgreen>''/percorso/del/'''primo'''/file.wav''</font>"
   
   
   fileWAV_2 = "<FONT Color=gray>''/percorso/del/secondo/file.wav''</font>"
   fileWAV_2 = "<FONT Color=darkgreen>''/percorso/del/'''secondo'''/file.wav''</font>"
   
   
   fl = Open fileWAV_1 For Read
  wav1 = fileWAV_1
  ss1 = New Short[(Stat(fileWAV_1).Size - 44)]
  wav2 = fileWAV_2
  Seek #fl, 44
<FONT color=gray>' ''Individua la dimensione maggiore tra i due file wav:''</font>
  ss1.Read(fl, 0, ss1.Count / 2)
  If Stat(fileWAV_2).Size > Stat(fileWAV_1).Size Then
    wav1 = fileWAV_2
    wav2 = fileWAV_1
  Endif
<FONT color=gray>' ''Assegna a entrambi i vettori di tipo "Short[]" la medesima dimensione di elementi pari a quella maggiore individuata tra i due file wav.''</font>
<FONT color=gray>' ''Apre il 1° file wav e lo carica nel 1° vettore.''
' ''Il vettore "ss1" è sempre quello contenente i dati del file wav di dimensione maggiore fra i due file.''</font>
   fl = Open wav1 For Read
  ss1 = New Short[Lof(fl) / SizeOf(gb.Short)]
  ss1.Read(fl, 0, ss1.Count)
   fl.Close
   fl.Close
 
   fl = Open fileWAV_2 For Read
<FONT color=gray>' ''Apre il 2° file wav e lo carica nel 2° vettore:''</font>
  ss2 = New Short[(Stat(fileWAV_2).Size - 44)]
   fl = Open wav2 For Read
  Seek #fl, 44
  ss2 = New Short[ss1.count]
  ss2.Read(fl, 0, ss2.Count / 2)
  ss2.Read(fl, 0, Lof(fl) / SizeOf(gb.Short))
   fl.Close
   fl.Close
 
  ss3 = New Short[Max(ss1.Count, ss2.Count)]
   For i = 0 To (44 / SizeOf(gb.Short)) To ss1.Max
 
<FONT color=gray>' ''Somma le due onde e carica ciascun dato a cominciare dal byte d'indice 44, individuandolo tenuto conto della risoluzione a 16-bit del file wav:''</font>
   For i = 0 To (Max(ss1.Count, ss2.Count) / 2) - 1
     ss1[i] = CShort((CInt(ss1[i]) + CInt(ss2[i])) / 2)
    <FONT color=gray>' ''Somma le due onde:''</font>
     ss3[i] = CShort((CInt(ss1[i]) + CInt(ss2[i])) / 2)
   Next
   Next
<FONT color=gray>' ''Creiamo il blocco di intestazione del futuro file wav:''</font>
  he = CreaBloccoIntestazione(ss3.Count)
   
   
   fl = Open "/tmp/nuovo.wav" For Create
   fl = Open "/tmp/nuovo.wav" For Create
  <FONT color=gray>' ''Crea il nuovo file wav:''</font>
  <FONT color=gray>' ''Crea il nuovo file wav:''</font>
   he.Write(fl, 0, he.Count)
   ss1.Write(fl, 0, ss1.Count)
   fl.Close
   fl.Close
   
   
  fl = Open "/tmp/nuovo.wav" For Write Append
  End
  <FONT color=gray>' ''Crea il nuovo file wav:''</font>
  ss3.Write(fl, Stat("/tmp/nuovo.wav").Size, ss3.Count / 2)
 
<FONT color=gray>' ''Va in chiusura:''</font>
  fl.Close
  he.Clear
  ss1.Clear
  ss2.Clear
'''End'''
'''Private''' Function CreaBloccoIntestazione(dati_grezzi As Integer) as Byte[]
  Dim ini As String = "RIFF"
  Dim bh As Byte[] = [&57, &41, &56, &45, &66, &6D, &74, &20, &10, &00, &00, &00, &01, &00, &02, &00,
                    &44, &AC, &00, &00, &10, &B1, &02, &00, &04, &00, &10, &00, &64, &61, &74, &61]
  Dim bb As New Byte[]
  Dim i As Integer
  bb = Byte[].FromString(ini)
  i = dati_grezzi + 36
<FONT color=gray>' ''Imposta il valore dimensionale di 4 byte a partire dal 5° byte del futuro file: ''</font>
  bb.Add(i And &FF)
  bb.Add(Shr(i And &FF00&, 8))
  bb.Add(Shr(i And &FF0000&, 16))
  bb.Add(Shr(i And &FF000000&, 24))
  bb = bb.Insert(bh)
<FONT color=gray>' ''Imposta il valore dimensionale di 4 byte a partire dal 41° byte del futuro file e relativo alla dimensione dei dati audio grezzi:''</font>
  bb.Add(dati_grezzi And &FF)
  bb.Add(Shr(dati_grezzi And &FF00&, 8))
  bb.Add(Shr(dati_grezzi And &FF0000&, 16))
  bb.Add(Shr(dati_grezzi And &FF000000&, 24))
  Return bb
'''End'''

Versione attuale delle 06:08, 26 lug 2025

Per fondere (mischiare) due file audio di formato WAV con le sole funzioni di Gambas, bisognerà prestare cura ad almeno i seguenti aspetti:

  • i due file da fondere devono avere uguale frequenza, uguale risoluzione di campionamento ed uguale numero di canali;
  • il blocco d'intestazione del nuovo file wav ottenuto deve essere corrispondente a quello del file wav avente la maggiore quantità di dati audio fra i due file da fondere.

Il risultato finale è una somma campione per campione, con eventuale normalizzazione per evitare clipping.

Di seguito un possibile semplice codice supponendo che i due file wav siano di formato con risoluzione di campionamento a 16bit con segno:

Public Sub Main()

 Dim fileWAV_1, fileWAV_2, wav1, wav2 As String
 Dim fl As File
 Dim ss1, ss2 As Short[]
 Dim i As Integer

 fileWav_1 = "/percorso/del/primo/file.wav"

 fileWAV_2 = "/percorso/del/secondo/file.wav"

 wav1 = fileWAV_1
 wav2 = fileWAV_2
' Individua la dimensione maggiore tra i due file wav:
 If Stat(fileWAV_2).Size > Stat(fileWAV_1).Size Then 
   wav1 = fileWAV_2
   wav2 = fileWAV_1
 Endif

' Assegna a entrambi i vettori di tipo "Short[]" la medesima dimensione di elementi pari a quella maggiore individuata tra i due file wav.

' Apre il 1° file wav e lo carica nel 1° vettore.
' Il vettore "ss1" è sempre quello contenente i dati del file wav di dimensione maggiore fra i due file.
 fl = Open wav1 For Read
 ss1 = New Short[Lof(fl) / SizeOf(gb.Short)]
 ss1.Read(fl, 0, ss1.Count)
 fl.Close

' Apre il 2° file wav e lo carica nel 2° vettore:
 fl = Open wav2 For Read
 ss2 = New Short[ss1.count]
 ss2.Read(fl, 0, Lof(fl) / SizeOf(gb.Short))
 fl.Close

 For i = 0 To (44 / SizeOf(gb.Short)) To ss1.Max
' Somma le due onde e carica ciascun dato a cominciare dal byte d'indice 44, individuandolo tenuto conto della risoluzione a 16-bit del file wav:
   ss1[i] = CShort((CInt(ss1[i]) + CInt(ss2[i])) / 2)
 Next

 fl = Open "/tmp/nuovo.wav" For Create
' Crea il nuovo file wav:
 ss1.Write(fl, 0, ss1.Count)
 fl.Close

End