Convertire un file audio mpeg in .wav con le funzioni esterne del API di mpg123
Da Gambas-it.org - Wikipedia.
Versione del 13 gen 2024 alle 17:05 di Vuott (Discussione | contributi)
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.48.1 " e libsndfile.so.1.0.37.
Il codice prevede, fra l'altro, anche un oggetto ListBox, nel quale verranno mostrate alcune informazioni inerenti al file .wav creato:
Library "libmpg123:0.48.1" 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 ' 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, perror As Pointer) 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. 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.37" Public Struct SF_INFO frames As Long samplerate As Integer channels As Integer formatI As Integer sections As Integer seekable As Integer End Struct ' 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) ' Writes the data chunk in terms of 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) ' Writes the data chunk in terms of items. Private Extern sf_write_float(sndfile As Pointer, ptr As Pointer, items As Integer) As Integer ' int sf_close (SNDFILE *sndfile) ' Close the SNDFILE and clean up all memory allocations associated with this file. Private Extern sf_close(sndfile As Pointer) As Integer Public Sub Main() Dim mp3 As String Dim err, channels, encoding, buffer_size As Integer Dim more_samples, samples, done As Integer Dim rate As Long Dim mh, buffer, sndfile As Pointer Dim sfinfo As New SF_INFO mp3 = "/percorso/del/file.mp3" 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, mp3) 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(mp3) & ".wav") .Add("Canali = " & channels) .Add("Frequenza = " & rate & " Hz") End With ' Apre il file in scrittura: sndfile = sf_open(File.Dir(mp3) &/ File.BaseName(mp3) & ".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) ' Libera la memoria sinora occupata ed esce dalla libreria: Free(buffer) mpg123_close(mh) mpg123_delete(mh) mpg123_exit() End