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

Da Gambas-it.org - Wikipedia.

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 condivisa: "libsox.so.3.0.0 ".

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:

 Library "libsox:3.0.0"
 
 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 
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 = "/percorso/del/nuovo/file/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 sfIn == 0 Then Error.Raise("Impossibile aprire il file audio !")
 
 sigIn = sfIn + SizeOf(gb.Pointer)
 
' 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:                     ", Str(Time(0, 0, 0, (((.length * .channels) * 8) / (.rate * .channels * .precision)) * 1000))
 End With
 
 sfOut = sox_open_write(nuovo_file, sigIn, Null, Null, 0, Null)
 If sfOut == 0 Then Error.Raise("Impossibile aprire il nuovo file audio per la scrittura !")

 Repeat
   number_read = sox_read(sfIn, samples.Data, MAX_SAMPLES) 
   sox_write(sfOut, samples.Data, number_read)
 Until number_read = 0
  
' Va in chiusura:
 sox_close(sfOut)
 sox_close(sfIn)
 sox_quit()
 
End


Riferimenti