FastLED 3.9.15
Loading...
Searching...
No Matches

◆ scale16()

LIB8STATIC uint16_t scale16 ( uint16_t i,
fract16 scale )

Scale a 16-bit unsigned value by an 16-bit value, which is treated as the numerator of a fraction whose denominator is 65536.

In other words, it computes i * (scale / 65536)

Parameters
iinput value to scale
scalescale factor, in n/65536 units
Returns
scaled value
Examples
Pacifica.ino.

Definition at line 551 of file scale8.h.

551 {
552#if SCALE16_C == 1
553 uint16_t result;
554#if FASTLED_SCALE8_FIXED == 1
555 result = ((uint32_t)(i) * (1 + (uint32_t)(scale))) / 65536;
556#else
557 result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
558#endif
559 return result;
560#elif SCALE16_AVRASM == 1
561#if FASTLED_SCALE8_FIXED == 1
562 // implemented sort of like
563 // result = ((i * scale) + i ) / 65536
564 //
565 // why not like this, you may ask?
566 // result = (i * (scale+1)) / 65536
567 // the answer is that if scale is 65535, then scale+1
568 // will be zero, which is not what we want.
569 uint32_t result;
570 asm volatile(
571 // result.A-B = i.A x scale.A
572 " mul %A[i], %A[scale] \n\t"
573 // save results...
574 // basic idea:
575 //" mov %A[result], r0 \n\t"
576 //" mov %B[result], r1 \n\t"
577 // which can be written as...
578 " movw %A[result], r0 \n\t"
579 // Because we're going to add i.A-B to
580 // result.A-D, we DO need to keep both
581 // the r0 and r1 portions of the product
582 // UNlike in the 'unfixed scale8' version.
583 // So the movw here is needed.
584 : [result] "=r"(result)
585 : [i] "r"(i), [scale] "r"(scale)
586 : "r0", "r1");
587
588 asm volatile(
589 // result.C-D = i.B x scale.B
590 " mul %B[i], %B[scale] \n\t"
591 //" mov %C[result], r0 \n\t"
592 //" mov %D[result], r1 \n\t"
593 " movw %C[result], r0 \n\t"
594 : [result] "+r"(result)
595 : [i] "r"(i), [scale] "r"(scale)
596 : "r0", "r1");
597
598 const uint8_t zero = 0;
599 asm volatile(
600 // result.B-D += i.B x scale.A
601 " mul %B[i], %A[scale] \n\t"
602
603 " add %B[result], r0 \n\t"
604 " adc %C[result], r1 \n\t"
605 " adc %D[result], %[zero] \n\t"
606
607 // result.B-D += i.A x scale.B
608 " mul %A[i], %B[scale] \n\t"
609
610 " add %B[result], r0 \n\t"
611 " adc %C[result], r1 \n\t"
612 " adc %D[result], %[zero] \n\t"
613
614 // cleanup r1
615 " clr r1 \n\t"
616
617 : [result] "+r"(result)
618 : [i] "r"(i), [scale] "r"(scale), [zero] "r"(zero)
619 : "r0", "r1");
620
621 asm volatile(
622 // result.A-D += i.A-B
623 " add %A[result], %A[i] \n\t"
624 " adc %B[result], %B[i] \n\t"
625 " adc %C[result], %[zero] \n\t"
626 " adc %D[result], %[zero] \n\t"
627 : [result] "+r"(result)
628 : [i] "r"(i), [zero] "r"(zero));
629
630 result = result >> 16;
631 return result;
632#else
633 uint32_t result;
634 asm volatile(
635 // result.A-B = i.A x scale.A
636 " mul %A[i], %A[scale] \n\t"
637 // save results...
638 // basic idea:
639 //" mov %A[result], r0 \n\t"
640 //" mov %B[result], r1 \n\t"
641 // which can be written as...
642 " movw %A[result], r0 \n\t"
643 // We actually don't need to do anything with r0,
644 // as result.A is never used again here, so we
645 // could just move the high byte, but movw is
646 // one clock cycle, just like mov, so might as
647 // well, in case we want to use this code for
648 // a generic 16x16 multiply somewhere.
649
650 : [result] "=r"(result)
651 : [i] "r"(i), [scale] "r"(scale)
652 : "r0", "r1");
653
654 asm volatile(
655 // result.C-D = i.B x scale.B
656 " mul %B[i], %B[scale] \n\t"
657 //" mov %C[result], r0 \n\t"
658 //" mov %D[result], r1 \n\t"
659 " movw %C[result], r0 \n\t"
660 : [result] "+r"(result)
661 : [i] "r"(i), [scale] "r"(scale)
662 : "r0", "r1");
663
664 const uint8_t zero = 0;
665 asm volatile(
666 // result.B-D += i.B x scale.A
667 " mul %B[i], %A[scale] \n\t"
668
669 " add %B[result], r0 \n\t"
670 " adc %C[result], r1 \n\t"
671 " adc %D[result], %[zero] \n\t"
672
673 // result.B-D += i.A x scale.B
674 " mul %A[i], %B[scale] \n\t"
675
676 " add %B[result], r0 \n\t"
677 " adc %C[result], r1 \n\t"
678 " adc %D[result], %[zero] \n\t"
679
680 // cleanup r1
681 " clr r1 \n\t"
682
683 : [result] "+r"(result)
684 : [i] "r"(i), [scale] "r"(scale), [zero] "r"(zero)
685 : "r0", "r1");
686
687 result = result >> 16;
688 return result;
689#endif
690#else
691#error "No implementation for scale16 available."
692#endif
693}
uint16_t scale
Definition Noise.ino:74

References LIB8STATIC, and scale.

Referenced by beatsin16(), beatsin88(), ease16InOutCubic(), ease16InOutQuad(), fl::easeInQuad16(), fill_raw_2dnoise16(), FL_DISABLE_WARNING(), lerp15by16(), lerp16by16(), fl::Pacifica::pacifica_one_layer(), and pacifica_one_layer().

+ Here is the caller graph for this function: