lib8tion: Math functions specifically designed for LED programming
Typedefs
- typedef uint8_t fract8
ANSI unsigned short _Fract.
range is 0 to 0.99609375 in steps of 0.00390625 ANSI: unsigned short _Fract
- typedef int8_t sfract7
ANSI: signed short _Fract.
range is -0.9921875 to 0.9921875 in steps of 0.0078125 ANSI: signed short _Fract
- typedef uint16_t fract16
ANSI: unsigned _Fract.
range is 0 to 0.99998474121 in steps of 0.00001525878 ANSI: unsigned _Fract
- typedef int16_t sfract15
ANSI: signed _Fract.
range is -0.99996948242 to 0.99996948242 in steps of 0.00003051757 ANSI: signed _Fract
- typedef uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
- typedef int16_t saccum78
ANSI: signed short _Accum. 7 bits int, 8 bits fraction.
- typedef uint32_t accum1616
ANSI: signed _Accum. 16 bits int, 16 bits fraction.
- typedef int32_t saccum1516
ANSI: signed _Accum. 15 bits int, 16 bits fraction.
- typedef uint16_t accum124
no direct ANSI counterpart. 12 bits int, 4 bits fraction
- typedef int32_t saccum114
no direct ANSI counterpart. 1 bit int, 14 bits fraction
Functions
- inline float sfract15ToFloat(sfract15 y)
sfract15ToFloat: conversion from sfract15 fixed point to IEEE754 32-bit float.
- inline sfract15 floatToSfract15(float f)
conversion from IEEE754 float in the range (-1,1) to 16-bit fixed point.
Note that the extremes of one and negative one are NOT representable. The representable range is basically
- inline uint8_t lerp8by8(uint8_t a, uint8_t b, fract8 frac)
linear interpolation between two unsigned 8-bit values, with 8-bit fraction
- inline uint16_t lerp16by16(uint16_t a, uint16_t b, fract16 frac)
linear interpolation between two unsigned 16-bit values, with 16-bit fraction
- inline uint16_t lerp16by8(uint16_t a, uint16_t b, fract8 frac)
linear interpolation between two unsigned 16-bit values, with 8-bit fraction
- inline int16_t lerp15by8(int16_t a, int16_t b, fract8 frac)
linear interpolation between two signed 15-bit values, with 8-bit fraction
- inline int16_t lerp15by16(int16_t a, int16_t b, fract16 frac)
linear interpolation between two signed 15-bit values, with 8-bit fraction
- inline uint8_t map8(uint8_t in, uint8_t rangeStart, uint8_t rangeEnd)
map8: map from one full-range 8-bit value into a narrower range of 8-bit values, possibly a range of hues.
E.g. map myValue into a hue in the range blue..purple..pink..red hue = map8(myValue, HUE_BLUE, HUE_RED);
Combines nicely with the waveform functions (like sin8, etc) to produce continuous hue gradients back and forth:
Mathematically simiar to lerp8by8, but arguments are more like Arduino’s “map”; this function is similar tohue = map8(sin8(myValue), HUE_BLUE, HUE_RED);but faster and specifically designed for 8-bit values.map(in, 0, 255, rangeStart, rangeEnd)
- inline uint8_t ease8InOutQuad(uint8_t i)
ease8InOutQuad: 8-bit quadratic ease-in / ease-out function Takes around 13 cycles on AVR
- inline uint16_t ease16InOutQuad(uint16_t i)
ease16InOutQuad: 16-bit quadratic ease-in / ease-out function
- inline fract8 ease8InOutCubic(fract8 i)
ease8InOutCubic: 8-bit cubic ease-in / ease-out function Takes around 18 cycles on AVR
- inline fract8 ease8InOutApprox(fract8 i)
ease8InOutApprox: fast, rough 8-bit ease-in/ease-out function shaped approximately like ‘ease8InOutCubic’, it’s never off by more than a couple of percent from the actual cubic S-curve, and it executes more than twice as fast.
Use when the cycles are more important than visual smoothness. Asm version takes around 7 cycles on AVR.
- inline uint8_t triwave8(uint8_t in)
triwave8: triangle (sawtooth) wave generator.
Useful for turning a one-byte ever-increasing value into a one-byte value that oscillates up and down.
input output 0..127 0..254 (positive slope) 128..255 254..0 (negative slope)
On AVR this function takes just three cycles.
- inline uint8_t quadwave8(uint8_t in)
quadwave8: quadratic waveform generator.
Spends just a little more time at the limits than ‘sine’ does.
- inline uint8_t cubicwave8(uint8_t in)
cubicwave8: cubic waveform generator.
Spends visibly more time at the limits than ‘sine’ does.
- inline uint8_t squarewave8(uint8_t in, uint8_t pulsewidth)
squarewave8: square wave generator.
Useful for turning a one-byte ever-increasing value into a one-byte value that is either 0 or 255. The width of the output ‘pulse’ is determined by the pulsewidth argument:
If pulsewidth is 255, output is always 255. If pulsewidth < 255, then if input < pulsewidth then output is 255 if input >= pulsewidth then output is 0the output looking like:
255 +--pulsewidth--+ . | | 0 0 +--------(256-pulsewidth)--------
- Parameters:
in –
pulsewidth –
- Returns:
square wave output
- inline uint16_t beat88(accum88 beats_per_minute_88, uint32_t timebase)
beat16 generates a 16-bit ‘sawtooth’ wave at a given BPM, with BPM specified in Q8.8 fixed-point format; e.g.
for this function, 120 BPM MUST BE specified as 120*256 = 30720. If you just want to specify “120”, use beat16 or beat8.
- inline uint16_t beat16(accum88 beats_per_minute, uint32_t timebase)
beat16 generates a 16-bit ‘sawtooth’ wave at a given BPM
- inline uint8_t beat8(accum88 beats_per_minute, uint32_t timebase)
beat8 generates an 8-bit ‘sawtooth’ wave at a given BPM
- inline uint16_t beatsin88(accum88 beats_per_minute_88, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
beatsin88 generates a 16-bit sine wave at a given BPM, that oscillates within a given range.
For this function, BPM MUST BE SPECIFIED as a Q8.8 fixed-point value; e.g. 120BPM must be specified as 120*256 = 30720. If you just want to specify “120”, use beatsin16 or beatsin8.
- inline uint16_t beatsin16(accum88 beats_per_minute, uint16_t lowest, uint16_t highest, uint32_t timebase, uint16_t phase_offset)
beatsin16 generates a 16-bit sine wave at a given BPM, that oscillates within a given range.
- inline uint8_t beatsin8(accum88 beats_per_minute, uint8_t lowest, uint8_t highest, uint32_t timebase, uint8_t phase_offset)
beatsin8 generates an 8-bit sine wave at a given BPM, that oscillates within a given range.
- inline uint16_t seconds16()
Return the current seconds since boot in a 16-bit value.
Used as part of the “every N time-periods” mechanism
- inline uint16_t minutes16()
Return the current minutes since boot in a 16-bit value.
Used as part of the “every N time-periods” mechanism
- inline uint8_t hours8()
Return the current hours since boot in an 8-bit value.
Used as part of the “every N time-periods” mechanism
- inline uint16_t div1024_32_16(uint32_t in32)
Helper routine to divide a 32-bit value by 1024, returning only the low 16 bits.
You’d think this would be just result = (in32 >> 10) & 0xFFFF; and on ARM, that’s what you want and all is well. Used to convert millis to ‘binary seconds’ aka bseconds: one bsecond == 1024 millis.
- inline uint16_t bseconds16()
bseconds16 returns the current time-since-boot in “binary seconds”, which are actually 1024/1000 of a second long.
- union IEEE754binary32_t
#include <lib8tion.h>typedef for IEEE754 “binary32” float type internals
Public Members
- uint32_t i
- float f
- uint32_t mantissa
- uint32_t exponent
- uint32_t signbit
- struct IEEE754binary32_t::[anonymous] [anonymous]
- uint32_t mant7
- uint32_t mant16
- uint32_t exp_
- uint32_t sb_
- struct IEEE754binary32_t::[anonymous] [anonymous]
- uint32_t mant_lo8
- uint32_t mant_hi16_exp_lo1
- uint32_t sb_exphi7
- struct IEEE754binary32_t::[anonymous] [anonymous]