73#ifndef MAX_LIKELY_UPDATE_RATE_HZ
74#define MAX_LIKELY_UPDATE_RATE_HZ 400
78#ifndef MIN_ACCEPTABLE_DITHER_RATE_HZ
79#define MIN_ACCEPTABLE_DITHER_RATE_HZ 50
83#ifndef UPDATES_PER_FULL_DITHER_CYCLE
84#define UPDATES_PER_FULL_DITHER_CYCLE (MAX_LIKELY_UPDATE_RATE_HZ / MIN_ACCEPTABLE_DITHER_RATE_HZ)
95#ifndef RECOMMENDED_VIRTUAL_BITS
96#define RECOMMENDED_VIRTUAL_BITS ((UPDATES_PER_FULL_DITHER_CYCLE>1) + \
97 (UPDATES_PER_FULL_DITHER_CYCLE>2) + \
98 (UPDATES_PER_FULL_DITHER_CYCLE>4) + \
99 (UPDATES_PER_FULL_DITHER_CYCLE>8) + \
100 (UPDATES_PER_FULL_DITHER_CYCLE>16) + \
101 (UPDATES_PER_FULL_DITHER_CYCLE>32) + \
102 (UPDATES_PER_FULL_DITHER_CYCLE>64) + \
103 (UPDATES_PER_FULL_DITHER_CYCLE>128) )
108#define VIRTUAL_BITS RECOMMENDED_VIRTUAL_BITS
123 if (frame & 0x01) { q |= 0x80; }
124 if (frame & 0x02) { q |= 0x40; }
125 if (frame & 0x04) { q |= 0x20; }
126 if (frame & 0x08) { q |= 0x10; }
127 if (frame & 0x10) { q |= 0x08; }
128 if (frame & 0x20) { q |= 0x04; }
129 if (frame & 0x40) { q |= 0x02; }
130 if (frame & 0x80) { q |= 0x01; }
139 u8 d = fl::scale8(q, range);
140#if (FASTLED_SCALE8_FIXED == 1)
154 for (
int i = 0; i < 3; ++i) {
158 u8 range = s ? (256 / s) + 1 : 0;
160 if (range) { --range; }
169 for (
int i = 0; i < 3; ++i) {
172 d[i] = e[i] ?
offset(q,
static_cast<u8>(e[i] + 1)) : 0;
177 d[0] = d[1] = d[2] = e[0] = e[1] = e[2] = 0;
181 return (e[0] | e[1] | e[2]) != 0;
199 return b ? fl::qadd8(b, d) : 0;
215 d[0] = d[1] = d[2] = e[0] = e[1] = e[2] = 0;
229#if defined(NO_DITHERING) && (NO_DITHERING == 1)
fl::UISlider scale("Scale", 4,.1, 4,.1)
#define VIRTUAL_BITS
Alias for RECOMMENDED_VIRTUAL_BITS.
#define FASTLED_FORCE_INLINE
Legacy compatibility header for 8-bit math functions.
Legacy compatibility header for 8-bit scaling functions.
InputGamut g FL_NO_EXCEPT
BinaryDither Dither
The policy this build uses.
Base definition for an LED controller.
static FASTLED_FORCE_INLINE bool active(const u8(&e)[3]) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE void stepChannel(u8(&d)[3], const u8(&e)[3], int c) FL_NO_EXCEPT
step for a single channel (drivers that pre-step their first byte).
static FASTLED_FORCE_INLINE void reseed(u8(&d)[3], const u8(&e)[3], u8 frame) FL_NO_EXCEPT
Re-point d at frame, keeping the ranges init left in e.
static FASTLED_FORCE_INLINE void clear(u8(&d)[3], u8(&e)[3]) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE u8 apply(u8 b, u8 d) FL_NO_EXCEPT
Add the offset to a source byte, before scaling. Black is never lifted.
static FASTLED_FORCE_INLINE u8 phase(u8 frame) FL_NO_EXCEPT
The frame's offset pattern value Q: frame wrapped to VIRTUAL_BITS, bit-reversed so consecutive frames...
static FASTLED_FORCE_INLINE u8 offset(u8 q, u8 range) FL_NO_EXCEPT
Q scaled into [0, range): the offset for one channel.
static FASTLED_FORCE_INLINE void init(u8(&d)[3], u8(&e)[3], const u8(&scale)[3], u8 frame) FL_NO_EXCEPT
Set up e from the per-channel brightness scale and d from frame.
static FASTLED_FORCE_INLINE void step(u8(&d)[3], const u8(&e)[3]) FL_NO_EXCEPT
Next pixel: toggle each offset to its complement in [0, e], so neighbours dither in opposite directio...
Temporal binary dithering over caller-owned d[3]/e[3].
static FASTLED_FORCE_INLINE void init(u8(&d)[3], u8(&e)[3], const u8(&)[3], u8) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE void reseed(u8(&)[3], const u8(&)[3], u8) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE void clear(u8(&d)[3], u8(&e)[3]) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE u8 apply(u8 b, u8) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE void stepChannel(u8(&)[3], const u8(&)[3], int) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE void step(u8(&)[3], const u8(&)[3]) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE u8 offset(u8, u8) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE bool active(const u8(&)[3]) FL_NO_EXCEPT
static FASTLED_FORCE_INLINE u8 phase(u8) FL_NO_EXCEPT
The disabled policy: same interface, no work.