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

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

References LIB8STATIC, and scale.

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

+ Here is the caller graph for this function: