Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8028 hidnplayr 1
minimp3
2
==========
3
 
4
[![Build Status](https://travis-ci.org/lieff/minimp3.svg)](https://travis-ci.org/lieff/minimp3)
5
6
  Coverity Scan Build Status
7
       src="https://scan.coverity.com/projects/14844/badge.svg"/>
8
9
[![codecov](https://codecov.io/gh/lieff/minimp3/branch/master/graph/badge.svg)](https://codecov.io/gh/lieff/minimp3)
10
 
11
Minimalistic, single-header library for decoding MP3. minimp3 is designed to be
12
small, fast (with SSE and NEON support), and accurate (ISO conformant). You can
13
find a rough benchmark below, measured using ``perf`` on an i7-6700K, IO
14
included, 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
 
30
Conformance test passed on all vectors (PSNR > 96db).
31
 
32
## Comparison with keyj's [minimp3](http://keyj.emphy.de/minimp3/)
33
 
34
Comparison 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
 
44
Below, 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
 
61
Keyj minimp3 conformance test fails on all vectors (PSNR < 96db), and free
62
format 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
 
67
First, 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
 
82
Note that you must define ``MINIMP3_IMPLEMENTATION`` in exactly one source file.
83
You can ``#include`` ``minimp3.h`` in as many files as you like.
84
Also you can use ``MINIMP3_ONLY_MP3`` define to strip MP1/MP2 decoding code.
85
MINIMP3_ONLY_SIMD define controls generic (non SSE/NEON) code generation (always enabled on x64/arm64 targets).
86
In case you do not want any platform-specific SIMD optimizations, you can define ``MINIMP3_NO_SIMD``.
87
MINIMP3_NONSTANDARD_BUT_LOGICAL define saves some code bytes, and enforces non-stadnard but logical behaviour of mono-stereo transition (rare case).
88
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.
89
 
90
Then. 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
 
107
The ``mp3dec_decode_frame()`` function decodes one full MP3 frame from the
108
input buffer, which must be large enough to hold one full frame.
109
 
110
The decoder will analyze the input buffer to properly sync with the MP3 stream,
111
and will skip ID3 data, as well as any data which is not valid. Short buffers
112
may cause false sync and can produce 'squealing' artefacts. The bigger the size
113
of the input buffer, the more reliable the sync procedure. We recommend having
114
as many as 10 consecutive MP3 frames (~16KB) in the input buffer at a time.
115
 
116
The size of the consumed MP3 data is returned in the ``mp3dec_frame_info_t``
117
field of the ``frame_bytes`` struct; you must remove the data corresponding to
118
the ``frame_bytes`` field  from the input buffer before the next decoder
119
invocation.
120
 
121
The decoding function returns the number of decoded samples. The following cases
122
are possible:
123
 
124
- **0:** No MP3 data was found in the input buffer
125
- **384:**  Layer 1
126
- **576:**  MPEG 2 Layer 3
127
- **1152:** Otherwise
128
 
129
The following is a description of the possible combinations of the number of
130
samples and ``frame_bytes`` field values:
131
 
132
- More than 0 samples and ``frame_bytes > 0``:  Succesful decode
133
- 0 samples and ``frame_bytes >  0``: The decoder skipped ID3 or invalid data
134
- 0 samples and ``frame_bytes == 0``: Insufficient data
135
 
136
If ``frame_bytes == 0``, the other fields may be uninitialized or unchanged; if
137
``frame_bytes != 0``, the other fields are available. The application may call
138
``mp3dec_init()`` when changing decode position, but this is not necessary.
139
 
140
As a special case, the decoder supports already split MP3 streams (for example,
141
after doing an MP4 demux). In this case, the input buffer must contain _exactly
142
one_ non-free-format frame.
143
 
144
## Seeking
145
 
146
You can seek to any byte in the stream and call ``mp3dec_decode_frame``; this
147
will work in almost all cases, but is not completely guaranteed. Probablility of
148
sync procedure failure lowers when MAX_FRAME_SYNC_MATCHES value grows. Default
149
MAX_FRAME_SYNC_MATCHES=10 and probablility of sync failure should be very low.
150
If granule data is accidentally detected as a valid MP3 header, short audio artefacting is
151
possible.
152
 
153
High-level mp3dec_ex_seek function supports precise seek to sample (MP3D_SEEK_TO_SAMPLE)
154
using index and binary search.
155
 
156
## Track length detect
157
 
158
If the file is known to be cbr, then all frames have equal size and
159
lack ID3 tags, which allows us to decode the first frame and calculate all frame
160
positions as ``frame_bytes * N``. However, because of padding, frames can differ
161
in size even in this case.
162
 
163
In general case whole stream scan is needed to calculate it's length. Scan can be
164
omitted if vbr tag is present (added by encoders like lame and ffmpeg), which contains
165
length info. High-level functions automatically use the vbr tag if present.
166
 
167
## High-level API
168
 
169
If you need only decode file/buffer or use precise seek, you can use optional high-level API.
170
Just ``#include`` ``minimp3_ex.h`` instead and use following additional functions:
171
 
172
```c
173
#define MP3D_SEEK_TO_BYTE   0
174
#define MP3D_SEEK_TO_SAMPLE 1
175
 
176
#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
177
/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */
178
#define MINIMP3_IO_SIZE (128*1024) /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */
179
#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */
180
#define MINIMP3_ENABLE_RING 0      /* enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */
181
 
182
#define MP3D_E_MEMORY  -1
183
#define MP3D_E_IOERROR -2
184
 
185
typedef struct
186
{
187
    mp3d_sample_t *buffer;
188
    size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */
189
    int channels, hz, layer, avg_bitrate_kbps;
190
} mp3dec_file_info_t;
191
 
192
typedef size_t (*MP3D_READ_CB)(void *buf, size_t size, void *user_data);
193
typedef int (*MP3D_SEEK_CB)(uint64_t position, void *user_data);
194
 
195
typedef struct
196
{
197
    MP3D_READ_CB read;
198
    void *read_data;
199
    MP3D_SEEK_CB seek;
200
    void *seek_data;
201
} mp3dec_io_t;
202
 
203
typedef struct
204
{
205
    uint64_t samples;
206
    mp3dec_frame_info_t info;
207
    int last_error;
208
    ...
209
} mp3dec_ex_t;
210
 
211
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);
212
typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info);
213
 
214
/* decode whole buffer block */
215
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);
216
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);
217
/* iterate through frames */
218
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
219
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
220
/* streaming decoder with seeking capability */
221
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method);
222
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method);
223
void mp3dec_ex_close(mp3dec_ex_t *dec);
224
int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);
225
size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
226
#ifndef MINIMP3_NO_STDIO
227
/* stdio versions of file load, iterate and stream */
228
int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
229
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
230
int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method);
231
#ifdef _WIN32
232
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);
233
int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
234
int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method);
235
#endif
236
#endif
237
```
238
 
239
Use MINIMP3_NO_STDIO define to exclude STDIO functions.
240
MINIMP3_ALLOW_MONO_STEREO_TRANSITION allows mixing mono and stereo in same file.
241
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.
242
MP3D_PROGRESS_CB is optional and can be NULL, example of file decoding:
243
 
244
```c
245
    mp3dec_t mp3d;
246
    mp3dec_file_info_t info;
247
    if (mp3dec_load(&mp3d, input_file_name, &info, NULL, NULL))
248
    {
249
        /* error */
250
    }
251
    /* mp3dec_file_info_t contains decoded samples and info,
252
       use free(info.buffer) to deallocate samples */
253
```
254
 
255
Example of file decoding with seek capability:
256
 
257
```c
258
    mp3dec_ex_t dec;
259
    if (mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE))
260
    {
261
        /* error */
262
    }
263
    /* dec.samples, dec.info.hz, dec.info.layer, dec.info.channels should be filled */
264
    if (mp3dec_ex_seek(&dec, position))
265
    {
266
        /* error */
267
    }
268
    mp3d_sample_t *buffer = malloc(dec.samples*sizeof(mp3d_sample_t));
269
    size_t readed = mp3dec_ex_read(&dec, buffer, dec.samples);
270
    if (readed != dec.samples) /* normal eof or error condition */
271
    {
272
        if (dec.last_error)
273
        {
274
            /* error */
275
        }
276
    }
277
```
278
 
279
## Bindings
280
 
281
 * https://github.com/tosone/minimp3 - go bindings
282
 * https://github.com/notviri/rmp3 - rust `no_std` bindings which don't allocate.
283
 * https://github.com/germangb/minimp3-rs - rust bindings
284
 * https://github.com/johangu/node-minimp3 - NodeJS bindings
285
 * https://github.com/pyminimp3/pyminimp3 - python bindings
286
 * https://github.com/bashi/minimp3-wasm - wasm bindings
287
 
288
## Interesting links
289
 
290
 * http://keyj.emphy.de/minimp3/
291
 * https://github.com/technosaurus/PDMP3
292
 * https://github.com/technosaurus/PDMP2
293
 * https://github.com/packjpg/packMP3
294
 * https://sites.google.com/a/kmlager.com/www/projects
295
 * https://sourceforge.net/projects/mp3dec/
296
 * http://blog.bjrn.se/2008/10/lets-build-mp3-decoder.html
297
 * http://www.mp3-converter.com/mp3codec/
298
 * http://www.multiweb.cz/twoinches/mp3inside.htm
299
 * https://www.mp3-tech.org/
300
 * http://id3.org/mp3Frame
301
 * https://www.datavoyage.com/mpgscript/mpeghdr.htm