Unire 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
 
(4 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Per unire - l'uno dopo l'altro - due file audio di formato WAV con le sole funzioni di Gambas, bisognerà prestare cura ad almeno i seguenti aspetti:
Per unire - l'uno dopo l'altro - due file audio di formato WAV con le sole funzioni di Gambas, bisognerà prestare cura ad almeno i seguenti aspetti:
* i due file da unire devono avere uguale frequenza di campionamento ed uguale numero di canali;
* i due file da unire devono avere uguale frequenza e risoluzione di campionamento e uguale numero di canali;
* eliminare l'intero primo blocco, ossia l'<I>header</i>, al secondo file che sarà unito alla fine del primo file wav;
* eliminare l'intero blocco d'intestazione (''header'' ) del secondo file, ossia del file wav che sarà unito dopo (alla fine) del primo file wav;
* azzerare oppure, più correttamente, impostare i nuovi esatti valori che indicano le dimensioni del nuovo file wav unitario, presenti nei byte n. 4, 5, 6, 7 e nei byte n. 40, 41, 42, 43 dell'<I>header</i> del primo file.
* impostare i nuovi esatti valori che indicano le dimensioni del nuovo file wav unitario, presenti nei byte n. 4, 5, 6, 7 e nei byte n. 40, 41, 42, 43 del blocco d'intestazione del primo file.
 


===1° esempio===
Di seguito un possibile semplice codice:
Di seguito un possibile semplice codice:
  '''Public''' Sub Main()
  Public Sub Main()
   
   
   Dim fileWAV_1, fileWAV_2, s1, s2, fileWAV_finale As String
   Dim fileWAV_1, fileWAV_2, s1, s2, fileWAV_finale As String
Riga 12: Riga 12:
   Dim d1, d2 As Short
   Dim d1, d2 As Short
   Dim q1 As Integer
   Dim q1 As Integer
  fileWAV_1 = "<FONT color=darkgreen>''/percorso/del/'''primo'''/file.wav''</font>"
  fileWAV_2 = "<FONT color=darkgreen>''/percorso/del/'''secondo'''/file.wav''</font>"
  fileWAV_finale = "/tmp/finale.wav"
    
    
  fileWAV_1 = "<FONT color=gray>''/percorso/del/primo/file.wav''</font>"
  s1 = File.Load(fileWAV_1)
  fileWAV_2 = "<FONT color=gray>''/percorso/del/secondo/file.wav''</font>"
  s2 = File.Load(fileWAV_2)
  fileWAV_finale = "/tmp/finale.wav"
   
   
   d1 = InStr(s1, "data")
  s1 = File.Load(fileWAV_1)
  d2 = InStr(s2, "data")
  s2 = File.Load(fileWAV_2)
   
    
  d1 = InStr(s1, "data")
  d2 = InStr(s2, "data")
 
 
  <FONT color=gray>' ''Individua e somma le dimensioni dei dati grezzi audio di ciascun file wav:''</font>
  <FONT color=gray>' ''Individua e somma le dimensioni dei dati grezzi audio di ciascun file wav:''</font>
  q1 = (Stat(fileWAV_1).Size - (d1 + 7)) + (Stat(fileWAV_2).Size - (d2 + 7))
  q1 = (Stat(fileWAV_1).Size - (d1 + 7)) + (Stat(fileWAV_2).Size - (d2 + 7))
   
   
  <FONT color=gray>' ''Salva il nuovo file WAV unendo al primo file wav il secondo file wav privato del suo header:''</font>
  <FONT color=gray>' ''Salva il nuovo file WAV unendo al primo file wav il secondo file wav privato del suo header:''</font>
  File.Save(fileWAV_finale, s1 & Right(s2, Len(s2) - (d2 + 7)))
  File.Save(fileWAV_finale, s1 & Right(s2, Len(s2) - (d2 + 7)))
 
  <FONT color=gray>' ''Aggiorna i valori dei byte nn. 4, 5, 6, 7 e 40, 41, 42, 43 del primo file wav con la nuova dimensione del nuovo blocco dati audio grezzi:''</font>
  <FONT color=gray>' ''Aggiorna i valori dei byte nn. 4, 5, 6, 7 e 40, 41, 42, 43 del primo file wav con la nuova dimensione del nuovo blocco dati audio grezzi:''</font>
  fl = Open fileWAV_finale For Write
  fl = Open fileWAV_finale For Write
    
  Seek #fl, 4
   Seek #fl, 4
  Write #fl, (q1 + d1 + 7) - 8 As Integer
  Write #fl, (q1 + d1 + 7) - 8 As Integer
  Seek #fl, (d1 + 3)
  Seek #fl, (d1 + 3)
  Write #fl, q1 As Integer
  Write #fl, q1 As Integer
    
  fl.Close
   fl.Close
End
 
 
===2° esempio===
Qui mostriamo una versione con un controllo rapido dei formati, basato sul confronto delle parti essenziali dell’header “fmt ” dei due file.
<BR>In particolare controlla se sono identici: audioformat, numchannels, samplerate, bytepersec, blockalign, bitspersample.
Public Sub Main()
  Dim wav1Path As String = "<FONT color=darkgreen>''/percorso/del/'''primo'''/file.wav''</font>"
  Dim wav2Path As String = "<FONT color=darkgreen>''/percorso/del/'''secondo'''/file.wav''</font>"
  Dim outputPath As String = "/tmp/finale.wav"
  Dim s1 As String = File.Load(wav1Path)
  Dim s2 As String = File.Load(wav2Path)
<FONT color=gray>' ''Cerca la posizione del chunk "fmt " in entrambi i file.''
' ''Questo chunk contiene le informazioni sul formato audio (sample rate, canali, etc.).''</font>
  Dim fmtPos1 As Integer = InStr(s1, "fmt ")
  Dim fmtPos2 As Integer = InStr(s2, "fmt ")
<FONT color=gray>' ''Se non trova il chunk "fmt ", solleva errore:''</font>
  If fmtPos1 = 0 Or fmtPos2 = 0 Then
    Error.Raise("File WAV senza chunk fmt.")
  End If
<FONT color=gray>' ''Estrae i 16 byte successivi al chunk "fmt " per entrambi i file.''
' ''Sono i parametri fondamentali del formato audio da confrontarei 16 byte del chunk fmt (subchunk standard).''</font>
  Dim fmtChunk1 As String = Mid(s1, fmtPos1 + 4, 16)
  Dim fmtChunk2 As String = Mid(s2, fmtPos2 + 4, 16)
<FONT color=gray>' ''Controlla che i formati audio siano identici: se diversi, blocca l'esecuzione:''</font>
  If fmtChunk1 <> fmtChunk2 Then
    Error.Raise("I file WAV hanno formati audio diversi.")
  End If
<FONT color=gray>' ''Cerca la posizione del chunk "data" in entrambi i file.''
' ''Questo chunk contiene i dati audio veri e propri.''</font>
  Dim dataPos1 As Integer = InStr(s1, "data")
  Dim dataPos2 As Integer = InStr(s2, "data")
<FONT color=gray>' ''Se non trova il chunk "data", solleva errore:''</font>
  If dataPos1 = 0 Or dataPos2 = 0 Then
    Error.Raise("File WAV senza chunk data.")
  End If
<FONT color=gray>' ''Calcola la dimensione dei dati audio grezzi in ciascun file.''
' ''Len(s) - (posizione di "data" + 3) perché "data" è 4 caratteri, InStr è 1-based.''</font>
  Dim dataSize1 As Integer = Len(s1) - (dataPos1 + 3)
  Dim dataSize2 As Integer = Len(s2) - (dataPos2 + 3)
<FONT color=gray>' ''Nuova dimensione totale dei dati audio, somma dei due:''</font>
  Dim newDataSize As Integer = dataSize1 + dataSize2
<FONT color=gray>' ''Calcola la nuova dimensione del chunk RIFF (file senza i primi 8 byte dell'header più i nuovi dati):''</font>
  Dim newRiffSize As Integer = (Len(s1) - 8) + dataSize2
<FONT color=gray>' ''Estrae dal secondo file solo i dati audio grezzi (tutto dopo "data" + 4 byte dimensione chunk):''</font>
  Dim datiSecondo As String = Mid(s2, dataPos2 + 8)
<FONT color=gray>' ''Costruisce il file finale concatenando il primo file + dati grezzi del secondo:''</font>
  Dim finale As String = s1 & datiSecondo
<FONT color=gray>' ''Aggiorno nel file finale la dimensione del chunk RIFF (4 byte a offset 4, zero-based):''</font>
  finale = Mid(finale, 1, 4) & IntToLittleEndian(newRiffSize) & Mid(finale, 9)
<FONT color=gray>' ''Aggiorna la dimensione del chunk dati (4 byte subito dopo "data"):''</font>
  Dim chunkSizeOffset As Integer = dataPos1 + 3
  finale = Mid(finale, 1, chunkSizeOffset) & IntToLittleEndian(newDataSize) & Mid(finale, chunkSizeOffset + 5)
  File.Save(outputPath, finale)
  Print "File WAV unito salvato in: " & outputPath
End
<FONT color=gray>' ''Funzione di supporto che converte un intero a 32 bit in stringa 4 byte little endian.''</font>
Private Function IntToLittleEndian(value As Integer) As String
  Dim b1 As Byte = value And &HFF
  Dim b2 As Byte = (value Shr 8) And &HFF
  Dim b3 As Byte = (value Shr 16) And &HFF
  Dim b4 As Byte = (value Shr 24) And &HFF
  Return Chr(b1) & Chr(b2) & Chr(b3) & Chr(b4)
   
   
  '''End'''
  End

Versione attuale delle 00:35, 26 lug 2025

Per unire - l'uno dopo l'altro - due file audio di formato WAV con le sole funzioni di Gambas, bisognerà prestare cura ad almeno i seguenti aspetti:

  • i due file da unire devono avere uguale frequenza e risoluzione di campionamento e uguale numero di canali;
  • eliminare l'intero blocco d'intestazione (header ) del secondo file, ossia del file wav che sarà unito dopo (alla fine) del primo file wav;
  • impostare i nuovi esatti valori che indicano le dimensioni del nuovo file wav unitario, presenti nei byte n. 4, 5, 6, 7 e nei byte n. 40, 41, 42, 43 del blocco d'intestazione del primo file.

1° esempio

Di seguito un possibile semplice codice:

Public Sub Main()

 Dim fileWAV_1, fileWAV_2, s1, s2, fileWAV_finale As String
 Dim fl As File
 Dim d1, d2 As Short
 Dim q1 As Integer

 fileWAV_1 = "/percorso/del/primo/file.wav"
 fileWAV_2 = "/percorso/del/secondo/file.wav"
 fileWAV_finale = "/tmp/finale.wav"
 
 s1 = File.Load(fileWAV_1)
 s2 = File.Load(fileWAV_2)

 d1 = InStr(s1, "data")
 d2 = InStr(s2, "data")
   
' Individua e somma le dimensioni dei dati grezzi audio di ciascun file wav:
 q1 = (Stat(fileWAV_1).Size - (d1 + 7)) + (Stat(fileWAV_2).Size - (d2 + 7))

' Salva il nuovo file WAV unendo al primo file wav il secondo file wav privato del suo header:
 File.Save(fileWAV_finale, s1 & Right(s2, Len(s2) - (d2 + 7)))

' Aggiorna i valori dei byte nn. 4, 5, 6, 7 e 40, 41, 42, 43 del primo file wav con la nuova dimensione del nuovo blocco dati audio grezzi:
 fl = Open fileWAV_finale For Write

 Seek #fl, 4
 Write #fl, (q1 + d1 + 7) - 8 As Integer
 Seek #fl, (d1 + 3)
 Write #fl, q1 As Integer

 fl.Close

End


2° esempio

Qui mostriamo una versione con un controllo rapido dei formati, basato sul confronto delle parti essenziali dell’header “fmt ” dei due file.
In particolare controlla se sono identici: audioformat, numchannels, samplerate, bytepersec, blockalign, bitspersample.

Public Sub Main()

 Dim wav1Path As String = "/percorso/del/primo/file.wav"
 Dim wav2Path As String = "/percorso/del/secondo/file.wav"
 Dim outputPath As String = "/tmp/finale.wav"

 Dim s1 As String = File.Load(wav1Path)
 Dim s2 As String = File.Load(wav2Path)

' Cerca la posizione del chunk "fmt " in entrambi i file.
' Questo chunk contiene le informazioni sul formato audio (sample rate, canali, etc.).
 Dim fmtPos1 As Integer = InStr(s1, "fmt ")
 Dim fmtPos2 As Integer = InStr(s2, "fmt ")

' Se non trova il chunk "fmt ", solleva errore:
 If fmtPos1 = 0 Or fmtPos2 = 0 Then
   Error.Raise("File WAV senza chunk fmt.")
 End If

' Estrae i 16 byte successivi al chunk "fmt " per entrambi i file.
' Sono i parametri fondamentali del formato audio da confrontarei 16 byte del chunk fmt (subchunk standard).
 Dim fmtChunk1 As String = Mid(s1, fmtPos1 + 4, 16)
 Dim fmtChunk2 As String = Mid(s2, fmtPos2 + 4, 16)

' Controlla che i formati audio siano identici: se diversi, blocca l'esecuzione:
 If fmtChunk1 <> fmtChunk2 Then
   Error.Raise("I file WAV hanno formati audio diversi.")
 End If

' Cerca la posizione del chunk "data" in entrambi i file.
' Questo chunk contiene i dati audio veri e propri.
 Dim dataPos1 As Integer = InStr(s1, "data")
 Dim dataPos2 As Integer = InStr(s2, "data")

' Se non trova il chunk "data", solleva errore:
 If dataPos1 = 0 Or dataPos2 = 0 Then
   Error.Raise("File WAV senza chunk data.")
 End If

' Calcola la dimensione dei dati audio grezzi in ciascun file.
' Len(s) - (posizione di "data" + 3) perché "data" è 4 caratteri, InStr è 1-based.
 Dim dataSize1 As Integer = Len(s1) - (dataPos1 + 3)
 Dim dataSize2 As Integer = Len(s2) - (dataPos2 + 3)

' Nuova dimensione totale dei dati audio, somma dei due:
 Dim newDataSize As Integer = dataSize1 + dataSize2

' Calcola la nuova dimensione del chunk RIFF (file senza i primi 8 byte dell'header più i nuovi dati):
 Dim newRiffSize As Integer = (Len(s1) - 8) + dataSize2

' Estrae dal secondo file solo i dati audio grezzi (tutto dopo "data" + 4 byte dimensione chunk):
 Dim datiSecondo As String = Mid(s2, dataPos2 + 8)

' Costruisce il file finale concatenando il primo file + dati grezzi del secondo:
 Dim finale As String = s1 & datiSecondo

' Aggiorno nel file finale la dimensione del chunk RIFF (4 byte a offset 4, zero-based):
 finale = Mid(finale, 1, 4) & IntToLittleEndian(newRiffSize) & Mid(finale, 9)

' Aggiorna la dimensione del chunk dati (4 byte subito dopo "data"):
 Dim chunkSizeOffset As Integer = dataPos1 + 3
 finale = Mid(finale, 1, chunkSizeOffset) & IntToLittleEndian(newDataSize) & Mid(finale, chunkSizeOffset + 5)

 File.Save(outputPath, finale)

 Print "File WAV unito salvato in: " & outputPath

End


' Funzione di supporto che converte un intero a 32 bit in stringa 4 byte little endian.
Private Function IntToLittleEndian(value As Integer) As String

 Dim b1 As Byte = value And &HFF
 Dim b2 As Byte = (value Shr 8) And &HFF
 Dim b3 As Byte = (value Shr 16) And &HFF
 Dim b4 As Byte = (value Shr 24) And &HFF
 Return Chr(b1) & Chr(b2) & Chr(b3) & Chr(b4)

End