111 lines
3.4 KiB
C
111 lines
3.4 KiB
C
#pragma once
|
|
|
|
#ifndef __INC_LIB8TION_RANDOM_H
|
|
#define __INC_LIB8TION_RANDOM_H
|
|
|
|
#include "fl/stdint.h"
|
|
|
|
#include "lib8tion/lib8static.h"
|
|
|
|
/// @file random8.h
|
|
/// Fast, efficient random number generators specifically
|
|
/// designed for high-performance LED programming.
|
|
|
|
/// @ingroup lib8tion
|
|
/// @{
|
|
|
|
/// @defgroup Random Fast Random Number Generators
|
|
/// Fast 8-bit and 16-bit unsigned random number generators.
|
|
/// Significantly faster than Arduino random(), but
|
|
/// also somewhat less random. You can add entropy.
|
|
///
|
|
/// Pseudo-random number generation follows the form:
|
|
/// @code
|
|
/// X(n+1) = (2053 * X(n)) + 13849)
|
|
/// @endcode
|
|
/// @{
|
|
|
|
/// Multiplier value for pseudo-random number generation
|
|
#define FASTLED_RAND16_2053 ((uint16_t)(2053))
|
|
/// Increment value for pseudo-random number generation
|
|
#define FASTLED_RAND16_13849 ((uint16_t)(13849))
|
|
|
|
#if defined(LIB8_ATTINY)
|
|
/// Multiplies a value by the pseudo-random multiplier
|
|
#define APPLY_FASTLED_RAND16_2053(x) (x << 11) + (x << 2) + x
|
|
#else
|
|
/// Multiplies a value by the pseudo-random multiplier
|
|
#define APPLY_FASTLED_RAND16_2053(x) (x * FASTLED_RAND16_2053)
|
|
#endif
|
|
|
|
/// Seed for the random number generator functions
|
|
extern uint16_t rand16seed; // = RAND16_SEED;
|
|
|
|
/// Generate an 8-bit random number
|
|
/// @returns random 8-bit number, in the range 0-255
|
|
LIB8STATIC uint8_t random8() {
|
|
rand16seed = APPLY_FASTLED_RAND16_2053(rand16seed) + FASTLED_RAND16_13849;
|
|
// return the sum of the high and low bytes, for better
|
|
// mixing and non-sequential correlation
|
|
return (uint8_t)(((uint8_t)(rand16seed & 0xFF)) +
|
|
((uint8_t)(rand16seed >> 8)));
|
|
}
|
|
|
|
/// Generate a 16-bit random number
|
|
/// @returns random 16-bit number, in the range 0-65535
|
|
LIB8STATIC uint16_t random16() {
|
|
rand16seed = APPLY_FASTLED_RAND16_2053(rand16seed) + FASTLED_RAND16_13849;
|
|
return rand16seed;
|
|
}
|
|
|
|
/// Generate an 8-bit random number between 0 and lim
|
|
/// @param lim the upper bound for the result, exclusive
|
|
LIB8STATIC uint8_t random8(uint8_t lim) {
|
|
uint8_t r = random8();
|
|
r = (r * lim) >> 8;
|
|
return r;
|
|
}
|
|
|
|
/// Generate an 8-bit random number in the given range
|
|
/// @param min the lower bound for the random number, inclusive
|
|
/// @param lim the upper bound for the random number, exclusive
|
|
LIB8STATIC uint8_t random8(uint8_t min, uint8_t lim) {
|
|
uint8_t delta = lim - min;
|
|
uint8_t r = random8(delta) + min;
|
|
return r;
|
|
}
|
|
|
|
/// Generate an 16-bit random number between 0 and lim
|
|
/// @param lim the upper bound for the result, exclusive
|
|
LIB8STATIC uint16_t random16(uint16_t lim) {
|
|
uint16_t r = random16();
|
|
uint32_t p = (uint32_t)lim * (uint32_t)r;
|
|
r = p >> 16;
|
|
return r;
|
|
}
|
|
|
|
/// Generate an 16-bit random number in the given range
|
|
/// @param min the lower bound for the random number, inclusive
|
|
/// @param lim the upper bound for the random number, exclusive
|
|
LIB8STATIC uint16_t random16(uint16_t min, uint16_t lim) {
|
|
uint16_t delta = lim - min;
|
|
uint16_t r = random16(delta) + min;
|
|
return r;
|
|
}
|
|
|
|
/// Set the 16-bit seed used for the random number generator
|
|
LIB8STATIC void random16_set_seed(uint16_t seed) { rand16seed = seed; }
|
|
|
|
/// Get the current seed value for the random number generator
|
|
LIB8STATIC uint16_t random16_get_seed() { return rand16seed; }
|
|
|
|
/// Add entropy into the random number generator
|
|
LIB8STATIC void random16_add_entropy(uint16_t entropy) {
|
|
rand16seed += entropy;
|
|
}
|
|
|
|
/// @} Random
|
|
/// @} lib8tion
|
|
|
|
#endif
|