Ridurre a 8-bit la risoluzione di campionamento di un file audio WAV con le funzioni esterne del API di Sox

Da Gambas-it.org - Wikipedia.
Versione del 17 feb 2016 alle 19:25 di Vuott (Discussione | contributi) (Creata pagina con "La libreria '''Sox''' contiene risorse per poter gestire ampiamente i file audio: riproduzione e registrazione, conversione di vari formati audio in altri formati, nonché app...")

(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)

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 il membro "encoding.encoding." della Struttura sox_format_t per il nuovo file con il valore della Costante SOX_ENCODING_UNSIGNED.


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


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:

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


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
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 IsNull(sfIn) Then Error.Raise("Impossibile aprire il file audio !")
 
  sigIn = sfIn + 8
  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
 
' Sostituiamo la necessaria funzione "memcpy()" di C, con le seguenti 5 righe:
  sfOut = Alloc(728)
  st = Memory sfOut For Write
  For s = 0 To 727
    Write #st, Byte@(sfIn + CInt(s)) As Byte
  Next
  st.Close

  
  encoOut = sfOut + 40
  With encoOut
    .encoding = SOX_ENCODING_UNSIGNED
    .bits_per_sample = 8
  End With
 
  sigOut = sfOut + 8
  With sigOut
    .rate = 8000
    .precision = 16
    .length = SOX_UNSPEC
  End With
  
' Impostiamo il "percorso" del nuovo file da creare:
  sfOut = sox_open_write("/percorso/del/nuovo/file/audio.wav", sigOut, encoOut, Null, 0, Null)
  If IsNull(sfOut) Then Error.Raise("Impossibile aprire il nuovo file audio per la scrittura !")
   
  encoIn = sfIn + 40
    
  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



Riferimenti