Unire due file WAV: differenze tra le versioni
Vai alla navigazione
Vai alla ricerca
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| (6 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 | * i due file da unire devono avere uguale frequenza e risoluzione di campionamento e uguale numero di canali; | ||
* eliminare l'intero | * 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 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" | |||
s1 = File.Load(fileWAV_1) | |||
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> | |||
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>' ''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>' '' | |||
<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