Differenze tra le versioni di "Convertire la frequenza di campionamento di un file WAV con le funzioni esterne del API di SDL2"
Da Gambas-it.org - Wikipedia.
(11 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
La libreria '''''SDL 2''''' è un [http://it.wikipedia.org/wiki/Application_programming_interface API] multi-piattaforma contenente funzioni per la gestione multimediale dell'audio e del video. | La libreria '''''SDL 2''''' è un [http://it.wikipedia.org/wiki/Application_programming_interface API] multi-piattaforma contenente funzioni per la gestione multimediale dell'audio e del video. | ||
+ | Sarà necessario avere installate nel sistema e richiamare in Gambas la libreria condivisa: "''libSDL2-2.0.so.0.3000.0'' ". | ||
− | Mostriamo di seguito un esempio di codice per convertire la frequenza di campionamento di un file WAV | + | Mostriamo di seguito un esempio di codice per convertire la frequenza di campionamento di un file WAV da 44100 hertz a 22050 hertz: |
− | + | Library "libSDL2-2.0:0.3000.0" | |
− | |||
− | |||
− | |||
− | Library "libSDL2-2.0" | ||
Public Struct SDL_AudioSpec | Public Struct SDL_AudioSpec | ||
Riga 58: | Riga 55: | ||
Private Extern SDL_Quit() | Private Extern SDL_Quit() | ||
+ | <FONT Color=gray>' ''SDL_RWops * SDL_RWFromFile(const char *file, const char *mode)'' | ||
+ | ' ''Create a new SDL_RWops structure for reading from and/or writing to a named file.''</font> | ||
+ | Private Extern SDL_RWFromFile(filewav As String, mode As String) As Pointer In "libSDL2_mixer-2.0" | ||
+ | |||
− | + | Public Sub Main() | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | Dim | + | Dim wav, convertito As String |
− | |||
Dim data, pbb As Pointer | Dim data, pbb As Pointer | ||
Dim lun, cvtfreq, bitsize, blockalign, avgbytes As Integer | Dim lun, cvtfreq, bitsize, blockalign, avgbytes As Integer | ||
Riga 75: | Riga 70: | ||
Dim bb As Byte[] | Dim bb As Byte[] | ||
Dim st As Stream | Dim st As Stream | ||
+ | |||
+ | wav = "<FONT Color=darkgreen>''/percorso/del/file.wav''</font>" | ||
+ | convertito = "<FONT Color=darkgreen>''/percorso/del/file.wav/convertito''</font>" | ||
<FONT Color=gray>' ''Imposta la nuova frequenza di campionamento, nella quale il file wav sarà convertito:''</font> | <FONT Color=gray>' ''Imposta la nuova frequenza di campionamento, nella quale il file wav sarà convertito:''</font> | ||
Riga 82: | Riga 80: | ||
If SDL_Init(SDL_INIT_AUDIO) < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL2 !") | If SDL_Init(SDL_INIT_AUDIO) < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL2 !") | ||
− | If IsNull(SDL_LoadWAV_RW(SDL_RWFromFile( | + | If IsNull(SDL_LoadWAV_RW(SDL_RWFromFile(wav, "rb"), 1, spec, VarPtr(data), VarPtr(lun))) Then |
− | Error.Raise("Impossibile caricare il file audio: " & | + | Error.Raise("Impossibile caricare il file audio: " & wav & " !") |
Endif | Endif | ||
Riga 91: | Riga 89: | ||
cvt.len = lun | cvt.len = lun | ||
− | cvt.buf = Alloc( | + | cvt.buf = Alloc(SizeOf(gb.Short), cvt.len) |
+ | |||
+ | <FONT Color=gray>' ''Inizia la procedura per trasferire con sicurezza i dati dall'area di memoria, puntata dal Puntatore "data", all'area di memoria puntata dal Puntatore "cvt.buf".'' | ||
+ | ' ''Per velocizzare tale procedura si utilizzerà il Metodo "Write" di un vettore di tipo "Byte[]".''</font> | ||
+ | bb = New Byte[cvt.len] | ||
+ | |||
+ | <FONT Color=gray>' ''Innanzitutto vengono usati i "Memory Stream" per leggere i dati contenuti dal puntatore "data":''</font> | ||
+ | st = Memory data For Read | ||
+ | <FONT Color=gray>' ''I dati letti sono caricati nel vettore "bb" di tipo "Byte[]":''</font> | ||
+ | bb.Read(st, 0, bb.Count) | ||
+ | st.Close | ||
+ | |||
+ | <FONT Color=gray>' ''I dati ora presenti nel vettore "bb" vengono, quindi, scritti nell'area di memoria puntata dal Puntatore "cvt.buf":''</font> | ||
+ | st = Memory cvt.buf For Write | ||
+ | bb.Write(st, 0, bb.Count) | ||
+ | st.Close | ||
− | |||
− | |||
If SDL_ConvertAudio(cvt) = -1 Then Error.Raise("Conversione fallita !") | If SDL_ConvertAudio(cvt) = -1 Then Error.Raise("Conversione fallita !") | ||
− | + | ||
bitsize = spec.format And SDL_AUDIO_MASK_BITSIZE | bitsize = spec.format And SDL_AUDIO_MASK_BITSIZE | ||
blockalign = (bitsize / 8) * spec.channels | blockalign = (bitsize / 8) * spec.channels | ||
avgbytes = cvtfreq * blockalign | avgbytes = cvtfreq * blockalign | ||
− | + | ||
<FONT Color=gray>' ''Scrive l'header del file WAV in uscita:''</font> | <FONT Color=gray>' ''Scrive l'header del file WAV in uscita:''</font> | ||
fl = Open convertito For Create | fl = Open convertito For Create | ||
Write #fl, &46464952 As Integer <FONT Color=gray>' ''RIFF''</font> | Write #fl, &46464952 As Integer <FONT Color=gray>' ''RIFF''</font> | ||
+ | Write #fl, (cvt.len_cvt + 36) As Integer | ||
Write #fl, &45564157 As Integer <FONT Color=gray>' ''WAVE''</font> | Write #fl, &45564157 As Integer <FONT Color=gray>' ''WAVE''</font> | ||
Write #fl, &20746D66 As Integer <FONT Color=gray>' ''fmt''</font> | Write #fl, &20746D66 As Integer <FONT Color=gray>' ''fmt''</font> | ||
Riga 117: | Riga 129: | ||
bb = New Byte[cvt.len_cvt] | bb = New Byte[cvt.len_cvt] | ||
− | + | ||
− | + | <FONT Color=gray>' ''Vengono usati i "Memory Stream" per far leggere dal vettore "bb" i dati (ormai convertiti) contenuti dal puntatore "cvt.buf":''</font> | |
− | <FONT Color=gray>' ''Vengono usati i "Memory Stream" per | + | st = Memory cvt.buf For Read |
− | st = Memory | + | bb.Read(st, 0, bb.Count) |
− | |||
− | |||
− | |||
<FONT Color=gray>' ''Scrive i valori contenuti dal vettore "bb" nel file precedentemente aperto:''</font> | <FONT Color=gray>' ''Scrive i valori contenuti dal vettore "bb" nel file precedentemente aperto:''</font> | ||
Riga 130: | Riga 139: | ||
<FONT Color=gray>' ''Va in chiusura:''</font> | <FONT Color=gray>' ''Va in chiusura:''</font> | ||
st.Close | st.Close | ||
− | Free(cvt.buf | + | Free(cvt.buf) |
fl.Close | fl.Close | ||
SDL_Quit() | SDL_Quit() | ||
− | + | End | |
− | |||
Versione delle 16:38, 18 mar 2024
La libreria SDL 2 è un API multi-piattaforma contenente funzioni per la gestione multimediale dell'audio e del video.
Sarà necessario avere installate nel sistema e richiamare in Gambas la libreria condivisa: "libSDL2-2.0.so.0.3000.0 ".
Mostriamo di seguito un esempio di codice per convertire la frequenza di campionamento di un file WAV da 44100 hertz a 22050 hertz:
Library "libSDL2-2.0:0.3000.0" Public Struct SDL_AudioSpec freq As Integer format As Short channels As Byte silence As Byte samples As Short padding As Short size As Integer callback As Pointer userdata As Pointer End Struct Public Struct SDL_AudioCVT needed As Integer src_format As Short dst_format As Short rate_incr As Float buf As Pointer len As Integer len_cvt As Integer len_mult As Integer len_ratio As Float filters[10] As Pointer filter_index As Integer End Struct Private Const SDL_INIT_AUDIO As Integer = 16 Private Const SDL_AUDIO_MASK_BITSIZE As Integer = 127 ' int SDL_Init(Uint32 flags) ' Initialize the SDL library. Private Extern SDL_Init(flags As Integer) As Integer ' SDL_AudioSpec* SDL_LoadWAV_RW(SDL_RWops * src, int freesrc, SDL_AudioSpec* spec, Uint8** audio_buf, Uint32* audio_len) ' Loads a WAVE from the data source. Private Extern SDL_LoadWAV_RW(SDL_RWops As Pointer, freesrc As Integer, SDL_spec As SDL_AudioSpec, audio_buf As Pointer, audio_len As Pointer) As SDL_AudioSpec ' int SDL_BuildAudioCVT(SDL_AudioCVT * cvt, SDL_AudioFormat src_format, Uint8 src_channels, int src_rate, SDL_AudioFormat dst_format, Uint8 dst_channels, int dst_rate) ' Initialize an SDL_AudioCVT structure for conversion. Private Extern SDL_BuildAudioCVT(SDL_cvt As SDL_AudioCVT, src_format As Integer, src_channels As Byte, src_rate As Integer, dst_format As Integer, dst_channels As Byte, dst_rate As Integer) As Integer ' int SDL_ConvertAudio(SDL_AudioCVT* cvt) ' Converts audio data to a desired audio format. Private Extern SDL_ConvertAudio(SDL_cvt As SDL_AudioCVT) As Integer ' void SDL_Quit(void) ' Clean up all initialized subsystems. Private Extern SDL_Quit() ' SDL_RWops * SDL_RWFromFile(const char *file, const char *mode) ' Create a new SDL_RWops structure for reading from and/or writing to a named file. Private Extern SDL_RWFromFile(filewav As String, mode As String) As Pointer In "libSDL2_mixer-2.0" Public Sub Main() Dim wav, convertito As String Dim data, pbb As Pointer Dim lun, cvtfreq, bitsize, blockalign, avgbytes As Integer Dim spec As New SDL_AudioSpec Dim cvt As New SDL_AudioCVT Dim fl As File Dim bb As Byte[] Dim st As Stream wav = "/percorso/del/file.wav" convertito = "/percorso/del/file.wav/convertito" ' Imposta la nuova frequenza di campionamento, nella quale il file wav sarà convertito: cvtfreq = 22050 ' Inizializza la libreria SDL2: If SDL_Init(SDL_INIT_AUDIO) < 0 Then Error.Raise("Impossibile inizializzare la libreria SDL2 !") If IsNull(SDL_LoadWAV_RW(SDL_RWFromFile(wav, "rb"), 1, spec, VarPtr(data), VarPtr(lun))) Then Error.Raise("Impossibile caricare il file audio: " & wav & " !") Endif If SDL_BuildAudioCVT(cvt, spec.format, spec.channels, spec.freq, spec.format, spec.channels, cvtfreq) = -1 Then Error.Raise("Impossibile realizzare il CVT !") Endif cvt.len = lun cvt.buf = Alloc(SizeOf(gb.Short), cvt.len) ' Inizia la procedura per trasferire con sicurezza i dati dall'area di memoria, puntata dal Puntatore "data", all'area di memoria puntata dal Puntatore "cvt.buf". ' Per velocizzare tale procedura si utilizzerà il Metodo "Write" di un vettore di tipo "Byte[]". bb = New Byte[cvt.len] ' Innanzitutto vengono usati i "Memory Stream" per leggere i dati contenuti dal puntatore "data": st = Memory data For Read ' I dati letti sono caricati nel vettore "bb" di tipo "Byte[]": bb.Read(st, 0, bb.Count) st.Close ' I dati ora presenti nel vettore "bb" vengono, quindi, scritti nell'area di memoria puntata dal Puntatore "cvt.buf": st = Memory cvt.buf For Write bb.Write(st, 0, bb.Count) st.Close If SDL_ConvertAudio(cvt) = -1 Then Error.Raise("Conversione fallita !") bitsize = spec.format And SDL_AUDIO_MASK_BITSIZE blockalign = (bitsize / 8) * spec.channels avgbytes = cvtfreq * blockalign ' Scrive l'header del file WAV in uscita: fl = Open convertito For Create Write #fl, &46464952 As Integer ' RIFF Write #fl, (cvt.len_cvt + 36) As Integer Write #fl, &45564157 As Integer ' WAVE Write #fl, &20746D66 As Integer ' fmt Write #fl, 16 As Integer ' chunk size Write #fl, 1 As Short ' uncompressed Write #fl, spec.channels As Short ' channels Write #fl, cvtfreq As Integer ' sample rate Write #fl, avgbytes As Integer ' average bytes per second Write #fl, blockalign As Short ' block align Write #fl, bitsize As Short ' significant bits per sample Write #fl, &61746164 As Integer ' data Write #fl, cvt.len_cvt As Integer ' size bb = New Byte[cvt.len_cvt] ' Vengono usati i "Memory Stream" per far leggere dal vettore "bb" i dati (ormai convertiti) contenuti dal puntatore "cvt.buf": st = Memory cvt.buf For Read bb.Read(st, 0, bb.Count) ' Scrive i valori contenuti dal vettore "bb" nel file precedentemente aperto: bb.Write(fl, 0, bb.Count) ' Va in chiusura: st.Close Free(cvt.buf) fl.Close SDL_Quit() End