Convertire un file audio mpeg in .wav con le funzioni esterne del API di mpg123
Da Gambas-it.org - Wikipedia.
Versione del 20 set 2013 alle 16:12 di Vuott (Discussione | contributi) (Creata pagina con 'Mostriamo un codice per convertire un file mpeg layers 1, 2 e 3 (ad esempio .mp3) in un file .wav mediante le funzioni esterne del API di '''mpg123''' e della libreria ''libsn...')
Mostriamo un codice per convertire un file mpeg layers 1, 2 e 3 (ad esempio .mp3) in un file .wav mediante le funzioni esterne del API di mpg123 e della libreria libsndfile.
E' necessario avere installato nel sistema le seguenti librerie: libmpg123.so.0.36.6 e libsndfile.so.1.0.25.
Il codice prevede, fra l'altro, anche un oggetto ListBox, nel quale verranno mostrate alcune informazioni inerenti al file .wav creato:
Public Struct SF_INFO frames As Long samplerate As Integer channels As Integer formatI As Integer sections As Integer seekable As Integer End Struct Private Const MPG123_OK As Byte = 0 Private Const MPG123_ERR As Short = -1 Private Const MPG123_DONE As Short = -12 Private Const MPG123_ADD_FLAGS As Byte = 2 Private Const MPG123_FORCE_FLOAT As Short = 1024 Private Const SF_FORMAT_WAV As Integer = 65536 ' Microsoft WAV format (little endian default) Private Const MPG123_ENC_SIGNED_16 As Byte = 208 Private Const SF_FORMAT_PCM_16 As Byte = 2 ' Signed 16 bit data Private Const SF_FORMAT_FLOAT As Byte = 6 ' 32 bit float data Private Const SFM_WRITE As Byte = 32 ' Modalità di apertura di un file Private percorsoFile As String Library "libmpg123:0.36.6" ' int mpg123_init (void) --> Function to initialise the mpg123 library. Private Extern mpg123_init() As Integer ' const char* mpg123_plain_strerror (int errcode) --> Return a string describing that error errcode means. Private Extern mpg123_plain_strerror(errcode As Integer) As String ' mpg123_handle *, mpg123_new (const char *decoder, int *error) --> Create a handle with optional choice of decoder (named by a string) Private Extern mpg123_new(decoder As String, errorI As Integer) As Pointer ' int mpg123_param (mpg123_handle * mh, Enum mpg123_parms type, long value, double fvalue) ' Set a specific parameter, For a specific mpg123_handle, using a parameter type key chosen From the mpg123_parms enumeration, To the specified value. Private Extern mpg123_param(mhP As Pointer, type As Integer, valueL As Long, fvalue As Float) As Integer ' int mpg123_open (mpg123_handle * mh, const char * path) --> Open and prepare to decode the specified file by filesystem path. This does not open HTTP urls. Private Extern mpg123_open(mhP As Pointer, pathFile As String) As Integer ' const char* mpg123_strerror (mpg123_handle * mh) --> Give string describing what error has occured in the context of handle mh. Private Extern mpg123_strerror(mhP As Pointer) As String ' int mpg123_getformat (mpg123_handle * mh, long * rate, Int * channels, Int * encoding) --> Get the current output format written to the addresses given. Private Extern mpg123_getformat(mhP As Pointer, ratP As Pointer, channP As Pointer, encodP As Pointer) As Integer ' int mpg123_format_none (mpg123_handle * mh) --> Configure a mpg123 handle to accept no output format at all, use before specifying supported formats with mpg123_format. Private Extern mpg123_format_none(mhP As Pointer) As Integer ' int mpg123_format (mpg123_handle * mh, long rate, Int channels, Int encodings) --> Set the audio Format support Of a mpg123_handle Private Extern mpg123_format(mhP As Pointer, ratInt As Integer, canali As Integer, encodInt As Integer) As Integer ' size_t mpg123_outblock (mpg123_handle * mh) --> The max size of one frame's decoded output with current settings. ' Use that to determine an appropriate minimum buffer size for decoding one frame. Private Extern mpg123_outblock(mhP As Pointer) As Integer ' int mpg123_read (mpg123_handle * mh, unsigned char * outmemory, size_t outmemsize, size_t * done) --> Read from stream and decode up to outmemsize bytes. Private Extern mpg123_read(mhP As Pointer, outmemory As Pointer, outmemsize As Integer, done As Pointer) As Integer ' int mpg123_encsize (int encoding) --> Return the size (in bytes) of one mono sample of the named encoding Private Extern mpg123_encsize(encodInt As Integer) As Integer ' int mpg123_close (mpg123_handle * mh) --> Closes the source, if libmpg123 opened it Private Extern mpg123_close(mhP As Pointer) As Integer ' void mpg123_delete (mpg123_handle * mh) --> Delete handle, mh is either a valid mpg123 handle or NULL Private Extern mpg123_delete(mhP As Pointer) ' void mpg123_exit (void) --> Function to close down the mpg123 library. Private Extern mpg123_exit() Library "libsndfile:1.0.25" ' int sf_close (SNDFILE *sndfile) --> Chiude il file precedentemente aperto. Private Extern sf_close(sndfile As Pointer) As Integer ' SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) --> Open the specified file for read, write or both. Private Extern sf_open(path As String, mode As Integer, sfinStru As SF_INFO) As Pointer ' sf_count_t sf_write_short (SNDFILE *sndfile, short *ptr, sf_count_t items) Private Extern sf_write_short(sndfile As Pointer, ptr As Pointer, items As Integer) As Integer ' sf_count_t sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t items) Private Extern sf_write_float(sndfile As Pointer, ptr As Pointer, items As Integer) As Integer ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Public Sub Button1_Click() ' decodifica Dim err, channels, encoding, buffer_size, more_samples, samples, done As Integer Dim rate As Long Dim mh, buffer, sndfile As Pointer Dim sfinfo As New SF_INFO err = mpg123_init() If err <> MPG123_OK Then Error.Raise("Configurazione di base errata ! " & mpg123_plain_strerror(err)) mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0) mh = mpg123_new(Null, 0) ' Apre il file mpeg in lettura: err = mpg123_open(mh, percorsoFile) If err <> MPG123_OK Then Error.Raise("Attenzione ! Problemi con 'mpg123': " & mpg123_strerror(mh)) mpg123_getformat(mh, VarPtr(rate), VarPtr(channels), VarPtr(encoding)) mpg123_format_none(mh) mpg123_format(mh, rate, channels, encoding) With sfinfo .samplerate = rate .channels = channels If encoding = MPG123_ENC_SIGNED_16 Then .formatI = SF_FORMAT_WAV Or SF_FORMAT_PCM_16 Else .formatI = SF_FORMAT_WAV Or SF_FORMAT_FLOAT Endif End With With ListBox1 .Clear .Add(" ******** Creazione del file WAV ********") .Add(Null) .Add("Nome: " & File.BaseName(percorsoFile) & ".wav") .Add("Canali = " & channels) .Add("Frequenza = " & rate & " Hz") End With ' Apre il file in scrittura: sndfile = sf_open(File.Dir(percorsoFile) &/ File.BaseName(percorsoFile) & ".wav", SFM_WRITE, sfinfo) buffer_size = mpg123_outblock(mh) buffer = Alloc(buffer_size) Do err = mpg123_read(mh, buffer, buffer_size, VarPtr(done)) If encoding And MPG123_ENC_SIGNED_16 Then more_samples = sf_write_short(sndfile, buffer, done / SizeOf(gb.Short)) Else more_samples = sf_write_float(sndfile, buffer, done / SizeOf(gb.Float)) Endif If (more_samples < 0) Or (more_samples * mpg123_encsize(encoding) <> done) Then Error.Raise("Attenzione: è stato scritto un numero di campioni che non corrisponde ai byte ottenuti da 'libmpg123': " & more_samples * mpg123_encsize(encoding) & " <> " & done) Endif samples += more_samples Loop While err = MPG123_OK If err <> MPG123_DONE Then If err = MPG123_ERR Error.Raise("Attenzione: decodifica terminata prematuramente ! " & mpg123_strerror(mh)) Else Error.Raise("Attenzione: decodifica terminata prematuramente ! " & mpg123_plain_strerror(err)) Endif Endif sf_close(sndfile) samples /= channels ListBox1.Add("Campioni audio scritti: " & samples) ' Chiude l'handle ed esce dalla libreria: mpg123_close(mh) mpg123_delete(mh) mpg123_exit() End