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

Issues
  • 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
  • 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 0
  • 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
  • Don't enable ARMv6 features for ARMv6-m

    Don't enable ARMv6 features for ARMv6-m

    The existing check for ARMv6 and greater matches on ARMv6-m. This causes build failures on cortex-m0 and cortex-m0+ as they do not support the ssat instruction.

    This is what the problematic code in minimp3.h looks like:

    #if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64)
    #define HAVE_ARMV6 1
    static __inline__ __attribute__((always_inline)) int32_t minimp3_clip_int16_arm(int32_t a)
    {
        int32_t x = 0;
        __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a));
        return x;
    }
    #else
    #define HAVE_ARMV6 0
    #endif
    

    when compiled for -armv6-m or -armv6s-m you get

    $ arm-none-eabi-gcc -O3  -ffunction-sections -fdata-sections -g -fno-omit-frame-pointer -mthumb -march=armv6s-m -I minimp3 -Wall -Wextra -DMINIMP3_NO_SIMD -DMINIMP3_ONLY_MP3 -DMINIMP3_IMPLEMENTATION -o /home/9names/soundtest/minimp3/minimp3.o -c minimp3/minimp3.c
    /tmp/ccsTu1My.s: Assembler messages:
    /tmp/ccsTu1My.s:3095: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:3284: Error: selected processor does not support `ssat r3,#16,r3' in Thumb mode
    /tmp/ccsTu1My.s:18200: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:18565: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:18920: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:19279: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:19635: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:19989: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:20341: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    /tmp/ccsTu1My.s:20699: Error: selected processor does not support `ssat r0,#16,r0' in Thumb mode
    
    selected processor does not support `ssat r0,#16,r0' in Thumb mode
    

    Adding the additional check that __ARM_ARCH_6M__ is not present in the #ifdef chain solves this issue, and as this is only present on cortex-m0/cortex-m0+ processors it should not break any other targets.

    opened by 9names 0
  • Eliminated warnings in Visual Studio 2019.

    Eliminated warnings in Visual Studio 2019.

    The Microsoft C/C++ compiler warned about possibly writing too much memory in lines like this:

    memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
    

    Although the code is correct, it confuses the compiler into thinking more memory is being zeroed out than intended. scratch.grbuf[0] holds only half as many bytes as scratch.grbuf, but the code intends to zero out the entire array, not just the first half.

    Replaced with identical code that eliminates the warning:

    memset(scratch.grbuf, 0, sizeof(scratch.grbuf));
    

    This is also easier to understand and verify as correct.

    opened by cosinekitty 0
  • CC0-1.0 Patents

    CC0-1.0 Patents

    Hi, are there any patents included in the minimp3 library? I am asking because the CC0-1.0 does not provide rights for patents and if some are included it might prevent us to use it. See also: https://wiki.creativecommons.org/wiki/CC0_FAQ

    It would be nice if you could add a statement somewhere in the README about it!

    Thanks!

    opened by dsciarra 1
  • MP3解码出现bug

    MP3解码出现bug

    本人使用 int mp3dec_decode_frame(mp3dec_t *dec, const unsigned char *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info) ; 函数是出现Bus error (core dumped) 。使用的平台是rv1109 的开发板。 请问有什么解决办法吗

    opened by lisMy521 1
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 7.9k Aug 8, 2022
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 934 Aug 3, 2022
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.8k Jul 31, 2022
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 Aug 6, 2022
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 25 Jun 12, 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 247 Aug 5, 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 406 Jul 29, 2022
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 25 Jul 15, 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 25 Jun 23, 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 24 Jul 11, 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 2 Apr 26, 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 7 Mar 24, 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 107 Apr 28, 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 71 Jul 30, 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 28 Feb 11, 2022
Arduino PNG image decoder library

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

Larry Bank 91 Jun 24, 2022
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 18 May 30, 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.1k Aug 8, 2022
Minimalistic logging library with threads and manual callstacks

Minimalistic logging library with threads and manual callstacks

Sergey Kosarevsky 21 Jun 24, 2022
Minimalistic GUI library for OpenGL

NanoGUI NanoGUI is a minimalistic cross-platform widget library for OpenGL 3.x or higher. It supports automatic layout generation, stateful C++11 lamb

Wenzel Jakob 4.1k Jul 31, 2022
very basic and minimalistic hooking "library" for windows (x64 support soon)

IceHook very basic and minimalistic hooking "library" for windows (x64 support soon) Example how to use: typedef void(__stdcall* twglSwapBuffers)(HDC

null 5 Jul 25, 2022
Cut down and minimalistic C++ string formatting library

nanofmt https://github.com/potatoengine/nanofmt License Copyright (c) Sean Middleditch and contributors nanofmt is released under the MIT license. nan

Sean Middleditch 10 Jun 7, 2022
Ureact - Minimalistic reactive library for c++

µReact µReact is an open-source minimalistic single-header reactive programming library for C++17. ❗️ This library is a work-in-progress. It should no

Yaroslav 122 Aug 4, 2022
Minimalistic assertion library for raylib.

raylib-assert Minimalistic assertion library for raylib. Example #include "raylib.h" #include "raylib-assert.h" int main(void) { Assert(10 == 10)

Rob Loach 2 Jan 12, 2022
NanoGUI is a minimalistic cross-platform widget library for OpenGL 3.x/DirectX11[12]/Vulkan

NanoGUI NanoGUI is a minimalistic cross-platform widget library for OpenGL 3.x/DirectX11[12]/Vulkan. It supports automatic layout generation, stateful

dalerank 68 Jul 15, 2022
Minimal Huffman coder/decoder

huffandpuff This is an extremely minimal huffman encoder/decoder. It uses no calls at all, not even stdlib/stdio, making it suitable for embedded appl

Adam Ierymenko 87 Aug 6, 2022
MPack - A C encoder/decoder for the MessagePack serialization format / msgpack.org[C]

Introduction MPack is a C implementation of an encoder and decoder for the MessagePack serialization format. It is: Simple and easy to use Secure agai

Nicholas Fraser 376 Jul 27, 2022
SleighCraft is a decoder based on ghidra's decompiler implementation.

SleighCraft is a decoder (or, linear disassembler) based on ghidra's decompiler implementation. Sleighcraft can be used in Rust or Python, with both high-level and low-level API.

PortalLab 231 Jul 10, 2022