Differenze tra le versioni di "La gestione mediante le funzioni esterne dell'API di Lame"

Da Gambas-it.org - Wikipedia.
Riga 9: Riga 9:
  
  
Ne mostriamo di seguito un esempio:
+
Ne mostriamo di seguito un esempio per la conversione di un file wav a 44100 hertz, 16bit, 2 canali:
 
  Private Const PCM_SIZE As Short = 8192
 
  Private Const PCM_SIZE As Short = 8192
 
  Private Const MP3_SIZE As Short = 8192
 
  Private Const MP3_SIZE As Short = 8192
Riga 17: Riga 17:
 
  Library "libmp3lame:0.0.0"
 
  Library "libmp3lame:0.0.0"
 
   
 
   
  <FONT color=gray>' ''lame_global_flags lame_init()  --> initialize the encoder. sets default for all encoder parameters''</font>
+
  <FONT color=gray>' ''lame_global_flags lame_init()''
 +
  ' ''Initialize the encoder. sets default for all encoder parameters''</font>
 
  Private Extern lame_init() As Pointer
 
  Private Extern lame_init() As Pointer
 
   
 
   
  <FONT color=gray>' ''int lame_set_in_samplerate(lame_global_flags flags, int rate) --> input sample rate in Hz''</font>
+
  <FONT color=gray>' ''int lame_set_in_samplerate(lame_global_flags flags, int rate)''
 +
' ''Input sample rate in Hz''</font>
 
  Private Extern lame_set_in_samplerate(lame As Pointer, rate As Integer) As Integer
 
  Private Extern lame_set_in_samplerate(lame As Pointer, rate As Integer) As Integer
 
   
 
   
  <FONT color=gray>' ''int lame_set_brate(lame_global_flags flags, int brate) --> set one of bit-rate compression ratio.''</font>
+
  <FONT color=gray>' ''int lame_set_brate(lame_global_flags flags, int brate)''
 +
' ''Set one of bit-rate compression ratio.''</font>
 
  Private Extern lame_set_brate(lame As Pointer, brate As Integer) As Integer
 
  Private Extern lame_set_brate(lame As Pointer, brate As Integer) As Integer
 
   
 
   
  <FONT color=gray>' ''int lame_set_VBR(lame_global_flags flags, int vbr_mode)  --> Types of VBR.''</font>
+
  <FONT color=gray>' ''int lame_set_VBR(lame_global_flags flags, int vbr_mode)''
 +
  ' ''Types of VBR.''</font>
 
  Private Extern lame_set_VBR(lame As Pointer, vbr As Integer) As Integer
 
  Private Extern lame_set_VBR(lame As Pointer, vbr As Integer) As Integer
 
   
 
   
  <FONT color=gray>' ''int lame_init_params(lame_global_flags flags)  --> sets more internal configuration based On data provided above.returns - 1 If something failed.''</font>
+
  <FONT color=gray>' ''int lame_init_params(lame_global_flags flags)''
 +
  ' ''Sets more internal configuration based On data provided above.returns - 1 If something failed.''</font>
 
  Private Extern lame_init_params(lame As Pointer) As Integer
 
  Private Extern lame_init_params(lame As Pointer) As Integer
 
   
 
   
  <FONT color=gray>' ''size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) --> legge da filStr nmemb elementi, ciascuno di dimensione size.''
+
  <FONT color=gray>' ''size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)''
 +
' ''Legge da filStr nmemb elementi, ciascuno di dimensione size.''
 
  ' ''Gli elementi letti vengono immagazzinati nel buffer puntato da ptr che deve essere di dimensioni adeguate.''
 
  ' ''Gli elementi letti vengono immagazzinati nel buffer puntato da ptr che deve essere di dimensioni adeguate.''
 
  ' ''La funzione fread() ritorna il numero di elementi letti.''</font>
 
  ' ''La funzione fread() ritorna il numero di elementi letti.''</font>
Riga 42: Riga 48:
 
  Private Extern lame_encode_buffer_interleaved(lame As Pointer, pcm As Pointer, num_samples As Integer, mp3buf As Pointer, mp3buf_size As Integer) As Integer
 
  Private Extern lame_encode_buffer_interleaved(lame As Pointer, pcm As Pointer, num_samples As Integer, mp3buf As Pointer, mp3buf_size As Integer) As Integer
 
   
 
   
  <FONT color=gray>' ''int lame_encode_flush(lame_global_flags gfp, unsigned char* mp3buf, Int size)  --> lame_encode_flush will flush the intenal PCM buffers.''
+
  <FONT color=gray>' ''int lame_encode_flush(lame_global_flags gfp, unsigned char* mp3buf, Int size)''
 +
  ' ''lame_encode_flush will flush the intenal PCM buffers.''
 
  ' ''"mp3buf" should be at least 7200 bytes long to hold all possible emitted data.''</font>
 
  ' ''"mp3buf" should be at least 7200 bytes long to hold all possible emitted data.''</font>
 
  Private Extern lame_encode_flush(lame As Pointer, mp3buf As Pointer, size As Integer) As Integer
 
  Private Extern lame_encode_flush(lame As Pointer, mp3buf As Pointer, size As Integer) As Integer
 
    
 
    
  <FONT color=gray>' ''size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)  --> La funzione fwrite() scrive su filStr nmemb elementi, ciascuno di dimensione size.''
+
  <FONT color=gray>' ''size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)''
 +
  ' ''La funzione fwrite() scrive su filStr nmemb elementi, ciascuno di dimensione size.''
 
  ' ''Il primo elemento e' individuato dal puntatore ptr. La funzione fwrite() ritorna il numero di elementi scritti.''</font>
 
  ' ''Il primo elemento e' individuato dal puntatore ptr. La funzione fwrite() ritorna il numero di elementi scritti.''</font>
 
  Private Extern fwrite(ptr As Pointer, size As Integer, nmemb As Integer, filStr As Pointer) As Integer In "libc:6"
 
  Private Extern fwrite(ptr As Pointer, size As Integer, nmemb As Integer, filStr As Pointer) As Integer In "libc:6"
 
   
 
   
  <FONT color=gray>' ''int lame_close(lame_global_flags flags)  --> final call to fFree all remaining buffers.''</font>
+
  <FONT color=gray>' ''int lame_close(lame_global_flags flags)''
 +
  ' ''Final call to fFree all remaining buffers.''</font>
 
  Private Extern lame_close(lame As Pointer) As Integer
 
  Private Extern lame_close(lame As Pointer) As Integer
 
   
 
   
  <FONT color=gray>' ''FILE *fopen(const char *path, const char *mode)  --> La funzione fopen() apre il file path associandolo ad uno stream.''</font>
+
  <FONT color=gray>' ''FILE *fopen(const char *path, const char *mode)''
 +
  ' ''La funzione fopen() apre il file path associandolo ad uno stream.''</font>
 
  Private Extern fopen(path As String, mode As String) As Pointer In "libc:6"
 
  Private Extern fopen(path As String, mode As String) As Pointer In "libc:6"
 
   
 
   
  <FONT color=gray>' ''int fclose(FILE *stream)  --> La funzione fclose() chiude il file associato a "stream" durante l'apertura con "fopen()".''</font>
+
  <FONT color=gray>' ''int fclose(FILE *stream)''
 +
  ' ''La funzione fclose() chiude il file associato a "stream" durante l'apertura con "fopen()".''</font>
 
  Private Extern fclose(filStr As Pointer) As Integer In "libc:6"
 
  Private Extern fclose(filStr As Pointer) As Integer In "libc:6"
 
   
 
   
 
   
 
   
  '''Public''' Sub Button1_Click()
+
  '''Public''' Sub Main()
 
   
 
   
 
   Dim letto, scritto As Integer
 
   Dim letto, scritto As Integer
Riga 98: Riga 109:
 
   Loop While letto <> 0
 
   Loop While letto <> 0
 
   
 
   
  <FONT color=gray>' ''Chiude l'handle alla libreria e i due file:''</font>
+
  <FONT color=gray>' ''Libera le due aree allocate; chiude l'handle della libreria e i due file:''</font>
 +
  Free(pcm_buffer)
 +
  Free(mp3_buffer)
 
   lame_close(handle)
 
   lame_close(handle)
 
   fclose(mp3)
 
   fclose(mp3)

Versione delle 03:47, 20 ott 2014

LAME (LAME Ain't an Mp3 Encoder) è un codificatore MPEG Audio Layer III (mp3) di alta qualità rilasciato sotto licenza LGPL.


Convertire un file .wav in file mp3

Con le risorse dell'API di LAME è possibile realizzare facilmente un semplice applicativo capace di convertire un file audio .wav in un file audio mp3.

Innanzitutto in Gambas dovremo dichiarare la libreria condivisa .so, contenente le funzioni di LAME, che attualmente è "libmp3lame.so.0.0.0":

Library "libmp3lame:0.0.0"


Ne mostriamo di seguito un esempio per la conversione di un file wav a 44100 hertz, 16bit, 2 canali:

Private Const PCM_SIZE As Short = 8192
Private Const MP3_SIZE As Short = 8192
Private Const vbr_default As Byte = 4


Library "libmp3lame:0.0.0"

' lame_global_flags lame_init()
' Initialize the encoder. sets default for all encoder parameters
Private Extern lame_init() As Pointer

' int lame_set_in_samplerate(lame_global_flags flags, int rate)
' Input sample rate in Hz
Private Extern lame_set_in_samplerate(lame As Pointer, rate As Integer) As Integer

' int lame_set_brate(lame_global_flags flags, int brate)
' Set one of bit-rate compression ratio.
Private Extern lame_set_brate(lame As Pointer, brate As Integer) As Integer

' int lame_set_VBR(lame_global_flags flags, int vbr_mode)
' Types of VBR.
Private Extern lame_set_VBR(lame As Pointer, vbr As Integer) As Integer

' int lame_init_params(lame_global_flags flags)
' Sets more internal configuration based On data provided above.returns - 1 If something failed.
Private Extern lame_init_params(lame As Pointer) As Integer

' size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
' Legge da filStr nmemb elementi, ciascuno di dimensione size.
' Gli elementi letti vengono immagazzinati nel buffer puntato da ptr che deve essere di dimensioni adeguate.
' La funzione fread() ritorna il numero di elementi letti.
Private Extern fread(ptr As Pointer, size As Integer, nmemb As Integer, filStr As Pointer) As Integer In "libc:6"

' int lame_encode_buffer_interleaved(lame_global_flags gfp, byte[] pcm, int num_samples, byte[] mp3buf, int mp3buf_size)
' This is a convenience method using byte[] array instead of short[], the byte[] buffer used must be 2x the length of the analogous short[] version.
' Input has L & R channel data interleaved. NOTE: num_samples = number of samples in the L (or R) channel, not the total number of samples in pcm[]
Private Extern lame_encode_buffer_interleaved(lame As Pointer, pcm As Pointer, num_samples As Integer, mp3buf As Pointer, mp3buf_size As Integer) As Integer

' int lame_encode_flush(lame_global_flags gfp, unsigned char* mp3buf, Int size)
' lame_encode_flush will flush the intenal PCM buffers.
' "mp3buf" should be at least 7200 bytes long to hold all possible emitted data.
Private Extern lame_encode_flush(lame As Pointer, mp3buf As Pointer, size As Integer) As Integer
 
' size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
' La funzione fwrite() scrive su filStr nmemb elementi, ciascuno di dimensione size.
' Il primo elemento e' individuato dal puntatore ptr. La funzione fwrite() ritorna il numero di elementi scritti.
Private Extern fwrite(ptr As Pointer, size As Integer, nmemb As Integer, filStr As Pointer) As Integer In "libc:6"

' int lame_close(lame_global_flags flags)
' Final call to fFree all remaining buffers.
Private Extern lame_close(lame As Pointer) As Integer

' FILE *fopen(const char *path, const char *mode)
' La funzione fopen() apre il file path associandolo ad uno stream.
Private Extern fopen(path As String, mode As String) As Pointer In "libc:6"

' int fclose(FILE *stream)
' La funzione fclose() chiude il file associato a "stream" durante l'apertura con "fopen()".
Private Extern fclose(filStr As Pointer) As Integer In "libc:6"


Public Sub Main()

 Dim letto, scritto As Integer
 Dim pcm, mp3, handle, pcm_buffer, mp3_buffer As Pointer


  pcm_buffer = Alloc(PCM_SIZE * 4)
  mp3_buffer = Alloc(MP3_SIZE)

  pcm = fopen("percorso_del_file.wav", "rb")
  mp3 = fopen("percorso_del_file.mp3", "wb")

' La libreria va innanzitutto inizializzata:
  handle = lame_init()

' L'inizializzazione imposta i parametri con valori predefiniti.
' E' possibile modificare tali valori con apposite funzioni del tipo "lame_set_*()":
  lame_set_in_samplerate(handle, 44100)
  lame_set_brate(handle, 128)
  lame_set_VBR(handle, vbr_default)
   
' Dopo aver impostato i parametri, si controlla che tutto sia a posto mediante la funzione:
  lame_init_params(handle)
 
  Do

' Si legge dal file .wav:
     letto = fread(pcm_buffer, 2 * SizeOf(gb.Short), PCM_SIZE, pcm)
     If letto = 0 Then
       scritto = lame_encode_flush(handle, mp3_buffer, MP3_SIZE)
     Else
       scritto = lame_encode_buffer_interleaved(handle, pcm_buffer, letto, mp3_buffer, MP3_SIZE)
' Si scrivono i dati codificati in mpeg nel file di destinazione:
       fwrite(mp3_buffer, scritto, 1, mp3)
     Endif      

  Loop While letto <> 0

' Libera le due aree allocate; chiude l'handle della libreria e i due file:
  Free(pcm_buffer)
  Free(mp3_buffer)
  lame_close(handle)
  fclose(mp3)
  fclose(pcm)

End


Nello stesso esempio potremo ridurre le funzioni a quelle sole strettamente appartenenti all'API di LAME:

Private Const vbr_default As Byte = 4


Library "libmp3lame:0.0.0"

' lame_global_flags lame_init()
Private Extern lame_init() As Pointer

' int lame_set_in_samplerate(lame_global_flags flags, int rate)
Private Extern lame_set_in_samplerate(lame As Pointer, rate As Integer) As Integer

' int lame_set_brate(lame_global_flags flags, int brate)
Private Extern lame_set_brate(lame As Pointer, brate As Integer) As Integer

' int lame_set_VBR(lame_global_flags flags, int vbr_mode)
Private Extern lame_set_VBR(lame As Pointer, vbr As Integer) As Integer

' int lame_init_params(lame_global_flags flags)
Private Extern lame_init_params(lame As Pointer) As Integer
 
' int lame_encode_buffer_interleaved(lame_global_flags gfp, byte[] pcm, int num_samples, byte[] mp3buf, int mp3buf_size)
Private Extern lame_encode_buffer_interleaved(lame As Pointer, pcm As Byte[], num_samples As Integer, mp3buf As Byte[], mp3buf_size As Integer) As Integer

' int lame_encode_flush(lame_global_flags gfp, unsigned char* mp3buf, Int size)
Private Extern lame_encode_flush(lame As Pointer, mp3buf As Byte[], size As Integer) As Integer

' int lame_close(lame_global_flags flags)
Private Extern lame_close(lame As Pointer) As Integer
 

Public Sub Button1_Click()

 Dim handle As Pointer
 Dim pcm, mp3 As File
 Dim percorsoFile As String = "/percorso/del/file.wav"
 Dim scritto, i, campioni, dimensione As Integer
 Dim pcm_buffer As New Byte[]
 Dim mp3_buffer As Byte[]
 Dim k, b As Byte


  pcm = Open percorsoFile For Read
  mp3 = Open "/percorso/del/nuovo/file.mp3" For Create

  dimensione = CInt(Stat(percorsoFile).Size)

  mp3_buffer = New Byte[dimensione]

  campioni = dimensione \ 4

' Il decodificatore necessita di essere inizializzato:
   handle = lame_init()

' L'inizializzazione imposta i parametri con valori predefiniti.
' E' possibile modificare tali valori con apposite funzioni del tipo "lame_set_*()":
   lame_set_in_samplerate(handle, 44100)
   lame_set_brate(handle, 128)
   lame_set_VBR(handle, vbr_default)

' Dopo aver impostato i parametri, si controlla che tutto sia a posto mediante la funzione:
   lame_init_params(handle)

  While Not Eof(pcm)
    Read #pcm, i
    pcm_buffer.Add(i)
  Wend

   scritto = lame_encode_buffer_interleaved(handle, pcm_buffer, campioni, mp3_buffer, dimensione)

  While b < scritto
    k = mp3_buffer[b]
    Write #mp3, k As Byte
    Inc b
  Wend

   scritto = lame_encode_flush(handle, mp3_buffer, dimensione)

' Chiude l'handle alla libreria e i due file:
   lame_close(handle)
   
   mp3.Close
   
   pcm.Close

End


Riferimenti