B4A Library Mp3 converter and decoder - play an MP3 with AudioTrack

Discussion in 'Additional libraries, classes and official updates' started by stevel05, Nov 8, 2013.

  1. stevel05

    stevel05 Expert Licensed User

    Here is an MP3 converter / decoder library based on jLayer which is released under the LGPL license see the link for requirements.

    The library is in two parts:

    A converter that will convert an MP3 file to a WAV file, the resulting file specifications are determined from the source file. It is common that non 44100Hz stereo WAV files fail to play on android devices. If a converted file won't play it is likely that the original source file was not 44100Hz stereo. This library does not allow modifications to the sample rate or number of channels. I haven't tested it's speed against warwounds liblame decoder, I expect that the jlayer converter will be slower, but it's here for completeness as it's in the jLayer library.

    A decoder which converts the MP3 by MP3 frames that can be stored in a byte array which allows the results to be streamed to AudioTrack for playing. The decoder returns PCM stereo samples so you could also recreate a WAV file with the appropriate header file.

    The attached demo shows one method for streaming the MP3 using AudioTrack. This is by neccessity CPU intensive and may not work well on older devices. I have tested it on a Sony Experia SP which handles it very well, and an older Stealth Hydro Tablet which seems to provide acceptable performance.

    Library documentation:

    SLMP3
    Author:
    Steve Laming
    Version: 1.2
    • SLConvertMP3
      Events:
      • Finished
      Methods:
      • Convert (eventName As String, sourceFile As String, destFile As String)
        Convert sourcefile(MP3) to destfile (WAV)
    • SLStreamMP3
      Methods:
      • GetNoChannels As Int
      • GetSampleFrequency As Int
      • Initialize (inpStream As InputStream)
        Initialize to read from inpStream
      • Initialize2 (inpStream As InputStream, startMs As Long, endMs As Long)
        Initialize to read from inpStream
        And positions at the first frame in inpstream to be decoded and streamed
        The decoder works on frames so the ms times returned may not be exact
      • SeekTo (seekPos As Long)
        Seek to seekPos, it will only seek forwards.
        See the demo app for how to seek backwards.
      • Stream (noFrames As Int) As Byte[]
        Return the output from the next decoded noFrames
      • currPos As Float
        get the current play position in ms

    Xml Document converted with warwounds B4A library reference generator

    The decoding processes are blocking, so should be run in a separate thread.

    Uncompressed audio files can be huge, the SLByteArrayBuffer is used to allow constant resizing of the buffer to stop it growing too large and causing out of memory errors.

    Streaming

    There are two options for streaming a file, from the beginning to the end (Initialize), or by time (Initialize2) specifying a start and end time in milliseconds. As the decoder works in frames the played times may not be totally accurate, but to the nearest frame, this will probably be unnoticable in most scenarios.

    For the streaming itself, it is possible to set the number of frames that the encoder will process in a single call. This needs to be fairly low as once the AudioTrack starts playing it needs a constant flow of data to play glitch free. To reduce the memory usage, the output buffer is managed and limited to a size of 200000 bytes.

    The Demo

    The demo app shows both streaming options which simply use alternative initialization methods.

    An input stream is required to feed the decoder, the demo reads the MP3 file into an array and creates the input stream from there. MP3 files are not normally that large and most songs should not provide an array that is too large. if you have problems using large MP3 files an alternative method of creating the inputstream may be required.

    Seek

    V1.2 of the library introduces a seekTo, this only seeks forward from the current play point.
    V1.1 of the demo implements a seek back by re-initializing the file then calling seekTo with an imperceptible delay. It may be noticeable on very large files if the seek is near the end.

    Demo Requirements:

    mp3streams

    Mp3test

    • SLMP3Library
    Usage

    Download and unzip the xml and jar files to your additional libraries directory.

    For the demo: ensure that the required libraries (see above) are installed and selected.

    SLMP3 V1.0 superseded.
    SLMP3 V1.1 superseded.
    • MP3 convert now runs in an async stream so you don't need to run it in a thread.
    • Added _Finished callback.

    SLMP3 V1.2 attached. - Added methods to GetSampleFrequency and GetNoChannels from the decoder and SeekTo.


    mp3streamdemo V1.1 attached:
    Updated demo to allow skipping of the MP3. and get SampleRate and
    no channels from the decoder.​

    Mp3Test V1.0 attached

    10/11/2013 SLMP3 updated removed documentation errors.
     

    Attached Files:

    Last edited: Jul 30, 2014
  2. stevel05

    stevel05 Expert Licensed User

    Updated lib to V1.1 Now runs convert in an async stream, you don't need to run it in a thread and added Finished event.

    Added a demo (MP3Test,zip) for this.
     
    Douglas Farias likes this.
  3. stevel05

    stevel05 Expert Licensed User

    Updated Lib to V1.2 added three methods to return SampleRate and no of channels, and allow Skip Forward.
     
    Douglas Farias and Theera like this.
  4. aloof

    aloof Member Licensed User

    Hi mate, do you allow paid apps with your code? the LGPL seems like a grey area.. havent really done it before
     
  5. stevel05

    stevel05 Expert Licensed User

    Hi,

    My code is just a wrapper for jLayer, as with all my libraries, there is no restriction for use on my part. You'll still need to check that your use is in line with the license of the base library in this case jLayer and LGPL. I haven't used it in a commercial app myself, perhaps someone on the forum has experience of LGPL and can advise, or point you in the right direction.
     
    Erel likes this.
  6. stari

    stari Active Member Licensed User

    Hi, i try to play, but i get error: Sub doconvert not found. Sugestion ?
     
Loading...