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 "fl/math/types.h"
8
9#include "led_sysdefs.h"
10#include "platforms/is_platform.h"
11
12
16
17#include "fl/stl/stdint.h"
18#include "fl/math/lib8static.h"
19#include "fl/math/math8.h"
20#include "fl/math/qfx.h"
21#include "fl/math/memmove.h"
22#include "platforms/math8_config.h"
23#include "fl/math/ease.h"
24#include "fl/math/squarewave.h"
25#include "fl/math/beat.h"
27#include "fl/stl/chrono.h"
28
29
30#if !defined(FL_IS_AVR)
31// memmove, memcpy, and memset are defined in lib8tion/memmove.h and fl/stl/cstring.h
32#endif // end of !defined(FL_IS_AVR)
33
224
225
226
227
228#include "fl/math/math8.h"
229#include "fl/math/scale8.h"
230#include "fl/math/random8.h"
231#include "fl/math/trig8.h"
232
233// Bring types and common math functions into global scope for backward compatibility.
234// Only import names that are actually defined in namespace fl (via platforms/ headers).
235// Functions defined with LIB8STATIC outside namespace fl (e.g., random8.h) are already global.
236//
237// On AVR, Arduino's USBAPI.h defines u8/u16/u32 at global scope with potentially
238// different underlying types (e.g. unsigned short vs unsigned int for u16).
239// Skip those to avoid redeclaration conflicts.
240#if !defined(FL_IS_AVR)
241using fl::u8;
242// On AVR+Arduino, USBAPI.h (included via Arduino.h) already provides a global
243// 'typedef unsigned short u16;'. fl::u16 on AVR is 'unsigned int' — same width
244// but a different type — so 'using fl::u16;' would conflict. Skip it on AVR and
245// let USBAPI.h's typedef provide the global u16 name instead.
246#if !defined(FL_IS_AVR) || !defined(ARDUINO)
247using fl::u16;
248#endif
249using fl::u32;
250#endif
251using fl::u64;
252using fl::i8;
253using fl::i16;
254using fl::i32;
255using fl::i64;
256// scale8.h (namespace fl)
257using fl::scale8;
258using fl::scale8_video;
259using fl::scale16;
260using fl::scale16by8;
261using fl::scale8_LEAVING_R1_DIRTY;
262using fl::nscale8x3;
263using fl::nscale8x3_video;
264using fl::scale8_video_LEAVING_R1_DIRTY;
265using fl::cleanup_R1;
266// trig8.h (namespace fl)
267using fl::sin8;
268using fl::sin16;
269using fl::cos8;
270using fl::cos16;
271// math8.h (namespace fl)
272using fl::qadd8;
273using fl::qsub8;
274using fl::qadd7;
275using fl::qmul8;
276using fl::add8;
277using fl::add8to16;
278using fl::sub8;
279using fl::avg8;
280using fl::avg16;
281using fl::avg8r;
282using fl::avg16r;
283using fl::avg7;
284using fl::avg15;
285using fl::mul8;
286using fl::abs8;
287using fl::blend8;
288using fl::mod8;
289using fl::addmod8;
290using fl::submod8;
291using fl::sqrt16;
292using fl::sqrt8;
293using fl::dim8_raw;
294// qfx.h (namespace fl)
295using fl::q44;
296using fl::q62;
297using fl::q88;
298using fl::q124;
299// squarewave.h (namespace fl)
300using fl::squarewave8;
301// beat.h (namespace fl)
302using fl::beat88;
303using fl::beat16;
304using fl::beat8;
305using fl::beatsin88;
306using fl::beatsin16;
307using fl::beatsin8;
308// time_functions.h (namespace fl)
309using fl::seconds16;
310using fl::minutes16;
311using fl::hours8;
313using fl::bseconds16;
314
316
317
318
325
328{
329 return y / 32768.0f;
330}
331
336{
337 return static_cast<sfract15>(f * 32768.0f);
338}
339
341
342
343
344
345
360
364{
365 fl::u8 result;
366 if( b > a) {
367 fl::u8 delta = b - a;
368 fl::u8 scaled = scale8( delta, frac);
369 result = a + scaled;
370 } else {
371 fl::u8 delta = a - b;
372 fl::u8 scaled = scale8( delta, frac);
373 result = a - scaled;
374 }
375 return result;
376}
377
380LIB8STATIC fl::u16 lerp16by16( fl::u16 a, fl::u16 b, fract16 frac)
381{
382 fl::u16 result;
383 if( b > a ) {
384 fl::u16 delta = b - a;
385 fl::u16 scaled = scale16(delta, frac);
386 result = a + scaled;
387 } else {
388 fl::u16 delta = a - b;
389 fl::u16 scaled = scale16( delta, frac);
390 result = a - scaled;
391 }
392 return result;
393}
394
397LIB8STATIC fl::u16 lerp16by8( fl::u16 a, fl::u16 b, fract8 frac)
398{
399 fl::u16 result;
400 if( b > a) {
401 fl::u16 delta = b - a;
402 fl::u16 scaled = scale16by8( delta, frac);
403 result = a + scaled;
404 } else {
405 fl::u16 delta = a - b;
406 fl::u16 scaled = scale16by8( delta, frac);
407 result = a - scaled;
408 }
409 return result;
410}
411
414LIB8STATIC fl::i16 lerp15by8( fl::i16 a, fl::i16 b, fract8 frac)
415{
416 fl::i16 result;
417 if( b > a) {
418 fl::u16 delta = b - a;
419 fl::u16 scaled = scale16by8( delta, frac);
420 result = a + scaled;
421 } else {
422 fl::u16 delta = a - b;
423 fl::u16 scaled = scale16by8( delta, frac);
424 result = a - scaled;
425 }
426 return result;
427}
428
431LIB8STATIC fl::i16 lerp15by16( fl::i16 a, fl::i16 b, fract16 frac)
432{
433 fl::i16 result;
434 if( b > a) {
435 fl::u16 delta = b - a;
436 fl::u16 scaled = scale16( delta, frac);
437 result = a + scaled;
438 } else {
439 fl::u16 delta = a - b;
440 fl::u16 scaled = scale16( delta, frac);
441 result = a - scaled;
442 }
443 return result;
444}
445
467LIB8STATIC fl::u8 map8( fl::u8 in, fl::u8 rangeStart, fl::u8 rangeEnd)
468{
469 fl::u8 rangeWidth = rangeEnd - rangeStart;
470 fl::u8 out = scale8( in, rangeWidth);
471 out += rangeStart;
472 return out;
473}
474
476
477
484
487#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
489{
490 fl::u8 j = i;
491 if( j & 0x80 ) {
492 j = 255 - j;
493 }
494 fl::u8 jj = scale8( j, j);
495 fl::u8 jj2 = jj << 1;
496 if( i & 0x80 ) {
497 jj2 = 255 - jj2;
498 }
499 return jj2;
500}
501
502#elif EASE8_AVRASM == 1
503// This AVR asm version of ease8InOutQuad preserves one more
504// low-bit of precision than the C version, and is also slightly
505// smaller and faster.
507 fl::u8 j=val;
508 asm volatile (
509 "sbrc %[val], 7 \n"
510 "com %[j] \n"
511 "mul %[j], %[j] \n"
512 "add r0, %[j] \n"
513 "ldi %[j], 0 \n"
514 "adc %[j], r1 \n"
515 "lsl r0 \n" // carry = high bit of low byte of mul product
516 "rol %[j] \n" // j = (j * 2) + carry // preserve add'l bit of precision
517 "sbrc %[val], 7 \n"
518 "com %[j] \n"
519 "clr __zero_reg__ \n"
520 : [j] "+&a" (j)
521 : [val] "a" (val)
522 : "r0", "r1"
523 );
524 return j;
525}
526
527#else
528#error "No implementation for ease8InOutQuad available."
529#endif
530
531LIB8STATIC fl::u16 ease16InOutQuad(fl::u16 i)
532{
533 // This is the legacy version, there is a slightly more accurate version in fl/ease.cpp
534 // with fl::easeInOutQuad16. However the difference is minimal.
535 //
536 // 16-bit quadratic ease-in / ease-out function
537 fl::u16 j = i;
538 if (j & 0x8000) {
539 j = 65535 - j;
540 }
541 fl::u16 jj = scale16(j, j);
542 fl::u16 jj2 = jj << 1;
543 if (i & 0x8000) {
544 jj2 = 65535 - jj2;
545 }
546 return jj2;
547}
548
549LIB8STATIC fl::u16 ease16InOutCubic(fl::u16 i) {
550 // This function produces wrong results, use fl::easeInOutCubic16 instead
551 //
552 // 16-bit cubic ease-in / ease-out function
553 // Equivalent to ease8InOutCubic() but for 16-bit values
554 // Formula: 3(x^2) - 2(x^3) applied with proper ease-in-out curve
555
556 // Apply the cubic formula directly, similar to the 8-bit version
557 // scale16(a, b) computes (a * b) / 65536
558 fl::u32 ii = scale16(i, i); // i^2 scaled to 16-bit
559 fl::u32 iii = scale16(ii, i); // i^3 scaled to 16-bit
560
561 // Apply cubic formula: 3x^2 - 2x^3
562 fl::u32 r1 = (3 * ii) - (2 * iii);
563
564 // Clamp result to 16-bit range
565 if (r1 > 65535) {
566 return 65535;
567 }
568 return (fl::u16)r1;
569}
570
571
575{
576 fl::u8 ii = scale8_LEAVING_R1_DIRTY( i, i);
577 fl::u8 iii = scale8_LEAVING_R1_DIRTY( ii, i);
578
579 fl::u16 r1 = (3 * (fl::u16)(ii)) - ( 2 * (fl::u16)(iii));
580
581 /* the code generated for the above *'s automatically
582 cleans up R1, so there's no need to explicitily call
583 cleanup_R1(); */
584
585 fl::u8 result = r1;
586
587 // if we got "256", return 255:
588 if( r1 & 0x100 ) {
589 result = 255;
590 }
591 return result;
592}
593
594
602#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
604{
605 if( i < 64) {
606 // start with slope 0.5
607 i /= 2;
608 } else if( i > (255 - 64)) {
609 // end with slope 0.5
610 i = 255 - i;
611 i /= 2;
612 i = 255 - i;
613 } else {
614 // in the middle, use slope 192/128 = 1.5
615 i -= 64;
616 i += (i / 2);
617 i += 32;
618 }
619
620 return i;
621}
622
623#elif EASE8_AVRASM == 1
625{
626 // takes around 7 cycles on AVR
627 asm volatile (
628 " subi %[i], 64 \n\t"
629 " cpi %[i], 128 \n\t"
630 " brcc Lshift_%= \n\t"
631
632 // middle case
633 " mov __tmp_reg__, %[i] \n\t"
634 " lsr __tmp_reg__ \n\t"
635 " add %[i], __tmp_reg__ \n\t"
636 " subi %[i], 224 \n\t"
637 " rjmp Ldone_%= \n\t"
638
639 // start or end case
640 "Lshift_%=: \n\t"
641 " lsr %[i] \n\t"
642 " subi %[i], 96 \n\t"
643
644 "Ldone_%=: \n\t"
645
646 : [i] "+a" (i)
647 :
648 : "r0"
649 );
650 return i;
651}
652#else
653#error "No implementation for ease8 available."
654#endif
655
657
658
665
666
679{
680 if( in & 0x80) {
681 in = 255 - in;
682 }
683 fl::u8 out = in << 1;
684 return out;
685}
686
698{
699 return ease8InOutQuad( triwave8( in));
700}
701
709
710
711// squarewave8 is now in fl/math/squarewave.h (namespace fl),
712// brought into global scope via 'using fl::squarewave8' above.
713
715
717
718
725
726#if ((defined(ARDUINO) || defined(FL_IS_STM32_F2) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
727// Forward declaration of Arduino function 'millis'.
728//uint32_t millis();
729
740#define GET_MILLIS fl::millis
741#else
742fl::u32 get_millisecond_timer();
743#define GET_MILLIS get_millisecond_timer
744#endif
745
747
748
751
752
753// Beat generators (beat88, beat16, beat8, beatsin88, beatsin16, beatsin8) are now
754// in fl/math/beat.h (namespace fl), brought into global scope via 'using' above.
755
756// Time functions (seconds16, minutes16, hours8, div1024_32_16, bseconds16) are now
757// in fl/math/time_functions.h (namespace fl), brought into global scope via 'using' above.
758
762#if 1
763#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
764class NAME { \
765public: \
766 TIMETYPE mPrevTrigger; \
767 TIMETYPE mPeriod; \
768 \
769 NAME() { reset(); mPeriod = 1; }; \
770 NAME(TIMETYPE period) { reset(); setPeriod(period); }; \
771 void setPeriod( TIMETYPE period) { mPeriod = period; }; \
772 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); }; \
773 TIMETYPE getPeriod() { return mPeriod; }; \
774 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; } \
775 TIMETYPE getRemaining() { return mPeriod - getElapsed(); } \
776 TIMETYPE getLastTriggerTime() { return mPrevTrigger; } \
777 bool ready() { \
778 bool isReady = (getElapsed() >= mPeriod); \
779 if( isReady ) { reset(); } \
780 return isReady; \
781 } \
782 void reset() { mPrevTrigger = getTime(); }; \
783 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
784 \
785 operator bool() { return ready(); } \
786};
787
792
793#if defined(FASTLED_DOXYGEN)
807public:
808 TIMETYPE mPrevTrigger;
809 TIMETYPE mPeriod;
810
812 CEveryNTime() { reset(); mPeriod = 1; };
815 CEveryNTime(TIMETYPE period) { reset(); setPeriod(period); };
816
818 void setPeriod( TIMETYPE period) { mPeriod = period; };
819
821 TIMETYPE getTime() { return (TIMETYPE)(TIMEGETTER()); };
822
824 TIMETYPE getPeriod() { return mPeriod; };
825
827 TIMETYPE getElapsed() { return getTime() - mPrevTrigger; }
828
830 TIMETYPE getRemaining() { return mPeriod - getElapsed(); }
831
833 TIMETYPE getLastTriggerTime() { return mPrevTrigger; }
834
836 bool ready() {
837 bool isReady = (getElapsed() >= mPeriod);
838 if( isReady ) { reset(); }
839 return isReady;
840 }
841
843 void reset() { mPrevTrigger = getTime(); };
844
847
849 operator bool() { return ready(); }
850};
851#endif // FASTLED_DOXYGEN
852
855
858
861
864
867
869#define CEveryNMilliseconds CEveryNMillis
870
873public:
875 fl::u32 mPeriod;
876
877 CEveryNMillisDynamic(fl::u32 period) : mPeriod(period) { reset(); };
878 fl::u32 getTime() { return GET_MILLIS(); };
879 fl::u32 getPeriod() const { return mPeriod; };
880 fl::u32 getElapsed() { return getTime() - mPrevTrigger; }
881 fl::u32 getRemaining() { return getPeriod() - getElapsed(); }
882 fl::u32 getLastTriggerTime() { return mPrevTrigger; }
883 bool ready() {
884 bool isReady = (getElapsed() >= getPeriod());
885 if( isReady ) { reset(); }
886 return isReady;
887 }
888 void reset() { mPrevTrigger = getTime(); };
890 void setPeriod(fl::u32 period) { mPeriod = period; }
891
892 operator bool() { return ready(); }
893};
894
895
896
897
898// ————————————————————————————————————————————————
899// Random‐interval version of EVERY_N_MILLISECONDS:
900// on each trigger, pick the next period randomly in [MIN..MAX].
901// ————————————————————————————————————————————————
903public:
905 fl::u32 mPeriod;
906 fl::u32 mMinPeriod;
907 fl::u32 mMaxPeriod;
908
909 CEveryNMillisRandom(fl::u32 minPeriod, fl::u32 maxPeriod)
910 : mMinPeriod(minPeriod), mMaxPeriod(maxPeriod)
911 {
912 computeNext();
913 reset();
914 }
915
916 void computeNext() {
917 // random16(x) returns [0..x-1], so this yields MIN..MAX
918 fl::u32 range = mMaxPeriod - mMinPeriod + 1;
919 mPeriod = mMinPeriod + random16(range);
920 }
921
922 fl::u32 getTime() const { return GET_MILLIS(); }
923
924 bool ready() {
925 fl::u32 now = getTime();
926 if (now - mPrevTrigger >= mPeriod) {
927 mPrevTrigger = now;
928 computeNext();
929 return true;
930 }
931 return false;
932 }
933
934 void reset() { mPrevTrigger = getTime(); }
935};
936
937#else
938
939// Under C++11 rules, we would be allowed to use not-external
940// -linkage-type symbols as template arguments,
941// e.g., LIB8STATIC seconds16, and we'd be able to use these
942// templates as shown below.
943// However, under C++03 rules, we cannot do that, and thus we
944// have to resort to the preprocessor to 'instantiate' 'templates',
945// as handled above.
946template<typename timeType,timeType (*timeGetter)()>
947class CEveryNTimePeriods {
948public:
949 timeType mPrevTrigger;
950 timeType mPeriod;
951
952 CEveryNTimePeriods() { reset(); mPeriod = 1; };
953 CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); };
954 void setPeriod( timeType period) { mPeriod = period; };
955 timeType getTime() { return (timeType)(timeGetter()); };
956 timeType getPeriod() { return mPeriod; };
957 timeType getElapsed() { return getTime() - mPrevTrigger; }
958 timeType getRemaining() { return mPeriod - getElapsed(); }
959 timeType getLastTriggerTime() { return mPrevTrigger; }
960 bool ready() {
961 bool isReady = (getElapsed() >= mPeriod);
962 if( isReady ) { reset(); }
963 return isReady;
964 }
965 void reset() { mPrevTrigger = getTime(); };
966 void trigger() { mPrevTrigger = getTime() - mPeriod; };
967
968 operator bool() { return ready(); }
969};
970typedef CEveryNTimePeriods<fl::u16,seconds16> CEveryNSeconds;
971typedef CEveryNTimePeriods<fl::u16,bseconds16> CEveryNBSeconds;
972typedef CEveryNTimePeriods<fl::u32,millis> CEveryNMillis;
973typedef CEveryNTimePeriods<fl::u16,minutes16> CEveryNMinutes;
974typedef CEveryNTimePeriods<fl::u8,hours8> CEveryNHours;
975#endif
976
977
992
994#define CONCAT_HELPER( x, y ) x##y
995#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
997
998
1001#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1002
1005#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1006
1007
1010#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1011
1014#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1015
1016
1019#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1020
1023#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1024
1025
1028#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1029
1032#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1033
1034
1037#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1038
1041#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1042
1043
1045#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1047#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1048
1050#define EVERY_N_MILLISECONDS_DYNAMIC(PERIOD_FUNC) EVERY_N_MILLISECONDS_DYNAMIC_I(CONCAT_MACRO(__dynamic_millis_timer, __COUNTER__ ), (PERIOD_FUNC))
1051
1053#define EVERY_N_MILLISECONDS_DYNAMIC_I(NAME, PERIOD_FUNC) \
1054 static CEveryNMillisDynamic NAME(1); \
1055 NAME.setPeriod(PERIOD_FUNC); \
1056 if( NAME )
1057
1058
1059#define EVERY_N_MILLISECONDS_RANDOM(MIN, MAX) \
1060 EVERY_N_MILLISECONDS_RANDOM_I( \
1061 CONCAT_MACRO(_permRand, __COUNTER__), MIN, MAX)
1062
1063#define EVERY_N_MILLISECONDS_RANDOM_I(NAME, MIN, MAX) \
1064 static CEveryNMillisRandom NAME(MIN, MAX); \
1065 if (NAME.ready())
1066
1069
1070
1071// These defines are used to declare hidden or commented symbols for the
1072// purposes of Doxygen documentation generation. They do not affect your program.
1073#ifdef FASTLED_DOXYGEN
1077#define USE_GET_MILLISECOND_TIMER
1078#endif
1079
1080#endif
1081
1082// Using declarations moved to top of file
int y
Definition simple.h:93
FastLED chrono implementation - duration types for time measurements.
fl::u32 getLastTriggerTime()
Definition lib8tion.h:882
void setPeriod(fl::u32 period)
Definition lib8tion.h:890
fl::u32 getPeriod() const
Definition lib8tion.h:879
fl::u32 getElapsed()
Definition lib8tion.h:880
fl::u32 getRemaining()
Definition lib8tion.h:881
CEveryNMillisDynamic(fl::u32 period)
Definition lib8tion.h:877
CEveryNMillisRandom(fl::u32 minPeriod, fl::u32 maxPeriod)
Definition lib8tion.h:909
fl::u32 getTime() const
Definition lib8tion.h:922
void trigger()
Reset the timestamp so it is ready() on next call.
Definition lib8tion.h:846
TIMETYPE mPeriod
Timing interval to check.
Definition lib8tion.h:809
CEveryNTime(TIMETYPE period)
Constructor.
Definition lib8tion.h:815
TIMETYPE getLastTriggerTime()
Get the timestamp of the most recent trigger event.
Definition lib8tion.h:833
CEveryNTime()
Default constructor.
Definition lib8tion.h:812
TIMETYPE getTime()
Get the current time according to the class' timekeeper.
Definition lib8tion.h:821
TIMETYPE getElapsed()
Get the time elapsed since the last trigger event.
Definition lib8tion.h:827
void setPeriod(TIMETYPE period)
Set the time interval between triggers.
Definition lib8tion.h:818
bool ready()
Check if the time interval has elapsed.
Definition lib8tion.h:836
void reset()
Reset the timestamp to the current time.
Definition lib8tion.h:843
TIMETYPE getPeriod()
Get the time interval between triggers.
Definition lib8tion.h:824
TIMETYPE mPrevTrigger
Timestamp of the last time the class was "ready".
Definition lib8tion.h:808
TIMETYPE getRemaining()
Get the time until the next trigger event.
Definition lib8tion.h:830
fl::UIButton trigger("Trigger")
Defines static inlining macros for lib8tion functions.
Legacy compatibility header for 8-bit math functions.
Fast, efficient random number generators specifically designed for high-performance LED programming.
Legacy compatibility header for 8-bit scaling functions.
Legacy compatibility header for trigonometry functions.
Defines fractional types used for lib8tion functions.
LIB8STATIC u16 beat16(accum88 beats_per_minute, u32 timebase=0) FL_NOEXCEPT
Generates a 16-bit "sawtooth" wave at a given BPM.
Definition beat.h:41
LIB8STATIC u16 beatsin88(accum88 beats_per_minute_88, u16 lowest=0, u16 highest=65535, u32 timebase=0, u16 phase_offset=0) FL_NOEXCEPT
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition beat.h:63
LIB8STATIC u8 beatsin8(accum88 beats_per_minute, u8 lowest=0, u8 highest=255, u32 timebase=0, u8 phase_offset=0) FL_NOEXCEPT
Generates an 8-bit sine wave at a given BPM that oscillates within a given range.
Definition beat.h:105
LIB8STATIC u8 beat8(accum88 beats_per_minute, u32 timebase=0) FL_NOEXCEPT
Generates an 8-bit "sawtooth" wave at a given BPM.
Definition beat.h:51
LIB8STATIC u16 beat88(accum88 beats_per_minute_88, u32 timebase=0) FL_NOEXCEPT
Generates a 16-bit "sawtooth" wave at a given BPM, with BPM specified in Q8.8 fixed-point format.
Definition beat.h:26
LIB8STATIC u16 beatsin16(accum88 beats_per_minute, u16 lowest=0, u16 highest=65535, u32 timebase=0, u16 phase_offset=0) FL_NOEXCEPT
Generates a 16-bit sine wave at a given BPM that oscillates within a given range.
Definition beat.h:84
LIB8STATIC fl::u16 ease16InOutQuad(fl::u16 i)
Definition lib8tion.h:531
LIB8STATIC fract8 ease8InOutApprox(fract8 i)
Fast, rough 8-bit ease-in/ease-out function.
Definition lib8tion.h:603
LIB8STATIC fract8 ease8InOutCubic(fract8 i)
8-bit cubic ease-in / ease-out function.
Definition lib8tion.h:574
LIB8STATIC fl::u16 ease16InOutCubic(fl::u16 i)
Definition lib8tion.h:549
LIB8STATIC fl::u8 ease8InOutQuad(fl::u8 i)
8-bit quadratic ease-in / ease-out function.
Definition lib8tion.h:488
LIB8STATIC sfract15 floatToSfract15(float f)
Conversion from IEEE754 float in the range (-1,1) to 16-bit fixed point (sfract15).
Definition lib8tion.h:335
LIB8STATIC float sfract15ToFloat(sfract15 y)
Conversion from 16-bit fixed point (sfract15) to IEEE754 32-bit float.
Definition lib8tion.h:327
qfx< u16, 12, 4 > q124
A 12.4 integer (12 bits integer, 4 bits fraction)
Definition qfx.h:51
qfx< u16, 8, 8 > q88
A 8.8 integer (8 bits integer, 8 bits fraction)
Definition qfx.h:49
qfx< u8, 4, 4 > q44
A 4.4 integer (4 bits integer, 4 bits fraction)
Definition qfx.h:45
qfx< u8, 6, 2 > q62
A 6.2 integer (6 bits integer, 2 bits fraction)
Definition qfx.h:47
LIB8STATIC fl::i16 lerp15by16(fl::i16 a, fl::i16 b, fract16 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
Definition lib8tion.h:431
LIB8STATIC fl::u8 lerp8by8(fl::u8 a, fl::u8 b, fract8 frac)
Linear interpolation between two unsigned 8-bit values, with 8-bit fraction.
Definition lib8tion.h:363
LIB8STATIC fl::i16 lerp15by8(fl::i16 a, fl::i16 b, fract8 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
Definition lib8tion.h:414
LIB8STATIC fl::u16 lerp16by8(fl::u16 a, fl::u16 b, fract8 frac)
Linear interpolation between two unsigned 16-bit values, with 8-bit fraction.
Definition lib8tion.h:397
LIB8STATIC fl::u16 lerp16by16(fl::u16 a, fl::u16 b, fract16 frac)
Linear interpolation between two unsigned 16-bit values, with 16-bit fraction.
Definition lib8tion.h:380
LIB8STATIC fl::u8 map8(fl::u8 in, fl::u8 rangeStart, fl::u8 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:467
LIB8STATIC fl::u16 random16() FL_NOEXCEPT
Generate a 16-bit random number.
Definition random8.h:63
LIB8STATIC u16 bseconds16() FL_NOEXCEPT
Returns the current time-since-boot in "binary seconds", which are actually 1024/1000 of a second lon...
LIB8STATIC u16 div1024_32_16(u32 in32) FL_NOEXCEPT
Helper routine to divide a 32-bit value by 1024, returning only the low 16 bits.
#define GET_MILLIS
The a number of functions need access to a millisecond counter in order to keep time.
Definition lib8tion.h:740
LIB8STATIC u16 minutes16() FL_NOEXCEPT
Return the current minutes since boot in a 16-bit value.
LIB8STATIC u16 seconds16() FL_NOEXCEPT
Return the current seconds since boot in a 16-bit value.
LIB8STATIC u8 hours8() FL_NOEXCEPT
Return the current hours since boot in an 8-bit value.
LIB8STATIC fl::u8 cubicwave8(fl::u8 in)
Cubic waveform generator.
Definition lib8tion.h:705
LIB8STATIC fl::u8 quadwave8(fl::u8 in)
Quadratic waveform generator.
Definition lib8tion.h:697
LIB8STATIC u8 squarewave8(u8 in, u8 pulsewidth=128) FL_NOEXCEPT
Square wave generator.
Definition squarewave.h:22
LIB8STATIC fl::u8 triwave8(fl::u8 in)
Triangle wave generator.
Definition lib8tion.h:678
#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME, TIMETYPE, TIMEGETTER)
Preprocessor-based class "template" for CEveryNTime, used with EVERY_N_TIME timekeepers.
Definition lib8tion.h:763
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
Definition lib8static.h:12
Determines which platform system definitions to include.
LIB8STATIC u16 bseconds16() FL_NOEXCEPT
Returns the current time-since-boot in "binary seconds", which are actually 1024/1000 of a second lon...
LIB8STATIC u16 minutes16() FL_NOEXCEPT
Return the current minutes since boot in a 16-bit value.
LIB8STATIC u16 seconds16() FL_NOEXCEPT
Return the current seconds since boot in a 16-bit value.
LIB8STATIC u8 hours8() FL_NOEXCEPT
Return the current hours since boot in an 8-bit value.
Waveform beat generators — sawtooth and sine waves at a given BPM.
u16 fract16
ANSI: unsigned _Fract.
Definition s16x16x4.h:171
i16 sfract15
ANSI: signed _Fract.
Definition s16x16x4.h:180
u8 fract8
Fixed-Point Fractional Types.
Definition s16x16x4.h:161
unsigned char u8
Definition stdint.h:131
fl::i64 i64
Definition s16x16x4.h:222
signed char i8
Definition stdint.h:130
fl::u64 u64
Definition s16x16x4.h:221
Square wave generator function.
Timekeeping helper functions — seconds, minutes, hours, bseconds.