Differenze tra le versioni di "Ridurre a 8-bit la risoluzione di campionamento di un file audio WAV con le funzioni esterne del API di Sox"
(3 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
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. | 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 diminuire a 8-bit la risoluzione di campionamento di un file WAV, campionato ad esempio a 16-bit, bisognerà impostare con il valore della Costante ''SOX_ENCODING_UNSIGNED'' il membro "''->encoding.encoding''" della Struttura | + | Per poter diminuire a 8-bit la risoluzione di campionamento di un file WAV, campionato ad esempio a 16-bit, bisognerà impostare con il valore della Costante ''SOX_ENCODING_UNSIGNED'' il membro "''->encoding.encoding''" della Struttura ''sox_format_t'', relativa ai nuovi dati del nuovo file wav. |
− | |||
− | |||
− | |||
+ | E' necessario avere installata nel proprio sistema e richiamare in Gambas la libreria condivisa: "''libsox.so.3.0.0'' ". | ||
Mostriamo un esempio, nel quale un file di formato WAV a 16-bit, 44100 hertz, viene diminuita a 8-bit la risoluzione di campionamento e a 8000 hertz la frequenza di campionamento: | Mostriamo un esempio, nel quale un file di formato WAV a 16-bit, 44100 hertz, viene diminuita a 8-bit la risoluzione di campionamento e a 8000 hertz la frequenza di campionamento: | ||
+ | Library "libsox:3.0.0 | ||
+ | |||
Public Struct sox_signalinfo_t | Public Struct sox_signalinfo_t | ||
rate As Float | rate As Float | ||
Riga 71: | Riga 71: | ||
priv As Pointer | priv As Pointer | ||
End Struct | End Struct | ||
− | + | ||
− | |||
− | |||
− | |||
Private Enum SOX_EOF = -1, SOX_SUCCESS, SOX_EHDR = 2000, SOX_EFMT, SOX_ENOMEM, SOX_EPERM, SOX_ENOTSUP, SOX_EINVAL | Private Enum SOX_EOF = -1, SOX_SUCCESS, SOX_EHDR = 2000, SOX_EFMT, SOX_ENOMEM, SOX_EPERM, SOX_ENOTSUP, SOX_EINVAL | ||
Private Const SOX_ENCODING_UNSIGNED As Integer = 2 | Private Const SOX_ENCODING_UNSIGNED As Integer = 2 | ||
Riga 141: | Riga 138: | ||
Dim st As Stream | Dim st As Stream | ||
Dim s As Short | Dim s As Short | ||
− | + | ||
− | + | fileAUDIO = "<FONT Color=gray>''/percorso/del/file/audio.wav''</font>" | |
− | + | ||
<FONT Color=gray>' ''Inizializza la libreria "libsox":''</font> | <FONT Color=gray>' ''Inizializza la libreria "libsox":''</font> | ||
− | + | 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) | ||
+ | With sigIn | ||
+ | Print "File audio \e[31msorgente\e[0m: ", 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 | ||
+ | |||
+ | <FONT Color=gray>' ''Sostituisce la necessaria funzione "memcpy()" di C, con le seguenti 5 righe:''</font> | ||
+ | sfOut = Alloc(SizeOf(gb.Byte), 728) | ||
+ | st = Memory sfOut For Write | ||
+ | For s = 0 To 727 | ||
+ | Write #st, Byte@(sfIn + CInt(s)) As Byte | ||
+ | Next | ||
+ | st.Close | ||
+ | |||
+ | encoOut = sfOut + (SizeOf(gb.Pointer) * 5) | ||
+ | With encoOut | ||
+ | <FONT Color=#B22222>.encoding = SOX_ENCODING_UNSIGNED</font> | ||
+ | <FONT Color=#B22222>.bits_per_sample = 8</font> | ||
+ | End With | ||
+ | |||
+ | sigOut = sfOut + SizeOf(gb.Pointer) | ||
+ | With sigOut | ||
+ | <FONT Color=#B22222>.rate = 8000</font> | ||
+ | .precision = 16 | ||
+ | .length = SOX_UNSPEC | ||
+ | End With | ||
+ | |||
+ | Free(sfOut) | ||
+ | |||
+ | <FONT Color=gray>' ''Imposta il "percorso" del nuovo file da creare:''</font> | ||
+ | sfOut = sox_open_write("<FONT Color=gray>''/percorso/del/nuovo/file/audio.wav''</font>", sigOut, encoOut, Null, 0, Null) | ||
+ | If sfOut == 0 Then Error.Raise("Impossibile aprire il nuovo file audio per la scrittura !") | ||
+ | |||
+ | encoIn = sfIn + (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, sigIn) | ||
+ | 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' !") | |
− | + | eff.handler.flags = eff.handler.flags Or SOX_EFF_LENGTH | |
− | + | err = sox_add_effect(chain, eff, sigIn, sigOut) | |
− | + | If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_add_effect' !") | |
− | + | Endif | |
− | + | ||
+ | If sigIn.channels <> sigOut.channels Then | ||
+ | eff = sox_create_effect(sox_find_effect("channels")) | ||
+ | sox_effect_options(eff, 0, Null) | ||
+ | sox_add_effect(chain, eff, sigIn, sigOut) | ||
+ | Endif | ||
− | + | eff = sox_create_effect(sox_find_effect("output")) | |
− | + | argsP[0] = sfOut | |
− | + | sox_effect_options(eff, 1, argsP) | |
− | + | sox_add_effect(chain, eff, sigIn, sigOut) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<FONT Color=gray>' ''Esegue i dati audio:''</font> | <FONT Color=gray>' ''Esegue 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(sfIn) | |
− | + | sox_quit() | |
− | + | ||
'''End''' | '''End''' | ||
− | |||
Versione attuale delle 17:09, 16 ott 2022
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 diminuire a 8-bit la risoluzione di campionamento di un file WAV, campionato ad esempio a 16-bit, bisognerà impostare con il valore della Costante SOX_ENCODING_UNSIGNED il membro "->encoding.encoding" della Struttura sox_format_t, relativa ai nuovi dati del nuovo file wav.
E' necessario avere installata nel proprio sistema e richiamare in Gambas la libreria condivisa: "libsox.so.3.0.0 ".
Mostriamo un esempio, nel quale un file di formato WAV a 16-bit, 44100 hertz, viene diminuita a 8-bit la risoluzione di campionamento e a 8000 hertz la frequenza di campionamento:
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 Private Const SOX_ENCODING_UNSIGNED As Integer = 2 Private Const SOX_UNSPEC As Integer = 0 Private Const SOX_EFF_LENGTH As Integer = 8 ' 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. 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() 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] Dim st As Stream Dim s As Short fileAUDIO = "/percorso/del/file/audio.wav" ' 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) With sigIn Print "File audio \e[31msorgente\e[0m: ", 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 ' Sostituisce la necessaria funzione "memcpy()" di C, con le seguenti 5 righe: sfOut = Alloc(SizeOf(gb.Byte), 728) st = Memory sfOut For Write For s = 0 To 727 Write #st, Byte@(sfIn + CInt(s)) As Byte Next st.Close encoOut = sfOut + (SizeOf(gb.Pointer) * 5) With encoOut .encoding = SOX_ENCODING_UNSIGNED .bits_per_sample = 8 End With sigOut = sfOut + SizeOf(gb.Pointer) With sigOut .rate = 8000 .precision = 16 .length = SOX_UNSPEC End With Free(sfOut) ' Imposta il "percorso" del nuovo file da creare: sfOut = sox_open_write("/percorso/del/nuovo/file/audio.wav", sigOut, encoOut, Null, 0, Null) If sfOut == 0 Then Error.Raise("Impossibile aprire il nuovo file audio per la scrittura !") encoIn = sfIn + (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, sigIn) 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' !") eff.handler.flags = eff.handler.flags Or SOX_EFF_LENGTH err = sox_add_effect(chain, eff, sigIn, sigOut) If err <> SOX_SUCCESS Then Error.Raise("Errore nella funzione 'sox_add_effect' !") Endif If sigIn.channels <> sigOut.channels Then eff = sox_create_effect(sox_find_effect("channels")) sox_effect_options(eff, 0, Null) sox_add_effect(chain, eff, sigIn, sigOut) Endif eff = sox_create_effect(sox_find_effect("output")) argsP[0] = sfOut sox_effect_options(eff, 1, argsP) sox_add_effect(chain, eff, sigIn, sigOut) ' Esegue 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