B4A Library [lib] liblame MP3 encoder/decoder

liblame MP3 encoder and decoder library for B4A
Here we have a fully functional stereo encoder and somewhat unpredictable decoder...

This B4A library wraps various pieces of 3rd party code that is all licenced under the LGPLv2:
  • liblame is the port of the C LAME library to Android.
  • libwave contains some helper classes required to load and save wav type files.
  • Lame4Android is a complete Android application that puts everything together.
The library is pretty simple to use, it adds a liblameDecoder object and a liblameEncoder object to your project:
  • liblameDecoder
    Events:
    • DecodeComplete(Success As Boolean)
    Methods:
    • Decode ()
      Start the decoding process.
      The event DecodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Decoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source mp3 and destination wav file names.
      Returns True on success, False on error.
  • liblameEncoder
    Events:
    • EncodeComplete(Success As Boolean)
    Methods:
    • Encode ()
      Start the encoding process.
      The event EncodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Encoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source wav and destination mp3 file names.
      The Encoder will default to Quality of Encoder.LAME_PRESET_DEFAULT.
      Returns True on success, False on error.
    • SetQuality (Quality As Int)
      Set the encoding quality.
      Choose from:
      Encoder.LAME_PRESET_DEFAULT
      Encoder.LAME_PRESET_MEDIUM
      Encoder.LAME_PRESET_STANDARD
      Encoder.LAME_PRESET_EXTREME

And some example code:

B4X:
'Activity module
Sub Process_Globals

End Sub

Sub Globals
   Dim DecodeButton, EncodeButton As Button
   Dim LameDecoder As liblameDecoder
   Dim LameEncoder As liblameEncoder
End Sub

Sub Activity_Create(FirstTime As Boolean)

   '   **   the example project does NOT contain file_to_encode.wav   **
   If File.Exists(File.DirRootExternal, "file_to_encode.wav")=False Then
      File.Copy(File.DirAssets, "file_to_encode.wav", File.DirRootExternal, "file_to_encode.wav")
   End If

   LameDecoder.Initialize("LameDecoder")
   LameEncoder.Initialize("LameEncoder")

   DecodeButton.Initialize("DecodeButton")
   DecodeButton.Text="Decoder test"
   Activity.AddView(DecodeButton, 0, 0, 100%x, 75dip)

   EncodeButton.Initialize("EncodeButton")
   EncodeButton.Text="Encoder test"
   Activity.AddView(EncodeButton, 0, 75dip, 100%x, 75dip)

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub DecodeButton_Click
   Log("liblame decoder test")

   If LameDecoder.SetFiles(File.Combine(File.DirRootExternal, "encoded_file.mp3"), File.Combine(File.DirRootExternal, "decoded_file.wav")) Then
      ProgressDialogShow2("Decoding...", False)
      LameDecoder.Decode
   Else
      Log("An error occurred while calling LameDecoder.SetFiles")
   End If
End Sub

Sub EncodeButton_Click
   Log("liblame encoder test")

   If LameEncoder.SetFiles(File.Combine(File.DirRootExternal, "file_to_encode.wav"), File.Combine(File.DirRootExternal, "encoded_file.mp3")) Then
      '   LameEncoder.SetQuality(LameEncoder.LAME_PRESET_STANDARD)   '   adjust to suit
      ProgressDialogShow2("Encoding...", False)
      LameEncoder.Encode
   Else
      Log("An error occurred while calling LameEncoder.SetFiles")
   End If
End Sub

Sub LameDecoder_DecodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Decode SUCCEEDED")
   Else
      Log("liblame Decode FAILED")
   End If
End Sub

Sub LameEncoder_EncodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Encode SUCCEEDED")
   Else
      Log("liblame Encode FAILED")
   End If
End Sub

The code copies a non-existent wav file from assets to external memory, to keep the attachment size down i have not included any wav file for you to test with.
Click the Encode button and wait while the wav file is encoded to mp3, you can then click the Decode button and wait while that mp3 file is decoded back to wav format.
Now you can compare the original wav file with the new wav file.
Read on...

The library has it's limits...

It encodes stereo 44100Hz 16 bit wav files to mp3 with no problems.
It decodes these encoded mp3s with no problems.

Encoding wav files with different sample rates and mono wav files generally produces the expected encoded mp3, but trying to decode that mp3 tends to fail, read on...

Decoding mp3s that have been encoded with a different encoder produces very unpredictable results.
Sometime the decoding simply adds or removes a few audio frames from the start or end of the decoded file - the decoder fails to take account of the true amount of frame padding that the mp3 has been encoded with.
The decoder assumes that the file to be decoded has been encoded with default LAME properties such as the amount of frame padding.
Sometimes the decoder produces a small wav file of random noise.
And on at one test file the decoded crashed with a memory error (segment fault) that occured in the native C code.

The liblame library was created for forum member Djembefola, and he has worked around these problems.
(Mainly by ensuring that all files to be decoded have originally been encoded with a compatible version of the original LAME encoder).

So i've made the library available to you all but please note that fixing the problems requires both a knowledge of C and also an understanding of the mp3 encoding and decoding processes - i have neither!
More technical info can be found on the official LAME FAQs web page.

Martin.
 

Attachments

  • liblame_v1.01.zip
    288.7 KB · Views: 1,042
Last edited:

Juzer Hussain

Active Member
Licensed User
Longtime User
liblame MP3 encoder and decoder library for B4A
Here we have a fully functional stereo encoder and somewhat unpredictable decoder...

This B4A library wraps various pieces of 3rd party code that is all licenced under the LGPLv2:
  • liblame is the port of the C LAME library to Android.
  • libwave contains some helper classes required to load and save wav type files.
  • Lame4Android is a complete Android application that puts everything together.
The library is pretty simple to use, it adds a liblameDecoder object and a liblameEncoder object to your project:
  • liblameDecoder
    Events:
    • DecodeComplete(Success As Boolean)
    Methods:
    • Decode ()
      Start the decoding process.
      The event DecodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Decoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source mp3 and destination wav file names.
      Returns True on success, False on error.
  • liblameEncoder
    Events:
    • EncodeComplete(Success As Boolean)
    Methods:
    • Encode ()
      Start the encoding process.
      The event EncodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Encoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source wav and destination mp3 file names.
      The Encoder will default to Quality of Encoder.LAME_PRESET_DEFAULT.
      Returns True on success, False on error.
    • SetQuality (Quality As Int)
      Set the encoding quality.
      Choose from:
      Encoder.LAME_PRESET_DEFAULT
      Encoder.LAME_PRESET_MEDIUM
      Encoder.LAME_PRESET_STANDARD
      Encoder.LAME_PRESET_EXTREME

And some example code:

B4X:
'Activity module
Sub Process_Globals

End Sub

Sub Globals
   Dim DecodeButton, EncodeButton As Button
   Dim LameDecoder As liblameDecoder
   Dim LameEncoder As liblameEncoder
End Sub

Sub Activity_Create(FirstTime As Boolean)

   '   **   the example project does NOT contain file_to_encode.wav   **
   If File.Exists(File.DirRootExternal, "file_to_encode.wav")=False Then
      File.Copy(File.DirAssets, "file_to_encode.wav", File.DirRootExternal, "file_to_encode.wav")
   End If

   LameDecoder.Initialize("LameDecoder")
   LameEncoder.Initialize("LameEncoder")

   DecodeButton.Initialize("DecodeButton")
   DecodeButton.Text="Decoder test"
   Activity.AddView(DecodeButton, 0, 0, 100%x, 75dip)

   EncodeButton.Initialize("EncodeButton")
   EncodeButton.Text="Encoder test"
   Activity.AddView(EncodeButton, 0, 75dip, 100%x, 75dip)

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub DecodeButton_Click
   Log("liblame decoder test")

   If LameDecoder.SetFiles(File.Combine(File.DirRootExternal, "encoded_file.mp3"), File.Combine(File.DirRootExternal, "decoded_file.wav")) Then
      ProgressDialogShow2("Decoding...", False)
      LameDecoder.Decode
   Else
      Log("An error occurred while calling LameDecoder.SetFiles")
   End If
End Sub

Sub EncodeButton_Click
   Log("liblame encoder test")

   If LameEncoder.SetFiles(File.Combine(File.DirRootExternal, "file_to_encode.wav"), File.Combine(File.DirRootExternal, "encoded_file.mp3")) Then
      '   LameEncoder.SetQuality(LameEncoder.LAME_PRESET_STANDARD)   '   adjust to suit
      ProgressDialogShow2("Encoding...", False)
      LameEncoder.Encode
   Else
      Log("An error occurred while calling LameEncoder.SetFiles")
   End If
End Sub

Sub LameDecoder_DecodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Decode SUCCEEDED")
   Else
      Log("liblame Decode FAILED")
   End If
End Sub

Sub LameEncoder_EncodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Encode SUCCEEDED")
   Else
      Log("liblame Encode FAILED")
   End If
End Sub

The code copies a non-existent wav file from assets to external memory, to keep the attachment size down i have not included any wav file for you to test with.
Click the Encode button and wait while the wav file is encoded to mp3, you can then click the Decode button and wait while that mp3 file is decoded back to wav format.
Now you can compare the original wav file with the new wav file.
Read on...

The library has it's limits...

It encodes stereo 44100Hz 16 bit wav files to mp3 with no problems.
It decodes these encoded mp3s with no problems.

Encoding wav files with different sample rates and mono wav files generally produces the expected encoded mp3, but trying to decode that mp3 tends to fail, read on...

Decoding mp3s that have been encoded with a different encoder produces very unpredictable results.
Sometime the decoding simply adds or removes a few audio frames from the start or end of the decoded file - the decoder fails to take account of the true amount of frame padding that the mp3 has been encoded with.
The decoder assumes that the file to be decoded has been encoded with default LAME properties such as the amount of frame padding.
Sometimes the decoder produces a small wav file of random noise.
And on at one test file the decoded crashed with a memory error (segment fault) that occured in the native C code.

The liblame library was created for forum member Djembefola, and he has worked around these problems.
(Mainly by ensuring that all files to be decoded have originally been encoded with a compatible version of the original LAME encoder).

So i've made the library available to you all but please note that fixing the problems requires both a knowledge of C and also an understanding of the mp3 encoding and decoding processes - i have neither!
More technical info can be found on the official LAME FAQs web page.

Martin.
liblame MP3 encoder and decoder library for B4A
Here we have a fully functional stereo encoder and somewhat unpredictable decoder...

This B4A library wraps various pieces of 3rd party code that is all licenced under the LGPLv2:
  • liblame is the port of the C LAME library to Android.
  • libwave contains some helper classes required to load and save wav type files.
  • Lame4Android is a complete Android application that puts everything together.
The library is pretty simple to use, it adds a liblameDecoder object and a liblameEncoder object to your project:
  • liblameDecoder
    Events:
    • DecodeComplete(Success As Boolean)
    Methods:
    • Decode ()
      Start the decoding process.
      The event DecodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Decoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source mp3 and destination wav file names.
      Returns True on success, False on error.
  • liblameEncoder
    Events:
    • EncodeComplete(Success As Boolean)
    Methods:
    • Encode ()
      Start the encoding process.
      The event EncodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Encoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source wav and destination mp3 file names.
      The Encoder will default to Quality of Encoder.LAME_PRESET_DEFAULT.
      Returns True on success, False on error.
    • SetQuality (Quality As Int)
      Set the encoding quality.
      Choose from:
      Encoder.LAME_PRESET_DEFAULT
      Encoder.LAME_PRESET_MEDIUM
      Encoder.LAME_PRESET_STANDARD
      Encoder.LAME_PRESET_EXTREME

And some example code:

B4X:
'Activity module
Sub Process_Globals

End Sub

Sub Globals
   Dim DecodeButton, EncodeButton As Button
   Dim LameDecoder As liblameDecoder
   Dim LameEncoder As liblameEncoder
End Sub

Sub Activity_Create(FirstTime As Boolean)

   '   **   the example project does NOT contain file_to_encode.wav   **
   If File.Exists(File.DirRootExternal, "file_to_encode.wav")=False Then
      File.Copy(File.DirAssets, "file_to_encode.wav", File.DirRootExternal, "file_to_encode.wav")
   End If

   LameDecoder.Initialize("LameDecoder")
   LameEncoder.Initialize("LameEncoder")

   DecodeButton.Initialize("DecodeButton")
   DecodeButton.Text="Decoder test"
   Activity.AddView(DecodeButton, 0, 0, 100%x, 75dip)

   EncodeButton.Initialize("EncodeButton")
   EncodeButton.Text="Encoder test"
   Activity.AddView(EncodeButton, 0, 75dip, 100%x, 75dip)

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub DecodeButton_Click
   Log("liblame decoder test")

   If LameDecoder.SetFiles(File.Combine(File.DirRootExternal, "encoded_file.mp3"), File.Combine(File.DirRootExternal, "decoded_file.wav")) Then
      ProgressDialogShow2("Decoding...", False)
      LameDecoder.Decode
   Else
      Log("An error occurred while calling LameDecoder.SetFiles")
   End If
End Sub

Sub EncodeButton_Click
   Log("liblame encoder test")

   If LameEncoder.SetFiles(File.Combine(File.DirRootExternal, "file_to_encode.wav"), File.Combine(File.DirRootExternal, "encoded_file.mp3")) Then
      '   LameEncoder.SetQuality(LameEncoder.LAME_PRESET_STANDARD)   '   adjust to suit
      ProgressDialogShow2("Encoding...", False)
      LameEncoder.Encode
   Else
      Log("An error occurred while calling LameEncoder.SetFiles")
   End If
End Sub

Sub LameDecoder_DecodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Decode SUCCEEDED")
   Else
      Log("liblame Decode FAILED")
   End If
End Sub

Sub LameEncoder_EncodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Encode SUCCEEDED")
   Else
      Log("liblame Encode FAILED")
   End If
End Sub

The code copies a non-existent wav file from assets to external memory, to keep the attachment size down i have not included any wav file for you to test with.
Click the Encode button and wait while the wav file is encoded to mp3, you can then click the Decode button and wait while that mp3 file is decoded back to wav format.
Now you can compare the original wav file with the new wav file.
Read on...

The library has it's limits...

It encodes stereo 44100Hz 16 bit wav files to mp3 with no problems.
It decodes these encoded mp3s with no problems.

Encoding wav files with different sample rates and mono wav files generally produces the expected encoded mp3, but trying to decode that mp3 tends to fail, read on...

Decoding mp3s that have been encoded with a different encoder produces very unpredictable results.
Sometime the decoding simply adds or removes a few audio frames from the start or end of the decoded file - the decoder fails to take account of the true amount of frame padding that the mp3 has been encoded with.
The decoder assumes that the file to be decoded has been encoded with default LAME properties such as the amount of frame padding.
Sometimes the decoder produces a small wav file of random noise.
And on at one test file the decoded crashed with a memory error (segment fault) that occured in the native C code.

The liblame library was created for forum member Djembefola, and he has worked around these problems.
(Mainly by ensuring that all files to be decoded have originally been encoded with a compatible version of the original LAME encoder).

So i've made the library available to you all but please note that fixing the problems requires both a knowledge of C and also an understanding of the mp3 encoding and decoding processes - i have neither!
More technical info can be found on the official LAME FAQs web page.

Martin.

Hi Martin,

Is there any update to this library for android version 8.1.1 and targetSDKver=26

Juzer
 

Albert Lin

Member
Licensed User
Longtime User
liblame MP3 encoder and decoder library for B4A
Here we have a fully functional stereo encoder and somewhat unpredictable decoder...

This B4A library wraps various pieces of 3rd party code that is all licenced under the LGPLv2:
  • liblame is the port of the C LAME library to Android.
  • libwave contains some helper classes required to load and save wav type files.
  • Lame4Android is a complete Android application that puts everything together.
The library is pretty simple to use, it adds a liblameDecoder object and a liblameEncoder object to your project:
  • liblameDecoder
    Events:
    • DecodeComplete(Success As Boolean)
  • Methods:
    • Decode ()
      Start the decoding process.
      The event DecodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Decoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source mp3 and destination wav file names.
      Returns True on success, False on error.
  • liblameEncoder
    Events:
    • EncodeComplete(Success As Boolean)
  • Methods:
    • Encode ()
      Start the encoding process.
      The event EncodeComplete(Success As Boolean) will be raised on completion.
    • Initialize (EventName As String)
      Initialize the Encoder with an event name.
    • IsInitialized As Boolean
    • SetFiles (InputFilename As String, OutputFilename As String) As Boolean
      Set the source wav and destination mp3 file names.
      The Encoder will default to Quality of Encoder.LAME_PRESET_DEFAULT.
      Returns True on success, False on error.
    • SetQuality (Quality As Int)
      Set the encoding quality.
      Choose from:
      Encoder.LAME_PRESET_DEFAULT
      Encoder.LAME_PRESET_MEDIUM
      Encoder.LAME_PRESET_STANDARD
      Encoder.LAME_PRESET_EXTREME

And some example code:

B4X:
'Activity module
Sub Process_Globals

End Sub

Sub Globals
   Dim DecodeButton, EncodeButton As Button
   Dim LameDecoder As liblameDecoder
   Dim LameEncoder As liblameEncoder
End Sub

Sub Activity_Create(FirstTime As Boolean)

   '   **   the example project does NOT contain file_to_encode.wav   **
   If File.Exists(File.DirRootExternal, "file_to_encode.wav")=False Then
      File.Copy(File.DirAssets, "file_to_encode.wav", File.DirRootExternal, "file_to_encode.wav")
   End If

   LameDecoder.Initialize("LameDecoder")
   LameEncoder.Initialize("LameEncoder")

   DecodeButton.Initialize("DecodeButton")
   DecodeButton.Text="Decoder test"
   Activity.AddView(DecodeButton, 0, 0, 100%x, 75dip)

   EncodeButton.Initialize("EncodeButton")
   EncodeButton.Text="Encoder test"
   Activity.AddView(EncodeButton, 0, 75dip, 100%x, 75dip)

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub DecodeButton_Click
   Log("liblame decoder test")

   If LameDecoder.SetFiles(File.Combine(File.DirRootExternal, "encoded_file.mp3"), File.Combine(File.DirRootExternal, "decoded_file.wav")) Then
      ProgressDialogShow2("Decoding...", False)
      LameDecoder.Decode
   Else
      Log("An error occurred while calling LameDecoder.SetFiles")
   End If
End Sub

Sub EncodeButton_Click
   Log("liblame encoder test")

   If LameEncoder.SetFiles(File.Combine(File.DirRootExternal, "file_to_encode.wav"), File.Combine(File.DirRootExternal, "encoded_file.mp3")) Then
      '   LameEncoder.SetQuality(LameEncoder.LAME_PRESET_STANDARD)   '   adjust to suit
      ProgressDialogShow2("Encoding...", False)
      LameEncoder.Encode
   Else
      Log("An error occurred while calling LameEncoder.SetFiles")
   End If
End Sub

Sub LameDecoder_DecodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Decode SUCCEEDED")
   Else
      Log("liblame Decode FAILED")
   End If
End Sub

Sub LameEncoder_EncodeComplete(Success As Boolean)
   ProgressDialogHide
   If Success Then
      Log("liblame Encode SUCCEEDED")
   Else
      Log("liblame Encode FAILED")
   End If
End Sub

The code copies a non-existent wav file from assets to external memory, to keep the attachment size down i have not included any wav file for you to test with.
Click the Encode button and wait while the wav file is encoded to mp3, you can then click the Decode button and wait while that mp3 file is decoded back to wav format.
Now you can compare the original wav file with the new wav file.
Read on...

The library has it's limits...

It encodes stereo 44100Hz 16 bit wav files to mp3 with no problems.
It decodes these encoded mp3s with no problems.

Encoding wav files with different sample rates and mono wav files generally produces the expected encoded mp3, but trying to decode that mp3 tends to fail, read on...

Decoding mp3s that have been encoded with a different encoder produces very unpredictable results.
Sometime the decoding simply adds or removes a few audio frames from the start or end of the decoded file - the decoder fails to take account of the true amount of frame padding that the mp3 has been encoded with.
The decoder assumes that the file to be decoded has been encoded with default LAME properties such as the amount of frame padding.
Sometimes the decoder produces a small wav file of random noise.
And on at one test file the decoded crashed with a memory error (segment fault) that occured in the native C code.

The liblame library was created for forum member Djembefola, and he has worked around these problems.
(Mainly by ensuring that all files to be decoded have originally been encoded with a compatible version of the original LAME encoder).

So i've made the library available to you all but please note that fixing the problems requires both a knowledge of C and also an understanding of the mp3 encoding and decoding processes - i have neither!
More technical info can be found on the official LAME FAQs web page.

Martin.
Hi Warwound
It's very nice of having this encoder. everything works good.
But I cause crash when encode .wav to .mp3 with API29.
It is fine with API22. Could you please tell me how to make it work with API29

All the best,
Albert Lin
 
Top