Differenze tra le versioni di "Convertire un file audio da un formato audio in un altro con le funzioni esterne del API di Sox"

Da Gambas-it.org - Wikipedia.
Riga 6: Riga 6:
  
  
Mostriamo un esempio, nel quale un file di formato ''wav'' viene ''convertito in formato ''mp3'':
+
Mostriamo un esempio, nel quale un file di formato ''wav'' viene convertito in formato ''OggVorbis'':
 
   Public Struct sox_signalinfo_t
 
   Public Struct sox_signalinfo_t
 
   rate As Float
 
   rate As Float
Riga 25: Riga 25:
 
  End Struct
 
  End Struct
 
   
 
   
  Public Struct sox_effects_globals_t
+
  Private Const MAX_SAMPLES As Long = 2048
  plot As Integer
 
  global_info As Pointer
 
End Struct
 
 
Public Struct sox_effects_chain_t
 
  effects As Pointer
 
  table_size As Integer
 
  length As Integer
 
  ibufc As Pointer
 
  obufc As Pointer
 
  global_info As Struct Sox_effects_globals_t
 
  in_enc As Pointer
 
  out_enc As Pointer
 
End Struct
 
 
Public Struct sox_effect_handler_t
 
  name As Pointer
 
  usage As Pointer
 
  flags As Integer
 
  sox_effect_handler_getopts As Pointer
 
  sox_effect_handler_start As Pointer
 
  sox_effect_handler_flow As Pointer
 
  sox_effect_handler_drain As Pointer
 
  sox_effect_handler_stop As Pointer
 
  sox_effect_handler_kill As Pointer
 
  priv_size As Long
 
End Struct
 
 
 
Public Struct sox_effect_t
 
  global_info As Pointer
 
  in_signal As Struct Sox_signalinfo_t
 
  out_signal As Struct Sox_signalinfo_t
 
  in_encoding As Pointer
 
  out_encoding As Pointer
 
  handler As Struct Sox_effect_handler_t
 
  obuf As Pointer
 
  obeg As Long
 
  oend As Long
 
  imin As Long
 
  clips As Long
 
  flows As Long
 
  flow As Long
 
  priv As Pointer
 
End Struct
 
 
   
 
   
 +
 
 
  Library "libsox:2.0.1"
 
  Library "libsox:2.0.1"
 
   
 
   
Riga 87: Riga 44:
 
  Private Extern sox_open_write(path As String, signal As Sox_signalinfo_t, encoding As Sox_encodinginfo_t, filetype As String, oob As Pointer, filename As String) As Pointer
 
  Private Extern sox_open_write(path As String, signal As Sox_signalinfo_t, encoding As Sox_encodinginfo_t, filetype As String, oob As Pointer, filename As String) As Pointer
 
   
 
   
  <FONT color=gray>' ''sox_effects_chain_t * sox_create_effects_chain(sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc)''
+
  <FONT color=gray>' ''size_t sox_read(sox_format_t * ft, sox_sample_t *buf, size_t len)''
  ' ''Initializes an effects chain.''</font>
+
  ' ''Reads samples from a decoding session into a sample buffer.''</font>
  Private Extern sox_create_effects_chain(in_enc As Sox_encodinginfo_t, out_enc As Sox_encodinginfo_t) As Sox_effects_chain_t
+
  Private Extern sox_read(ft As Pointer, buf As Pointer, lenl As Long) As Long
 
   
 
   
  <FONT color=gray>' ''sox_effect_t * sox_create_effect(sox_effect_handler_t const * eh)''
+
  <FONT color=gray>' ''size_t sox_write(sox_format_t * ft, sox_sample_t const * buf, size_t len)''
' ''Creates an effect using the given handler.''</font>
+
  ' Writes samples to an encoding session from a sample buffer.''</font>
Private Extern sox_create_effect(eh As Sox_effect_handler_t) As Sox_effect_t
+
  Private Extern sox_write(ft As Pointer, buf As Pointer, lenl As Long) As Long
 
<FONT color=gray>' ''sox_effect_handler_t const * sox_find_effect(char const * name)''
 
' ''Finds the effect handler with the given name.''</font>
 
Private Extern sox_find_effect(name As String) As Pointer
 
 
<FONT color=gray>' ''int sox_effect_options(sox_effect_t *effp, int argc, char * const argv[])''
 
  ' ''Applies the command-line options to the effect.''</font>
 
  Private Extern sox_effect_options(effp As Sox_effect_t, argc As Integer, argv As Pointer[]) As Integer
 
 
<FONT color=gray>' ''int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out)''
 
' ''Adds an effect to the effects chain, returns SOX_SUCCESS if successful. Returns SOX_SUCCESS if successful.''</font>
 
Private Extern sox_add_effect(chain As Sox_effects_chain_t, effp As Sox_effect_t, inS As Sox_signalinfo_t, ouS As Sox_signalinfo_t) As Integer
 
 
<FONT color=gray>' ''int sox_flow_effects(sox_effects_chain_t * chain, sox_flow_effects_callback callback, void * client_data)''
 
' ''Runs the effects chain, returns SOX_SUCCESS if successful. Returns SOX_SUCCESS if successful.''</font>
 
Private Extern sox_flow_effects(chain As Sox_effects_chain_t, callback As Pointer, client_data As Pointer) As Integer
 
 
<FONT color=gray>' ''void sox_delete_effects_chain(sox_effects_chain_t *ecp)''
 
' ''Closes an effects chain.''</font>
 
Private Extern sox_delete_effects_chain(chain As Sox_effects_chain_t)
 
 
   
 
   
 
  <FONT color=gray>' ''int sox_close(sox_format_t * ft)''
 
  <FONT color=gray>' ''int sox_close(sox_format_t * ft)''
 
  ' ''Closes an encoding or decoding session. Returns SOX_SUCCESS if successful.''</font>
 
  ' ''Closes an encoding or decoding session. Returns SOX_SUCCESS if successful.''</font>
  Private Extern sox_close(ft As Pointer)
+
  Private Extern sox_close(ft As Pointer) As Integer
 
   
 
   
  <FONT color=gray>' ''sox_quit(void)''
+
  <FONT color=gray>' ''int sox_quit(void)''
 
  ' ''Close effects library and unload format handler plugins. Returns SOX_SUCCESS if successful.''</font>
 
  ' ''Close effects library and unload format handler plugins. Returns SOX_SUCCESS if successful.''</font>
  Private Extern sox_quit()
+
  Private Extern sox_quit() As Integer
 
   
 
   
 
   
 
   
 
  '''Public''' Sub Main()
 
  '''Public''' Sub Main()
 
   
 
   
   Dim fileAUDIO As String
+
   Dim fileAUDIO, nuovo_file As String
 
   Dim err As Integer
 
   Dim err As Integer
 
   Dim sfIn, sfOut As Pointer
 
   Dim sfIn, sfOut As Pointer
 
   Dim sigIn, sigOut As New Sox_signalinfo_t
 
   Dim sigIn, sigOut As New Sox_signalinfo_t
   Dim encoIn, encoOut As New Sox_encodinginfo_t
+
   Dim number_read As Long
  Dim chain As Sox_effects_chain_t
+
   Dim samples As New Integer[MAX_SAMPLES]
  Dim eff As New Sox_effect_t
 
   Dim argsP As New Pointer[10]
 
 
    
 
    
 
   fileAUDIO = "<FONT color=gray>''/percorso/del/file/audio.wav''</font>"
 
   fileAUDIO = "<FONT color=gray>''/percorso/del/file/audio.wav''</font>"
 +
 +
<FONT color=gray>' ''Poiché dal file audio esistente vogliamo creare un file audio di un altro formato,''
 +
' ''allora indicheremo il "percorso" ed il "formato" prescelto del file da creare:''</font>
 +
  nuovo_file = "/tmp/audio.ogg"
 
    
 
    
 
  <FONT color=gray>' ''Inizializza la libreria "libsox":''</font>
 
  <FONT color=gray>' ''Inizializza la libreria "libsox":''</font>
Riga 146: Riga 85:
 
   sigIn = sfIn + 8
 
   sigIn = sfIn + 8
 
    
 
    
 +
<FONT color=gray>' ''Mostra alcune caratteristiche del file originario da convertire:''</font>
 
   With sigIn
 
   With sigIn
 
     Print "File audio sorgente:        ", String@(Pointer@(sfIn))
 
     Print "File audio sorgente:        ", String@(Pointer@(sfIn))
Riga 155: Riga 95:
 
   End With
 
   End With
 
    
 
    
<FONT color=gray>' ''Poiché dal file audio esistente vogliamo creare un file audio di un altro formato,''
+
   sfOut = sox_open_write(nuovo_file, sigIn, Null, Null, 0, Null)
' ''allora indicheremo il "percorso" ed il "formato" prescelto del file da creare:''</font>
+
   If IsNull(sfOut) Then Error.Raise("Impossibile aprire il nuovo file audio per la scrittura !")
   sfOut = sox_open_write("<FONT color=gray>''/percorso/del/file/audio.mp3''</font>", sigIn, Null, Null, 0, Null)
 
    
 
  sigOut = sfOut + 8
 
  encoIn = sfIn + 40
 
  encoOut = sfOut + 40
 
 
    
 
    
   chain = sox_create_effects_chain(encoIn, encoOut)
+
   Do
 
+
    number_read = sox_read(sfIn, samples.Data, MAX_SAMPLES)  
  eff = sox_create_effect(sox_find_effect("input"))
+
     sox_write(sfOut, samples.Data, number_read)
 
+
   Loop Until number_read = 0
  argsP[0] = sfIn
 
 
 
  err = sox_effect_options(eff, 1, argsP)
 
  If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_effect_options' !")
 
 
 
  err = sox_add_effect(chain, eff, sigIn, sigOut)
 
  If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_add_effect' !")
 
 
 
  If sigIn.rate <> sigOut.rate Then
 
     eff = sox_create_effect(sox_find_effect("rate"))
 
    err = sox_effect_options(eff, 0, Null)
 
    If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_effect_options' !") 
 
    err = sox_add_effect(chain, eff, sigIn, sigOut)
 
    If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_add_effect' !")
 
  Endif
 
 
 
<FONT color=gray>' ''Crea l'effetto "Volume", lo inizializza con il parametro desiderato:''</font>
 
   eff = sox_create_effect(sox_find_effect("vol"))
 
 
 
<FONT color=gray>' ''Diminuisce il volume d'ascolto assegnando il valore "-12dB":''</font>
 
  argsP[0] = Alloc("-12dB")
 
  err = sox_effect_options(eff, 1, argsP)
 
  If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_effect_options' !")
 
 
 
  err = sox_add_effect(chain, eff, sigIn, sigOut)
 
  If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_add_effect' !")
 
 
 
 
 
  eff = sox_create_effect(sox_find_effect("output"))
 
  argsP[0] = sfOut
 
 
 
  err = sox_effect_options(eff, 1, argsP)
 
  If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_effect_options' !")
 
 
 
  err = sox_add_effect(chain, eff, sigIn, sigOut)
 
  If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_add_effect' !")
 
 
 
<FONT color=gray>' ''Esegue il i dati audio:''</font>
 
  sox_flow_effects(chain, Null, Null)
 
 
    
 
    
 
    
 
    
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
  Free(argsP.Data)
 
  sox_delete_effects_chain(chain)
 
 
   sox_close(sfOut)
 
   sox_close(sfOut)
 
   sox_close(sfIn)
 
   sox_close(sfIn)
Riga 221: Riga 115:
  
 
=Riferimenti=
 
=Riferimenti=
[1] [http://sox.sourceforge.net/libsox.html Il sito di Sox]
+
* http://sox.sourceforge.net/libsox.html
 
+
* http://fossies.org/dox/sox-14.4.1/index.html
[2] [http://fossies.org/dox/sox-14.4.1/index.html Sito del API di Sox]
+
* http://sox.sourcearchive.com/documentation/14.3.2-3/index.html
 
 
[3] [http://sox.sourcearchive.com/documentation/14.3.2-3/index.html Altro sito del API di Sox]
 

Versione delle 19:18, 13 feb 2016

La libreria Sox contiene risorse per poter gestire ampiamente i file audio: riproduzione e registrazione, conversione di vari formati audio in altri formati, nonché applicazione di vari effetti. Sox consente di eseguire numerosissimi formati di file audio.

Per poter utilizzare in Gambas le risorse del API di Sox bisognerà aver installato e richiamare la libreria dinamica condivisa: libsox.so.2.0.1

Se intendiamo convertire un file audio da un formato audio in altro formato, bisognerà avere cura di specificare nella funzione sox_open_write() il percorso ove sarà generato il nuovo file e l'estensione del nuovo formato.


Mostriamo un esempio, nel quale un file di formato wav viene convertito in formato OggVorbis:

 Public Struct sox_signalinfo_t
  rate As Float
  channels As Integer
  precision As Integer
  length As Long
  mult As Pointer
End Struct

Public Struct sox_encodinginfo_t
  encoding As Integer
  bits_per_sample As Integer
  compression As Float
  reverse_bytes As Integer
  reverse_nibbles As Integer
  reverse_bits As Integer
  opposite_endian As Integer
End Struct

Private Const MAX_SAMPLES As Long = 2048

 
Library "libsox:2.0.1"

Private Enum SOX_EOF = -1, SOX_SUCCESS, SOX_EHDR = 2000, SOX_EFMT, SOX_ENOMEM, SOX_EPERM, SOX_ENOTSUP, SOX_EINVAL 

' int sox_format_init(void)
' Client API: Initialize effects library. SOX_SUCCESS if successful.
Private Extern sox_init() As Integer

' sox_format_t * sox_open_read(char const *path, sox_signalinfo_t const *signal, sox_encodinginfo_t const *encoding, char const *filetype)
' Opens a decoding session for a file. returns the handle for the new session, or null on failure.
Private Extern sox_open_read(path As String, signal As Sox_signalinfo_t, encoding As sox_encodinginfo_t, filetype As String) As Pointer

' sox_format_t * sox_open_write(char const *path, sox_signalinfo_t const *signal, sox_encodinginfo_t const *encoding, char const *filetype, sox_oob_t const *oob, sox_bool(*overwrite_permitted)(const char *filename)
' Opens a decoding session for a file. returns the handle for the new session, or null on failure.
Private Extern sox_open_write(path As String, signal As Sox_signalinfo_t, encoding As Sox_encodinginfo_t, filetype As String, oob As Pointer, filename As String) As Pointer

' size_t sox_read(sox_format_t * ft, sox_sample_t *buf, size_t len)
' Reads samples from a decoding session into a sample buffer.
Private Extern sox_read(ft As Pointer, buf As Pointer, lenl As Long) As Long

' size_t sox_write(sox_format_t * ft, sox_sample_t const * buf, size_t len)
' Writes samples to an encoding session from a sample buffer.
Private Extern sox_write(ft As Pointer, buf As Pointer, lenl As Long) As Long

' int sox_close(sox_format_t * ft)
' Closes an encoding or decoding session. Returns SOX_SUCCESS if successful.
Private Extern sox_close(ft As Pointer) As Integer

' int sox_quit(void)
' Close effects library and unload format handler plugins. Returns SOX_SUCCESS if successful.
Private Extern sox_quit() As Integer


Public Sub Main()

 Dim fileAUDIO, nuovo_file As String
 Dim err As Integer
 Dim sfIn, sfOut As Pointer
 Dim sigIn, sigOut As New Sox_signalinfo_t
 Dim number_read As Long
 Dim samples As New Integer[MAX_SAMPLES]
 
  fileAUDIO = "/percorso/del/file/audio.wav"

' Poiché dal file audio esistente vogliamo creare un file audio di un altro formato,
' allora indicheremo il "percorso" ed il "formato" prescelto del file da creare:
  nuovo_file = "/tmp/audio.ogg"
  
' Inizializza la libreria "libsox":
  err = sox_init()
  If err <> SOX_SUCCESS Then Error.Raise("Impossibile inizializzare la libreria 'libsox' !")
  
  sfIn = sox_open_read(fileAUDIO, Null, Null, Null)
  If IsNull(sfIn) Then Error.Raise("Impossibile aprire il file audio !")
  
  sigIn = sfIn + 8
  
' Mostra alcune caratteristiche del file originario da convertire:
  With sigIn
    Print "File audio sorgente:        ", String@(Pointer@(sfIn))
    Print "Frequenza di campionamento: ", .rate; " hertz"
    Print "Canali:                     ", .channels
    Print "Risoluzione:                ", .precision; " bit"
    Print "Quantità dati audio:        ", .length * .channels; " byte"
    Print "Durata:                     ", CStr(Date(0, 0, 0, 0, 0, 0, (((.length * .channels) * 8) / (.rate * .channels * .precision)) * 1000))
  End With
  
  sfOut = sox_open_write(nuovo_file, sigIn, Null, Null, 0, Null)
  If IsNull(sfOut) Then Error.Raise("Impossibile aprire il nuovo file audio per la scrittura !")
  
  Do
    number_read = sox_read(sfIn, samples.Data, MAX_SAMPLES) 
    sox_write(sfOut, samples.Data, number_read)
  Loop Until number_read = 0
  
  
' Va in chiusura:
  sox_close(sfOut)
  sox_close(sfIn)
  sox_quit()
  
End



Riferimenti