Eseguire un file audio mediante 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 ".
Nel caso di esecuzione di un file audio bisognerà avere cura di individuare nella funzione "sox_open_write()" il dispositivo audio (ad esempio ALSA ).
Mostriamo un esempio, il cui codice prevede l'esecuzione di un file audio e la preventiva diminuzione del volume:
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 Public Struct sox_effects_globals_t 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 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 ' sox_effects_chain_t * sox_create_effects_chain(sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc) ' Initializes an effects chain. Private Extern sox_create_effects_chain(in_enc As Sox_encodinginfo_t, out_enc As Sox_encodinginfo_t) As Sox_effects_chain_t ' sox_effect_t * sox_create_effect(sox_effect_handler_t const * eh) ' Creates an effect using the given handler. Private Extern sox_create_effect(eh As Sox_effect_handler_t) As Sox_effect_t ' sox_effect_handler_t const * sox_find_effect(char const * name) ' Finds the effect handler with the given name. Private Extern sox_find_effect(name As String) As Pointer ' int sox_effect_options(sox_effect_t *effp, int argc, char * const argv[]) ' Applies the command-line options to the effect. Private Extern sox_effect_options(effp As Sox_effect_t, argc As Integer, argv As Pointer[]) As Integer ' 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. 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 ' 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. Private Extern sox_flow_effects(chain As Sox_effects_chain_t, callback As Pointer, client_data As Pointer) As Integer ' void sox_delete_effects_chain(sox_effects_chain_t *ecp) ' Closes an effects chain. Private Extern sox_delete_effects_chain(chain As Sox_effects_chain_t) ' 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) ' sox_quit(void) ' Close effects library and unload format handler plugins. Returns SOX_SUCCESS if successful. Private Extern sox_quit() Public Sub Main() Dim fileAUDIO As String Dim err As Integer Dim sfIn, sfOut As Pointer Dim sigIn, sigOut As New Sox_signalinfo_t Dim encoIn, encoOut As New Sox_encodinginfo_t Dim chain As Sox_effects_chain_t Dim eff As New Sox_effect_t Dim argsP As New Pointer[10] fileAUDIO = "/percorso/del/file/audio" ' 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 + 8 With sigIn Print "File audio: ", 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 ' Poiché vogliamo eseguire il file audio, allora scriveremo i dati in ALSA nel modo seguente: sfOut = sox_open_write("default", sigIn, Null, "alsa", 0, Null) If sfOut == 0 Then Error.Raise("Impossibile scrivere i dati audio !") sigOut = sfOut + SizeOf(gb.Pointer) encoIn = sfIn + (SizeOf(gb.Pointer) * 5) encoOut = sfOut + (SizeOf(gb.Pointer) * 5) chain = sox_create_effects_chain(encoIn, encoOut) eff = sox_create_effect(sox_find_effect("input")) 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 ' Crea l'effetto "Volume", lo inizializza con il parametro desiderato: eff = sox_create_effect(sox_find_effect("vol")) ' Diminuisce il volume d'ascolto assegnando il valore "-12dB": 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' !") ' Esegue il i dati audio: sox_flow_effects(chain, Null, Null) ' Va in chiusura: Free(argsP.Data) sox_delete_effects_chain(chain) sox_close(sfOut) sox_close(sfIn) sox_quit() End