Differenze tra le versioni di "Convertire un file WAV in formato OggVorbis con le funzioni esterne del API di libfishsound, libsndfile e liboggz"
Da Gambas-it.org - Wikipedia.
(6 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 7: | Riga 7: | ||
E' necessaria, pertanto, la installazione nel sistema e richiamare in Gambas le seguenti librerie condivise: | E' necessaria, pertanto, la installazione nel sistema e richiamare in Gambas le seguenti librerie condivise: | ||
* ''libfishsound.so.1.3.0'' | * ''libfishsound.so.1.3.0'' | ||
− | * ''libsndfile.so.1.0. | + | * ''libsndfile.so.1.0.37'' |
* ''liboggz.so.2.6.0'' | * ''liboggz.so.2.6.0'' | ||
+ | Library "<FONT Color=blue>libfishsound:1.3.0</font>" | ||
+ | |||
Public Struct ogg_packet | Public Struct ogg_packet | ||
packet As Pointer | packet As Pointer | ||
Riga 21: | Riga 23: | ||
Private serialno As Long | Private serialno As Long | ||
Private b_o_s As Integer = 1 | Private b_o_s As Integer = 1 | ||
− | |||
− | |||
Public Struct FishSoundInfo | Public Struct FishSoundInfo | ||
Riga 66: | Riga 66: | ||
− | Library "libsndfile" | + | Library "<FONT Color=red>libsndfile:1.0.37</font>" |
Public Struct SF_INFO | Public Struct SF_INFO | ||
Riga 72: | Riga 72: | ||
samplerate As Integer | samplerate As Integer | ||
channels As Integer | channels As Integer | ||
− | + | format_ As Integer | |
sections As Integer | sections As Integer | ||
seekable As Integer | seekable As Integer | ||
Riga 92: | Riga 92: | ||
− | Library "liboggz:2.6.0" | + | Library "<FONT Color=darkorange>liboggz:2.6.0</font>" |
Private Const OGGZ_WRITE As Integer = 1 | Private Const OGGZ_WRITE As Integer = 1 | ||
Riga 117: | Riga 117: | ||
− | + | Public Sub Main() | |
Dim fileWAV, fileOGG As String | Dim fileWAV, fileOGG As String | ||
Riga 126: | Riga 126: | ||
Dim pcm As New Single[2048] | Dim pcm As New Single[2048] | ||
− | + | formato = FISH_SOUND_VORBIS | |
− | + | fileWAV = "<FONT Color=darkgreen>''/percorso/del/file.wav''</font>" | |
− | + | fileOGG = "<FONT Color=darkgreen>''/percorso/del/file.ogg''</font>" | |
− | + | snd = sf_open(fileWAV, SFM_READ, sfinfo) | |
− | + | If snd == 0 Then Error.Raise("Impossibile aprire il file " & fileWAV & " !") | |
− | + | oggz = oggz_open(fileOGG, OGGZ_WRITE) | |
− | + | If oggz == 0 Then Error.Raise("Impossibile aprire il file in scrittura !") | |
− | + | serialno = oggz_serialno_new(oggz) | |
− | + | With fsinfo | |
− | + | .channels = sfinfo.channels | |
− | + | .samplerate = sfinfo.samplerate | |
− | + | .formatFSI = formato | |
− | + | End With | |
− | + | fsound = fish_sound_new(FISH_SOUND_ENCODE_, fsinfo) | |
− | + | If fsound == 0 Then Error.Raise("Errore !") | |
− | + | ||
+ | fish_sound_set_encoded_callback(fsound, encoded, oggz) | ||
− | + | fish_sound_set_interleave(fsound, 1) | |
− | + | fish_sound_comment_add_byname(fsound, "Encoder", "fishsound-encode") | |
− | + | ||
− | + | Write "\e[5mAttendere...\e[0m" | |
− | + | Flush | |
− | |||
− | |||
− | + | While sf_readf_float(snd, pcm, ENCODE_BLOCK_SIZE) > 0 | |
+ | fish_sound_encode(fsound, pcm.data, ENCODE_BLOCK_SIZE) | ||
+ | oggz_run(oggz) | ||
+ | Wend | ||
+ | |||
+ | fish_sound_flush(fsound) | ||
− | + | oggz_run(oggz) | |
− | |||
<FONT Color=gray>' ''Va in chiusura:''</font> | <FONT Color=gray>' ''Va in chiusura:''</font> | ||
− | + | Write "\rConversione terminata !" | |
− | + | fish_sound_delete(fsound) | |
− | + | oggz_close(oggz) | |
+ | sf_close(snd) | ||
− | + | End | |
− | + | Private Function encoded(fsound As Pointer, buf As Pointer, bytes As Long, user_data As Pointer) As Integer | |
Dim err As Integer | Dim err As Integer | ||
Dim ogp As New Ogg_packet | Dim ogp As New Ogg_packet | ||
− | + | With ogp | |
− | + | .packet = buf | |
− | + | .bytes = bytes | |
− | + | .b_o_s = b_o_s | |
− | + | .e_o_s = 0 | |
− | + | .granulepos = fish_sound_get_frameno(fsound) | |
− | + | .packetno = -1 | |
− | + | End With | |
− | + | err = oggz_write_feed(user_data, ogp, serialno, 0, 0) | |
− | + | If err Then Print "err: "; err | |
− | + | b_o_s = 0 | |
− | + | Return 0 | |
− | + | ||
− | + | End | |
− | |||
Versione attuale delle 05:13, 18 giu 2024
La libreria Libfishsound fornisce una semplice interfaccia di programmazione di livello superiore per la decodifica e la codifica di dati audio utilizzando i codec di Xiph.org (FLAC, Speex e Vorbis).
Liboggz, invece, è una libreria per la lettura, la scrittura e la gestione di file Ogg.
Mostriamo di seguito un semplice esempio, il quale utilizzando congiuntamente le funzioni esterne del API di libfishsound, libsndfile e liboggz, consente di convertire un file di formato WAV in un file audio di formato OGG-Vorbis.
E' necessaria, pertanto, la installazione nel sistema e richiamare in Gambas le seguenti librerie condivise:
- libfishsound.so.1.3.0
- libsndfile.so.1.0.37
- liboggz.so.2.6.0
Library "libfishsound:1.3.0" Public Struct ogg_packet packet As Pointer bytes As Long b_o_s As Long e_o_s As Long granulepos As Long packetno As Long End Struct Private Const ENCODE_BLOCK_SIZE As Long = 1152 Private serialno As Long Private b_o_s As Integer = 1 Public Struct FishSoundInfo samplerate As Integer channels As Integer formatFSI As Integer End Struct Private Enum FISH_SOUND_UNKNOWN = 0, FISH_SOUND_VORBIS Private Const FISH_SOUND_ENCODE_ As Integer = &20 ' FishSound * fish_sound_new (int mode, FishSoundInfo * fsinfo) ' Instantiate a new FishSound* handle. Private Extern fish_sound_new(mode As Integer, FSInfo As FishSoundInfo) As Pointer ' int fish_sound_set_encoded_callback (FishSound * fsound, FishSoundEncoded encoded, void * user_data) ' Set the callback for libfishsound to call when it has a block of encoded data ready. Private Extern fish_sound_set_encoded_callback(FS As Pointer, FishSoundEncoded As Pointer, data As Pointer) As Integer ' int fish_sound_set_interleave (FishSound * fsound, int interleave) ' Set the PCM format used by a FishSound object. DEPRECATED FUNCTION. Private Extern fish_sound_set_interleave(FS As Pointer, interleave As Integer) As Integer ' int fish_sound_comment_add_byname (FishSound * fsound, const char * name, const char * value) ' Add a comment by name and value. Private Extern fish_sound_comment_add_byname(FS As Pointer, name As String, value As String) As Integer ' long fish_sound_encode (FishSound * fsound, float ** pcm, long frames) ' Encode a block of audio. DEPRECATED FUNCTION. Private Extern fish_sound_encode(FS As Pointer, pcm As Pointer, frames As Long) As Long ' long fish_sound_flush (FishSound * fsound) ' Flush any internally buffered data, forcing encode. Private Extern fish_sound_flush(FS As Pointer) As Long ' long fish_sound_get_frameno (FishSound * fsound) ' Query the current frame number of a FishSound object. Private Extern fish_sound_get_frameno(FS As Pointer) As Long ' int fish_sound_delete (FishSound * fsound) ' Delete a FishSound object. Private Extern fish_sound_delete(FS As Pointer) As Integer Library "libsndfile:1.0.37" Public Struct SF_INFO frames As Long samplerate As Integer channels As Integer format_ As Integer sections As Integer seekable As Integer End Struct Private Const SFM_READ As Integer = 16 ' SNDFILE * sf_open (const char *path, int mode, SF_INFO *sfinfo) ' Open the specified file for read, write or both. Private Extern sf_open(path As String, mode As Integer, SFinf As SF_INFO) As Pointer ' sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames) ' Function for reading the data chunk in terms of frames. Passes data in the native float format. Private Extern sf_readf_float(sndfile As Pointer, ptr As Single[], frames As Long) As Long ' int sf_close (SNDFILE *sndfile) ' Close the SNDFILE and clean up all memory allocations associated with this file. Private Extern sf_close(sndfile As Pointer) As Integer Library "liboggz:2.6.0" Private Const OGGZ_WRITE As Integer = 1 ' OGGZ * oggz_open (const char * filename, int flags) ' Open an Ogg file, creating an OGGZ handle for it. Private Extern oggz_open(filename As String, flags As Integer) As Pointer ' long oggz_serialno_new (OGGZ * oggz) ' Request a new serialno, as required for a new stream. Private Extern oggz_serialno_new(OGG As Pointer) As Long ' long oggz_run (OGGZ * oggz) ' Run an OGGZ until completion, or error. Private Extern oggz_run(OGG As Pointer) As Long ' int oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, int * guard) ' Add a packet to \a oggz's packet queue. Private Extern oggz_write_feed(OGGZ As Pointer, ogg_p As Ogg_packet, ser As Long, flushI As Integer, guard As Pointer) As Integer ' int oggz_close (OGGZ * oggz) ' Close an OGGZ handle. Private Extern oggz_close(OGG As Pointer) As Integer Public Sub Main() Dim fileWAV, fileOGG As String Dim snd, oggz, fsound As Pointer Dim sfinfo As New SF_INFO Dim fsinfo As New FishSoundInfo Dim formato, rit As Integer Dim pcm As New Single[2048] formato = FISH_SOUND_VORBIS fileWAV = "/percorso/del/file.wav" fileOGG = "/percorso/del/file.ogg" snd = sf_open(fileWAV, SFM_READ, sfinfo) If snd == 0 Then Error.Raise("Impossibile aprire il file " & fileWAV & " !") oggz = oggz_open(fileOGG, OGGZ_WRITE) If oggz == 0 Then Error.Raise("Impossibile aprire il file in scrittura !") serialno = oggz_serialno_new(oggz) With fsinfo .channels = sfinfo.channels .samplerate = sfinfo.samplerate .formatFSI = formato End With fsound = fish_sound_new(FISH_SOUND_ENCODE_, fsinfo) If fsound == 0 Then Error.Raise("Errore !") fish_sound_set_encoded_callback(fsound, encoded, oggz) fish_sound_set_interleave(fsound, 1) fish_sound_comment_add_byname(fsound, "Encoder", "fishsound-encode") Write "\e[5mAttendere...\e[0m" Flush While sf_readf_float(snd, pcm, ENCODE_BLOCK_SIZE) > 0 fish_sound_encode(fsound, pcm.data, ENCODE_BLOCK_SIZE) oggz_run(oggz) Wend fish_sound_flush(fsound) oggz_run(oggz) ' Va in chiusura: Write "\rConversione terminata !" fish_sound_delete(fsound) oggz_close(oggz) sf_close(snd) End Private Function encoded(fsound As Pointer, buf As Pointer, bytes As Long, user_data As Pointer) As Integer Dim err As Integer Dim ogp As New Ogg_packet With ogp .packet = buf .bytes = bytes .b_o_s = b_o_s .e_o_s = 0 .granulepos = fish_sound_get_frameno(fsound) .packetno = -1 End With err = oggz_write_feed(user_data, ogp, serialno, 0, 0) If err Then Print "err: "; err b_o_s = 0 Return 0 End