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 1: Riga 1:
 
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).
 
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).
<BR>Per poter fruire in Gambas delle sue risorse, è necessario installare e richiamare la libreria condivisa: "''libfishsound.so.1.3.0''"
 
 
  
 
'''Liboggz''', invece, è una libreria per la lettura, la scrittura e la gestione di file ''Ogg''.
 
'''Liboggz''', invece, è una libreria per la lettura, la scrittura e la gestione di file ''Ogg''.
<BR>Per poter fruire in Gambas delle sue riorse, è necessario installare e richiamare la libreria condivisa: "''liboggz.so.2.6.0''"
 
  
 +
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:
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 delle seguenti librerie condivise:
 
 
* ''libfishsound.so.1.3.0''
 
* ''libfishsound.so.1.3.0''
* ''libsndfile.so.1.0.25''
+
* ''libsndfile.so.1.0.37''
 
* ''liboggz.so.2.6.0''
 
* ''liboggz.so.2.6.0''
 
  Public Struct ogg_packet
 
  Public Struct ogg_packet
Riga 69: Riga 66:
 
   
 
   
 
   
 
   
  Library "libsndfile:1.0.25"
+
  Library "libsndfile:1.0.37"
 
   
 
   
 
  Public Struct SF_INFO
 
  Public Struct SF_INFO
Riga 75: Riga 72:
 
   samplerate As Integer
 
   samplerate As Integer
 
   channels As Integer   
 
   channels As Integer   
   formatI As Integer
+
   format_ As Integer
 
   sections As Integer
 
   sections As Integer
 
   seekable As Integer
 
   seekable As Integer
Riga 120: Riga 117:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
 
   Dim fileWAV, fileOGG As String
 
   Dim fileWAV, fileOGG As String
Riga 129: Riga 126:
 
   Dim pcm As New Single[2048]
 
   Dim pcm As New Single[2048]
 
   
 
   
  formato = FISH_SOUND_VORBIS
+
  formato = FISH_SOUND_VORBIS
 
   
 
   
  fileWAV = "''/percorso/del/file.wav''"
+
  fileWAV = "<FONT Color=darkgreen>''/percorso/del/file.wav''</font>"
  fileOGG = "''/percorso/del/file.ogg''"
+
  fileOGG = "<FONT Color=darkgreen>''/percorso/del/file.ogg''</font>"
 
      
 
      
  snd = sf_open(fileWAV, SFM_READ, sfinfo)
+
  snd = sf_open(fileWAV, SFM_READ, sfinfo)
  If IsNull(snd) Then Error.Raise("Impossibile aprire il file " & fileWAV & " !")
+
  If snd == 0 Then Error.Raise("Impossibile aprire il file " & fileWAV & " !")
 
   
 
   
  oggz = oggz_open(fileOGG, OGGZ_WRITE)
+
  oggz = oggz_open(fileOGG, OGGZ_WRITE)
  If IsNull(oggz) Then Error.Raise("Impossibile aprire il file in scrittura !")
+
  If oggz == 0 Then Error.Raise("Impossibile aprire il file in scrittura !")
 
      
 
      
  serialno = oggz_serialno_new(oggz)
+
  serialno = oggz_serialno_new(oggz)
 
      
 
      
  With fsinfo
+
  With fsinfo
    .channels = sfinfo.channels
+
    .channels = sfinfo.channels
    .samplerate = sfinfo.samplerate
+
    .samplerate = sfinfo.samplerate
    .formatFSI = formato
+
    .formatFSI = formato
  End With
+
  End With
 
      
 
      
  fsound = fish_sound_new(FISH_SOUND_ENCODE_, fsinfo)
+
  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_encoded_callback(fsound, encoded, oggz)
 
    
 
    
  fish_sound_set_interleave(fsound, 1)
+
  fish_sound_set_interleave(fsound, 1)
 
      
 
      
  fish_sound_comment_add_byname(fsound, "Encoder", "fishsound-encode")
+
  fish_sound_comment_add_byname(fsound, "Encoder", "fishsound-encode")
   
+
  While sf_readf_float(snd, pcm, ENCODE_BLOCK_SIZE) > 0
+
  Write "\e[5mAttendere...\e[0m"
    fish_sound_encode(fsound, pcm.data, ENCODE_BLOCK_SIZE)
+
  Flush
    oggz_run(oggz)
 
  Wend
 
 
    
 
    
  fish_sound_flush(fsound)
+
  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)     
+
  oggz_run(oggz)     
 
    
 
    
 
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
 
  <FONT Color=gray>' ''Va in chiusura:''</font>
  oggz_close(oggz)
+
  Write "\rConversione terminata !"
  fish_sound_delete(fsound)
+
  fish_sound_delete(fsound)
  sf_close(snd)
+
  oggz_close(oggz)
 +
  sf_close(snd)
 
   
 
   
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Function encoded(fsound As Pointer, buf As Pointer, bytes As Long, user_data As Pointer) As Integer
+
  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
+
  With ogp
    .packet = buf
+
    .packet = buf
    .bytes = bytes
+
    .bytes = bytes
    .b_o_s = b_o_s
+
    .b_o_s = b_o_s
    .e_o_s = 0
+
    .e_o_s = 0
    .granulepos = fish_sound_get_frameno(fsound)
+
    .granulepos = fish_sound_get_frameno(fsound)
    .packetno = -1
+
    .packetno = -1
  End With
+
  End With
 
   
 
   
  err = oggz_write_feed(user_data, ogp, serialno, 0, 0)
+
  err = oggz_write_feed(user_data, ogp, serialno, 0, 0)
  If (err) Then Print "err: "; err
+
  If err Then Print "err: "; err
 
    
 
    
  b_o_s = 0
+
  b_o_s = 0
 
   
 
   
  Return 0
+
  Return 0
 
+
  '''End'''
+
  End
 
 
  
  

Versione attuale delle 05:46, 14 gen 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
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

Library "libfishsound:1.3.0"

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


Riferimenti