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 546 of file scale8.h.

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

References LIB8STATIC, and scale.

Referenced by beatsin16(), beatsin88(), ease16InOutQuad(), fill_raw_2dnoise16(), lerp15by16(), lerp16by16(), fl::Pacifica::pacifica_one_layer(), pacifica_one_layer(), fl::Transform16::ToBounds(), and fl::Transform16::ToBounds().

+ Here is the caller graph for this function: