1 /* 2 https://github.com/lieff/minimp3 3 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. 4 This software is distributed without any warranty. 5 See <http://creativecommons.org/publicdomain/zero/1.0/>. 6 */ 7 /** 8 Translated to D by Guillaume Piolat. 9 Stripped down a bit for the needs of audio-formats. 10 */ 11 module audioformats.minimp3_ex; 12 13 import core.stdc.stdlib; 14 import core.stdc.string; 15 16 import audioformats.minimp3; 17 18 nothrow: 19 @nogc: 20 21 enum MP3D_SEEK_TO_BYTE = 0; 22 enum MP3D_SEEK_TO_SAMPLE = 1; 23 24 enum MINIMP3_PREDECODE_FRAMES = 2; /* frames to pre-decode and skip after seek (to fill internal structures) */ 25 /*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */ 26 enum MINIMP3_IO_SIZE = (128*1024); /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */ 27 enum MINIMP3_BUF_SIZE = (16*1024); /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */ 28 enum MINIMP3_ENABLE_RING = 0; /* enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */ 29 30 enum MP3D_E_PARAM = -1; 31 enum MP3D_E_MEMORY = -2; 32 enum MP3D_E_IOERROR = -3; 33 enum MP3D_E_USER = -4; /* can be used to stop processing from callbacks without indicating specific error */ 34 enum MP3D_E_DECODE = -5; /* decode error which can't be safely skipped, such as sample rate, layer and channels change */ 35 36 struct mp3dec_file_info_t 37 { 38 mp3d_sample_t *buffer; 39 size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */ 40 int channels, hz, layer, avg_bitrate_kbps; 41 } 42 43 struct mp3dec_map_info_t 44 { 45 const(uint8_t) *buffer; 46 size_t size; 47 } 48 49 struct mp3dec_frame_t 50 { 51 uint64_t sample; 52 uint64_t offset; 53 } 54 55 struct mp3dec_index_t 56 { 57 mp3dec_frame_t *frames; 58 size_t num_frames, capacity; 59 } 60 61 alias MP3D_READ_CB = size_t function(void *buf, size_t size, void *user_data); 62 alias MP3D_SEEK_CB = int function(uint64_t position, void *user_data); 63 64 65 struct mp3dec_io_t 66 { 67 MP3D_READ_CB read; 68 void *read_data; 69 MP3D_SEEK_CB seek; 70 void *seek_data; 71 } 72 73 struct mp3dec_ex_t 74 { 75 mp3dec_t mp3d; 76 mp3dec_map_info_t file; 77 mp3dec_io_t *io; 78 mp3dec_index_t index; 79 uint64_t offset, samples, detected_samples, cur_sample, start_offset, end_offset; 80 mp3dec_frame_info_t info; 81 mp3d_sample_t[MINIMP3_MAX_SAMPLES_PER_FRAME] buffer; 82 size_t input_consumed, input_filled; 83 int is_file, seek_method, vbr_tag_found; 84 int free_format_bytes; 85 int buffer_samples, buffer_consumed, to_skip, start_delay; 86 int last_error; 87 } 88 89 alias MP3D_ITERATE_CB = int function(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); 90 alias MP3D_PROGRESS_CB = int function(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info); 91 92 93 void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size) 94 { 95 size_t buf_size = *pbuf_size; 96 if (buf_size >= 128 && !memcmp(buf + buf_size - 128, "TAG".ptr, 3)) 97 { 98 buf_size -= 128; 99 if (buf_size >= 227 && !memcmp(buf + buf_size - 227, "TAG+".ptr, 4)) 100 buf_size -= 227; 101 } 102 if (buf_size > 32 && !memcmp(buf + buf_size - 32, "APETAGEX".ptr, 8)) 103 { 104 buf_size -= 32; 105 const uint8_t *tag = buf + buf_size + 8 + 4; 106 uint32_t tag_size = cast(uint32_t)(tag[3] << 24) | (tag[2] << 16) | (tag[1] << 8) | tag[0]; 107 if (buf_size >= tag_size) 108 buf_size -= tag_size; 109 } 110 *pbuf_size = buf_size; 111 } 112 113 enum MINIMP3_ID3_DETECT_SIZE = 10; 114 115 size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size) 116 { 117 if (buf_size >= MINIMP3_ID3_DETECT_SIZE && !memcmp(buf, "ID3".ptr, 3) && !((buf[5] & 15) || (buf[6] & 0x80) || (buf[7] & 0x80) || (buf[8] & 0x80) || (buf[9] & 0x80))) 118 { 119 size_t id3v2size = (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10; 120 if ((buf[5] & 16)) 121 id3v2size += 10; /* footer */ 122 return id3v2size; 123 }enum MINIMP3_ID3_DETECT_SIZE = 10; 124 return 0; 125 } 126 127 void mp3dec_skip_id3(const(uint8_t)**pbuf, size_t *pbuf_size) 128 { 129 uint8_t *buf = cast(uint8_t *)(*pbuf); 130 size_t buf_size = *pbuf_size; 131 size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size); 132 if (id3v2size) 133 { 134 if (id3v2size >= buf_size) 135 id3v2size = buf_size; 136 buf += id3v2size; 137 buf_size -= id3v2size; 138 } 139 mp3dec_skip_id3v1(buf, &buf_size); 140 *pbuf = cast(const uint8_t *)buf; 141 *pbuf_size = buf_size; 142 } 143 144 static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *frames, int *delay, int *padding) 145 { 146 static immutable char[4] g_xing_tag = "Xing"; 147 static immutable char[4] g_info_tag = "Info"; 148 149 enum FRAMES_FLAG = 1; 150 enum BYTES_FLAG = 2; 151 enum TOC_FLAG = 4; 152 enum VBR_SCALE_FLAG = 8; 153 /* Side info offsets after header: 154 / Mono Stereo 155 / MPEG1 17 32 156 / MPEG2 & 2.5 9 17*/ 157 bs_t[1] bs; 158 L3_gr_info_t[4] gr_info; 159 bs_init(bs.ptr, frame + HDR_SIZE, frame_size - HDR_SIZE); 160 if (HDR_IS_CRC(frame)) 161 get_bits(bs.ptr, 16); 162 if (L3_read_side_info(bs.ptr, gr_info.ptr, frame) < 0) 163 return 0; /* side info corrupted */ 164 165 const(uint8_t)*tag = frame + HDR_SIZE + bs[0].pos/8; 166 if (memcmp(g_xing_tag.ptr, tag, 4) && memcmp(g_info_tag.ptr, tag, 4)) 167 return 0; 168 int flags = tag[7]; 169 if (!((flags & FRAMES_FLAG))) 170 return -1; 171 tag += 8; 172 *frames = cast(uint32_t)(tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3]; 173 tag += 4; 174 if (flags & BYTES_FLAG) 175 tag += 4; 176 if (flags & TOC_FLAG) 177 tag += 100; 178 if (flags & VBR_SCALE_FLAG) 179 tag += 4; 180 *delay = *padding = 0; 181 if (*tag) 182 { /* extension, LAME, Lavc, etc. Should be the same structure. */ 183 tag += 21; 184 if (tag - frame + 14 >= frame_size) 185 return 0; 186 *delay = ((tag[0] << 4) | (tag[1] >> 4)) + (528 + 1); 187 *padding = (((tag[1] & 0xF) << 8) | tag[2]) - (528 + 1); 188 } 189 return 1; 190 } 191 192 int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size) 193 { 194 return mp3dec_detect_cb(null, cast(uint8_t *)buf, buf_size); 195 } 196 197 int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size) 198 { 199 if (!buf || cast(size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE)) 200 return MP3D_E_PARAM; 201 size_t filled = buf_size; 202 if (io) 203 { 204 if (io.seek(0, io.seek_data)) 205 return MP3D_E_IOERROR; 206 filled = io.read(buf, MINIMP3_ID3_DETECT_SIZE, io.read_data); 207 if (filled > MINIMP3_ID3_DETECT_SIZE) 208 return MP3D_E_IOERROR; 209 } 210 if (filled < MINIMP3_ID3_DETECT_SIZE) 211 return MP3D_E_USER; /* too small, can't be mp3/mpa */ 212 if (mp3dec_skip_id3v2(buf, filled)) 213 return 0; /* id3v2 tag is enough evidence */ 214 if (io) 215 { 216 size_t readed = io.read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io.read_data); 217 if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE)) 218 return MP3D_E_IOERROR; 219 filled += readed; 220 if (filled < MINIMP3_BUF_SIZE) 221 mp3dec_skip_id3v1(buf, &filled); 222 } else 223 { 224 mp3dec_skip_id3v1(buf, &filled); 225 if (filled > MINIMP3_BUF_SIZE) 226 filled = MINIMP3_BUF_SIZE; 227 } 228 int free_format_bytes, frame_size; 229 mp3d_find_frame(buf, cast(int)filled, &free_format_bytes, &frame_size); 230 if (frame_size) 231 return 0; /* MAX_FRAME_SYNC_MATCHES consecutive frames found */ 232 return MP3D_E_USER; 233 } 234 235 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) 236 { 237 return mp3dec_load_cb(dec, null, cast(uint8_t *)buf, buf_size, info, progress_cb, user_data); 238 } 239 240 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) 241 { 242 if (!dec || !buf || !info || cast(size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE)) 243 return MP3D_E_PARAM; 244 uint64_t detected_samples = 0; 245 size_t orig_buf_size = buf_size; 246 int to_skip = 0; 247 mp3dec_frame_info_t frame_info; 248 memset(info, 0, (*info).sizeof); 249 memset(&frame_info, 0, (frame_info).sizeof); 250 251 /* skip id3 */ 252 size_t filled = 0, consumed = 0; 253 int eof = 0, ret2 = 0; 254 if (io) 255 { 256 if (io.seek(0, io.seek_data)) 257 return MP3D_E_IOERROR; 258 filled = io.read(buf, MINIMP3_ID3_DETECT_SIZE, io.read_data); 259 if (filled > MINIMP3_ID3_DETECT_SIZE) 260 return MP3D_E_IOERROR; 261 if (MINIMP3_ID3_DETECT_SIZE != filled) 262 return 0; 263 size_t id3v2size = mp3dec_skip_id3v2(buf, filled); 264 if (id3v2size) 265 { 266 if (io.seek(id3v2size, io.seek_data)) 267 return MP3D_E_IOERROR; 268 filled = io.read(buf, buf_size, io.read_data); 269 if (filled > buf_size) 270 return MP3D_E_IOERROR; 271 } else 272 { 273 size_t readed = io.read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io.read_data); 274 if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE)) 275 return MP3D_E_IOERROR; 276 filled += readed; 277 } 278 if (filled < MINIMP3_BUF_SIZE) 279 mp3dec_skip_id3v1(buf, &filled); 280 } else 281 { 282 mp3dec_skip_id3(cast(const(uint8_t)**)&buf, &buf_size); 283 if (!buf_size) 284 return 0; 285 } 286 /* try to make allocation size assumption by first frame or vbr tag */ 287 mp3dec_init(dec); 288 int samples; 289 do 290 { 291 uint32_t frames; 292 int i, delay, padding, free_format_bytes = 0, frame_size = 0; 293 const(uint8_t) *hdr; 294 if (io) 295 { 296 if (!eof && filled - consumed < MINIMP3_BUF_SIZE) 297 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */ 298 memmove(buf, buf + consumed, filled - consumed); 299 filled -= consumed; 300 consumed = 0; 301 size_t readed = io.read(buf + filled, buf_size - filled, io.read_data); 302 if (readed > (buf_size - filled)) 303 return MP3D_E_IOERROR; 304 if (readed != (buf_size - filled)) 305 eof = 1; 306 filled += readed; 307 if (eof) 308 mp3dec_skip_id3v1(buf, &filled); 309 } 310 i = mp3d_find_frame(buf + consumed, cast(int)(filled - consumed), &free_format_bytes, &frame_size); 311 consumed += i; 312 hdr = buf + consumed; 313 } else 314 { 315 i = mp3d_find_frame(buf, cast(int)buf_size, &free_format_bytes, &frame_size); 316 buf += i; 317 buf_size -= i; 318 hdr = buf; 319 } 320 if (i && !frame_size) 321 continue; 322 if (!frame_size) 323 return 0; 324 frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2; 325 frame_info.hz = hdr_sample_rate_hz(hdr); 326 frame_info.layer = 4 - HDR_GET_LAYER(hdr); 327 frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr); 328 frame_info.frame_bytes = frame_size; 329 samples = hdr_frame_samples(hdr)*frame_info.channels; 330 if (3 != frame_info.layer) 331 break; 332 int ret = mp3dec_check_vbrtag(hdr, frame_size, &frames, &delay, &padding); 333 if (ret > 0) 334 { 335 padding *= frame_info.channels; 336 to_skip = delay*frame_info.channels; 337 detected_samples = samples*cast(uint64_t)frames; 338 if (detected_samples >= cast(uint64_t)to_skip) 339 detected_samples -= to_skip; 340 if (padding > 0 && detected_samples >= cast(uint64_t)padding) 341 detected_samples -= padding; 342 if (!detected_samples) 343 return 0; 344 } 345 if (ret) 346 { 347 if (io) 348 { 349 consumed += frame_size; 350 } else 351 { 352 buf += frame_size; 353 buf_size -= frame_size; 354 } 355 } 356 break; 357 } while(1); 358 size_t allocated = MINIMP3_MAX_SAMPLES_PER_FRAME*(mp3d_sample_t.sizeof); 359 if (detected_samples) 360 allocated += detected_samples*(mp3d_sample_t.sizeof); 361 else 362 allocated += (buf_size/frame_info.frame_bytes)*samples*(mp3d_sample_t.sizeof); 363 info.buffer = cast(mp3d_sample_t*) malloc(allocated); 364 if (!info.buffer) 365 return MP3D_E_MEMORY; 366 /* save info */ 367 info.channels = frame_info.channels; 368 info.hz = frame_info.hz; 369 info.layer = frame_info.layer; 370 /* decode all frames */ 371 size_t avg_bitrate_kbps = 0, frames = 0; 372 do 373 { 374 if ((allocated - info.samples*(mp3d_sample_t.sizeof)) < MINIMP3_MAX_SAMPLES_PER_FRAME*(mp3d_sample_t.sizeof)) 375 { 376 allocated *= 2; 377 mp3d_sample_t *alloc_buf = cast(mp3d_sample_t*)realloc(info.buffer, allocated); 378 if (!alloc_buf) 379 return MP3D_E_MEMORY; 380 info.buffer = alloc_buf; 381 } 382 if (io) 383 { 384 if (!eof && filled - consumed < MINIMP3_BUF_SIZE) 385 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */ 386 memmove(buf, buf + consumed, filled - consumed); 387 filled -= consumed; 388 consumed = 0; 389 size_t readed = io.read(buf + filled, buf_size - filled, io.read_data); 390 if (readed != (buf_size - filled)) 391 eof = 1; 392 filled += readed; 393 if (eof) 394 mp3dec_skip_id3v1(buf, &filled); 395 } 396 samples = mp3dec_decode_frame(dec, buf + consumed, cast(int)(filled - consumed), info.buffer + info.samples, &frame_info); 397 consumed += frame_info.frame_bytes; 398 } else 399 { 400 samples = mp3dec_decode_frame(dec, buf, cast(int)MINIMP3_MIN(buf_size, cast(size_t)int.max), info.buffer + info.samples, &frame_info); 401 buf += frame_info.frame_bytes; 402 buf_size -= frame_info.frame_bytes; 403 } 404 if (samples) 405 { 406 if (info.hz != frame_info.hz || info.layer != frame_info.layer) 407 { 408 ret2 = MP3D_E_DECODE; 409 break; 410 } 411 if (info.channels && info.channels != frame_info.channels) 412 { 413 ret2 = MP3D_E_DECODE; 414 break; 415 } 416 samples *= frame_info.channels; 417 if (to_skip) 418 { 419 size_t skip = MINIMP3_MIN(samples, to_skip); 420 to_skip -= skip; 421 samples -= skip; 422 memmove(info.buffer, info.buffer + skip, samples); 423 } 424 info.samples += samples; 425 avg_bitrate_kbps += frame_info.bitrate_kbps; 426 frames++; 427 if (progress_cb) 428 { 429 ret2 = progress_cb(user_data, orig_buf_size, (orig_buf_size - buf_size), &frame_info); 430 if (ret2) 431 break; 432 } 433 } 434 } while (frame_info.frame_bytes); 435 if (detected_samples && info.samples > detected_samples) 436 info.samples = cast(size_t) detected_samples; /* cut padding */ 437 /* reallocate to normal buffer size */ 438 if (allocated != info.samples*(mp3d_sample_t.sizeof)) 439 { 440 mp3d_sample_t *alloc_buf = cast(mp3d_sample_t*)realloc(info.buffer, info.samples*(mp3d_sample_t.sizeof)); 441 if (!alloc_buf && info.samples) 442 return MP3D_E_MEMORY; 443 info.buffer = alloc_buf; 444 } 445 if (frames) 446 info.avg_bitrate_kbps = cast(int)(avg_bitrate_kbps/frames); 447 return ret2; 448 } 449 450 int mp3dec_iterate_buf(const(uint8_t)*buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data) 451 { 452 const uint8_t *orig_buf = buf; 453 if (!buf || cast(size_t)-1 == buf_size || !callback) 454 return MP3D_E_PARAM; 455 /* skip id3 */ 456 mp3dec_skip_id3(&buf, &buf_size); 457 if (!buf_size) 458 return 0; 459 mp3dec_frame_info_t frame_info; 460 memset(&frame_info, 0, (frame_info.sizeof)); 461 do 462 { 463 int free_format_bytes = 0, frame_size = 0, ret; 464 int i = mp3d_find_frame(buf, cast(int)buf_size, &free_format_bytes, &frame_size); 465 buf += i; 466 buf_size -= i; 467 if (i && !frame_size) 468 continue; 469 if (!frame_size) 470 break; 471 const uint8_t *hdr = buf; 472 frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2; 473 frame_info.hz = hdr_sample_rate_hz(hdr); 474 frame_info.layer = 4 - HDR_GET_LAYER(hdr); 475 frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr); 476 frame_info.frame_bytes = frame_size; 477 478 if (callback) 479 { 480 ret = callback(user_data, hdr, frame_size, free_format_bytes, buf_size, (hdr - orig_buf), &frame_info); 481 if (ret) 482 return ret; 483 } 484 buf += frame_size; 485 buf_size -= frame_size; 486 } while (1); 487 return 0; 488 } 489 490 int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data) 491 { 492 if (!io || !buf || cast(size_t)-1 == buf_size || buf_size < MINIMP3_BUF_SIZE || !callback) 493 return MP3D_E_PARAM; 494 size_t filled = io.read(buf, MINIMP3_ID3_DETECT_SIZE, io.read_data), consumed = 0; 495 uint64_t readed2 = 0; 496 mp3dec_frame_info_t frame_info; 497 int eof = 0; 498 memset(&frame_info, 0, (frame_info.sizeof)); 499 if (filled > MINIMP3_ID3_DETECT_SIZE) 500 return MP3D_E_IOERROR; 501 if (MINIMP3_ID3_DETECT_SIZE != filled) 502 return 0; 503 size_t id3v2size = mp3dec_skip_id3v2(buf, filled); 504 if (id3v2size) 505 { 506 if (io.seek(id3v2size, io.seek_data)) 507 return MP3D_E_IOERROR; 508 filled = io.read(buf, buf_size, io.read_data); 509 if (filled > buf_size) 510 return MP3D_E_IOERROR; 511 readed2 += id3v2size; 512 } else 513 { 514 size_t readed = io.read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io.read_data); 515 if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE)) 516 return MP3D_E_IOERROR; 517 filled += readed; 518 } 519 if (filled < MINIMP3_BUF_SIZE) 520 mp3dec_skip_id3v1(buf, &filled); 521 do 522 { 523 int free_format_bytes = 0, frame_size = 0, ret; 524 int i = mp3d_find_frame(buf + consumed, cast(int)(filled - consumed), &free_format_bytes, &frame_size); 525 if (i && !frame_size) 526 { 527 consumed += i; 528 continue; 529 } 530 if (!frame_size) 531 break; 532 const uint8_t *hdr = buf + consumed + i; 533 frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2; 534 frame_info.hz = hdr_sample_rate_hz(hdr); 535 frame_info.layer = 4 - HDR_GET_LAYER(hdr); 536 frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr); 537 frame_info.frame_bytes = frame_size; 538 539 readed2 += i; 540 if (callback) 541 { 542 ret = callback(user_data, hdr, frame_size, free_format_bytes, filled - consumed, readed2, &frame_info); 543 if (ret) 544 return ret; 545 } 546 readed2 += frame_size; 547 consumed += i + frame_size; 548 if (!eof && filled - consumed < MINIMP3_BUF_SIZE) 549 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */ 550 memmove(buf, buf + consumed, filled - consumed); 551 filled -= consumed; 552 consumed = 0; 553 size_t readed = io.read(buf + filled, buf_size - filled, io.read_data); 554 if (readed > (buf_size - filled)) 555 return MP3D_E_IOERROR; 556 if (readed != (buf_size - filled)) 557 eof = 1; 558 filled += readed; 559 if (eof) 560 mp3dec_skip_id3v1(buf, &filled); 561 } 562 } while (1); 563 return 0; 564 } 565 566 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) 567 { 568 mp3dec_frame_t *idx_frame; 569 mp3dec_ex_t *dec = cast(mp3dec_ex_t *)user_data; 570 if (!dec.index.frames && !dec.start_offset) 571 { /* detect VBR tag and try to avoid full scan */ 572 uint32_t frames; 573 int delay, padding; 574 dec.info = *info; 575 dec.start_offset = dec.offset = offset; 576 dec.end_offset = (offset + buf_size); 577 dec.free_format_bytes = free_format_bytes; /* should not change */ 578 if (3 == dec.info.layer) 579 { 580 int ret = mp3dec_check_vbrtag(frame, frame_size, &frames, &delay, &padding); 581 if (ret) 582 dec.start_offset = dec.offset = offset + frame_size; 583 if (ret > 0) 584 { 585 padding *= info.channels; 586 dec.start_delay = dec.to_skip = delay*info.channels; 587 dec.samples = hdr_frame_samples(frame)*info.channels*cast(uint64_t)frames; 588 if (dec.samples >= cast(uint64_t)dec.start_delay) 589 dec.samples -= dec.start_delay; 590 if (padding > 0 && dec.samples >= cast(uint64_t)padding) 591 dec.samples -= padding; 592 dec.detected_samples = dec.samples; 593 dec.vbr_tag_found = 1; 594 return MP3D_E_USER; 595 } else if (ret < 0) 596 return 0; 597 } 598 } 599 if (dec.index.num_frames + 1 > dec.index.capacity) 600 { 601 if (!dec.index.capacity) 602 dec.index.capacity = 4096; 603 else 604 dec.index.capacity *= 2; 605 mp3dec_frame_t *alloc_buf = cast(mp3dec_frame_t *)realloc(cast(void*)dec.index.frames, (mp3dec_frame_t.sizeof)*dec.index.capacity); 606 if (!alloc_buf) 607 return MP3D_E_MEMORY; 608 dec.index.frames = alloc_buf; 609 } 610 idx_frame = &dec.index.frames[dec.index.num_frames++]; 611 idx_frame.offset = offset; 612 idx_frame.sample = dec.samples; 613 if (!dec.buffer_samples && dec.index.num_frames < 256) 614 { /* for some cutted mp3 frames, bit-reservoir not filled and decoding can't be started from first frames */ 615 /* try to decode up to 255 first frames till samples starts to decode */ 616 dec.buffer_samples = mp3dec_decode_frame(&dec.mp3d, frame, cast(int)MINIMP3_MIN(buf_size, cast(size_t)int.max), dec.buffer.ptr, info); 617 dec.samples += dec.buffer_samples*info.channels; 618 } else 619 dec.samples += hdr_frame_samples(frame)*info.channels; 620 return 0; 621 } 622 623 int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method) 624 { 625 if (!dec || !buf || cast(size_t)-1 == buf_size || !(MP3D_SEEK_TO_BYTE == seek_method || MP3D_SEEK_TO_SAMPLE == seek_method)) 626 return MP3D_E_PARAM; 627 memset(dec, 0, (*dec).sizeof); 628 dec.file.buffer = buf; 629 dec.file.size = buf_size; 630 dec.seek_method = seek_method; 631 mp3dec_init(&dec.mp3d); 632 int ret = mp3dec_iterate_buf(dec.file.buffer, dec.file.size, &mp3dec_load_index, dec); 633 if (ret && MP3D_E_USER != ret) 634 return ret; 635 mp3dec_init(&dec.mp3d); 636 dec.buffer_samples = 0; 637 return 0; 638 } 639 640 size_t mp3dec_idx_binary_search(mp3dec_index_t *idx, uint64_t position) 641 { 642 size_t end = idx.num_frames, start = 0, index = 0; 643 while (start <= end) 644 { 645 size_t mid = (start + end) / 2; 646 if (idx.frames[mid].sample >= position) 647 { /* move left side. */ 648 if (idx.frames[mid].sample == position) 649 return mid; 650 end = mid - 1; 651 } else 652 { /* move to right side */ 653 index = mid; 654 start = mid + 1; 655 if (start == idx.num_frames) 656 break; 657 } 658 } 659 return index; 660 } 661 662 int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position) 663 { 664 size_t i; 665 if (!dec) 666 return MP3D_E_PARAM; 667 if (MP3D_SEEK_TO_BYTE == dec.seek_method) 668 { 669 if (dec.io) 670 { 671 dec.offset = position; 672 } else 673 { 674 dec.offset = MINIMP3_MIN(position, dec.file.size); 675 } 676 dec.cur_sample = 0; 677 goto do_exit; 678 } 679 dec.cur_sample = position; 680 position += dec.start_delay; 681 if (0 == position) 682 { /* optimize seek to zero, no index needed */ 683 seek_zero: 684 dec.offset = dec.start_offset; 685 dec.to_skip = 0; 686 goto do_exit; 687 } 688 if (!dec.index.frames && dec.vbr_tag_found) 689 { /* no index created yet (vbr tag used to calculate track length) */ 690 dec.samples = 0; 691 dec.buffer_samples = 0; 692 if (dec.io) 693 { 694 if (dec.io.seek(dec.start_offset, dec.io.seek_data)) 695 return MP3D_E_IOERROR; 696 int ret = mp3dec_iterate_cb(dec.io, cast(uint8_t *)dec.file.buffer, dec.file.size, &mp3dec_load_index, dec); 697 if (ret && MP3D_E_USER != ret) 698 return ret; 699 } else 700 { 701 int ret = mp3dec_iterate_buf(dec.file.buffer + dec.start_offset, cast(size_t)(dec.file.size - dec.start_offset), &mp3dec_load_index, dec); 702 if (ret && MP3D_E_USER != ret) 703 return ret; 704 } 705 for (i = 0; i < dec.index.num_frames; i++) 706 dec.index.frames[i].offset += dec.start_offset; 707 dec.samples = dec.detected_samples; 708 } 709 if (!dec.index.frames) 710 goto seek_zero; /* no frames in file - seek to zero */ 711 i = mp3dec_idx_binary_search(&dec.index, position); 712 if (i) 713 { 714 int to_fill_bytes = 511; 715 int skip_frames = MINIMP3_PREDECODE_FRAMES; 716 i -= MINIMP3_MIN(i, cast(size_t)skip_frames); 717 if (3 == dec.info.layer) 718 { 719 while (i && to_fill_bytes) 720 { /* make sure bit-reservoir is filled when we start decoding */ 721 bs_t[1] bs; 722 L3_gr_info_t[4] gr_info; 723 int frame_bytes, frame_size; 724 const(uint8_t) *hdr; 725 if (dec.io) 726 { 727 hdr = dec.file.buffer; 728 if (dec.io.seek(dec.index.frames[i - 1].offset, dec.io.seek_data)) 729 return MP3D_E_IOERROR; 730 size_t readed = dec.io.read(cast(uint8_t *)hdr, HDR_SIZE, dec.io.read_data); 731 if (readed != HDR_SIZE) 732 return MP3D_E_IOERROR; 733 frame_size = hdr_frame_bytes(hdr, dec.free_format_bytes) + hdr_padding(hdr); 734 readed = dec.io.read(cast(uint8_t *)hdr + HDR_SIZE, frame_size - HDR_SIZE, dec.io.read_data); 735 if (readed != cast(size_t)(frame_size - HDR_SIZE)) 736 return MP3D_E_IOERROR; 737 bs_init(bs.ptr, hdr + HDR_SIZE, frame_size - HDR_SIZE); 738 } else 739 { 740 hdr = dec.file.buffer + dec.index.frames[i - 1].offset; 741 frame_size = hdr_frame_bytes(hdr, dec.free_format_bytes) + hdr_padding(hdr); 742 bs_init(bs.ptr, hdr + HDR_SIZE, frame_size - HDR_SIZE); 743 } 744 if (HDR_IS_CRC(hdr)) 745 get_bits(bs.ptr, 16); 746 i--; 747 if (L3_read_side_info(bs.ptr, gr_info.ptr, hdr) < 0) 748 break; /* frame not decodable, we can start from here */ 749 frame_bytes = (bs[0].limit - bs[0].pos)/8; 750 to_fill_bytes -= MINIMP3_MIN(to_fill_bytes, frame_bytes); 751 } 752 } 753 } 754 dec.offset = dec.index.frames[i].offset; 755 dec.to_skip = cast(int)(position - dec.index.frames[i].sample); 756 while ((i + 1) < dec.index.num_frames && !dec.index.frames[i].sample && !dec.index.frames[i + 1].sample) 757 { /* skip not decodable first frames */ 758 const(uint8_t) *hdr; 759 if (dec.io) 760 { 761 hdr = dec.file.buffer; 762 if (dec.io.seek(dec.index.frames[i].offset, dec.io.seek_data)) 763 return MP3D_E_IOERROR; 764 size_t readed = dec.io.read(cast(uint8_t *)hdr, HDR_SIZE, dec.io.read_data); 765 if (readed != HDR_SIZE) 766 return MP3D_E_IOERROR; 767 } else 768 hdr = dec.file.buffer + dec.index.frames[i].offset; 769 dec.to_skip += hdr_frame_samples(hdr)*dec.info.channels; 770 i++; 771 } 772 do_exit: 773 if (dec.io) 774 { 775 if (dec.io.seek(dec.offset, dec.io.seek_data)) 776 return MP3D_E_IOERROR; 777 } 778 dec.buffer_samples = 0; 779 dec.buffer_consumed = 0; 780 dec.input_consumed = 0; 781 dec.input_filled = 0; 782 dec.last_error = 0; 783 mp3dec_init(&dec.mp3d); 784 return 0; 785 } 786 787 size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples) 788 { 789 if (!dec || !buf) 790 return MP3D_E_PARAM; 791 uint64_t end_offset = dec.end_offset ? dec.end_offset : dec.file.size; 792 size_t samples_requested = samples; 793 int eof = 0; 794 mp3dec_frame_info_t frame_info; 795 memset(&frame_info, 0, (frame_info.sizeof)); 796 if (dec.detected_samples && dec.cur_sample >= dec.detected_samples) 797 return 0; /* at end of stream */ 798 if (dec.last_error) 799 return 0; /* error eof state, seek can reset it */ 800 if (dec.buffer_consumed < dec.buffer_samples) 801 { 802 size_t to_copy = MINIMP3_MIN(cast(size_t)(dec.buffer_samples - dec.buffer_consumed), samples); 803 if (dec.detected_samples) 804 { /* count decoded samples to properly cut padding */ 805 if (dec.cur_sample + to_copy >= dec.detected_samples) 806 to_copy = cast(size_t)(dec.detected_samples - dec.cur_sample); 807 } 808 dec.cur_sample += to_copy; 809 memcpy(buf, dec.buffer.ptr + dec.buffer_consumed, to_copy*(mp3d_sample_t.sizeof)); 810 buf += to_copy; 811 dec.buffer_consumed += to_copy; 812 samples -= to_copy; 813 } 814 while (samples) 815 { 816 if (dec.detected_samples && dec.cur_sample >= dec.detected_samples) 817 break; 818 const(uint8_t) *dec_buf; 819 if (dec.io) 820 { 821 if (!eof && (dec.input_filled - dec.input_consumed) < MINIMP3_BUF_SIZE) 822 { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */ 823 memmove(cast(uint8_t*)dec.file.buffer, cast(uint8_t*)dec.file.buffer + dec.input_consumed, dec.input_filled - dec.input_consumed); 824 dec.input_filled -= dec.input_consumed; 825 dec.input_consumed = 0; 826 size_t readed = dec.io.read(cast(uint8_t*)dec.file.buffer + dec.input_filled, dec.file.size - dec.input_filled, dec.io.read_data); 827 if (readed > (dec.file.size - dec.input_filled)) 828 { 829 dec.last_error = MP3D_E_IOERROR; 830 readed = 0; 831 } 832 if (readed != (dec.file.size - dec.input_filled)) 833 eof = 1; 834 dec.input_filled += readed; 835 if (eof) 836 mp3dec_skip_id3v1(cast(uint8_t*)dec.file.buffer, &dec.input_filled); 837 } 838 dec_buf = dec.file.buffer + dec.input_consumed; 839 if (!(dec.input_filled - dec.input_consumed)) 840 break; 841 dec.buffer_samples = mp3dec_decode_frame(&dec.mp3d, dec_buf, cast(int)(dec.input_filled - dec.input_consumed), dec.buffer.ptr, &frame_info); 842 dec.input_consumed += frame_info.frame_bytes; 843 } else 844 { 845 dec_buf = dec.file.buffer + dec.offset; 846 uint64_t buf_size = end_offset - dec.offset; 847 if (!buf_size) 848 break; 849 dec.buffer_samples = mp3dec_decode_frame(&dec.mp3d, dec_buf, cast(int) MINIMP3_MIN(buf_size, cast(uint64_t)int.max), dec.buffer.ptr, &frame_info); 850 } 851 dec.buffer_consumed = 0; 852 if (dec.info.hz != frame_info.hz || dec.info.layer != frame_info.layer 853 || dec.info.channels != frame_info.channels 854 ) 855 { 856 dec.last_error = MP3D_E_DECODE; 857 break; 858 } 859 if (dec.buffer_samples) 860 { 861 dec.buffer_samples *= frame_info.channels; 862 if (dec.to_skip) 863 { 864 size_t skip = MINIMP3_MIN(dec.buffer_samples, dec.to_skip); 865 dec.buffer_consumed += skip; 866 dec.to_skip -= skip; 867 } 868 size_t to_copy = MINIMP3_MIN(cast(size_t)(dec.buffer_samples - dec.buffer_consumed), samples); 869 if (dec.detected_samples) 870 { /* ^ handle padding */ 871 if (dec.cur_sample + to_copy >= dec.detected_samples) 872 to_copy = cast(size_t)(dec.detected_samples - dec.cur_sample); 873 } 874 dec.cur_sample += to_copy; 875 memcpy(buf, dec.buffer.ptr + dec.buffer_consumed, to_copy*(mp3d_sample_t.sizeof)); 876 buf += to_copy; 877 dec.buffer_consumed += to_copy; 878 samples -= to_copy; 879 } else if (dec.to_skip) 880 { /* In mp3 decoding not always can start decode from any frame because of bit reservoir, 881 count skip samples for such frames */ 882 int frame_samples = hdr_frame_samples(dec_buf)*frame_info.channels; 883 dec.to_skip -= MINIMP3_MIN(frame_samples, dec.to_skip); 884 } 885 dec.offset += frame_info.frame_bytes; 886 } 887 return samples_requested - samples; 888 } 889 890 891 void mp3dec_close_file(mp3dec_map_info_t *map_info) 892 { 893 if (map_info.buffer) 894 free(cast(void *)map_info.buffer); 895 map_info.buffer = null; 896 map_info.size = 0; 897 } 898 899 int mp3dec_detect_mapinfo(mp3dec_map_info_t *map_info) 900 { 901 int ret = mp3dec_detect_buf(map_info.buffer, map_info.size); 902 mp3dec_close_file(map_info); 903 return ret; 904 } 905 906 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) 907 { 908 int ret = mp3dec_load_buf(dec, map_info.buffer, map_info.size, info, progress_cb, user_data); 909 mp3dec_close_file(map_info); 910 return ret; 911 } 912 913 int mp3dec_iterate_mapinfo(mp3dec_map_info_t *map_info, MP3D_ITERATE_CB callback, void *user_data) 914 { 915 int ret = mp3dec_iterate_buf(map_info.buffer, map_info.size, callback, user_data); 916 mp3dec_close_file(map_info); 917 return ret; 918 } 919 920 static int mp3dec_ex_open_mapinfo(mp3dec_ex_t *dec, int seek_method) 921 { 922 int ret = mp3dec_ex_open_buf(dec, dec.file.buffer, dec.file.size, seek_method); 923 dec.is_file = 1; 924 if (ret) 925 mp3dec_ex_close(dec); 926 return ret; 927 } 928 929 int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method) 930 { 931 if (!dec || !io || !(MP3D_SEEK_TO_BYTE == seek_method || MP3D_SEEK_TO_SAMPLE == seek_method)) 932 return MP3D_E_PARAM; 933 memset(dec, 0, (*dec).sizeof); 934 dec.file.size = MINIMP3_IO_SIZE; 935 dec.file.buffer = cast(const uint8_t*)malloc(dec.file.size); 936 if (!dec.file.buffer) 937 return MP3D_E_MEMORY; 938 dec.seek_method = seek_method; 939 dec.io = io; 940 mp3dec_init(&dec.mp3d); 941 if (io.seek(0, io.seek_data)) 942 return MP3D_E_IOERROR; 943 int ret = mp3dec_iterate_cb(io, cast(uint8_t *)dec.file.buffer, dec.file.size, &mp3dec_load_index, dec); 944 if (ret && MP3D_E_USER != ret) 945 return ret; 946 if (dec.io.seek(dec.start_offset, dec.io.seek_data)) 947 return MP3D_E_IOERROR; 948 mp3dec_init(&dec.mp3d); 949 dec.buffer_samples = 0; 950 return 0; 951 } 952 953 void mp3dec_ex_close(mp3dec_ex_t *dec) 954 { 955 if (dec.index.frames) 956 free(dec.index.frames); 957 memset(dec, 0, (*dec).sizeof); 958 } 959 960