Unire due file WAV: differenze tra le versioni
Vai alla navigazione
Vai alla ricerca
(Creata pagina con 'Per unire due file audio di formato WAV con le sole funzioni di Gambas, bisognerà prestare cure ad almeno i due seguenti punti: * i due file da unire devono avere uguale freq...') |
Nessun oggetto della modifica |
||
| (20 versioni intermedie di uno stesso utente non sono mostrate) | |||
| Riga 1: | Riga 1: | ||
Per unire due file audio di formato WAV con le sole funzioni di Gambas, bisognerà prestare | 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 | * 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: | Di seguito un possibile semplice codice: | ||
Public Sub Main() | |||
Dim | Dim fileWAV_1, fileWAV_2, s1, s2, fileWAV_finale As String | ||
Dim | Dim fl As File | ||
Dim d1, d2 As Short | |||
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" | |||
s1 = File.Load(fileWAV_1) | |||
s2 = File.Load(fileWAV_2) | |||
<FONT color=gray>' '' | |||
d1 = InStr(s1, "data") | |||
d2 = InStr(s2, "data") | |||
<FONT color=gray>' '' | <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)) | |||
<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))) | |||
<FONT color=gray>' '' | |||
<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 | |||
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. | |||
<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 | |||
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