Convertire un file audio in formato OggVorbis con le funzioni esterne del API di libfishsound, libsndfile e liboggz
Da Gambas-it.org - Wikipedia.
Versione del 24 ott 2024 alle 21:01 di Vuott (Discussione | contributi) (Creata pagina con "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 Xi...")
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 audio 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 fileAUDIO, 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 fileAUDIO = "/percorso/del/file/audio" fileOGG = "/percorso/del/file.ogg" snd = sf_open(fileAUDIO, SFM_READ, sfinfo) If snd == 0 Then Error.Raise("Impossibile aprire il file " & fileAUDIO & " !") 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