3#ifndef __INC_LIB8TION_H
4#define __INC_LIB8TION_H
10#include "platforms/is_platform.h"
22#include "platforms/math8_config.h"
30#if !defined(FL_IS_AVR)
240#if !defined(FL_IS_AVR)
246#if !defined(FL_IS_AVR) || !defined(ARDUINO)
258using fl::scale8_video;
261using fl::scale8_LEAVING_R1_DIRTY;
263using fl::nscale8x3_video;
264using fl::scale8_video_LEAVING_R1_DIRTY;
337 return static_cast<sfract15>(f * 32768.0f);
368 fl::u8 scaled = scale8( delta, frac);
372 fl::u8 scaled = scale8( delta, frac);
384 fl::u16 delta = b - a;
385 fl::u16 scaled = scale16(delta, frac);
388 fl::u16 delta = a - b;
389 fl::u16 scaled = scale16( delta, frac);
401 fl::u16 delta = b - a;
402 fl::u16 scaled = scale16by8( delta, frac);
405 fl::u16 delta = a - b;
406 fl::u16 scaled = scale16by8( delta, frac);
418 fl::u16 delta = b - a;
419 fl::u16 scaled = scale16by8( delta, frac);
422 fl::u16 delta = a - b;
423 fl::u16 scaled = scale16by8( delta, frac);
435 fl::u16 delta = b - a;
436 fl::u16 scaled = scale16( delta, frac);
439 fl::u16 delta = a - b;
440 fl::u16 scaled = scale16( delta, frac);
469 fl::u8 rangeWidth = rangeEnd - rangeStart;
470 fl::u8 out = scale8( in, rangeWidth);
487#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
494 fl::u8 jj = scale8( j, j);
502#elif EASE8_AVRASM == 1
519 "clr __zero_reg__ \n"
528#error "No implementation for ease8InOutQuad available."
541 fl::u16 jj = scale16(j, j);
542 fl::u16 jj2 = jj << 1;
558 fl::u32 ii = scale16(i, i);
559 fl::u32 iii = scale16(ii, i);
562 fl::u32 r1 = (3 * ii) - (2 * iii);
576 fl::u8 ii = scale8_LEAVING_R1_DIRTY( i, i);
577 fl::u8 iii = scale8_LEAVING_R1_DIRTY( ii, i);
579 fl::u16 r1 = (3 * (fl::u16)(ii)) - ( 2 * (fl::u16)(iii));
602#if (EASE8_C == 1) || defined(FASTLED_DOXYGEN)
608 }
else if( i > (255 - 64)) {
623#elif EASE8_AVRASM == 1
628 " subi %[i], 64 \n\t"
629 " cpi %[i], 128 \n\t"
630 " brcc Lshift_%= \n\t"
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"
642 " subi %[i], 96 \n\t"
653#error "No implementation for ease8 available."
726#if ((defined(ARDUINO) || defined(FL_IS_STM32_F2) || defined(FASTLED_HAS_MILLIS)) && !defined(USE_GET_MILLISECOND_TIMER)) || defined(FASTLED_DOXYGEN)
740#define GET_MILLIS fl::millis
742fl::u32 get_millisecond_timer();
743#define GET_MILLIS get_millisecond_timer
763#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME,TIMETYPE,TIMEGETTER) \
766 TIMETYPE mPrevTrigger; \
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; } \
778 bool isReady = (getElapsed() >= mPeriod); \
779 if( isReady ) { reset(); } \
782 void reset() { mPrevTrigger = getTime(); }; \
783 void trigger() { mPrevTrigger = getTime() - mPeriod; }; \
785 operator bool() { return ready(); } \
793#if defined(FASTLED_DOXYGEN)
821 TIMETYPE
getTime() {
return (TIMETYPE)(TIMEGETTER()); };
838 if( isReady ) {
reset(); }
869#define CEveryNMilliseconds CEveryNMillis
885 if( isReady ) {
reset(); }
946template<
typename timeType,timeType (*timeGetter)()>
947class CEveryNTimePeriods {
949 timeType mPrevTrigger;
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; }
961 bool isReady = (getElapsed() >= mPeriod);
962 if( isReady ) { reset(); }
965 void reset() { mPrevTrigger = getTime(); };
966 void trigger() { mPrevTrigger = getTime() - mPeriod; };
968 operator bool() {
return ready(); }
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;
994#define CONCAT_HELPER( x, y ) x##y
995#define CONCAT_MACRO( x, y ) CONCAT_HELPER( x, y )
1001#define EVERY_N_MILLIS(N) EVERY_N_MILLIS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1005#define EVERY_N_MILLIS_I(NAME,N) static CEveryNMillis NAME(N); if( NAME )
1010#define EVERY_N_SECONDS(N) EVERY_N_SECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1014#define EVERY_N_SECONDS_I(NAME,N) static CEveryNSeconds NAME(N); if( NAME )
1019#define EVERY_N_BSECONDS(N) EVERY_N_BSECONDS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1023#define EVERY_N_BSECONDS_I(NAME,N) static CEveryNBSeconds NAME(N); if( NAME )
1028#define EVERY_N_MINUTES(N) EVERY_N_MINUTES_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1032#define EVERY_N_MINUTES_I(NAME,N) static CEveryNMinutes NAME(N); if( NAME )
1037#define EVERY_N_HOURS(N) EVERY_N_HOURS_I(CONCAT_MACRO(PER, __COUNTER__ ),N)
1041#define EVERY_N_HOURS_I(NAME,N) static CEveryNHours NAME(N); if( NAME )
1045#define EVERY_N_MILLISECONDS(N) EVERY_N_MILLIS(N)
1047#define EVERY_N_MILLISECONDS_I(NAME,N) EVERY_N_MILLIS_I(NAME,N)
1050#define EVERY_N_MILLISECONDS_DYNAMIC(PERIOD_FUNC) EVERY_N_MILLISECONDS_DYNAMIC_I(CONCAT_MACRO(__dynamic_millis_timer, __COUNTER__ ), (PERIOD_FUNC))
1053#define EVERY_N_MILLISECONDS_DYNAMIC_I(NAME, PERIOD_FUNC) \
1054 static CEveryNMillisDynamic NAME(1); \
1055 NAME.setPeriod(PERIOD_FUNC); \
1059#define EVERY_N_MILLISECONDS_RANDOM(MIN, MAX) \
1060 EVERY_N_MILLISECONDS_RANDOM_I( \
1061 CONCAT_MACRO(_permRand, __COUNTER__), MIN, MAX)
1063#define EVERY_N_MILLISECONDS_RANDOM_I(NAME, MIN, MAX) \
1064 static CEveryNMillisRandom NAME(MIN, MAX); \
1073#ifdef FASTLED_DOXYGEN
1077#define USE_GET_MILLISECOND_TIMER
FastLED chrono implementation - duration types for time measurements.
fl::u32 getLastTriggerTime()
void setPeriod(fl::u32 period)
fl::u32 getPeriod() const
CEveryNMillisDynamic(fl::u32 period)
CEveryNMillisRandom(fl::u32 minPeriod, fl::u32 maxPeriod)
void trigger()
Reset the timestamp so it is ready() on next call.
TIMETYPE mPeriod
Timing interval to check.
CEveryNTime(TIMETYPE period)
Constructor.
TIMETYPE getLastTriggerTime()
Get the timestamp of the most recent trigger event.
CEveryNTime()
Default constructor.
TIMETYPE getTime()
Get the current time according to the class' timekeeper.
TIMETYPE getElapsed()
Get the time elapsed since the last trigger event.
void setPeriod(TIMETYPE period)
Set the time interval between triggers.
bool ready()
Check if the time interval has elapsed.
void reset()
Reset the timestamp to the current time.
TIMETYPE getPeriod()
Get the time interval between triggers.
TIMETYPE mPrevTrigger
Timestamp of the last time the class was "ready".
TIMETYPE getRemaining()
Get the time until the next trigger event.
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.
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.
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.
LIB8STATIC u8 beat8(accum88 beats_per_minute, u32 timebase=0) FL_NOEXCEPT
Generates an 8-bit "sawtooth" wave at a given BPM.
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.
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.
LIB8STATIC fl::u16 ease16InOutQuad(fl::u16 i)
LIB8STATIC fract8 ease8InOutApprox(fract8 i)
Fast, rough 8-bit ease-in/ease-out function.
LIB8STATIC fract8 ease8InOutCubic(fract8 i)
8-bit cubic ease-in / ease-out function.
LIB8STATIC fl::u16 ease16InOutCubic(fl::u16 i)
LIB8STATIC fl::u8 ease8InOutQuad(fl::u8 i)
8-bit quadratic ease-in / ease-out function.
LIB8STATIC sfract15 floatToSfract15(float f)
Conversion from IEEE754 float in the range (-1,1) to 16-bit fixed point (sfract15).
LIB8STATIC float sfract15ToFloat(sfract15 y)
Conversion from 16-bit fixed point (sfract15) to IEEE754 32-bit float.
qfx< u16, 12, 4 > q124
A 12.4 integer (12 bits integer, 4 bits fraction)
qfx< u16, 8, 8 > q88
A 8.8 integer (8 bits integer, 8 bits fraction)
qfx< u8, 4, 4 > q44
A 4.4 integer (4 bits integer, 4 bits fraction)
qfx< u8, 6, 2 > q62
A 6.2 integer (6 bits integer, 2 bits fraction)
LIB8STATIC fl::i16 lerp15by16(fl::i16 a, fl::i16 b, fract16 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
LIB8STATIC fl::u8 lerp8by8(fl::u8 a, fl::u8 b, fract8 frac)
Linear interpolation between two unsigned 8-bit values, with 8-bit fraction.
LIB8STATIC fl::i16 lerp15by8(fl::i16 a, fl::i16 b, fract8 frac)
Linear interpolation between two signed 15-bit values, with 8-bit fraction.
LIB8STATIC fl::u16 lerp16by8(fl::u16 a, fl::u16 b, fract8 frac)
Linear interpolation between two unsigned 16-bit values, with 8-bit fraction.
LIB8STATIC fl::u16 lerp16by16(fl::u16 a, fl::u16 b, fract16 frac)
Linear interpolation between two unsigned 16-bit values, with 16-bit fraction.
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.
LIB8STATIC fl::u16 random16() FL_NOEXCEPT
Generate a 16-bit random number.
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.
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.
#define INSTANTIATE_EVERY_N_TIME_PERIODS(NAME, TIMETYPE, TIMEGETTER)
Preprocessor-based class "template" for CEveryNTime, used with EVERY_N_TIME timekeepers.
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
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.
i16 sfract15
ANSI: signed _Fract.
u8 fract8
Fixed-Point Fractional Types.
Square wave generator function.
Timekeeping helper functions — seconds, minutes, hours, bseconds.