FastLED 3.10.6
Loading...
Searching...
No Matches

◆ mp3d_synth_pair()

static void mp3d_synth_pair ( mp3d_sample_t * pcm,
int nch,
const int32_t * z )
static

Definition at line 616 of file minimp3_synth_fixed.h.

617{
618 int64_t a;
619 /* The sums and differences are computed with defined wraparound, then
620 widened (FastLED#4133).
621
622 `(int64_t)(x - y)` evaluates `x - y` in int32 first and only then widens,
623 which overflows once the polyphase inputs get large -- undefined
624 behaviour, not merely a wrong number. Ordinary audio never gets there; a
625 malformed intensity-stereo stream does, and UBSan caught it on
626 l3-nonstandard-big-iscf.
627
628 Widening both operands first was the obvious fix and it is the wrong one
629 here: an int64 add or subtract costs two instructions plus carry on a
630 32-bit target, and the codegen ledger measured it at +34% on the Xtensa
631 polyphase inner loop -- 251 instructions against 187 -- which is the
632 hottest kernel on the most constrained platform FastLED targets.
633
634 Unsigned arithmetic wraps by definition in C, so MP3D_WRAP_SUB and
635 MP3D_WRAP_ADD emit exactly the same single 32-bit instruction the
636 undefined version did, and produce exactly the same bits. No well-formed
637 stream reaches the wrap; a malformed one now gets a defined, reproducible
638 answer instead of whatever the optimiser felt entitled to assume. */
639 a = (int64_t)MP3D_WRAP_SUB(z[14*64], z[ 0]) * 29;
640 a += (int64_t)MP3D_WRAP_ADD(z[ 1*64], z[13*64]) * 213;
641 a += (int64_t)MP3D_WRAP_SUB(z[12*64], z[ 2*64]) * 459;
642 a += (int64_t)MP3D_WRAP_ADD(z[ 3*64], z[11*64]) * 2037;
643 a += (int64_t)MP3D_WRAP_SUB(z[10*64], z[ 4*64]) * 5153;
644 a += (int64_t)MP3D_WRAP_ADD(z[ 5*64], z[ 9*64]) * 6574;
645 a += (int64_t)MP3D_WRAP_SUB(z[ 8*64], z[ 6*64]) * 37489;
646 a += (int64_t) z[ 7*64] * 75038;
647 pcm[0] = mp3d_scale_pcm(a);
648
649 z += 2;
650 a = (int64_t)z[14*64] * 104;
651 a += (int64_t)z[12*64] * 1567;
652 a += (int64_t)z[10*64] * 9727;
653 a += (int64_t)z[ 8*64] * 64019;
654 a += (int64_t)z[ 6*64] * -9975;
655 a += (int64_t)z[ 4*64] * -45;
656 a += (int64_t)z[ 2*64] * 146;
657 a += (int64_t)z[ 0*64] * -5;
658 pcm[16*nch] = mp3d_scale_pcm(a);
659}
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:93
MP3D_LEAF mp3d_sample_t mp3d_scale_pcm(int64_t sample) FL_NO_EXCEPT

References FL_NO_EXCEPT, mp3d_scale_pcm(), and z.

Referenced by mp3d_synth().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: