Minimalistic MP3 decoder single header library

Overview

minimp3

Build Status Coverity Scan Build Status codecov

Minimalistic, single-header library for decoding MP3. minimp3 is designed to be small, fast (with SSE and NEON support), and accurate (ISO conformant). You can find a rough benchmark below, measured using perf on an i7-6700K, IO included, no CPU heat to address speedstep:

Vector Hz Samples Sec Clockticks Clockticks per second PSNR Max diff
compl.bit 48000 248832 5.184 14306684 2.759M 124.22 1
he_32khz.bit 32000 172800 5.4 8426158 1.560M 139.67 1
he_44khz.bit 44100 472320 10.710 21296300 1.988M 144.04 1
he_48khz.bit 48000 172800 3.6 8453846 2.348M 139.67 1
hecommon.bit 44100 69120 1.567 3169715 2.022M 133.93 1
he_free.bit 44100 156672 3.552 5798418 1.632M 137.48 1
he_mode.bit 44100 262656 5.955 9882314 1.659M 118.00 1
si.bit 44100 135936 3.082 7170520 2.326M 120.30 1
si_block.bit 44100 73728 1.671 4233136 2.533M 125.18 1
si_huff.bit 44100 86400 1.959 4785322 2.442M 107.98 1
sin1k0db.bit 44100 725760 16.457 24842977 1.509M 111.03 1

Conformance test passed on all vectors (PSNR > 96db).

Comparison with keyj's minimp3

Comparison by features:

Keyj minimp3 Current
Fixed point Floating point
source: 84kb 70kb
binary: 34kb (20kb compressed) 30kb (20kb)
no vector opts SSE/NEON intrinsics
no free format free format support

Below, you can find the benchmark and conformance test for keyj's minimp3:

Vector Hz Samples Sec Clockticks Clockticks per second PSNR Max diff
compl.bit 48000 248832 5.184 31849373 6.143M 71.50 41
he_32khz.bit 32000 172800 5.4 26302319 4.870M 71.63 24
he_44khz.bit 44100 472320 10.710 41628861 3.886M 71.63 24
he_48khz.bit 48000 172800 3.6 25899527 7.194M 71.63 24
hecommon.bit 44100 69120 1.567 20437779 13.039M 71.58 25
he_free.bit 44100 0 0 - - - -
he_mode.bit 44100 262656 5.955 30988984 5.203M 71.78 27
si.bit 44100 135936 3.082 24096223 7.817M 72.35 36
si_block.bit 44100 73728 1.671 20722017 12.394M 71.84 26
si_huff.bit 44100 86400 1.959 21121376 10.780M 27.80 65535
sin1k0db.bit 44100 730368 16.561 55569636 3.355M 0.15 58814

Keyj minimp3 conformance test fails on all vectors (PSNR < 96db), and free format is unsupported. This caused some problems when it was used here, and was the main motivation for this work.

Usage

First, we need to initialize the decoder structure:

//#define MINIMP3_ONLY_MP3
//#define MINIMP3_ONLY_SIMD
//#define MINIMP3_NO_SIMD
//#define MINIMP3_NONSTANDARD_BUT_LOGICAL
//#define MINIMP3_FLOAT_OUTPUT
#define MINIMP3_IMPLEMENTATION
#include "minimp3.h"
...
    static mp3dec_t mp3d;
    mp3dec_init(&mp3d);

Note that you must define MINIMP3_IMPLEMENTATION in exactly one source file. You can #include minimp3.h in as many files as you like. Also you can use MINIMP3_ONLY_MP3 define to strip MP1/MP2 decoding code. MINIMP3_ONLY_SIMD define controls generic (non SSE/NEON) code generation (always enabled on x64/arm64 targets). In case you do not want any platform-specific SIMD optimizations, you can define MINIMP3_NO_SIMD. MINIMP3_NONSTANDARD_BUT_LOGICAL define saves some code bytes, and enforces non-standard but logical behaviour of mono-stereo transition (rare case). MINIMP3_FLOAT_OUTPUT makes mp3dec_decode_frame() output to be float instead of short and additional function mp3dec_f32_to_s16 will be available for float->short conversion if needed.

Then. we decode the input stream frame-by-frame:

    /*typedef struct
    {
        int frame_bytes;
        int channels;
        int hz;
        int layer;
        int bitrate_kbps;
    } mp3dec_frame_info_t;*/
    mp3dec_frame_info_t info;
    short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
    /*unsigned char *input_buf; - input byte stream*/
    samples = mp3dec_decode_frame(&mp3d, input_buf, buf_size, pcm, &info);

The mp3dec_decode_frame() function decodes one full MP3 frame from the input buffer, which must be large enough to hold one full frame.

The decoder will analyze the input buffer to properly sync with the MP3 stream, and will skip ID3 data, as well as any data which is not valid. Short buffers may cause false sync and can produce 'squealing' artefacts. The bigger the size of the input buffer, the more reliable the sync procedure. We recommend having as many as 10 consecutive MP3 frames (~16KB) in the input buffer at a time.

At end of stream just pass rest of the buffer, sync procedure should work even with just 1 frame in stream (except for free format and garbage at the end can mess things up, so id3v1 and ape tags must be removed first).

For free format there minimum 3 frames needed to do proper sync: 2 frames to detect frame length and 1 next frame to check detect is good.

The size of the consumed MP3 data is returned in the mp3dec_frame_info_t field of the frame_bytes struct; you must remove the data corresponding to the frame_bytes field from the input buffer before the next decoder invocation.

The decoding function returns the number of decoded samples. The following cases are possible:

  • 0: No MP3 data was found in the input buffer
  • 384: Layer 1
  • 576: MPEG 2 Layer 3
  • 1152: Otherwise

The following is a description of the possible combinations of the number of samples and frame_bytes field values:

  • More than 0 samples and frame_bytes > 0: Succesful decode
  • 0 samples and frame_bytes > 0: The decoder skipped ID3 or invalid data
  • 0 samples and frame_bytes == 0: Insufficient data

If frame_bytes == 0, the other fields may be uninitialized or unchanged; if frame_bytes != 0, the other fields are available. The application may call mp3dec_init() when changing decode position, but this is not necessary.

As a special case, the decoder supports already split MP3 streams (for example, after doing an MP4 demux). In this case, the input buffer must contain exactly one non-free-format frame.

Seeking

You can seek to any byte in the stream and call mp3dec_decode_frame; this will work in almost all cases, but is not completely guaranteed. Probablility of sync procedure failure lowers when MAX_FRAME_SYNC_MATCHES value grows. Default MAX_FRAME_SYNC_MATCHES=10 and probablility of sync failure should be very low. If granule data is accidentally detected as a valid MP3 header, short audio artefacting is possible.

High-level mp3dec_ex_seek function supports precise seek to sample (MP3D_SEEK_TO_SAMPLE) using index and binary search.

Track length detect

If the file is known to be cbr, then all frames have equal size and lack ID3 tags, which allows us to decode the first frame and calculate all frame positions as frame_bytes * N. However, because of padding, frames can differ in size even in this case.

In general case whole stream scan is needed to calculate it's length. Scan can be omitted if vbr tag is present (added by encoders like lame and ffmpeg), which contains length info. High-level functions automatically use the vbr tag if present.

High-level API

If you need only decode file/buffer or use precise seek, you can use optional high-level API. Just #include minimp3_ex.h instead and use following additional functions:

#define MP3D_SEEK_TO_BYTE   0
#define MP3D_SEEK_TO_SAMPLE 1

#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */
#define MINIMP3_IO_SIZE (128*1024) /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */
#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */
#define MINIMP3_ENABLE_RING 0      /* enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */

#define MP3D_E_MEMORY  -1
#define MP3D_E_IOERROR -2

typedef struct
{
    mp3d_sample_t *buffer;
    size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */
    int channels, hz, layer, avg_bitrate_kbps;
} mp3dec_file_info_t;

typedef size_t (*MP3D_READ_CB)(void *buf, size_t size, void *user_data);
typedef int (*MP3D_SEEK_CB)(uint64_t position, void *user_data);

typedef struct
{
    MP3D_READ_CB read;
    void *read_data;
    MP3D_SEEK_CB seek;
    void *seek_data;
} mp3dec_io_t;

typedef struct
{
    uint64_t samples;
    mp3dec_frame_info_t info;
    int last_error;
    ...
} mp3dec_ex_t;

typedef int (*MP3D_ITERATE_CB)(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info);
typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info);

/* decode whole buffer block */
int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
/* iterate through frames */
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
/* streaming decoder with seeking capability */
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method);
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method);
void mp3dec_ex_close(mp3dec_ex_t *dec);
int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);
size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
#ifndef MINIMP3_NO_STDIO
/* stdio versions of file load, iterate and stream */
int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method);
#ifdef _WIN32
int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method);
#endif
#endif

Use MINIMP3_NO_STDIO define to exclude STDIO functions. MINIMP3_ALLOW_MONO_STEREO_TRANSITION allows mixing mono and stereo in same file. In that case mp3dec_frame_info_t->channels = 0 is reported on such files and correct channels number passed to progress_cb callback for each frame in mp3dec_frame_info_t structure. MP3D_PROGRESS_CB is optional and can be NULL, example of file decoding:

    mp3dec_t mp3d;
    mp3dec_file_info_t info;
    if (mp3dec_load(&mp3d, input_file_name, &info, NULL, NULL))
    {
        /* error */
    }
    /* mp3dec_file_info_t contains decoded samples and info,
       use free(info.buffer) to deallocate samples */

Example of file decoding with seek capability:

    mp3dec_ex_t dec;
    if (mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE))
    {
        /* error */
    }
    /* dec.samples, dec.info.hz, dec.info.layer, dec.info.channels should be filled */
    if (mp3dec_ex_seek(&dec, position))
    {
        /* error */
    }
    mp3d_sample_t *buffer = malloc(dec.samples*sizeof(mp3d_sample_t));
    size_t readed = mp3dec_ex_read(&dec, buffer, dec.samples);
    if (readed != dec.samples) /* normal eof or error condition */
    {
        if (dec.last_error)
        {
            /* error */
        }
    }

Bindings

Interesting links

Comments
  • Decoding of the first frame

    Decoding of the first frame

    When a frame following the first frame is decoded it uses the previous frame. How is the first frame decoded, and what is used instead of the previous frame?

    question 
    opened by ghost 69
  • Add some fuzzer lib test

    Add some fuzzer lib test

    As suggested here https://github.com/hajimehoshi/go-mp3/issues/23#issuecomment-364003179 http://lcamtuf.coredump.cx/afl/ https://github.com/google/fuzzer-test-suite/blob/master/tutorial/libFuzzerTutorial.md

    opened by lieff 23
  • How to remove extra delay samples?

    How to remove extra delay samples?

    If I encode wav file (with 87,840,000 samples) to mp3 with Lame then decode it with minimp3, I get extra samples (now 87,841,152) . If I decode with lame or ffmpeg I get the original number of samples back.

    Notably when decoding with lame I get

    input:  totalFile_t.mp3  (48 kHz, 2 channels, MPEG-1 Layer III)
    output: totalFile_t.wav  (16 bit, Microsoft WAVE)
    skipping initial 1105 samples (encoder+decoder delay)
    skipping final 47 samples (encoder padding-decoder delay)
    Frame# 76251/76251  128 kbps   MS
    

    When adding the samples skipped from the delays (1105 + 47), it matches the length of minimp3. How can I calculate the number of samples to skip at the beginning and end to get minimp3 to match the length of the original (ie the output of lame and ffmpeg)?

    question 
    opened by Cocalus 22
  • Consider using #ifndef-style include guards instead of #pragma once

    Consider using #ifndef-style include guards instead of #pragma once

    I'm trying out minimp3 in one of my projects and the use of #pragma once instead of #ifndef-style include guards is a bit annoying:

    1. For projects that are compiled as a single translation unit, #pragma once will not work when they need to keep the header and implementation sections separate (the header section will be included in one part, but due to #pragma once, the implementation section will never be able to be included in the same translation unit).
    2. In the project I'm working on, being able to detect minimp3 at compile time with something like #ifdef MINIMP3_H or something similar would be really useful. (At the moment I'm using #ifdef MINIMP3_MAX_SAMPLES_PER_FRAME which feels a bit silly...)

    Another quick note, it's not possible to compile minimp3 and stb_vorbis in the same translation unit because they both define an un-namespaced function called get_bits(). This is actually really inconvenient when writing a decoder abstraction and compiling as a single translation unit, which is what I'm working on.

    Thanks for your work on this project!

    opened by mackron 17
  • undefined behavior warning on arm with -mfpu=neon

    undefined behavior warning on arm with -mfpu=neon

    When building on armhf with -mfpu=neon using gcc 10.2, I get the following failure:

    In file included from minimp3_ex.h:9,
                     from minimp3_test.c:40:
    minimp3.h: In function ‘mp3dec_decode_frame’:
    minimp3.h:894:23: error: iteration 1073741823 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
    minimp3.h:892:5: note: within this loop
    

    This seems really puzzling... the loop it's referring to can never do more than 576 iterations. But perhaps it's talking about the loop after it's done structural transformations and there's an actual issue somewhere higher up? Either way, regardless of whether this is a minimp3 bug or a gcc bug, it's making me nervous.

    opened by mvduin 12
  • Finding accurate track length by iterating using input buffer

    Finding accurate track length by iterating using input buffer

    Hello,

    I haven't been using this library for very long so I am wondering if there is faster way to find track length than what I have done below. Currently it is way to slow to even be useful.

    while(1){
    		bytesread = 0;
    		samplesCount += mp3dec_decode_frame(&mp3d, (const uint8_t*) &input_data[0], MP3_BUF, 0, &info); 									
    		memmove(&input_data[0], &input_data[info.frame_bytes], (MP3_BUF - info.frame_bytes));      											
    		f_read(&FileRead, &input_data[MP3_BUF - info.frame_bytes], info.frame_bytes, (unsigned int*) &bytesread);  							
    		
    		if(bytesread == 0){																													
    			while(info.frame_bytes){																											
    				bufPos += info.frame_bytes;																										
    				samplesCount += mp3dec_decode_frame(&mp3d, (const uint8_t*) &input_data[bufPos], MP3_BUF - bufPos, 0, &info);					
    			}
    		}
    		if (info.frame_bytes <= 0) break;									
    	}
    	return samplesCount/info.hz;
    
    opened by rmsaad 10
  • Seeking issues

    Seeking issues

    Hello!

    There're no way to contact to author, so I have to use bugtracker for that:)

    I use my own mpeg stream parser, so minimp3 operates with (offset,size) pairs over the raw data. There's a some problem with mp3dec_decode_frame problem while seeking. It returns 0 samples with proper frame_bytes at the first non-sequential frame decoding. Next call over the same frame also gives the same result. BUT third call works well with glitchy sound at the beginning. Some additional information:

    1. there's memset(&scratch, 0, sizeof(scratch)); patch at the beginning of mp3dec_decode_frame - else valgrind warns about unitialized memory usage (but issue is reproduced even without this patch)
    2. mp3dec_init is called before non-sequential frame decoding (no change if removed)
    3. decoding over several frames' raw data (as recommended in readme) has no any effect

    Thank you for any help!

    opened by vitamin-caig 10
  • Add float32 output, rename original 16-bit output method

    Add float32 output, rename original 16-bit output method

    Wouldn't let me reopen the previous PR due to the force push to fix the broken commit. Anyway as I said, this should handle issue #26. mp3dec_decode_frame was changed to output "raw" floating-point samples (unclamped, without 16-bit quantization), and a new mp3dec_decode_frame_s16 method was added for 16-bit output, which should produce the same exact output as current. The test code was modified to simply use the 16-bit output function for identical behavior, rather than attempting more invasive changes to use 32-bit float.

    I haven't been able to test the NEON changes, but it should work.

    opened by kcat 9
  • miniaac?

    miniaac?

    Sorry, this is not an issue with minimp3 but I don't believe there is any other way to ask this question. I would like to use minimp3 on a project but there is no point unless AAC can be decoded as well. The FFmpeg source code for the AAC decoder looks a little terrifying and appears to be vastly more complex than minimp3 but then articles such as this one do not given this impression. So, I was wondering if anyone can answer these questions:

    1. Is decoding AAC actually much more complex than decoding mp3? And are the processing requirements (CPU, RAM, ROM) for decoding AAC much higher? (If so, then how much approximately?)
    2. Are there any small open source AAC decoders available or in the pipeline?
    3. Could minimp3 be extended to support AAC or is AAC too different?
    question 
    opened by incrediball 7
  • Get information about frame offset

    Get information about frame offset

    Hi there,

    Many thanks for the wonderful library.

    Would be great if you could allow getting the frame offset in 'mp3dec_decode_frame'

    My code changes:

    typedef struct
    {
    -    int frame_bytes, channels, hz, layer, bitrate_kbps;
    into->
    +    int frame_offset, frame_size, channels, hz, layer, bitrate_kbps; // ESENTHEL CHANGED
    } mp3dec_frame_info_t;
    
    -            info->frame_bytes = i;
    into
    +            info->frame_offset = i; // ESENTHEL CHANGED
    +           info->frame_size   = 0; // ESENTHEL CHANGED
    

    and finally:

    -    info->frame_bytes = i + frame_size;
    into
    +    info->frame_offset = i; // ESENTHEL CHANGED
    +    info->frame_size   = frame_size; // ESENTHEL CHANGED
    

    this allows to parse the MP3 first, remember each frame exact positions and sizes, so later when decoding, we can read only necesseary data, without having to rely on mp3d_find_frame iterating bytes, and possibly failing, because we've buffered only frame size, without the needed following data to properly detect the frame.

    opened by GregSlazinski 7
  • Not able to load valid(?) minimal mp3

    Not able to load valid(?) minimal mp3

    I'm trying to test a library I'm working on with a minimal generated mp3 with id3v2 tags: https://github.com/geokala/korama/blob/master/resources/test/library/ignored.mp3

    From looking at mp3 specs I believe the file to be a valid mp3, and it is treated as such by at least mpg123. The mp3 is tagged with ID3v2.

    However, it seems like minimp3 is failing to decode it- it gives the same output trying to parse it as it gives trying to parse minimp3's README.md.

    Is this a problem with the file, with the use of ID3v2 tags, or with minimp3?

    opened by geokala 6
  • Float decode out of range [-1, 1]

    Float decode out of range [-1, 1]

    Using

    #define MINIMP3_FLOAT_OUTPUT
    mp3dec_ex_open(MP3D_SEEK_TO_SAMPLE);
    mp3dec_ex_read();
    

    results in float samples that are outside the typical range of [-1, 1].

    Is this to be expected and to be trimmed/clipped by the user? Or is this a bug?

    Snippet from printing the out of range samples from the attached file:

    Sample -1.008740
    Sample -1.017203
    Sample -1.015058
    Sample 1.001051
    Sample 1.005223
    Sample 1.008936
    Sample 1.011510
    Sample 1.008202
    Sample -1.003591
    Sample -1.009071
    Sample -1.005774
    Sample 1.002314
    Sample -1.006699
    Sample -1.000278
    Sample -1.002885
    Sample 1.001274
    Sample 1.005011
    Sample -1.001993
    Sample -1.008192
    ....
    

    Sample file: 01m_40s__01m_50s.mp3.zip

    And thanks for writing this amazing piece of software!

    opened by szanni 0
  • Documentation for mp3dec_ex_read_frame()?

    Documentation for mp3dec_ex_read_frame()?

    It took me a while, but I'm finally updating my Rust bindings: https://github.com/mgeier/minimp3_ex-sys/pull/3

    While doing that, I didn't find any documentation of mp3dec_ex_read_frame() in the README.md.

    I think its usage is mostly clear from its similarity with mp3dec_ex_read(), but I'm wondering about the exact requirements for the frame_info parameter (which has been added in d86f4cbc9742c45b94cfb3e6cd86b951eeea7e5c).

    I understand that it has to be zero-initialized in the beginning, but does it have to be reset at any later point in time?

    Especially when seeking, should frame_info be reset after that or not?

    opened by mgeier 0
  • Seeking to 0 makes it impossible to read until end of file

    Seeking to 0 makes it impossible to read until end of file

    I'm using SFML https://github.com/SFML/SFML which in turn uses minimp3. Certain mp3 files fail to continue looping after the first loop.

    It looks like minimp3 stops returning the expected data until EOF after using mp3dec_ex_seek(dec, 0). This only happens on specific files. Due to never reaching the expected end, SFML inconveniently just stops playing audio altogether.

    Looking through the debugger, the "offset" member of the decoder object is incorrect after seeking to 0 vs when playing a new file from scratch. I've made a blind guess and moved position += dec->start_delay; after the if (0 == position) block and that seemed to have fixed it. But I practically have no understanding of what's going on and no time to dive more into it, so I'm not comfortable with making a pull request since I might be totally off the mark here.

    https://github.com/lieff/minimp3/blob/afb604c06bc8beb145fecd42c0ceb5bda8795144/minimp3_ex.h#L736

    I've attached an audio file from my users that experience this issue for repro:

    Feeling - Tung Wasabi (mp3cut.net).mp3.zip

    opened by Biohazard90 2
  • Add vcpkg installation instructions

    Add vcpkg installation instructions

    minimp3 is available as a port in vcpkg, a C++ library manager that simplifies installation for minimp3 and other project dependencies. Documenting the install process here will help users get started by providing a single set of commands to build minimp3, ready to be included in their projects.

    We also test whether our library ports build in various configurations (dynamic, static) on various platforms (OSX, Linux, Windows: x86, x64) to keep a wide coverage for users.

    I'm a maintainer for vcpkg, and here is what the port script looks like. We try to keep the library maintained as close as possible to the original library. :)

    opened by FrankXie05 0
  • Please help create a release tag in the latest location of the code.

    Please help create a release tag in the latest location of the code.

    Because some company policies require that open source software used must have a tag.

    I also hope you create a tag for the latest location of minimp4 (https://github.com/lieff/minimp4/)

    Thank you very much!

    opened by sinojelly 2
  • No method to free data allocated by mp3dec_load_buf

    No method to free data allocated by mp3dec_load_buf

    mp3dec_load_buf and mp3dec_load_cb allocate some data by making a call to malloc. There is no method for us to call to free that data.

    I wrote a small function for that.

    void mp3dec_free(mp3dec_file_info_t *info) 
    {
        free((void*)info->buffer);
    }
    
    opened by samhattangady 0
Owner
Lion
mov ax,0013h int 10h
Lion
Simple and Fast Multimedia Library

SFML — Simple and Fast Multimedia Library SFML is a simple, fast, cross-platform and object-oriented multimedia API. It provides access to windowing,

Simple and Fast Multimedia Library 8.3k Jan 8, 2023
TagLib Audio Meta-Data Library

TagLib TagLib Audio Metadata Library https://taglib.org/ TagLib is a library for reading and editing the metadata of several popular audio formats. Cu

TagLib 976 Jan 6, 2023
a library for audio and music analysis

aubio aubio is a library to label music and sounds. It listens to audio signals and attempts to detect events. For instance, when a drum is hit, at wh

aubio 2.9k Jan 1, 2023
PML is a simple, lightweight, easy to use multimedia library written in C.

PML is a simple, lightweight, easy to use multimedia library written in C. PML also works natively with C++, and bindings can be used/made to the native C code for other languages.

Fossbay 12 May 6, 2021
Minimalistic MP3 decoder single header library

minimp3 Minimalistic, single-header library for decoding MP3. minimp3 is designed to be small, fast (with SSE and NEON support), and accurate (ISO con

Lion 1.2k Jan 4, 2023
Minimalistic socket library inspired by Asio/Boost Asio, implemented in 1 single header file

cz-spas czspas (Small Portable Asynchronous Sockets) is minimalistic socket library inspired by Asio/Boost Asio, implemented in 1 single header file.

Rui Figueira 26 Nov 30, 2022
Minimalistic MP4 mux/demux single header library

Mini MP4 Easy embeddable MP4 mux/demux library. Usage Muxing Muxing can be done using 3 modes. Default mode uses one big mdat chunk: This is most effi

Lion 271 Dec 20, 2022
Cross platform C++11 library for decoding audio (mp3, wav, ogg, opus, flac, etc)

Libnyquist is a small C++11 library for reading sampled audio data from disk or memory. It is intended to be used an audio loading frontend for games, audio sequencers, music players, and more.

Dimitri Diakopoulos 442 Jan 2, 2023
A very simple example showing how to play mp3 files on the ESP32

ESP32 MP3 Player This repo contains a simple demonstration of how to play an MP3 file on the ESP32. You can configure the output to be either an I2S d

atomic14 38 Dec 23, 2022
MP3 Player/Organizer

I ♡ Music I ♡ Music is an MP3 player and organizer. It is designed for handling collections of albums in MP3 format, and it is very visual, attempting

Mattias Gustavsson 28 Dec 31, 2022
Wortuhr mit ESP8266 WeMos D1 mini und NeoPixel WS2812B LEDs mit mp3 Sounds, Animationen, Transitions, Events und Spiele

Wortuhr_ESP8266 Wortuhr mit ESP8266 WeMos D1 mini und NeoPixel WS2812B LEDs mit mp3 Sounds, Animationen, Transitions, Events und Spiele, Webzugriff So

null 25 Dec 22, 2022
JSON encoder/decoder in a single C file.

xJSON xJSON is a lightweight library that implements a JSON encoder, decoder and other utility functions. Usage To use xJSON, just add xjson.c and xjs

Francesco Cozzuto 4 Nov 1, 2022
A single file, single function, header to make notifications on the PS4 easier

Notifi Synopsis Adds a single function notifi(). It functions like printf however the first arg is the image to use (NULL and any invalid input should

Al Azif 9 Oct 4, 2022
Single-header single-function C/C++ immediate-mode camera for your graphics demos

Single-header single-function C/C++ immediate-mode camera for your graphics demos

Nicolas Guillemot 106 Oct 20, 2022
Single-header header-only C++11 / C++14 / C++17 library for easily managing set of auto-generated type-safe flags.

Single-header header-only C++11 / C++14 / C++17 library for easily managing set of auto-generated type-safe flags. Quick start #include <bitflags/bitf

Marin Peko 76 Nov 22, 2022
C XML Minimalistic Library (CXML) - An XML library for C with a focus on simplicity and ease of use.

cxml (C XML Minimalistic Library) is a powerful and flexible XML library for C with a focus on simplicity and ease of use, coupled with features that enables quick processing of XML documents.

null 29 Dec 26, 2022
Arduino PNG image decoder library

An 'embedded-friendly' (aka Arduino) PNG image decoding library

Larry Bank 102 Jan 6, 2023
A lean, efficient, accurate geohash encoder and decoder library implemented in C

Geohash encoder/decoder in C A lean, efficient, accurate geohash encoder and decoder library implemented in C. It does not depend on the C standard li

Christopher Wellons 20 Nov 20, 2022
Minimalistic C++/Python GUI library for OpenGL, GLES2/3, Metal, and WebAssembly/WebGL

NanoGUI NanoGUI is a minimalistic cross-platform widget library for OpenGL 3+, GLES 2/3, and Metal. It supports automatic layout generation, stateful

Mitsuba Physically Based Renderer 1.2k Dec 28, 2022
Minimalistic logging library with threads and manual callstacks

Minimalistic logging library with threads and manual callstacks

Sergey Kosarevsky 20 Dec 5, 2022