FastLED 3.9.15
Loading...
Searching...
No Matches
lib8tion.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef __INC_LIB8TION_H
4#define __INC_LIB8TION_H
5
6#include "FastLED.h"
7#include "lib8tion/types.h"
8
9#ifndef __INC_LED_SYSDEFS_H
10#error WTH? led_sysdefs needs to be included first
11#endif
12
16
17#include <stdint.h>
18#include "lib8tion/lib8static.h"
19#include "lib8tion/qfx.h"
20#include "lib8tion/memmove.h"
21
22
23#if !defined(__AVR__)
24#include <string.h>
25// for memmove, memcpy, and memset if not defined here
26#endif // end of !defined(__AVR__)
27
28#if defined(__arm__)
29
30#if defined(FASTLED_TEENSY3)
31// Can use Cortex M4 DSP instructions
32#define QADD8_C 0
33#define QADD7_C 0
34#define QADD8_ARM_DSP_ASM 1
35#define QADD7_ARM_DSP_ASM 1
36#else
37// Generic ARM
38#define QADD8_C 1
39#define QADD7_C 1
40#endif // end of defined(FASTLED_TEENSY3)
41
42#define QSUB8_C 1
43#define SCALE8_C 1
44#define SCALE16BY8_C 1
45#define SCALE16_C 1
46#define ABS8_C 1
47#define MUL8_C 1
48#define QMUL8_C 1
49#define ADD8_C 1
50#define SUB8_C 1
51#define EASE8_C 1
52#define AVG8_C 1
53#define AVG8R_C 1
54#define AVG7_C 1
55#define AVG16_C 1
56#define AVG16R_C 1
57#define AVG15_C 1
58#define BLEND8_C 1
59
60// end of #if defined(__arm__)
61
62#elif defined(ARDUINO_ARCH_APOLLO3)
63
64// Default to using the standard C functions for now
65#define QADD8_C 1
66#define QADD7_C 1
67#define QSUB8_C 1
68#define SCALE8_C 1
69#define SCALE16BY8_C 1
70#define SCALE16_C 1
71#define ABS8_C 1
72#define MUL8_C 1
73#define QMUL8_C 1
74#define ADD8_C 1
75#define SUB8_C 1
76#define EASE8_C 1
77#define AVG8_C 1
78#define AVG8R_C 1
79#define AVG7_C 1
80#define AVG16_C 1
81#define AVG16R_C 1
82#define AVG15_C 1
83#define BLEND8_C 1
84
85// end of #elif defined(ARDUINO_ARCH_APOLLO3)
86
87#elif defined(__AVR__)
88
89// AVR ATmega and friends Arduino
90
91#define QADD8_C 0
92#define QADD7_C 0
93#define QSUB8_C 0
94#define ABS8_C 0
95#define ADD8_C 0
96#define SUB8_C 0
97#define AVG8_C 0
98#define AVG8R_C 0
99#define AVG7_C 0
100#define AVG16_C 0
101#define AVG16R_C 0
102#define AVG15_C 0
103
104#define QADD8_AVRASM 1
105#define QADD7_AVRASM 1
106#define QSUB8_AVRASM 1
107#define ABS8_AVRASM 1
108#define ADD8_AVRASM 1
109#define SUB8_AVRASM 1
110#define AVG8_AVRASM 1
111#define AVG8R_AVRASM 1
112#define AVG7_AVRASM 1
113#define AVG16_AVRASM 1
114#define AVG16R_AVRASM 1
115#define AVG15_AVRASM 1
116
117// Note: these require hardware MUL instruction
118// -- sorry, ATtiny!
119#if !defined(LIB8_ATTINY)
120#define SCALE8_C 0
121#define SCALE16BY8_C 0
122#define SCALE16_C 0
123#define MUL8_C 0
124#define QMUL8_C 0
125#define EASE8_C 0
126#define BLEND8_C 0
127#define SCALE8_AVRASM 1
128#define SCALE16BY8_AVRASM 1
129#define SCALE16_AVRASM 1
130#define MUL8_AVRASM 1
131#define QMUL8_AVRASM 1
132#define EASE8_AVRASM 1
133#define CLEANUP_R1_AVRASM 1
134#define BLEND8_AVRASM 1
135#else
136// On ATtiny, we just use C implementations
137#define SCALE8_C 1
138#define SCALE16BY8_C 1
139#define SCALE16_C 1
140#define MUL8_C 1
141#define QMUL8_C 1
142#define EASE8_C 1
143#define BLEND8_C 1
144#define SCALE8_AVRASM 0
145#define SCALE16BY8_AVRASM 0
146#define SCALE16_AVRASM 0
147#define MUL8_AVRASM 0
148#define QMUL8_AVRASM 0
149#define EASE8_AVRASM 0
150#define BLEND8_AVRASM 0
151#endif // end of !defined(LIB8_ATTINY)
152
153// end of #elif defined(__AVR__)
154
155#else
156
157// Doxygen: ignore these macros
159
160// unspecified architecture, so
161// no ASM, everything in C
162#define QADD8_C 1
163#define QADD7_C 1
164#define QSUB8_C 1
165#define SCALE8_C 1
166#define SCALE16BY8_C 1
167#define SCALE16_C 1
168#define ABS8_C 1
169#define MUL8_C 1
170#define QMUL8_C 1
171#define ADD8_C 1
172#define SUB8_C 1
173#define EASE8_C 1
174#define AVG8_C 1
175#define AVG8R_C 1
176#define AVG7_C 1
177#define AVG16_C 1
178#define AVG16R_C 1
179#define AVG15_C 1
180#define BLEND8_C 1
181
183
184#endif
185
376
377
378
379
380#include "lib8tion/math8.h"
381#include "lib8tion/scale8.h"
382#include "lib8tion/random8.h"
383#include "lib8tion/trig8.h"
384
386
387
388
389
391
392
399
402{
403 return y / 32768.0;
404}
405
410{
411 return f * 32768.0;
412}
413
415
416
417
418
419
434
437LIB8STATIC uint8_t lerp8by8( uint8_t a, uint8_t b, fract8 frac)
438{
439 uint8_t result;
440 if( b > a) {
441 uint8_t delta = b - a;
442 uint8_t scaled = scale8( delta, frac);
443 result = a + scaled;
444 } else {
445 uint8_t delta = a - b;
446 uint8_t scaled = scale8( delta, frac);
447 result = a - scaled;
448 }
449 return result;
450}
451
454LIB8STATIC uint16_t lerp16by16( uint16_t a, uint16_t b, fract16 frac)
455{
456 uint16_t result;
457 if( b > a ) {
458 uint16_t delta = b - a;
459 uint16_t scaled = scale16(delta, frac);
460 result = a + scaled;
461 } else {
462 uint16_t delta = a - b;
463 uint16_t scaled = scale16( delta, frac);
464 result = a - scaled;
465 }
466 return result;
467}
468
471LIB8STATIC uint16_t lerp16by8( uint16_t a, uint16_t b, fract8 frac)
472{
473 uint16_t result;
474 if( b > a) {
475 uint16_t delta = b - a;
476 uint16_t scaled = scale16by8( delta, frac);
477 result = a + scaled;
478 } else {
479 uint16_t delta = a - b;
480 uint16_t scaled = scale16by8( delta, frac);
481 result = a - scaled;
482 }
483 return result;
484}
485
488LIB8STATIC int16_t lerp15by8( int16_t a, int16_t b, fract8 frac)
489{
490 int16_t result;
491 if( b > a) {
492 uint16_t delta = b - a;
493 uint16_t scaled = scale16by8( delta, frac);
494 result = a + scaled;
495 } else {
496 uint16_t delta = a - b;
497 uint16_t scaled = scale16by8( delta, frac);
498 result = a - scaled;
499 }
500 return result;
501}
502
505LIB8STATIC int16_t lerp15by16( int16_t a, int16_t b, fract16 frac)
506{
507 int16_t result;
508 if( b > a) {
509 uint16_t delta = b - a;
510 uint16_t scaled = scale16( delta, frac);
511 result = a + scaled;
512 } else {
513 uint16_t delta = a - b;
514 uint16_t scaled = scale16( delta, frac);
515 result = a - scaled;
516 }
517 return result;
518}
519
541LIB8STATIC uint8_t map8( uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
542{
543 uint8_t rangeWidth = rangeEnd - rangeStart;
544 uint8_t out = scale8( in, rangeWidth);
545 out += rangeStart;
546 return out;
547}
548
550
551
558
561#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
562LIB8STATIC uint8_t ease8InOutQuad( uint8_t i)
563{
564 uint8_t j = i;
565 if( j & 0x80 ) {
566 j = 255 - j;
567 }
568 uint8_t jj = scale8( j, j);
569 uint8_t jj2 = jj << 1;
570 if( i & 0x80 ) {
571 jj2 = 255 - jj2;
572 }
573 return jj2;
574}
575
576#elif EASE8_AVRASM == 1
577// This AVR asm version of ease8InOutQuad preserves one more
578// low-bit of precision than the C version, and is also slightly
579// smaller and faster.
580LIB8STATIC uint8_t ease8InOutQuad(uint8_t val) {
581 uint8_t j=val;
582 asm volatile (
583 "sbrc %[val], 7 \n"
584 "com %[j] \n"
585 "mul %[j], %[j] \n"
586 "add r0, %[j] \n"
587 "ldi %[j], 0 \n"
588 "adc %[j], r1 \n"
589 "lsl r0 \n" // carry = high bit of low byte of mul product
590 "rol %[j] \n" // j = (j * 2) + carry // preserve add'l bit of precision
591 "sbrc %[val], 7 \n"
592 "com %[j] \n"
593 "clr __zero_reg__ \n"
594 : [j] "+&a" (j)
595 : [val] "a" (val)
596 : "r0", "r1"
597 );
598 return j;
599}
600
601#else
602#error "No implementation for ease8InOutQuad available."
603#endif
604
607LIB8STATIC uint16_t ease16InOutQuad( uint16_t i)
608{
609 uint16_t j = i;
610 if( j & 0x8000 ) {
611 j = 65535 - j;
612 }
613 uint16_t jj = scale16( j, j);
614 uint16_t jj2 = jj << 1;
615 if( i & 0x8000 ) {
616 jj2 = 65535 - jj2;
617 }
618 return jj2;
619}
620
621
625{
626 uint8_t ii = scale8_LEAVING_R1_DIRTY( i, i);
627 uint8_t iii = scale8_LEAVING_R1_DIRTY( ii, i);
628
629 uint16_t r1 = (3 * (uint16_t)(ii)) - ( 2 * (uint16_t)(iii));
630
631 /* the code generated for the above *'s automatically
632 cleans up R1, so there's no need to explicitily call
633 cleanup_R1(); */
634
635 uint8_t result = r1;
636
637 // if we got "256", return 255:
638 if( r1 & 0x100 ) {
639 result = 255;
640 }
641 return result;
642}
643
644
652#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
654{
655 if( i < 64) {
656 // start with slope 0.5
657 i /= 2;
658 } else if( i > (255 - 64)) {
659 // end with slope 0.5
660 i = 255 - i;
661 i /= 2;
662 i = 255 - i;
663 } else {
664 // in the middle, use slope 192/128 = 1.5
665 i -= 64;
666 i += (i / 2);
667 i += 32;
668 }
669
670 return i;
671}
672
673#elif EASE8_AVRASM == 1
675{
676 // takes around 7 cycles on AVR
677 asm volatile (
678 " subi %[i], 64 \n\t"
679 " cpi %[i], 128 \n\t"
680 " brcc Lshift_%= \n\t"
681
682 // middle case
683 " mov __tmp_reg__, %[i] \n\t"
684 " lsr __tmp_reg__ \n\t"
685 " add %[i], __tmp_reg__ \n\t"
686 " subi %[i], 224 \n\t"
687 " rjmp Ldone_%= \n\t"
688
689 // start or end case
690 "Lshift_%=: \n\t"
691 " lsr %[i] \n\t"
692 " subi %[i], 96 \n\t"
693
694 "Ldone_%=: \n\t"
695
696 : [i] "+a" (i)
697 :
698 : "r0"
699 );
700 return i;
701}
702#else
703#error "No implementation for ease8 available."
704#endif
705
707
708
715
716
728LIB8STATIC uint8_t triwave8(uint8_t in)
729{
730 if( in & 0x80) {
731 in = 255 - in;
732 }
733 uint8_t out = in << 1;
734 return out;
735}
736
747LIB8STATIC uint8_t quadwave8(uint8_t in)
748{
749 return ease8InOutQuad( triwave8( in));
750}
751
755LIB8STATIC uint8_t cubicwave8(uint8_t in)
756{
757 return ease8InOutCubic( triwave8( in));
758}
759
760
784LIB8STATIC uint8_t squarewave8( uint8_t in, uint8_t pulsewidth=128)
785{
786 if( in < pulsewidth || (pulsewidth == 255)) {
787 return 255;
788 } else {
789 return 0;
790 }
791}
792
794
796
797
804
805#if ((defined(ARDUINO) || defined(SPARK) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
806// Forward declaration of Arduino function 'millis'.
807//uint32_t millis();
808
819#define GET_MILLIS millis
820#else
821uint32_t get_millisecond_timer();
822#define GET_MILLIS get_millisecond_timer
823#endif
824
826
827
830
831
870
871
879LIB8STATIC uint16_t beat88( accum88 beats_per_minute_88, uint32_t timebase = 0)
880{
881 // BPM is 'beats per minute', or 'beats per 60000ms'.
882 // To avoid using the (slower) division operator, we
883 // want to convert 'beats per 60000ms' to 'beats per 65536ms',
884 // and then use a simple, fast bit-shift to divide by 65536.
885 //
886 // The ratio 65536:60000 is 279.620266667:256; we'll call it 280:256.
887 // The conversion is accurate to about 0.05%, more or less,
888 // e.g. if you ask for "120 BPM", you'll get about "119.93".
889 return (((GET_MILLIS()) - timebase) * beats_per_minute_88 * 280) >> 16;
890}
891
895LIB8STATIC uint16_t beat16( accum88 beats_per_minute, uint32_t timebase = 0)
896{
897 // Convert simple 8-bit BPM's to full Q8.8 accum88's if needed
898 if( beats_per_minute < 256) beats_per_minute <<= 8;
899 return beat88(beats_per_minute, timebase);
900}
901
905LIB8STATIC uint8_t beat8( accum88 beats_per_minute, uint32_t timebase = 0)
906{
907 return beat16( beats_per_minute, timebase) >> 8;
908}
909
910
921LIB8STATIC uint16_t beatsin88( accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535,
922 uint32_t timebase = 0, uint16_t phase_offset = 0)
923{
924 uint16_t beat = beat88( beats_per_minute_88, timebase);
925 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
926 uint16_t rangewidth = highest - lowest;
927 uint16_t scaledbeat = scale16( beatsin, rangewidth);
928 uint16_t result = lowest + scaledbeat;
929 return result;
930}
931
939LIB8STATIC uint16_t beatsin16( accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535,
940 uint32_t timebase = 0, uint16_t phase_offset = 0)
941{
942 uint16_t beat = beat16( beats_per_minute, timebase);
943 uint16_t beatsin = (sin16( beat + phase_offset) + 32768);
944 uint16_t rangewidth = highest - lowest;
945 uint16_t scaledbeat = scale16( beatsin, rangewidth);
946 uint16_t result = lowest + scaledbeat;
947 return result;
948}
949
957LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255,
958 uint32_t timebase = 0, uint8_t phase_offset = 0)
959{
960 uint8_t beat = beat8( beats_per_minute, timebase);
961 uint8_t beatsin = sin8( beat + phase_offset);
962 uint8_t rangewidth = highest - lowest;
963 uint8_t scaledbeat = scale8( beatsin, rangewidth);
964 uint8_t result = lowest + scaledbeat;
965 return result;
966}
967
969
971
972
977
981{
982 uint32_t ms = GET_MILLIS();
983 uint16_t s16;
984 s16 = ms / 1000;
985 return s16;
986}
987
991{
992 uint32_t ms = GET_MILLIS();
993 uint16_t m16;
994 m16 = (ms / (60000L)) & 0xFFFF;
995 return m16;
996}
997
1001{
1002 uint32_t ms = GET_MILLIS();
1003 uint8_t h8;
1004 h8 = (ms / (3600000L)) & 0xFF;
1005 return h8;
1006}
1007
1008
1022LIB8STATIC uint16_t div1024_32_16( uint32_t in32)
1023{
1024 uint16_t out16;
1025#if defined(__AVR__)
1026 asm volatile (
1027 " lsr %D[in] \n\t"
1028 " ror %C[in] \n\t"
1029 " ror %B[in] \n\t"
1030 " lsr %D[in] \n\t"
1031 " ror %C[in] \n\t"
1032 " ror %B[in] \n\t"
1033 " mov %B[out],%C[in] \n\t"
1034 " mov %A[out],%B[in] \n\t"
1035 : [in] "+r" (in32),
1036 [out] "=r" (out16)
1037 );
1038#else
1039 out16 = (in32 >> 10) & 0xFFFF;
1040#endif
1041 return out16;
1042}
1043
1048{
1049 uint32_t ms = GET_MILLIS();
1050 uint16_t s16;
1051 s16 = div1024_32_16( ms);
1052 return s16;
1053}
1054
1058#if 1
1059#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
1060class NAME { \
1061public: \
1062 TIMETYPE mPrevTrigger; \
1063 TIMETYPE mPeriod; \
1064 \
1065 NAME() { reset(); mPeriod = 1; }; \
1066 NAME(TIMETYPE period) { reset(); setPeriod(period); }; \
1067 void setPeriod( TIMETYPE period) { mPeriod = period; }; \
1068 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); }; \
1069 TIMETYPE getPeriod() { return mPeriod; }; \
1070 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; } \
1071 TIMETYPE getRemaining() { return mPeriod - getElapsed(); } \
1072 TIMETYPE getLastTriggerTime() { return mPrevTrigger; } \
1073 bool ready() { \
1074 bool isReady = (getElapsed() >= mPeriod); \
1075 if( isReady ) { reset(); } \
1076 return isReady; \
1077 } \
1078 void reset() { mPrevTrigger = getTime(); }; \
1079 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
1080 \
1081 operator bool() { return ready(); } \
1082};
1083
1088
1089#if defined(FASTLED_DOXYGEN)
1103public:
1104 TIMETYPE mPrevTrigger;
1105 TIMETYPE mPeriod;
1106
1111 CEveryNTime(TIMETYPE period) { reset(); setPeriod(period); };
1112
1114 void setPeriod( TIMETYPE period) { mPeriod = period; };
1115
1117 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); };
1118
1120 TIMETYPE getPeriod() { return mPeriod; };
1121
1123 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; }
1124
1126 TIMETYPE getRemaining() { return mPeriod - getElapsed(); }
1127
1129 TIMETYPE getLastTriggerTime() { return mPrevTrigger; }
1130
1132 bool ready() {
1133 bool isReady = (getElapsed() >= mPeriod);
1134 if( isReady ) { reset(); }
1135 return isReady;
1136 }
1137
1139 void reset() { mPrevTrigger = getTime(); };
1140
1143
1145 operator bool() { return ready(); }
1146};
1147#endif // FASTLED_DOXYGEN
1148
1151
1154
1157
1160
1163
1165#define CEveryNMilliseconds CEveryNMillis
1166
1169public:
1171 uint32_t mPeriod;
1172
1173 CEveryNMillisDynamic(uint32_t period) : mPeriod(period) { reset(); };
1174 uint32_t getTime() { return GET_MILLIS(); };
1175 uint32_t getPeriod() const { return mPeriod; };
1176 uint32_t getElapsed() { return getTime() - mPrevTrigger; }
1177 uint32_t getRemaining() { return getPeriod() - getElapsed(); }
1178 uint32_t getLastTriggerTime() { return mPrevTrigger; }
1179 bool ready() {
1180 bool isReady = (getElapsed() >= getPeriod());
1181 if( isReady ) { reset(); }
1182 return isReady;
1183 }
1184 void reset() { mPrevTrigger = getTime(); };
1186 void setPeriod(uint32_t period) { mPeriod = period; }
1187
1188 operator bool() { return ready(); }
1189};
1190
1191
1192
1193
1194// ————————————————————————————————————————————————
1195// Random‐interval version of EVERY_N_MILLISECONDS:
1196// on each trigger, pick the next period randomly in [MIN..MAX].
1197// ————————————————————————————————————————————————
1199public:
1201 uint32_t mPeriod;
1202 uint32_t mMinPeriod;
1203 uint32_t mMaxPeriod;
1204
1205 CEveryNMillisRandom(uint32_t minPeriod, uint32_t maxPeriod)
1206 : mMinPeriod(minPeriod), mMaxPeriod(maxPeriod)
1207 {
1208 computeNext();
1209 reset();
1210 }
1211
1213 // random16(x) returns [0..x-1], so this yields MIN..MAX
1214 uint32_t range = mMaxPeriod - mMinPeriod + 1;
1215 mPeriod = mMinPeriod + random16(range);
1216 }
1217
1218 uint32_t getTime() const { return GET_MILLIS(); }
1219
1220 bool ready() {
1221 uint32_t now = getTime();
1222 if (now - mPrevTrigger >= mPeriod) {
1223 mPrevTrigger = now;
1224 computeNext();
1225 return true;
1226 }
1227 return false;
1228 }
1229
1231};
1232
1233#else
1234
1235// Under C++11 rules, we would be allowed to use not-external
1236// -linkage-type symbols as template arguments,
1237// e.g., LIB8STATIC seconds16, and we'd be able to use these
1238// templates as shown below.
1239// However, under C++03 rules, we cannot do that, and thus we
1240// have to resort to the preprocessor to 'instantiate' 'templates',
1241// as handled above.
1242template<typename timeType,timeType (*timeGetter)()>
1243class CEveryNTimePeriods {
1244public:
1245 timeType mPrevTrigger;
1246 timeType mPeriod;
1247
1248 CEveryNTimePeriods() { reset(); mPeriod = 1; };
1249 CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); };
1250 void setPeriod( timeType period) { mPeriod = period; };
1251 timeType getTime() { return (timeType)(timeGetter()); };
1252 timeType getPeriod() { return mPeriod; };
1253 timeType getElapsed() { return getTime() - mPrevTrigger; }
1254 timeType getRemaining() { return mPeriod - getElapsed(); }
1255 timeType getLastTriggerTime() { return mPrevTrigger; }
1256 bool ready() {
1257 bool isReady = (getElapsed() >= mPeriod);
1258 if( isReady ) { reset(); }
1259 return isReady;
1260 }
1261 void reset() { mPrevTrigger = getTime(); };
1262 void trigger() { mPrevTrigger = getTime() - mPeriod; };
1263
1264 operator bool() { return ready(); }
1265};
1266typedef CEveryNTimePeriods<uint16_t,seconds16> CEveryNSeconds;
1267typedef CEveryNTimePeriods<uint16_t,bseconds16> CEveryNBSeconds;
1268typedef CEveryNTimePeriods<uint32_t,millis> CEveryNMillis;
1269typedef CEveryNTimePeriods<uint16_t,minutes16> CEveryNMinutes;
1270typedef CEveryNTimePeriods<uint8_t,hours8> CEveryNHours;
1271#endif
1272
1273
1288
1290#define CONCAT_HELPER( x, y ) x##y
1291#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1293
1294
1297#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1298
1301#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1302
1303
1306#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1307
1310#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1311
1312
1315#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1316
1319#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1320
1321
1324#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1325
1328#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1329
1330
1333#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1334
1337#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1338
1339
1341#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1343#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1344
1346#define EVERY_N_MILLISECONDS_DYNAMIC(PERIOD_FUNC) EVERY_N_MILLISECONDS_DYNAMIC_I(CONCAT_MACRO(__dynamic_millis_timer, __COUNTER__ ), (PERIOD_FUNC))
1347
1349#define EVERY_N_MILLISECONDS_DYNAMIC_I(NAME, PERIOD_FUNC) \
1350 static CEveryNMillisDynamic NAME(1); \
1351 NAME.setPeriod(PERIOD_FUNC); \
1352 if( NAME )
1353
1354
1355#define EVERY_N_MILLISECONDS_RANDOM(MIN, MAX) \
1356 EVERY_N_MILLISECONDS_RANDOM_I( \
1357 CONCAT_MACRO(_permRand, __COUNTER__), MIN, MAX)
1358
1359#define EVERY_N_MILLISECONDS_RANDOM_I(NAME, MIN, MAX) \
1360 static CEveryNMillisRandom NAME(MIN, MAX); \
1361 if (NAME.ready())
1362
1365
1366
1367// These defines are used to declare hidden or commented symbols for the
1368// purposes of Doxygen documentation generation. They do not affect your program.
1369#ifdef FASTLED_DOXYGEN
1373#define USE_GET_MILLISECOND_TIMER
1374#endif
1375
1377
1378#endif
int y
Definition Audio.ino:72
UIButton trigger("Trigger")
central include file for FastLED, defines the CFastLED class/object
void setPeriod(uint32_t period)
Definition lib8tion.h:1186
uint32_t getLastTriggerTime()
Definition lib8tion.h:1178
uint32_t getPeriod() const
Definition lib8tion.h:1175
uint32_t getRemaining()
Definition lib8tion.h:1177
uint32_t getElapsed()
Definition lib8tion.h:1176
CEveryNMillisDynamic(uint32_t period)
Definition lib8tion.h:1173
CEveryNMillisRandom(uint32_t minPeriod, uint32_t maxPeriod)
Definition lib8tion.h:1205
uint32_t getTime() const
Definition lib8tion.h:1218
uint32_t mPrevTrigger
Definition lib8tion.h:1200
void trigger()
Reset the timestamp so it is ready() on next call.
Definition lib8tion.h:1142
TIMETYPE mPeriod
Timing interval to check.
Definition lib8tion.h:1105
CEveryNTime(TIMETYPE period)
Constructor.
Definition lib8tion.h:1111
TIMETYPE getLastTriggerTime()
Get the timestamp of the most recent trigger event.
Definition lib8tion.h:1129
CEveryNTime()
Default constructor.
Definition lib8tion.h:1108
TIMETYPE getTime()
Get the current time according to the class' timekeeper.
Definition lib8tion.h:1117
TIMETYPE getElapsed()
Get the time elapsed since the last trigger event.
Definition lib8tion.h:1123
void setPeriod(TIMETYPE period)
Set the time interval between triggers.
Definition lib8tion.h:1114
bool ready()
Check if the time interval has elapsed.
Definition lib8tion.h:1132
void reset()
Reset the timestamp to the current time.
Definition lib8tion.h:1139
TIMETYPE getPeriod()
Get the time interval between triggers.
Definition lib8tion.h:1120
TIMETYPE mPrevTrigger
Timestamp of the last time the class was "ready".
Definition lib8tion.h:1104
TIMETYPE getRemaining()
Get the time until the next trigger event.
Definition lib8tion.h:1126
LIB8STATIC uint8_t beat8(accum88 beats_per_minute, uint32_t timebase=0)
Generates an 8-bit "sawtooth" wave at a given BPM.
Definition lib8tion.h:905
LIB8STATIC uint16_t beat88(accum88 beats_per_minute_88, uint32_t timebase=0)
Generates a 16-bit "sawtooth" wave at a given BPM, with BPM specified in Q8.8 fixed-point format.
Definition lib8tion.h:879
LIB8STATIC uint16_t beatsin16(accum88 beats_per_minute, uint16_t lowest=0, uint16_t highest=65535, uint32_t timebase=0, uint16_t phase_offset=0)
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:939
LIB8STATIC uint16_t beat16(accum88 beats_per_minute, uint32_t timebase=0)
Generates a 16-bit "sawtooth" wave at a given BPM.
Definition lib8tion.h:895
LIB8STATIC uint8_t beatsin8(accum88 beats_per_minute, uint8_t lowest=0, uint8_t highest=255, uint32_t timebase=0, uint8_t phase_offset=0)
Generates an 8-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:957
LIB8STATIC uint16_t beatsin88(accum88 beats_per_minute_88, uint16_t lowest=0, uint16_t highest=65535, uint32_t timebase=0, uint16_t phase_offset=0)
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition lib8tion.h:921
LIB8STATIC uint16_t ease16InOutQuad(uint16_t i)
16-bit quadratic ease-in / ease-out function.
Definition lib8tion.h:607
LIB8STATIC fract8 ease8InOutApprox(fract8 i)
Fast, rough 8-bit ease-in/ease-out function.
Definition lib8tion.h:653
LIB8STATIC uint8_t ease8InOutQuad(uint8_t i)
8-bit quadratic ease-in / ease-out function.
Definition lib8tion.h:562
LIB8STATIC fract8 ease8InOutCubic(fract8 i)
8-bit cubic ease-in / ease-out function.
Definition lib8tion.h:624
LIB8STATIC sfract15 floatToSfract15(float f)
Conversion from IEEE754 float in the range (-1,1) to 16-bit fixed point (sfract15).
Definition lib8tion.h:409
LIB8STATIC float sfract15ToFloat(sfract15 y)
Conversion from 16-bit fixed point (sfract15) to IEEE754 32-bit float.
Definition lib8tion.h:401
int16_t sfract15
ANSI: signed _Fract.
Definition types.h:55
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
Definition types.h:58
uint8_t fract8
ANSI: unsigned short _Fract.
Definition types.h:36
uint16_t fract16
ANSI: unsigned _Fract.
Definition types.h:46
LIB8STATIC uint8_t lerp8by8(uint8_t a, uint8_t b, fract8 frac)
Linear interpolation between two unsigned 8-bit values, with 8-bit fraction.
Definition lib8tion.h:437
LIB8STATIC uint16_t lerp16by16(uint16_t a, uint16_t b, fract16 frac)
Linear interpolation between two unsigned 16-bit values, with 16-bit fraction.
Definition lib8tion.h:454
LIB8STATIC uint16_t lerp16by8(uint16_t a, uint16_t b, fract8 frac)
Linear interpolation between two unsigned 16-bit values, with 8-bit fraction.
Definition lib8tion.h:471
LIB8STATIC int16_t lerp15by8(int16_t a, int16_t b, fract8 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
Definition lib8tion.h:488
LIB8STATIC int16_t lerp15by16(int16_t a, int16_t b, fract16 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
Definition lib8tion.h:505
LIB8STATIC uint8_t map8(uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
Map from one full-range 8-bit value into a narrower range of 8-bit values, possibly a range of hues.
Definition lib8tion.h:541
LIB8STATIC uint16_t random16()
Generate a 16-bit random number.
Definition random8.h:56
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8() does not clean up the R1 register on AVR.
Definition scale8.h:176
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 who...
Definition scale8.h:546
LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8(uint16_t i, fract8 scale)
Scale a 16-bit unsigned value by an 8-bit value, which is treated as the numerator of a fraction whos...
Definition scale8.h:474
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Definition scale8.h:40
#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME, TIMETYPE, TIMEGETTER)
Preprocessor-based class "template" for CEveryNTime, used with EVERY_N_TIME timekeepers.
Definition lib8tion.h:1059
LIB8STATIC uint16_t minutes16()
Return the current minutes since boot in a 16-bit value.
Definition lib8tion.h:990
LIB8STATIC uint16_t bseconds16()
Returns the current time-since-boot in "binary seconds", which are actually 1024/1000 of a second lon...
Definition lib8tion.h:1047
#define GET_MILLIS
The a number of functions need access to a millisecond counter in order to keep time.
Definition lib8tion.h:819
LIB8STATIC uint16_t div1024_32_16(uint32_t in32)
Helper routine to divide a 32-bit value by 1024, returning only the low 16 bits.
Definition lib8tion.h:1022
LIB8STATIC uint8_t hours8()
Return the current hours since boot in an 8-bit value.
Definition lib8tion.h:1000
LIB8STATIC uint16_t seconds16()
Return the current seconds since boot in a 16-bit value.
Definition lib8tion.h:980
#define sin16
Platform-independent alias of the fast sin implementation.
Definition trig8.h:103
#define sin8
Platform-independent alias of the fast sin implementation.
Definition trig8.h:221
LIB8STATIC uint8_t cubicwave8(uint8_t in)
Cubic waveform generator.
Definition lib8tion.h:755
LIB8STATIC uint8_t squarewave8(uint8_t in, uint8_t pulsewidth=128)
Square wave generator.
Definition lib8tion.h:784
LIB8STATIC uint8_t quadwave8(uint8_t in)
Quadratic waveform generator.
Definition lib8tion.h:747
LIB8STATIC uint8_t triwave8(uint8_t in)
Triangle wave generator.
Definition lib8tion.h:728
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
Definition lib8static.h:10
Defines static inlining macros for lib8tion functions.
Defines fractional types used for lib8tion functions.
Fast, efficient 8-bit math functions specifically designed for high-performance LED programming.
#define FASTLED_NAMESPACE_END
Definition namespace.h:23
Fast, efficient random number generators specifically designed for high-performance LED programming.
Fast, efficient 8-bit scaling functions specifically designed for high-performance LED programming.
Fast, efficient 8-bit trigonometry functions specifically designed for high-performance LED programmi...