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
  • 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 0
  • 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
  • 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
Owner
Lion
mov ax,0013h int 10h
Lion
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 411 Sep 13, 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 30 Sep 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 26 Sep 10, 2022
An abstract soundfile decoder.

SDL_sound. An abstract soundfile decoder. SDL_sound is a library that handles the decoding of several popular sound file formats, such as .WAV and .

Ryan C. Gordon 119 Sep 12, 2022
MPEG-H 3D Audio Low Complexity Profile Decoder

Introduction of the MPEG-H 3D Audio Low Complexity Profile Decoder The advent of object-based audio and scene-based audio has revolutionized the 3D so

Ittiam Systems Pvt. Ltd. 46 Aug 18, 2022
Single file audio playback and capture library written in C.

A single file library for audio playback and capture. Example - Documentation - Supported Platforms - Backends - Major Features - Building - Unofficia

David Reid 2.4k Sep 21, 2022
Single file C library for decoding MPEG1 Video and MP2 Audio

PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer Single-file MIT licensed library for C/C++ See pl_mpeg.h for the documentation. Why?

Dominic Szablewski 577 Sep 21, 2022
Single file synth + demo song

P.S. is a music track written from scratch using the C programming language. All sounds and notes were entered manually without using any music progra

NightRadio 43 Aug 14, 2022
A tiny, header only, easy to use, cross-platform, portaudio wrapper, sound and notation manager, tailored for the demo scene.

TDAW A tiny, header only, easy to use, cross-platform, portaudio wrapper, sound and notation manager, tailored for the demo scene. This header enables

kbx 12 Sep 17, 2022
A simple C++ library for reading and writing audio files.

AudioFile A simple header-only C++ library for reading and writing audio files. Current supported formats: WAV AIFF Author AudioFile is written and ma

Adam Stark 644 Sep 16, 2022
A C library for reading and writing sound files containing sampled audio data.

libsndfile libsndfile is a C library for reading and writing files containing sampled audio data. Authors The libsndfile project was originally develo

null 1k Sep 15, 2022
C library for cross-platform real-time audio input and output

libsoundio C library providing cross-platform audio input and output. The API is suitable for real-time software such as digital audio workstations as

Andrew Kelley 1.6k Sep 19, 2022
C++ Audio and Music DSP Library

_____ _____ ___ __ _ _____ __ __ __ ____ ____ / \\_ \\ \/ / |/ \| | | | \_ \/ \ | Y Y \/ /_ \> <| | Y Y \ | |_|

Mick Grierson 1.3k Sep 15, 2022
🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)

Verovio is a fast, portable and lightweight library for engraving Music Encoding Initiative (MEI) digital scores into SVG images. Verovio also contain

RISM Switzerland 495 Sep 11, 2022
highly efficient sound library for the Gameboy Advance

The Apex Audio System (AAS) is a sound library for the GBA. It includes a highly efficient mixer, MOD playing routines and support for up to 16 channels. It is designed for developers using a GCC-based development environment. AAS uses RAW, WAV or *tracker 1-16 channel MOD files as input.

Ties Stuij 31 Jul 15, 2022
A lightweight music DSP library.

Soundpipe Soundpipe is a lightweight music DSP library written in C. It aims to provide a set of high-quality DSP modules for composers, sound designe

Paul Batchelor 102 Dec 14, 2021
PortAudio is a portable audio I/O library designed for cross-platform support of audio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.

PortAudio 704 Sep 15, 2022
LibMEI is a C++ library for reading and writing MEI files

C++ library and Python bindings for the Music Encoding Initiative format

Distributed Digital Music Archives and Libraries Lab 53 Aug 31, 2022
C++17 library for creating macOS Audio Server plugins.

libASPL Synopsis Instructions Versioning API reference Example driver Quick start Object model Types of setters Customization Thread and realtime safe

Victor Gaydov 27 Aug 21, 2022