425 {
427 return false;
428 }
429
430
433
434 if (bytes_left == 0) {
435 return false;
436 }
437
438
441
443 return false;
444 }
445
449
450
451 const fl::u8* decode_ptr = inptr;
452 fl::size decode_bytes = bytes_left;
453
454
455
456
457
460 Mp3VbrTag tag;
461 if (
Mp3ParseVbrTag(fl::span<const fl::u8>(inptr, bytes_left), &tag) &&
462 tag.present) {
465 }
466 }
467
469
470
471 fl::size consumed = (decode_ptr - inptr);
473
474
475 consumed = 1;
476 }
479
481
483 return false;
484 }
485
487
488 Mp3Frame frame;
489 frame.pcm =
mDecoder->mPcmBuffer.get();
490 frame.samples =
mDecoder->mFrameInfo.outputSamps /
mDecoder->mFrameInfo.nChans;
491 frame.channels =
mDecoder->mFrameInfo.nChans;
492 frame.sample_rate =
mDecoder->mFrameInfo.samprate;
493 frame.bitrate =
mDecoder->mFrameInfo.bitrate;
494 frame.version =
mDecoder->mFrameInfo.version;
495 frame.layer =
mDecoder->mFrameInfo.layer;
496
497
499 mInfo.sampleRate = frame.sample_rate;
500 mInfo.channels =
static_cast<fl::u8>(frame.channels);
501 mInfo.bitrate = frame.bitrate;
502 mInfo.version =
static_cast<fl::u8>(frame.version);
504 mInfo.isValid =
true;
506 }
507
508
509
510 int first = 0;
512 const fl::u32
available =
static_cast<fl::u32
>(frame.samples);
513 const fl::u32 drop =
515 first = static_cast<int>(drop);
517 if (first >= frame.samples) {
518 return false;
519 }
520 }
521 const int emitted = frame.samples - first;
522
523
524 if (frame.channels == 2) {
525 fl::vector<fl::i16> mono_pcm;
527
528 for (int i = first; i < frame.samples; i++) {
529 fl::i32 left = frame.pcm[i * 2];
530 fl::i32 right = frame.pcm[i * 2 + 1];
531 fl::i32 avg = (left + right) / 2;
532 mono_pcm.
push_back(
static_cast<fl::i16
>(avg));
533 }
534
535 *out_sample = audio::Sample(mono_pcm);
536 } else {
537
538 *out_sample = audio::Sample(
539 fl::span<const fl::i16>(frame.pcm + first, emitted));
540 }
541
542 return true;
543 }
544
545 return false;
546}
fl::unique_ptr< fl::u8[], Mp3MemoryDeleter< fl::u8 > > mBuffer
bool mHasDecodedFirstFrame
static constexpr fl::size BUFFER_SIZE
bool mInspectedFirstFrame
fl::unique_ptr< Mp3SelectedDecoder > mDecoder
void reserve(fl::size n) FL_NO_EXCEPT
void push_back(const T &value) FL_NO_EXCEPT
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
bool Mp3ParseVbrTag(fl::span< const fl::u8 > bytes, Mp3VbrTag *out) FL_NO_EXCEPT
static const fl::u32 MP3D_DECODER_DELAY
Metadata carried by an MP3's first frame when an encoder wrote a Xing, Info, or VBRI header there.
expected< T, E > result
Alias for expected (Rust-style naming)
int available() FL_NO_EXCEPT