LMMS
Loading...
Searching...
No Matches
minimp3_ex.h
Go to the documentation of this file.
1#ifndef MINIMP3_EXT_H
2#define MINIMP3_EXT_H
3/*
4 https://github.com/lieff/minimp3
5 To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
6 This software is distributed without any warranty.
7 See <http://creativecommons.org/publicdomain/zero/1.0/>.
8*/
9#include "minimp3.h"
10
11/* flags for mp3dec_ex_open_* functions */
12#define MP3D_SEEK_TO_BYTE 0 /* mp3dec_ex_seek seeks to byte in stream */
13#define MP3D_SEEK_TO_SAMPLE 1 /* mp3dec_ex_seek precisely seeks to sample using index (created during duration calculation scan or when mp3dec_ex_seek called) */
14#define MP3D_DO_NOT_SCAN 2 /* do not scan whole stream for duration if vbrtag not found, mp3dec_ex_t::samples will be filled only if mp3dec_ex_t::vbr_tag_found == 1 */
15
16/* compile-time config */
17#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
18/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */
19#define MINIMP3_IO_SIZE (128*1024) /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */
20#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */
21/*#define MINIMP3_SCAN_LIMIT (256*1024)*/ /* how many bytes will be scanned to search first valid mp3 frame, to prevent stall on large non-mp3 files */
22#define MINIMP3_ENABLE_RING 0 /* WIP enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */
23
24/* return error codes */
25#define MP3D_E_PARAM -1
26#define MP3D_E_MEMORY -2
27#define MP3D_E_IOERROR -3
28#define MP3D_E_USER -4 /* can be used to stop processing from callbacks without indicating specific error */
29#define MP3D_E_DECODE -5 /* decode error which can't be safely skipped, such as sample rate, layer and channels change */
30
31typedef struct
32{
34 size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */
37
38typedef struct
39{
41 size_t size;
43
44typedef struct
45{
46 uint64_t sample;
47 uint64_t offset;
49
55
56typedef size_t (*MP3D_READ_CB)(void *buf, size_t size, void *user_data);
57typedef int (*MP3D_SEEK_CB)(uint64_t position, void *user_data);
58
66
82
83typedef 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);
84typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info);
85
86#ifdef __cplusplus
87extern "C" {
88#endif
89
90/* detect mp3/mpa format */
91int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size);
92int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size);
93/* decode whole buffer block */
94int 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);
95int 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);
96/* iterate through frames */
97int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
98int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
99/* streaming decoder with seeking capability */
100int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags);
101int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int flags);
103int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);
104size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
105#ifndef MINIMP3_NO_STDIO
106/* stdio versions of file detect, load, iterate and stream */
107int mp3dec_detect(const char *file_name);
108int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
109int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
110int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int flags);
111#ifdef _WIN32
112int mp3dec_detect_w(const wchar_t *file_name);
113int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
114int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
115int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags);
116#endif
117#endif
118
119#ifdef __cplusplus
120}
121#endif
122#endif /*MINIMP3_EXT_H*/
123
124#ifdef MINIMP3_IMPLEMENTATION
125#include <limits.h>
126
127static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size)
128{
129 size_t buf_size = *pbuf_size;
130#ifndef MINIMP3_NOSKIP_ID3V1
131 if (buf_size >= 128 && !memcmp(buf + buf_size - 128, "TAG", 3))
132 {
133 buf_size -= 128;
134 if (buf_size >= 227 && !memcmp(buf + buf_size - 227, "TAG+", 4))
135 buf_size -= 227;
136 }
137#endif
138#ifndef MINIMP3_NOSKIP_APEV2
139 if (buf_size > 32 && !memcmp(buf + buf_size - 32, "APETAGEX", 8))
140 {
141 buf_size -= 32;
142 const uint8_t *tag = buf + buf_size + 8 + 4;
143 uint32_t tag_size = (uint32_t)(tag[3] << 24) | (tag[2] << 16) | (tag[1] << 8) | tag[0];
144 if (buf_size >= tag_size)
145 buf_size -= tag_size;
146 }
147#endif
148 *pbuf_size = buf_size;
149}
150
151static size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size)
152{
153#define MINIMP3_ID3_DETECT_SIZE 10
154#ifndef MINIMP3_NOSKIP_ID3V2
155 if (buf_size >= MINIMP3_ID3_DETECT_SIZE && !memcmp(buf, "ID3", 3) && !((buf[5] & 15) || (buf[6] & 0x80) || (buf[7] & 0x80) || (buf[8] & 0x80) || (buf[9] & 0x80)))
156 {
157 size_t id3v2size = (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10;
158 if ((buf[5] & 16))
159 id3v2size += 10; /* footer */
160 return id3v2size;
161 }
162#endif
163 return 0;
164}
165
166static void mp3dec_skip_id3(const uint8_t **pbuf, size_t *pbuf_size)
167{
168 uint8_t *buf = (uint8_t *)(*pbuf);
169 size_t buf_size = *pbuf_size;
170 size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size);
171 if (id3v2size)
172 {
173 if (id3v2size >= buf_size)
174 id3v2size = buf_size;
175 buf += id3v2size;
176 buf_size -= id3v2size;
177 }
179 *pbuf = (const uint8_t *)buf;
180 *pbuf_size = buf_size;
181}
182
183static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *frames, int *delay, int *padding)
184{
185 static const char g_xing_tag[4] = { 'X', 'i', 'n', 'g' };
186 static const char g_info_tag[4] = { 'I', 'n', 'f', 'o' };
187#define FRAMES_FLAG 1
188#define BYTES_FLAG 2
189#define TOC_FLAG 4
190#define VBR_SCALE_FLAG 8
191 /* Side info offsets after header:
192 / Mono Stereo
193 / MPEG1 17 32
194 / MPEG2 & 2.5 9 17*/
195 bs_t bs[1];
196 L3_gr_info_t gr_info[4];
197 bs_init(bs, frame + HDR_SIZE, frame_size - HDR_SIZE);
198 if (HDR_IS_CRC(frame))
199 get_bits(bs, 16);
200 if (L3_read_side_info(bs, gr_info, frame) < 0)
201 return 0; /* side info corrupted */
202
203 const uint8_t *tag = frame + HDR_SIZE + bs->pos/8;
204 if (memcmp(g_xing_tag, tag, 4) && memcmp(g_info_tag, tag, 4))
205 return 0;
206 int flags = tag[7];
207 if (!((flags & FRAMES_FLAG)))
208 return -1;
209 tag += 8;
210 *frames = (uint32_t)(tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3];
211 tag += 4;
212 if (flags & BYTES_FLAG)
213 tag += 4;
214 if (flags & TOC_FLAG)
215 tag += 100;
216 if (flags & VBR_SCALE_FLAG)
217 tag += 4;
218 *delay = *padding = 0;
219 if (*tag)
220 { /* extension, LAME, Lavc, etc. Should be the same structure. */
221 tag += 21;
222 if (tag - frame + 14 >= frame_size)
223 return 0;
224 *delay = ((tag[0] << 4) | (tag[1] >> 4)) + (528 + 1);
225 *padding = (((tag[1] & 0xF) << 8) | tag[2]) - (528 + 1);
226 }
227 return 1;
228}
229
230int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size)
231{
232 return mp3dec_detect_cb(0, (uint8_t *)buf, buf_size);
233}
234
236{
237 if (!buf || (size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE))
238 return MP3D_E_PARAM;
239 size_t filled = buf_size;
240 if (io)
241 {
242 if (io->seek(0, io->seek_data))
243 return MP3D_E_IOERROR;
244 filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data);
245 if (filled > MINIMP3_ID3_DETECT_SIZE)
246 return MP3D_E_IOERROR;
247 }
248 if (filled < MINIMP3_ID3_DETECT_SIZE)
249 return MP3D_E_USER; /* too small, can't be mp3/mpa */
250 if (mp3dec_skip_id3v2(buf, filled))
251 return 0; /* id3v2 tag is enough evidence */
252 if (io)
253 {
254 size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
255 if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
256 return MP3D_E_IOERROR;
257 filled += readed;
258 if (filled < MINIMP3_BUF_SIZE)
259 mp3dec_skip_id3v1(buf, &filled);
260 } else
261 {
262 mp3dec_skip_id3v1(buf, &filled);
263 if (filled > MINIMP3_BUF_SIZE)
264 filled = MINIMP3_BUF_SIZE;
265 }
266 int free_format_bytes, frame_size;
267 mp3d_find_frame(buf, filled, &free_format_bytes, &frame_size);
268 if (frame_size)
269 return 0; /* MAX_FRAME_SYNC_MATCHES consecutive frames found */
270 return MP3D_E_USER;
271}
272
273int 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)
274{
275 return mp3dec_load_cb(dec, 0, (uint8_t *)buf, buf_size, info, progress_cb, user_data);
276}
277
278int 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)
279{
280 if (!dec || !buf || !info || (size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE))
281 return MP3D_E_PARAM;
282 uint64_t detected_samples = 0;
283 size_t orig_buf_size = buf_size;
284 int to_skip = 0;
285 mp3dec_frame_info_t frame_info;
286 memset(info, 0, sizeof(*info));
287 memset(&frame_info, 0, sizeof(frame_info));
288
289 /* skip id3 */
290 size_t filled = 0, consumed = 0;
291 int eof = 0, ret = 0;
292 if (io)
293 {
294 if (io->seek(0, io->seek_data))
295 return MP3D_E_IOERROR;
296 filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data);
297 if (filled > MINIMP3_ID3_DETECT_SIZE)
298 return MP3D_E_IOERROR;
299 if (MINIMP3_ID3_DETECT_SIZE != filled)
300 return 0;
301 size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
302 if (id3v2size)
303 {
304 if (io->seek(id3v2size, io->seek_data))
305 return MP3D_E_IOERROR;
306 filled = io->read(buf, buf_size, io->read_data);
307 if (filled > buf_size)
308 return MP3D_E_IOERROR;
309 } else
310 {
311 size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
312 if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
313 return MP3D_E_IOERROR;
314 filled += readed;
315 }
316 if (filled < MINIMP3_BUF_SIZE)
317 mp3dec_skip_id3v1(buf, &filled);
318 } else
319 {
320 mp3dec_skip_id3((const uint8_t **)&buf, &buf_size);
321 if (!buf_size)
322 return 0;
323 }
324 /* try to make allocation size assumption by first frame or vbr tag */
325 mp3dec_init(dec);
326 int samples;
327 do
328 {
329 uint32_t frames;
330 int i, delay, padding, free_format_bytes = 0, frame_size = 0;
331 const uint8_t *hdr;
332 if (io)
333 {
334 if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
335 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
336 memmove(buf, buf + consumed, filled - consumed);
337 filled -= consumed;
338 consumed = 0;
339 size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
340 if (readed > (buf_size - filled))
341 return MP3D_E_IOERROR;
342 if (readed != (buf_size - filled))
343 eof = 1;
344 filled += readed;
345 if (eof)
346 mp3dec_skip_id3v1(buf, &filled);
347 }
348 i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size);
349 consumed += i;
350 hdr = buf + consumed;
351 } else
352 {
353 i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size);
354 buf += i;
355 buf_size -= i;
356 hdr = buf;
357 }
358 if (i && !frame_size)
359 continue;
360 if (!frame_size)
361 return 0;
362 frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
363 frame_info.hz = hdr_sample_rate_hz(hdr);
364 frame_info.layer = 4 - HDR_GET_LAYER(hdr);
365 frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
366 frame_info.frame_bytes = frame_size;
367 samples = hdr_frame_samples(hdr)*frame_info.channels;
368 if (3 != frame_info.layer)
369 break;
370 int ret = mp3dec_check_vbrtag(hdr, frame_size, &frames, &delay, &padding);
371 if (ret > 0)
372 {
373 padding *= frame_info.channels;
374 to_skip = delay*frame_info.channels;
375 detected_samples = samples*(uint64_t)frames;
376 if (detected_samples >= (uint64_t)to_skip)
377 detected_samples -= to_skip;
378 if (padding > 0 && detected_samples >= (uint64_t)padding)
379 detected_samples -= padding;
380 if (!detected_samples)
381 return 0;
382 }
383 if (ret)
384 {
385 if (io)
386 {
387 consumed += frame_size;
388 } else
389 {
390 buf += frame_size;
391 buf_size -= frame_size;
392 }
393 }
394 break;
395 } while(1);
396 size_t allocated = MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t);
397 if (detected_samples)
398 allocated += detected_samples*sizeof(mp3d_sample_t);
399 else
400 allocated += (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t);
401 info->buffer = (mp3d_sample_t*)malloc(allocated);
402 if (!info->buffer)
403 return MP3D_E_MEMORY;
404 /* save info */
405 info->channels = frame_info.channels;
406 info->hz = frame_info.hz;
407 info->layer = frame_info.layer;
408 /* decode all frames */
409 size_t avg_bitrate_kbps = 0, frames = 0;
410 do
411 {
412 if ((allocated - info->samples*sizeof(mp3d_sample_t)) < MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t))
413 {
414 allocated *= 2;
415 mp3d_sample_t *alloc_buf = (mp3d_sample_t*)realloc(info->buffer, allocated);
416 if (!alloc_buf)
417 return MP3D_E_MEMORY;
418 info->buffer = alloc_buf;
419 }
420 if (io)
421 {
422 if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
423 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
424 memmove(buf, buf + consumed, filled - consumed);
425 filled -= consumed;
426 consumed = 0;
427 size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
428 if (readed != (buf_size - filled))
429 eof = 1;
430 filled += readed;
431 if (eof)
432 mp3dec_skip_id3v1(buf, &filled);
433 }
434 samples = mp3dec_decode_frame(dec, buf + consumed, filled - consumed, info->buffer + info->samples, &frame_info);
435 consumed += frame_info.frame_bytes;
436 } else
437 {
438 samples = mp3dec_decode_frame(dec, buf, MINIMP3_MIN(buf_size, (size_t)INT_MAX), info->buffer + info->samples, &frame_info);
439 buf += frame_info.frame_bytes;
440 buf_size -= frame_info.frame_bytes;
441 }
442 if (samples)
443 {
444 if (info->hz != frame_info.hz || info->layer != frame_info.layer)
445 {
446 ret = MP3D_E_DECODE;
447 break;
448 }
449 if (info->channels && info->channels != frame_info.channels)
450 {
451#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
452 info->channels = 0; /* mark file with mono-stereo transition */
453#else
454 ret = MP3D_E_DECODE;
455 break;
456#endif
457 }
458 samples *= frame_info.channels;
459 if (to_skip)
460 {
461 size_t skip = MINIMP3_MIN(samples, to_skip);
462 to_skip -= skip;
463 samples -= skip;
464 memmove(info->buffer, info->buffer + skip, samples*sizeof(mp3d_sample_t));
465 }
466 info->samples += samples;
467 avg_bitrate_kbps += frame_info.bitrate_kbps;
468 frames++;
469 if (progress_cb)
470 {
471 ret = progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info);
472 if (ret)
473 break;
474 }
475 }
476 } while (frame_info.frame_bytes);
477 if (detected_samples && info->samples > detected_samples)
478 info->samples = detected_samples; /* cut padding */
479 /* reallocate to normal buffer size */
480 if (allocated != info->samples*sizeof(mp3d_sample_t))
481 {
482 mp3d_sample_t *alloc_buf = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t));
483 if (!alloc_buf && info->samples)
484 return MP3D_E_MEMORY;
485 info->buffer = alloc_buf;
486 }
487 if (frames)
488 info->avg_bitrate_kbps = avg_bitrate_kbps/frames;
489 return ret;
490}
491
492int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
493{
494 const uint8_t *orig_buf = buf;
495 if (!buf || (size_t)-1 == buf_size || !callback)
496 return MP3D_E_PARAM;
497 /* skip id3 */
499 if (!buf_size)
500 return 0;
501 mp3dec_frame_info_t frame_info;
502 memset(&frame_info, 0, sizeof(frame_info));
503 do
504 {
505 int free_format_bytes = 0, frame_size = 0, ret;
506 int i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size);
507 buf += i;
508 buf_size -= i;
509 if (i && !frame_size)
510 continue;
511 if (!frame_size)
512 break;
513 const uint8_t *hdr = buf;
514 frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
515 frame_info.hz = hdr_sample_rate_hz(hdr);
516 frame_info.layer = 4 - HDR_GET_LAYER(hdr);
517 frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
518 frame_info.frame_bytes = frame_size;
519
520 if (callback)
521 {
522 if ((ret = callback(user_data, hdr, frame_size, free_format_bytes, buf_size, hdr - orig_buf, &frame_info)))
523 return ret;
524 }
525 buf += frame_size;
526 buf_size -= frame_size;
527 } while (1);
528 return 0;
529}
530
532{
533 if (!io || !buf || (size_t)-1 == buf_size || buf_size < MINIMP3_BUF_SIZE || !callback)
534 return MP3D_E_PARAM;
535 size_t filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0;
536 uint64_t readed = 0;
537 mp3dec_frame_info_t frame_info;
538 int eof = 0;
539 memset(&frame_info, 0, sizeof(frame_info));
540 if (filled > MINIMP3_ID3_DETECT_SIZE)
541 return MP3D_E_IOERROR;
542 if (MINIMP3_ID3_DETECT_SIZE != filled)
543 return 0;
544 size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
545 if (id3v2size)
546 {
547 if (io->seek(id3v2size, io->seek_data))
548 return MP3D_E_IOERROR;
549 filled = io->read(buf, buf_size, io->read_data);
550 if (filled > buf_size)
551 return MP3D_E_IOERROR;
552 readed += id3v2size;
553 } else
554 {
555 size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
556 if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
557 return MP3D_E_IOERROR;
558 filled += readed;
559 }
560 if (filled < MINIMP3_BUF_SIZE)
561 mp3dec_skip_id3v1(buf, &filled);
562 do
563 {
564 int free_format_bytes = 0, frame_size = 0, ret;
565 int i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size);
566 if (i && !frame_size)
567 {
568 consumed += i;
569 continue;
570 }
571 if (!frame_size)
572 break;
573 const uint8_t *hdr = buf + consumed + i;
574 frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
575 frame_info.hz = hdr_sample_rate_hz(hdr);
576 frame_info.layer = 4 - HDR_GET_LAYER(hdr);
577 frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
578 frame_info.frame_bytes = frame_size;
579
580 readed += i;
581 if (callback)
582 {
583 if ((ret = callback(user_data, hdr, frame_size, free_format_bytes, filled - consumed, readed, &frame_info)))
584 return ret;
585 }
586 readed += frame_size;
587 consumed += i + frame_size;
588 if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
589 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
590 memmove(buf, buf + consumed, filled - consumed);
591 filled -= consumed;
592 consumed = 0;
593 size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
594 if (readed > (buf_size - filled))
595 return MP3D_E_IOERROR;
596 if (readed != (buf_size - filled))
597 eof = 1;
598 filled += readed;
599 if (eof)
600 mp3dec_skip_id3v1(buf, &filled);
601 }
602 } while (1);
603 return 0;
604}
605
606static int mp3dec_load_index(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)
607{
608 mp3dec_frame_t *idx_frame;
609 mp3dec_ex_t *dec = (mp3dec_ex_t *)user_data;
610 if (!dec->index.frames && !dec->start_offset)
611 { /* detect VBR tag and try to avoid full scan */
612 uint32_t frames;
613 int delay, padding;
614 dec->info = *info;
615 dec->start_offset = dec->offset = offset;
616 dec->end_offset = offset + buf_size;
617 dec->free_format_bytes = free_format_bytes; /* should not change */
618 if (3 == dec->info.layer)
619 {
620 int ret = mp3dec_check_vbrtag(frame, frame_size, &frames, &delay, &padding);
621 if (ret)
622 dec->start_offset = dec->offset = offset + frame_size;
623 if (ret > 0)
624 {
625 padding *= info->channels;
626 dec->start_delay = dec->to_skip = delay*info->channels;
627 dec->samples = hdr_frame_samples(frame)*info->channels*(uint64_t)frames;
628 if (dec->samples >= (uint64_t)dec->start_delay)
629 dec->samples -= dec->start_delay;
630 if (padding > 0 && dec->samples >= (uint64_t)padding)
631 dec->samples -= padding;
632 dec->detected_samples = dec->samples;
633 dec->vbr_tag_found = 1;
634 return MP3D_E_USER;
635 } else if (ret < 0)
636 return 0;
637 }
638 }
639 if (dec->flags & MP3D_DO_NOT_SCAN)
640 return MP3D_E_USER;
641 if (dec->index.num_frames + 1 > dec->index.capacity)
642 {
643 if (!dec->index.capacity)
644 dec->index.capacity = 4096;
645 else
646 dec->index.capacity *= 2;
647 mp3dec_frame_t *alloc_buf = (mp3dec_frame_t *)realloc((void*)dec->index.frames, sizeof(mp3dec_frame_t)*dec->index.capacity);
648 if (!alloc_buf)
649 return MP3D_E_MEMORY;
650 dec->index.frames = alloc_buf;
651 }
652 idx_frame = &dec->index.frames[dec->index.num_frames++];
653 idx_frame->offset = offset;
654 idx_frame->sample = dec->samples;
655 if (!dec->buffer_samples && dec->index.num_frames < 256)
656 { /* for some cutted mp3 frames, bit-reservoir not filled and decoding can't be started from first frames */
657 /* try to decode up to 255 first frames till samples starts to decode */
658 dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, frame, MINIMP3_MIN(buf_size, (size_t)INT_MAX), dec->buffer, info);
659 dec->samples += dec->buffer_samples*info->channels;
660 } else
661 dec->samples += hdr_frame_samples(frame)*info->channels;
662 return 0;
663}
664
665int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags)
666{
667 if (!dec || !buf || (size_t)-1 == buf_size || (flags & (~3)))
668 return MP3D_E_PARAM;
669 memset(dec, 0, sizeof(*dec));
670 dec->file.buffer = buf;
671 dec->file.size = buf_size;
672 dec->flags = flags;
673 mp3dec_init(&dec->mp3d);
674 int ret = mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
675 if (ret && MP3D_E_USER != ret)
676 return ret;
677 mp3dec_init(&dec->mp3d);
678 dec->buffer_samples = 0;
679 dec->indexes_built = !(dec->vbr_tag_found || (flags & MP3D_DO_NOT_SCAN));
680 dec->flags &= (~MP3D_DO_NOT_SCAN);
681 return 0;
682}
683
684#ifndef MINIMP3_SEEK_IDX_LINEAR_SEARCH
685static size_t mp3dec_idx_binary_search(mp3dec_index_t *idx, uint64_t position)
686{
687 size_t end = idx->num_frames, start = 0, index = 0;
688 while (start <= end)
689 {
690 size_t mid = (start + end) / 2;
691 if (idx->frames[mid].sample >= position)
692 { /* move left side. */
693 if (idx->frames[mid].sample == position)
694 return mid;
695 end = mid - 1;
696 } else
697 { /* move to right side */
698 index = mid;
699 start = mid + 1;
700 if (start == idx->num_frames)
701 break;
702 }
703 }
704 return index;
705}
706#endif
707
708int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position)
709{
710 size_t i;
711 if (!dec)
712 return MP3D_E_PARAM;
713 if (!(dec->flags & MP3D_SEEK_TO_SAMPLE))
714 {
715 if (dec->io)
716 {
717 dec->offset = position;
718 } else
719 {
720 dec->offset = MINIMP3_MIN(position, dec->file.size);
721 }
722 dec->cur_sample = 0;
723 goto do_exit;
724 }
725 dec->cur_sample = position;
726 position += dec->start_delay;
727 if (0 == position)
728 { /* optimize seek to zero, no index needed */
729seek_zero:
730 dec->offset = dec->start_offset;
731 dec->to_skip = 0;
732 goto do_exit;
733 }
734 if (!dec->indexes_built)
735 { /* no index created yet (vbr tag used to calculate track length or MP3D_DO_NOT_SCAN open flag used) */
736 dec->indexes_built = 1;
737 dec->samples = 0;
738 dec->buffer_samples = 0;
739 if (dec->io)
740 {
741 if (dec->io->seek(dec->start_offset, dec->io->seek_data))
742 return MP3D_E_IOERROR;
743 int ret = mp3dec_iterate_cb(dec->io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
744 if (ret && MP3D_E_USER != ret)
745 return ret;
746 } else
747 {
748 int ret = mp3dec_iterate_buf(dec->file.buffer + dec->start_offset, dec->file.size - dec->start_offset, mp3dec_load_index, dec);
749 if (ret && MP3D_E_USER != ret)
750 return ret;
751 }
752 for (i = 0; i < dec->index.num_frames; i++)
753 dec->index.frames[i].offset += dec->start_offset;
754 dec->samples = dec->detected_samples;
755 }
756 if (!dec->index.frames)
757 goto seek_zero; /* no frames in file - seek to zero */
758#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
759 for (i = 0; i < dec->index.num_frames; i++)
760 {
761 if (dec->index.frames[i].sample >= position)
762 break;
763 }
764#else
765 i = mp3dec_idx_binary_search(&dec->index, position);
766#endif
767 if (i)
768 {
769 int to_fill_bytes = 511;
770 int skip_frames = MINIMP3_PREDECODE_FRAMES
771#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
772 + ((dec->index.frames[i].sample == position) ? 0 : 1)
773#endif
774 ;
775 i -= MINIMP3_MIN(i, (size_t)skip_frames);
776 if (3 == dec->info.layer)
777 {
778 while (i && to_fill_bytes)
779 { /* make sure bit-reservoir is filled when we start decoding */
780 bs_t bs[1];
781 L3_gr_info_t gr_info[4];
782 int frame_bytes, frame_size;
783 const uint8_t *hdr;
784 if (dec->io)
785 {
786 hdr = dec->file.buffer;
787 if (dec->io->seek(dec->index.frames[i - 1].offset, dec->io->seek_data))
788 return MP3D_E_IOERROR;
789 size_t readed = dec->io->read((uint8_t *)hdr, HDR_SIZE, dec->io->read_data);
790 if (readed != HDR_SIZE)
791 return MP3D_E_IOERROR;
792 frame_size = hdr_frame_bytes(hdr, dec->free_format_bytes) + hdr_padding(hdr);
793 readed = dec->io->read((uint8_t *)hdr + HDR_SIZE, frame_size - HDR_SIZE, dec->io->read_data);
794 if (readed != (size_t)(frame_size - HDR_SIZE))
795 return MP3D_E_IOERROR;
796 bs_init(bs, hdr + HDR_SIZE, frame_size - HDR_SIZE);
797 } else
798 {
799 hdr = dec->file.buffer + dec->index.frames[i - 1].offset;
800 frame_size = hdr_frame_bytes(hdr, dec->free_format_bytes) + hdr_padding(hdr);
801 bs_init(bs, hdr + HDR_SIZE, frame_size - HDR_SIZE);
802 }
803 if (HDR_IS_CRC(hdr))
804 get_bits(bs, 16);
805 i--;
806 if (L3_read_side_info(bs, gr_info, hdr) < 0)
807 break; /* frame not decodable, we can start from here */
808 frame_bytes = (bs->limit - bs->pos)/8;
809 to_fill_bytes -= MINIMP3_MIN(to_fill_bytes, frame_bytes);
810 }
811 }
812 }
813 dec->offset = dec->index.frames[i].offset;
814 dec->to_skip = position - dec->index.frames[i].sample;
815 while ((i + 1) < dec->index.num_frames && !dec->index.frames[i].sample && !dec->index.frames[i + 1].sample)
816 { /* skip not decodable first frames */
817 const uint8_t *hdr;
818 if (dec->io)
819 {
820 hdr = dec->file.buffer;
821 if (dec->io->seek(dec->index.frames[i].offset, dec->io->seek_data))
822 return MP3D_E_IOERROR;
823 size_t readed = dec->io->read((uint8_t *)hdr, HDR_SIZE, dec->io->read_data);
824 if (readed != HDR_SIZE)
825 return MP3D_E_IOERROR;
826 } else
827 hdr = dec->file.buffer + dec->index.frames[i].offset;
828 dec->to_skip += hdr_frame_samples(hdr)*dec->info.channels;
829 i++;
830 }
831do_exit:
832 if (dec->io)
833 {
834 if (dec->io->seek(dec->offset, dec->io->seek_data))
835 return MP3D_E_IOERROR;
836 }
837 dec->buffer_samples = 0;
838 dec->buffer_consumed = 0;
839 dec->input_consumed = 0;
840 dec->input_filled = 0;
841 dec->last_error = 0;
842 mp3dec_init(&dec->mp3d);
843 return 0;
844}
845
846size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples)
847{
848 if (!dec || !buf)
849 {
850 if (dec)
852 return 0;
853 }
854 uint64_t end_offset = dec->end_offset ? dec->end_offset : dec->file.size;
855 size_t samples_requested = samples;
856 int eof = 0;
857 mp3dec_frame_info_t frame_info;
858 memset(&frame_info, 0, sizeof(frame_info));
859 if (dec->detected_samples && dec->cur_sample >= dec->detected_samples)
860 return 0; /* at end of stream */
861 if (dec->last_error)
862 return 0; /* error eof state, seek can reset it */
863 if (dec->buffer_consumed < dec->buffer_samples)
864 {
865 size_t to_copy = MINIMP3_MIN((size_t)(dec->buffer_samples - dec->buffer_consumed), samples);
866 if (dec->detected_samples)
867 { /* count decoded samples to properly cut padding */
868 if (dec->cur_sample + to_copy >= dec->detected_samples)
869 to_copy = dec->detected_samples - dec->cur_sample;
870 }
871 dec->cur_sample += to_copy;
872 memcpy(buf, dec->buffer + dec->buffer_consumed, to_copy*sizeof(mp3d_sample_t));
873 buf += to_copy;
874 dec->buffer_consumed += to_copy;
875 samples -= to_copy;
876 }
877 while (samples)
878 {
879 if (dec->detected_samples && dec->cur_sample >= dec->detected_samples)
880 break;
881 const uint8_t *dec_buf;
882 if (dec->io)
883 {
884 if (!eof && (dec->input_filled - dec->input_consumed) < MINIMP3_BUF_SIZE)
885 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
886 memmove((uint8_t*)dec->file.buffer, (uint8_t*)dec->file.buffer + dec->input_consumed, dec->input_filled - dec->input_consumed);
887 dec->input_filled -= dec->input_consumed;
888 dec->input_consumed = 0;
889 size_t readed = dec->io->read((uint8_t*)dec->file.buffer + dec->input_filled, dec->file.size - dec->input_filled, dec->io->read_data);
890 if (readed > (dec->file.size - dec->input_filled))
891 {
893 readed = 0;
894 }
895 if (readed != (dec->file.size - dec->input_filled))
896 eof = 1;
897 dec->input_filled += readed;
898 if (eof)
900 }
901 dec_buf = dec->file.buffer + dec->input_consumed;
902 if (!(dec->input_filled - dec->input_consumed))
903 break;
904 dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, dec_buf, dec->input_filled - dec->input_consumed, dec->buffer, &frame_info);
905 dec->input_consumed += frame_info.frame_bytes;
906 } else
907 {
908 dec_buf = dec->file.buffer + dec->offset;
909 uint64_t buf_size = end_offset - dec->offset;
910 if (!buf_size)
911 break;
912 dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, dec_buf, MINIMP3_MIN(buf_size, (uint64_t)INT_MAX), dec->buffer, &frame_info);
913 }
914 dec->buffer_consumed = 0;
915 if (dec->info.hz != frame_info.hz || dec->info.layer != frame_info.layer
916#ifndef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
917 || dec->info.channels != frame_info.channels
918#endif
919 )
920 {
922 break;
923 }
924 if (dec->buffer_samples)
925 {
926 dec->buffer_samples *= frame_info.channels;
927 if (dec->to_skip)
928 {
929 size_t skip = MINIMP3_MIN(dec->buffer_samples, dec->to_skip);
930 dec->buffer_consumed += skip;
931 dec->to_skip -= skip;
932 }
933 size_t to_copy = MINIMP3_MIN((size_t)(dec->buffer_samples - dec->buffer_consumed), samples);
934 if (dec->detected_samples)
935 { /* ^ handle padding */
936 if (dec->cur_sample + to_copy >= dec->detected_samples)
937 to_copy = dec->detected_samples - dec->cur_sample;
938 }
939 dec->cur_sample += to_copy;
940 memcpy(buf, dec->buffer + dec->buffer_consumed, to_copy*sizeof(mp3d_sample_t));
941 buf += to_copy;
942 dec->buffer_consumed += to_copy;
943 samples -= to_copy;
944 } else if (dec->to_skip)
945 { /* In mp3 decoding not always can start decode from any frame because of bit reservoir,
946 count skip samples for such frames */
947 int frame_samples = hdr_frame_samples(dec_buf)*frame_info.channels;
948 dec->to_skip -= MINIMP3_MIN(frame_samples, dec->to_skip);
949 }
950 dec->offset += frame_info.frame_bytes;
951 }
952 dec->info.bitrate_kbps = frame_info.bitrate_kbps;
953 return samples_requested - samples;
954}
955
956#ifndef MINIMP3_NO_STDIO
957
958#if defined(__linux__) || defined(__FreeBSD__)
959#include <errno.h>
960#include <sys/mman.h>
961#include <sys/types.h>
962#include <sys/stat.h>
963#include <unistd.h>
964#include <fcntl.h>
965#if !defined(_GNU_SOURCE)
966#include <sys/ipc.h>
967#include <sys/shm.h>
968#endif
969#if !defined(MAP_POPULATE) && defined(__linux__)
970#define MAP_POPULATE 0x08000
971#elif !defined(MAP_POPULATE)
972#define MAP_POPULATE 0
973#endif
974
975static void mp3dec_close_file(mp3dec_map_info_t *map_info)
976{
977 if (map_info->buffer && MAP_FAILED != map_info->buffer)
978 munmap((void *)map_info->buffer, map_info->size);
979 map_info->buffer = 0;
980 map_info->size = 0;
981}
982
983static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
984{
985 if (!file_name)
986 return MP3D_E_PARAM;
987 int file;
988 struct stat st;
989 memset(map_info, 0, sizeof(*map_info));
990retry_open:
991 file = open(file_name, O_RDONLY);
992 if (file < 0 && (errno == EAGAIN || errno == EINTR))
993 goto retry_open;
994 if (file < 0 || fstat(file, &st) < 0)
995 {
996 close(file);
997 return MP3D_E_IOERROR;
998 }
999
1000 map_info->size = st.st_size;
1001retry_mmap:
1002 map_info->buffer = (const uint8_t *)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, file, 0);
1003 if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1004 goto retry_mmap;
1005 close(file);
1006 if (MAP_FAILED == map_info->buffer)
1007 return MP3D_E_IOERROR;
1008 return 0;
1009}
1010
1011#if MINIMP3_ENABLE_RING && defined(__linux__) && defined(_GNU_SOURCE)
1012#define MINIMP3_HAVE_RING
1013static void mp3dec_close_ring(mp3dec_map_info_t *map_info)
1014{
1015#if defined(__linux__) && defined(_GNU_SOURCE)
1016 if (map_info->buffer && MAP_FAILED != map_info->buffer)
1017 munmap((void *)map_info->buffer, map_info->size*2);
1018#else
1019 if (map_info->buffer)
1020 {
1021 shmdt(map_info->buffer);
1022 shmdt(map_info->buffer + map_info->size);
1023 }
1024#endif
1025 map_info->buffer = 0;
1026 map_info->size = 0;
1027}
1028
1029static int mp3dec_open_ring(mp3dec_map_info_t *map_info, size_t size)
1030{
1031 int memfd, page_size;
1032#if defined(__linux__) && defined(_GNU_SOURCE)
1033 void *buffer;
1034 int res;
1035#endif
1036 memset(map_info, 0, sizeof(*map_info));
1037
1038#ifdef _SC_PAGESIZE
1039 page_size = sysconf(_SC_PAGESIZE);
1040#else
1041 page_size = getpagesize();
1042#endif
1043 map_info->size = (size + page_size - 1)/page_size*page_size;
1044
1045#if defined(__linux__) && defined(_GNU_SOURCE)
1046 memfd = memfd_create("mp3_ring", 0);
1047 if (memfd < 0)
1048 return MP3D_E_MEMORY;
1049
1050retry_ftruncate:
1051 res = ftruncate(memfd, map_info->size);
1052 if (res && (errno == EAGAIN || errno == EINTR))
1053 goto retry_ftruncate;
1054 if (res)
1055 goto error;
1056
1057retry_mmap:
1058 map_info->buffer = (const uint8_t *)mmap(NULL, map_info->size*2, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
1059 if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1060 goto retry_mmap;
1061 if (MAP_FAILED == map_info->buffer || !map_info->buffer)
1062 goto error;
1063retry_mmap2:
1064 buffer = mmap((void *)map_info->buffer, map_info->size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, memfd, 0);
1065 if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1066 goto retry_mmap2;
1067 if (MAP_FAILED == map_info->buffer || buffer != (void *)map_info->buffer)
1068 goto error;
1069retry_mmap3:
1070 buffer = mmap((void *)map_info->buffer + map_info->size, map_info->size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, memfd, 0);
1071 if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1072 goto retry_mmap3;
1073 if (MAP_FAILED == map_info->buffer || buffer != (void *)(map_info->buffer + map_info->size))
1074 goto error;
1075
1076 close(memfd);
1077 return 0;
1078error:
1079 close(memfd);
1080 mp3dec_close_ring(map_info);
1081 return MP3D_E_MEMORY;
1082#else
1083 memfd = shmget(IPC_PRIVATE, map_info->size, IPC_CREAT | 0700);
1084 if (memfd < 0)
1085 return MP3D_E_MEMORY;
1086retry_mmap:
1087 map_info->buffer = (const uint8_t *)mmap(NULL, map_info->size*2, PROT_NONE, MAP_PRIVATE, -1, 0);
1088 if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1089 goto retry_mmap;
1090 if (MAP_FAILED == map_info->buffer)
1091 goto error;
1092 if (map_info->buffer != shmat(memfd, map_info->buffer, 0))
1093 goto error;
1094 if ((map_info->buffer + map_info->size) != shmat(memfd, map_info->buffer + map_info->size, 0))
1095 goto error;
1096 if (shmctl(memfd, IPC_RMID, NULL) < 0)
1097 return MP3D_E_MEMORY;
1098 return 0;
1099error:
1100 shmctl(memfd, IPC_RMID, NULL);
1101 mp3dec_close_ring(map_info);
1102 return MP3D_E_MEMORY;
1103#endif
1104}
1105#endif /*MINIMP3_ENABLE_RING*/
1106#elif defined(_WIN32)
1107#include <windows.h>
1108
1109static void mp3dec_close_file(mp3dec_map_info_t *map_info)
1110{
1111 if (map_info->buffer)
1112 UnmapViewOfFile(map_info->buffer);
1113 map_info->buffer = 0;
1114 map_info->size = 0;
1115}
1116
1117static int mp3dec_open_file_h(HANDLE file, mp3dec_map_info_t *map_info)
1118{
1119 memset(map_info, 0, sizeof(*map_info));
1120
1121 HANDLE mapping = NULL;
1122 LARGE_INTEGER s;
1123 s.LowPart = GetFileSize(file, (DWORD*)&s.HighPart);
1124 if (s.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
1125 goto error;
1126 map_info->size = s.QuadPart;
1127
1128 mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
1129 if (!mapping)
1130 goto error;
1131 map_info->buffer = (const uint8_t*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, s.QuadPart);
1132 CloseHandle(mapping);
1133 if (!map_info->buffer)
1134 goto error;
1135
1137 return 0;
1138error:
1139 mp3dec_close_file(map_info);
1141 return MP3D_E_IOERROR;
1142}
1143
1144static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
1145{
1146 if (!file_name)
1147 return MP3D_E_PARAM;
1148 HANDLE file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
1149 if (INVALID_HANDLE_VALUE == file)
1150 return MP3D_E_IOERROR;
1151 return mp3dec_open_file_h(file, map_info);
1152}
1153
1154static int mp3dec_open_file_w(const wchar_t *file_name, mp3dec_map_info_t *map_info)
1155{
1156 if (!file_name)
1157 return MP3D_E_PARAM;
1158 HANDLE file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
1159 if (INVALID_HANDLE_VALUE == file)
1160 return MP3D_E_IOERROR;
1161 return mp3dec_open_file_h(file, map_info);
1162}
1163#else
1164#include <stdio.h>
1165
1167{
1168 if (map_info->buffer)
1169 free((void *)map_info->buffer);
1170 map_info->buffer = 0;
1171 map_info->size = 0;
1172}
1173
1174static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
1175{
1176 if (!file_name)
1177 return MP3D_E_PARAM;
1178 memset(map_info, 0, sizeof(*map_info));
1179 FILE *file = fopen(file_name, "rb");
1180 if (!file)
1181 return MP3D_E_IOERROR;
1182 int res = MP3D_E_IOERROR;
1183 long size = -1;
1184 if (fseek(file, 0, SEEK_END))
1185 goto error;
1186 size = ftell(file);
1187 if (size < 0)
1188 goto error;
1189 map_info->size = (size_t)size;
1190 if (fseek(file, 0, SEEK_SET))
1191 goto error;
1192 map_info->buffer = (uint8_t *)malloc(map_info->size);
1193 if (!map_info->buffer)
1194 {
1195 res = MP3D_E_MEMORY;
1196 goto error;
1197 }
1198 if (fread((void *)map_info->buffer, 1, map_info->size, file) != map_info->size)
1199 goto error;
1200 fclose(file);
1201 return 0;
1202error:
1203 mp3dec_close_file(map_info);
1204 fclose(file);
1205 return res;
1206}
1207#endif
1208
1210{
1211 int ret = mp3dec_detect_buf(map_info->buffer, map_info->size);
1212 mp3dec_close_file(map_info);
1213 return ret;
1214}
1215
1216static int mp3dec_load_mapinfo(mp3dec_t *dec, mp3dec_map_info_t *map_info, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1217{
1218 int ret = mp3dec_load_buf(dec, map_info->buffer, map_info->size, info, progress_cb, user_data);
1219 mp3dec_close_file(map_info);
1220 return ret;
1221}
1222
1224{
1225 int ret = mp3dec_iterate_buf(map_info->buffer, map_info->size, callback, user_data);
1226 mp3dec_close_file(map_info);
1227 return ret;
1228}
1229
1230static int mp3dec_ex_open_mapinfo(mp3dec_ex_t *dec, int flags)
1231{
1232 int ret = mp3dec_ex_open_buf(dec, dec->file.buffer, dec->file.size, flags);
1233 dec->is_file = 1;
1234 if (ret)
1235 mp3dec_ex_close(dec);
1236 return ret;
1237}
1238
1239int mp3dec_detect(const char *file_name)
1240{
1241 int ret;
1242 mp3dec_map_info_t map_info;
1243 if ((ret = mp3dec_open_file(file_name, &map_info)))
1244 return ret;
1245 return mp3dec_detect_mapinfo(&map_info);
1246}
1247
1248int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1249{
1250 int ret;
1251 mp3dec_map_info_t map_info;
1252 if ((ret = mp3dec_open_file(file_name, &map_info)))
1253 return ret;
1254 return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
1255}
1256
1257int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data)
1258{
1259 int ret;
1260 mp3dec_map_info_t map_info;
1261 if ((ret = mp3dec_open_file(file_name, &map_info)))
1262 return ret;
1263 return mp3dec_iterate_mapinfo(&map_info, callback, user_data);
1264}
1265
1266int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int flags)
1267{
1268 int ret;
1269 if (!dec)
1270 return MP3D_E_PARAM;
1271 if ((ret = mp3dec_open_file(file_name, &dec->file)))
1272 return ret;
1273 return mp3dec_ex_open_mapinfo(dec, flags);
1274}
1275
1277{
1278 if (!dec || !io || (flags & (~3)))
1279 return MP3D_E_PARAM;
1280 memset(dec, 0, sizeof(*dec));
1281#ifdef MINIMP3_HAVE_RING
1282 int ret;
1283 if (ret = mp3dec_open_ring(&dec->file, MINIMP3_IO_SIZE))
1284 return ret;
1285#else
1286 dec->file.size = MINIMP3_IO_SIZE;
1287 dec->file.buffer = (const uint8_t*)malloc(dec->file.size);
1288 if (!dec->file.buffer)
1289 return MP3D_E_MEMORY;
1290#endif
1291 dec->flags = flags;
1292 dec->io = io;
1293 mp3dec_init(&dec->mp3d);
1294 if (io->seek(0, io->seek_data))
1295 return MP3D_E_IOERROR;
1296 int ret = mp3dec_iterate_cb(io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
1297 if (ret && MP3D_E_USER != ret)
1298 return ret;
1299 if (dec->io->seek(dec->start_offset, dec->io->seek_data))
1300 return MP3D_E_IOERROR;
1301 mp3dec_init(&dec->mp3d);
1302 dec->buffer_samples = 0;
1303 dec->indexes_built = !(dec->vbr_tag_found || (flags & MP3D_DO_NOT_SCAN));
1304 dec->flags &= (~MP3D_DO_NOT_SCAN);
1305 return 0;
1306}
1307
1309{
1310#ifdef MINIMP3_HAVE_RING
1311 if (dec->io)
1312 mp3dec_close_ring(&dec->file);
1313#else
1314 if (dec->io && dec->file.buffer)
1315 free((void*)dec->file.buffer);
1316#endif
1317 if (dec->is_file)
1318 mp3dec_close_file(&dec->file);
1319 if (dec->index.frames)
1320 free(dec->index.frames);
1321 memset(dec, 0, sizeof(*dec));
1322}
1323
1324#ifdef _WIN32
1325int mp3dec_detect_w(const wchar_t *file_name)
1326{
1327 int ret;
1328 mp3dec_map_info_t map_info;
1329 if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1330 return ret;
1331 return mp3dec_detect_mapinfo(&map_info);
1332}
1333
1334int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1335{
1336 int ret;
1337 mp3dec_map_info_t map_info;
1338 if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1339 return ret;
1340 return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
1341}
1342
1343int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data)
1344{
1345 int ret;
1346 mp3dec_map_info_t map_info;
1347 if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1348 return ret;
1349 return mp3dec_iterate_mapinfo(&map_info, callback, user_data);
1350}
1351
1352int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags)
1353{
1354 int ret;
1355 if ((ret = mp3dec_open_file_w(file_name, &dec->file)))
1356 return ret;
1357 return mp3dec_ex_open_mapinfo(dec, flags);
1358}
1359#endif
1360#else /* MINIMP3_NO_STDIO */
1362{
1363 if (dec->index.frames)
1364 free(dec->index.frames);
1365 memset(dec, 0, sizeof(*dec));
1366}
1367#endif
1368
1369#endif /*MINIMP3_IMPLEMENTATION*/
#define NULL
Definition CarlaBridgeFormat.cpp:30
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
#define buf_size
virtual ASIOError start()=0
struct backing_store_struct * info
Definition jmemsys.h:183
unsigned int uint32_t
Definition mid.cpp:100
unsigned char uint8_t
Definition mid.cpp:98
#define MINIMP3_MAX_SAMPLES_PER_FRAME
Definition minimp3.h:11
int16_t mp3d_sample_t
Definition minimp3.h:31
void mp3dec_init(mp3dec_t *dec)
int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info)
#define BYTES_FLAG
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)
Definition minimp3_ex.h:83
#define MINIMP3_ID3_DETECT_SIZE
#define MINIMP3_BUF_SIZE
Definition minimp3_ex.h:20
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data)
Definition minimp3_ex.h:1257
#define MP3D_SEEK_TO_SAMPLE
Definition minimp3_ex.h:13
#define VBR_SCALE_FLAG
static void mp3dec_close_file(mp3dec_map_info_t *map_info)
Definition minimp3_ex.h:1166
int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
Definition minimp3_ex.h:1248
int(* MP3D_SEEK_CB)(uint64_t position, void *user_data)
Definition minimp3_ex.h:57
int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position)
Definition minimp3_ex.h:708
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)
Definition minimp3_ex.h:278
static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *frames, int *delay, int *padding)
Definition minimp3_ex.h:183
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags)
Definition minimp3_ex.h:665
#define MP3D_E_IOERROR
Definition minimp3_ex.h:27
static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
Definition minimp3_ex.h:1174
#define MINIMP3_PREDECODE_FRAMES
Definition minimp3_ex.h:17
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)
Definition minimp3_ex.h:273
static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size)
Definition minimp3_ex.h:127
int(* MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info)
Definition minimp3_ex.h:84
static size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size)
Definition minimp3_ex.h:151
static void mp3dec_skip_id3(const uint8_t **pbuf, size_t *pbuf_size)
Definition minimp3_ex.h:166
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int flags)
Definition minimp3_ex.h:1276
#define MP3D_E_MEMORY
Definition minimp3_ex.h:26
#define FRAMES_FLAG
void mp3dec_ex_close(mp3dec_ex_t *dec)
Definition minimp3_ex.h:1308
int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size)
Definition minimp3_ex.h:235
static int mp3dec_load_mapinfo(mp3dec_t *dec, mp3dec_map_info_t *map_info, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
Definition minimp3_ex.h:1216
#define MP3D_DO_NOT_SCAN
Definition minimp3_ex.h:14
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
Definition minimp3_ex.h:492
static int mp3dec_ex_open_mapinfo(mp3dec_ex_t *dec, int flags)
Definition minimp3_ex.h:1230
#define MP3D_E_USER
Definition minimp3_ex.h:28
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
Definition minimp3_ex.h:531
static size_t mp3dec_idx_binary_search(mp3dec_index_t *idx, uint64_t position)
Definition minimp3_ex.h:685
static int mp3dec_detect_mapinfo(mp3dec_map_info_t *map_info)
Definition minimp3_ex.h:1209
int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size)
Definition minimp3_ex.h:230
#define MP3D_E_DECODE
Definition minimp3_ex.h:29
size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples)
Definition minimp3_ex.h:846
size_t(* MP3D_READ_CB)(void *buf, size_t size, void *user_data)
Definition minimp3_ex.h:56
#define MINIMP3_IO_SIZE
Definition minimp3_ex.h:19
int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int flags)
Definition minimp3_ex.h:1266
#define TOC_FLAG
static int mp3dec_load_index(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)
Definition minimp3_ex.h:606
static int mp3dec_iterate_mapinfo(mp3dec_map_info_t *map_info, MP3D_ITERATE_CB callback, void *user_data)
Definition minimp3_ex.h:1223
#define MP3D_E_PARAM
Definition minimp3_ex.h:25
int mp3dec_detect(const char *file_name)
Definition minimp3_ex.h:1239
JOCTET * buffer
Definition juce_JPEGLoader.cpp:302
Definition minimp3_ex.h:68
uint64_t cur_sample
Definition minimp3_ex.h:73
int to_skip
Definition minimp3_ex.h:79
uint64_t samples
Definition minimp3_ex.h:73
mp3dec_t mp3d
Definition minimp3_ex.h:69
uint64_t end_offset
Definition minimp3_ex.h:73
int flags
Definition minimp3_ex.h:77
mp3dec_frame_info_t info
Definition minimp3_ex.h:74
int free_format_bytes
Definition minimp3_ex.h:78
mp3dec_io_t * io
Definition minimp3_ex.h:71
uint64_t offset
Definition minimp3_ex.h:73
int indexes_built
Definition minimp3_ex.h:77
mp3dec_index_t index
Definition minimp3_ex.h:72
size_t input_filled
Definition minimp3_ex.h:76
int vbr_tag_found
Definition minimp3_ex.h:77
uint64_t start_offset
Definition minimp3_ex.h:73
int buffer_samples
Definition minimp3_ex.h:79
mp3d_sample_t buffer[MINIMP3_MAX_SAMPLES_PER_FRAME]
Definition minimp3_ex.h:75
mp3dec_map_info_t file
Definition minimp3_ex.h:70
int start_delay
Definition minimp3_ex.h:79
int last_error
Definition minimp3_ex.h:80
size_t input_consumed
Definition minimp3_ex.h:76
uint64_t detected_samples
Definition minimp3_ex.h:73
int is_file
Definition minimp3_ex.h:77
int buffer_consumed
Definition minimp3_ex.h:79
Definition minimp3_ex.h:32
int avg_bitrate_kbps
Definition minimp3_ex.h:35
mp3d_sample_t * buffer
Definition minimp3_ex.h:33
int channels
Definition minimp3_ex.h:35
int layer
Definition minimp3_ex.h:35
int hz
Definition minimp3_ex.h:35
size_t samples
Definition minimp3_ex.h:34
Definition minimp3.h:14
int bitrate_kbps
Definition minimp3.h:15
int frame_bytes
Definition minimp3.h:15
int channels
Definition minimp3.h:15
int hz
Definition minimp3.h:15
int layer
Definition minimp3.h:15
Definition minimp3_ex.h:45
uint64_t offset
Definition minimp3_ex.h:47
uint64_t sample
Definition minimp3_ex.h:46
Definition minimp3_ex.h:51
mp3dec_frame_t * frames
Definition minimp3_ex.h:52
size_t num_frames
Definition minimp3_ex.h:53
size_t capacity
Definition minimp3_ex.h:53
Definition minimp3_ex.h:60
MP3D_SEEK_CB seek
Definition minimp3_ex.h:63
MP3D_READ_CB read
Definition minimp3_ex.h:61
void * read_data
Definition minimp3_ex.h:62
void * seek_data
Definition minimp3_ex.h:64
Definition minimp3_ex.h:39
size_t size
Definition minimp3_ex.h:41
const uint8_t * buffer
Definition minimp3_ex.h:40
Definition minimp3.h:19
RECT const char void(* callback)(const char *droppath))) SWELL_API_DEFINE(BOOL
Definition swell-functions.h:1004
unsigned int DWORD
Definition swell-types.h:164
void * HANDLE
Definition swell-types.h:212
BOOL CloseHandle(HANDLE hand)
Definition swell.cpp:157
memcpy(hh, h, RAND_HEAD_LEN)
int error
Definition extract.c:1038
ulg size
Definition extract.c:2350
typedef int(UZ_EXP MsgFn)()
#define SEEK_SET
Definition unzpriv.h:1302
#define SEEK_END
Definition unzpriv.h:1304
char * malloc()
struct zdirent * file
Definition win32.c:1500