Name |
Date |
Size |
#Lines |
LOC |
||
---|---|---|---|---|---|---|
.. | - | - | ||||
fuzzing/ | 12-May-2024 | - | 50 | 40 | ||
huffopt/ | 12-May-2024 | - | 1,857 | 1,783 | ||
player/ | 12-May-2024 | - | 130,365 | 121,385 | ||
scripts/ | 12-May-2024 | - | 270 | 212 | ||
vectors/ | 12-May-2024 | - | 11 | 11 | ||
.gitignore | D | 12-May-2024 | 81 | 8 | 8 | |
.travis.yml | D | 12-May-2024 | 654 | 35 | 30 | |
BUILD.gn | D | 12-May-2024 | 2.3 KiB | 90 | 80 | |
LICENSE | D | 12-May-2024 | 6.4 KiB | 118 | 96 | |
OAT.xml | D | 12-May-2024 | 15.1 KiB | 210 | 140 | |
README.OpenSource | D | 12-May-2024 | 385 | 12 | 11 | |
README.md | D | 12-May-2024 | 13.6 KiB | 311 | 257 | |
minimp3.c | D | 12-May-2024 | 129 | 5 | 5 | |
minimp3.h | D | 12-May-2024 | 74.8 KiB | 1,859 | 1,705 | |
minimp3_ex.h | D | 12-May-2024 | 48.2 KiB | 1,395 | 1,294 | |
minimp3_test.c | D | 12-May-2024 | 26.5 KiB | 792 | 743 |
README.OpenSource
1[ 2 { 3 "Name": "minimp3", 4 "License": "Creative Commons Zero v1.0 Universal", 5 "License File": "LICENSE", 6 "Version Number": "1.0.1", 7 "Owner": "lijianpeng7@huawei.com", 8 "Upstream URL": "https://github.com/JianpengLi1993/minimp3/releases/tag/v1.0.1", 9 "Description": "Minimalistic MP3 demuxer/decoder single header library." 10 } 11] 12
README.md
1minimp3 2========== 3 4[](https://travis-ci.org/lieff/minimp3) 5<a href="https://scan.coverity.com/projects/lieff-minimp3"> 6 <img alt="Coverity Scan Build Status" 7 src="https://scan.coverity.com/projects/14844/badge.svg"/> 8</a> 9[](https://codecov.io/gh/lieff/minimp3) 10 11Minimalistic, single-header library for decoding MP3. minimp3 is designed to be 12small, fast (with SSE and NEON support), and accurate (ISO conformant). You can 13find a rough benchmark below, measured using ``perf`` on an i7-6700K, IO 14included, no CPU heat to address speedstep: 15 16| Vector | Hz | Samples| Sec | Clockticks | Clockticks per second | PSNR | Max diff | 17| ----------- | ----- | ------ | ------ | --------- | ------ | ------ | - | 18|compl.bit | 48000 | 248832 | 5.184 | 14306684 | 2.759M | 124.22 | 1 | 19|he_32khz.bit | 32000 | 172800 | 5.4 | 8426158 | 1.560M | 139.67 | 1 | 20|he_44khz.bit | 44100 | 472320 | 10.710 | 21296300 | 1.988M | 144.04 | 1 | 21|he_48khz.bit | 48000 | 172800 | 3.6 | 8453846 | 2.348M | 139.67 | 1 | 22|hecommon.bit | 44100 | 69120 | 1.567 | 3169715 | 2.022M | 133.93 | 1 | 23|he_free.bit | 44100 | 156672 | 3.552 | 5798418 | 1.632M | 137.48 | 1 | 24|he_mode.bit | 44100 | 262656 | 5.955 | 9882314 | 1.659M | 118.00 | 1 | 25|si.bit | 44100 | 135936 | 3.082 | 7170520 | 2.326M | 120.30 | 1 | 26|si_block.bit | 44100 | 73728 | 1.671 | 4233136 | 2.533M | 125.18 | 1 | 27|si_huff.bit | 44100 | 86400 | 1.959 | 4785322 | 2.442M | 107.98 | 1 | 28|sin1k0db.bit | 44100 | 725760 | 16.457 | 24842977 | 1.509M | 111.03 | 1 | 29 30Conformance test passed on all vectors (PSNR > 96db). 31 32## Comparison with keyj's [minimp3](https://keyj.emphy.de/minimp3/) 33 34Comparison by features: 35 36| Keyj minimp3 | Current | 37| ------------ | ------- | 38| Fixed point | Floating point | 39| source: 84kb | 70kb | 40| binary: 34kb (20kb compressed) | 30kb (20kb) | 41| no vector opts | SSE/NEON intrinsics | 42| no free format | free format support | 43 44Below, you can find the benchmark and conformance test for keyj's minimp3: 45 46 47| Vector | Hz | Samples| Sec | Clockticks | Clockticks per second | PSNR | Max diff | 48| ----------- | ----- | ------ | ------ | --------- | ------ | ----- | - | 49|compl.bit | 48000 | 248832 | 5.184 | 31849373 | 6.143M | 71.50 | 41 | 50|he_32khz.bit | 32000 | 172800 | 5.4 | 26302319 | 4.870M | 71.63 | 24 | 51|he_44khz.bit | 44100 | 472320 | 10.710 | 41628861 | 3.886M | 71.63 | 24 | 52|he_48khz.bit | 48000 | 172800 | 3.6 | 25899527 | 7.194M | 71.63 | 24 | 53|hecommon.bit | 44100 | 69120 | 1.567 | 20437779 | 13.039M | 71.58 | 25 | 54|he_free.bit | 44100 | 0 | 0 | - | - | - | - | 55|he_mode.bit | 44100 | 262656 | 5.955 | 30988984 | 5.203M | 71.78 | 27 | 56|si.bit | 44100 | 135936 | 3.082 | 24096223 | 7.817M | 72.35 | 36 | 57|si_block.bit | 44100 | 73728 | 1.671 | 20722017 | 12.394M | 71.84 | 26 | 58|si_huff.bit | 44100 | 86400 | 1.959 | 21121376 | 10.780M | 27.80 | 65535 | 59|sin1k0db.bit | 44100 | 730368 | 16.561 | 55569636 | 3.355M | 0.15 | 58814 | 60 61Keyj minimp3 conformance test fails on all vectors (PSNR < 96db), and free 62format is unsupported. This caused some problems when it was used 63[here](https://github.com/lieff/lvg), and was the main motivation for this work. 64 65## Usage 66 67First, we need to initialize the decoder structure: 68 69```c 70//#define MINIMP3_ONLY_MP3 71//#define MINIMP3_ONLY_SIMD 72//#define MINIMP3_NO_SIMD 73//#define MINIMP3_NONSTANDARD_BUT_LOGICAL 74//#define MINIMP3_FLOAT_OUTPUT 75#define MINIMP3_IMPLEMENTATION 76#include "minimp3.h" 77... 78 static mp3dec_t mp3d; 79 mp3dec_init(&mp3d); 80``` 81 82Note that you must define ``MINIMP3_IMPLEMENTATION`` in exactly one source file. 83You can ``#include`` ``minimp3.h`` in as many files as you like. 84Also you can use ``MINIMP3_ONLY_MP3`` define to strip MP1/MP2 decoding code. 85MINIMP3_ONLY_SIMD define controls generic (non SSE/NEON) code generation (always enabled on x64/arm64 targets). 86In case you do not want any platform-specific SIMD optimizations, you can define ``MINIMP3_NO_SIMD``. 87MINIMP3_NONSTANDARD_BUT_LOGICAL define saves some code bytes, and enforces non-standard but logical behaviour of mono-stereo transition (rare case). 88MINIMP3_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. 89 90Then. we decode the input stream frame-by-frame: 91 92```c 93 /*typedef struct 94 { 95 int frame_bytes; 96 int channels; 97 int hz; 98 int layer; 99 int bitrate_kbps; 100 } mp3dec_frame_info_t;*/ 101 mp3dec_frame_info_t info; 102 short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; 103 /*unsigned char *input_buf; - input byte stream*/ 104 samples = mp3dec_decode_frame(&mp3d, input_buf, buf_size, pcm, &info); 105``` 106 107The ``mp3dec_decode_frame()`` function decodes one full MP3 frame from the 108input buffer, which must be large enough to hold one full frame. 109 110The decoder will analyze the input buffer to properly sync with the MP3 stream, 111and will skip ID3 data, as well as any data which is not valid. Short buffers 112may cause false sync and can produce 'squealing' artefacts. The bigger the size 113of the input buffer, the more reliable the sync procedure. We recommend having 114as many as 10 consecutive MP3 frames (~16KB) in the input buffer at a time. 115 116At end of stream just pass rest of the buffer, sync procedure should work even 117with just 1 frame in stream (except for free format and garbage at the end can 118mess things up, so id3v1 and ape tags must be removed first). 119 120For free format there minimum 3 frames needed to do proper sync: 2 frames to 121detect frame length and 1 next frame to check detect is good. 122 123The size of the consumed MP3 data is returned in the ``mp3dec_frame_info_t`` 124field of the ``frame_bytes`` struct; you must remove the data corresponding to 125the ``frame_bytes`` field from the input buffer before the next decoder 126invocation. 127 128The decoding function returns the number of decoded samples. The following cases 129are possible: 130 131- **0:** No MP3 data was found in the input buffer 132- **384:** Layer 1 133- **576:** MPEG 2 Layer 3 134- **1152:** Otherwise 135 136The following is a description of the possible combinations of the number of 137samples and ``frame_bytes`` field values: 138 139- More than 0 samples and ``frame_bytes > 0``: Succesful decode 140- 0 samples and ``frame_bytes > 0``: The decoder skipped ID3 or invalid data 141- 0 samples and ``frame_bytes == 0``: Insufficient data 142 143If ``frame_bytes == 0``, the other fields may be uninitialized or unchanged; if 144``frame_bytes != 0``, the other fields are available. The application may call 145``mp3dec_init()`` when changing decode position, but this is not necessary. 146 147As a special case, the decoder supports already split MP3 streams (for example, 148after doing an MP4 demux). In this case, the input buffer must contain _exactly 149one_ non-free-format frame. 150 151## Seeking 152 153You can seek to any byte in the stream and call ``mp3dec_decode_frame``; this 154will work in almost all cases, but is not completely guaranteed. Probablility of 155sync procedure failure lowers when MAX_FRAME_SYNC_MATCHES value grows. Default 156MAX_FRAME_SYNC_MATCHES=10 and probablility of sync failure should be very low. 157If granule data is accidentally detected as a valid MP3 header, short audio artefacting is 158possible. 159 160High-level mp3dec_ex_seek function supports precise seek to sample (MP3D_SEEK_TO_SAMPLE) 161using index and binary search. 162 163## Track length detect 164 165If the file is known to be cbr, then all frames have equal size and 166lack ID3 tags, which allows us to decode the first frame and calculate all frame 167positions as ``frame_bytes * N``. However, because of padding, frames can differ 168in size even in this case. 169 170In general case whole stream scan is needed to calculate it's length. Scan can be 171omitted if vbr tag is present (added by encoders like lame and ffmpeg), which contains 172length info. High-level functions automatically use the vbr tag if present. 173 174## High-level API 175 176If you need only decode file/buffer or use precise seek, you can use optional high-level API. 177Just ``#include`` ``minimp3_ex.h`` instead and use following additional functions: 178 179```c 180#define MP3D_SEEK_TO_BYTE 0 181#define MP3D_SEEK_TO_SAMPLE 1 182 183#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */ 184/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */ 185#define MINIMP3_IO_SIZE (128*1024) /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */ 186#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */ 187#define MINIMP3_ENABLE_RING 0 /* enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */ 188 189#define MP3D_E_MEMORY -1 190#define MP3D_E_IOERROR -2 191 192typedef struct 193{ 194 mp3d_sample_t *buffer; 195 size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */ 196 int channels, hz, layer, avg_bitrate_kbps; 197} mp3dec_file_info_t; 198 199typedef size_t (*MP3D_READ_CB)(void *buf, size_t size, void *user_data); 200typedef int (*MP3D_SEEK_CB)(uint64_t position, void *user_data); 201 202typedef struct 203{ 204 MP3D_READ_CB read; 205 void *read_data; 206 MP3D_SEEK_CB seek; 207 void *seek_data; 208} mp3dec_io_t; 209 210typedef struct 211{ 212 uint64_t samples; 213 mp3dec_frame_info_t info; 214 int last_error; 215 ... 216} mp3dec_ex_t; 217 218typedef 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); 219typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info); 220 221/* decode whole buffer block */ 222int 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); 223int 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); 224/* iterate through frames */ 225int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data); 226int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data); 227/* streaming decoder with seeking capability */ 228int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method); 229int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method); 230void mp3dec_ex_close(mp3dec_ex_t *dec); 231int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position); 232size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples); 233#ifndef MINIMP3_NO_STDIO 234/* stdio versions of file load, iterate and stream */ 235int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data); 236int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data); 237int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method); 238#ifdef _WIN32 239int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data); 240int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data); 241int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method); 242#endif 243#endif 244``` 245 246Use MINIMP3_NO_STDIO define to exclude STDIO functions. 247MINIMP3_ALLOW_MONO_STEREO_TRANSITION allows mixing mono and stereo in same file. 248In 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. 249MP3D_PROGRESS_CB is optional and can be NULL, example of file decoding: 250 251```c 252 mp3dec_t mp3d; 253 mp3dec_file_info_t info; 254 if (mp3dec_load(&mp3d, input_file_name, &info, NULL, NULL)) 255 { 256 /* error */ 257 } 258 /* mp3dec_file_info_t contains decoded samples and info, 259 use free(info.buffer) to deallocate samples */ 260``` 261 262Example of file decoding with seek capability: 263 264```c 265 mp3dec_ex_t dec; 266 if (mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE)) 267 { 268 /* error */ 269 } 270 /* dec.samples, dec.info.hz, dec.info.layer, dec.info.channels should be filled */ 271 if (mp3dec_ex_seek(&dec, position)) 272 { 273 /* error */ 274 } 275 mp3d_sample_t *buffer = malloc(dec.samples*sizeof(mp3d_sample_t)); 276 size_t readed = mp3dec_ex_read(&dec, buffer, dec.samples); 277 if (readed != dec.samples) /* normal eof or error condition */ 278 { 279 if (dec.last_error) 280 { 281 /* error */ 282 } 283 } 284``` 285 286## Bindings 287 288 * https://github.com/tosone/minimp3 - go bindings 289 * https://github.com/notviri/rmp3 - rust `no_std` bindings which don't allocate. 290 * https://github.com/germangb/minimp3-rs - rust bindings 291 * https://github.com/johangu/node-minimp3 - NodeJS bindings 292 * https://github.com/pyminimp3/pyminimp3 - python bindings 293 * https://github.com/bashi/minimp3-wasm - wasm bindings 294 * https://github.com/DasZiesel/minimp3-delphi - delphi bindings 295 * https://github.com/mgeier/minimp3_ex-sys - low-level rust bindings to `minimp3_ex` 296 297## Interesting links 298 299 * https://keyj.emphy.de/minimp3/ 300 * https://github.com/technosaurus/PDMP3 301 * https://github.com/technosaurus/PDMP2 302 * https://github.com/packjpg/packMP3 303 * https://sites.google.com/a/kmlager.com/www/projects 304 * https://sourceforge.net/projects/mp3dec/ 305 * http://blog.bjrn.se/2008/10/lets-build-mp3-decoder.html 306 * http://www.mp3-converter.com/mp3codec/ 307 * http://www.multiweb.cz/twoinches/mp3inside.htm 308 * https://www.mp3-tech.org/ 309 * https://id3.org/mp3Frame 310 * https://www.datavoyage.com/mpgscript/mpeghdr.htm 311