├── README.md ├── rng_and_noise.md └── tanh.md /README.md: -------------------------------------------------------------------------------- 1 | # Fast DSP Approximations 2 | 3 | This is a compilation of open source algorithms for fast approximations of expensive calculations, useful for DSP applications. 4 | 5 | Feel free to open a PR for any additions you would like to add! Be sure to add the appropriate license for each algorithm. 6 | 7 | * [RNG and Noise](rng_and_noise.md) 8 | * [tanh](tanh.md) -------------------------------------------------------------------------------- /rng_and_noise.md: -------------------------------------------------------------------------------- 1 | # XOrShift32 Random Number Generator 2 | A very fast random number generator that can be used to generate decent quality white noise. 3 | 4 | * license: Public Domain 5 | * original algorithm from https://www.airwindows.com/ditherfloat/, adapted by Billy Messenger 6 | 7 | C++: 8 | ```c++ 9 | #include 10 | 11 | class XOrShift32Rng { 12 | uint32_t m_fpd; 13 | 14 | public: 15 | XOrShift32Rng(uint32_t seed = 17) { 16 | // seed cannot be zero 17 | m_fpd = seed == 0 ? 17 : seed; 18 | } 19 | 20 | // Generates a random `uint32_t` 21 | inline uint32_t gen_uint32() { 22 | m_fpd ^= m_fpd << 13; 23 | m_fpd ^= m_fpd >> 17; 24 | m_fpd ^= m_fpd << 5; 25 | return m_fpd; 26 | } 27 | 28 | // Generates a random float in the range `[0.0, 1.0]` 29 | inline float gen_float() { 30 | return static_cast( this->gen_uint32() ) * (1.0f / 4294967295.0f); 31 | } 32 | 33 | // Generates a random double in the range `[0.0, 1.0]` 34 | inline double gen_double() { 35 | return static_cast( this->gen_uint32() ) * (1.0 / 4294967295.0); 36 | } 37 | 38 | // Generates a random float in the range `[-1.0, 1.0]` 39 | inline float gen_noise_float() { 40 | return static_cast( this->gen_uint32() ) * (2.0f / 4294967295.0f) - 1.0f; 41 | } 42 | 43 | // Generates a random double in the range `[-1.0, 1.0]` 44 | inline double gen_noise_double() { 45 | return static_cast( this->gen_uint32() ) * (2.0 / 4294967295.0) - 1.0; 46 | } 47 | }; 48 | ``` 49 | 50 | Rust: 51 | ```rust 52 | pub struct XOrShift32Rng { 53 | fpd: u32, 54 | } 55 | 56 | impl Default for XOrShift32Rng { 57 | fn default() -> XOrShift32Rng { 58 | XOrShift32Rng { fpd: 17 } 59 | } 60 | } 61 | 62 | impl XOrShift32Rng { 63 | pub fn new(mut seed: u32) -> XOrShift32Rng { 64 | // seed cannot be zero 65 | if seed == 0 { seed = 17; } 66 | XOrShift32Rng { fpd: seed } 67 | } 68 | 69 | /// Generates a random `u32` 70 | #[inline] 71 | pub fn gen_u32(&mut self) -> u32 { 72 | self.fpd ^= self.fpd << 13; 73 | self.fpd ^= self.fpd >> 17; 74 | self.fpd ^= self.fpd << 5; 75 | self.fpd 76 | } 77 | 78 | /// Generates a random `f32` in the range `[0.0, 1.0]` 79 | #[inline] 80 | pub fn gen_f32(&mut self) -> f32 { 81 | self.gen_u32() as f32 * (1.0 / 4_294_967_295.0) 82 | } 83 | 84 | /// Generates a random `f64` in the range `[0.0, 1.0]` 85 | #[inline] 86 | pub fn gen_f64(&mut self) -> f64 { 87 | f64::from(self.gen_u32()) * (1.0 / 4_294_967_295.0) 88 | } 89 | 90 | /// Generates a random `f32` in the range `[-1.0, 1.0]` 91 | #[inline] 92 | pub fn gen_noise_f32(&mut self) -> f32 { 93 | self.gen_u32() as f32 * (2.0 / 4_294_967_295.0) - 1.0; 94 | } 95 | 96 | /// Generates a random `f64` in the range `[-1.0, 1.0]` 97 | #[inline] 98 | pub fn gen_noise_f64(&mut self) -> f64 { 99 | f64::from(self.gen_u32()) * (2.0 / 4_294_967_295.0) - 1.0; 100 | } 101 | } 102 | ``` 103 | -------------------------------------------------------------------------------- /tanh.md: -------------------------------------------------------------------------------- 1 | # Levien tanh approximation 2 | * license: Public Domain 3 | * by Raph Levien and adpated by William Light 4 | 5 | C: 6 | ```c 7 | inline static float 8 | tanh_levien(const float x) 9 | { 10 | const float x2 = x * x; 11 | const float x3 = x2 * x; 12 | const float x5 = x3 * x2; 13 | 14 | const float a = x 15 | + (0.16489087f * x3) 16 | + (0.00985468f * x5); 17 | 18 | return a / sqrtf(1.f + (a * a)); 19 | } 20 | ``` 21 | 22 | Rust: 23 | ```rust 24 | #[inline] 25 | pub fn tanh_levien(x: f32) -> f32 { 26 | let x2 = x * x; 27 | let x3 = x2 * x; 28 | let x5 = x3 * x2; 29 | 30 | let a = x 31 | + (0.16489087 * x3) 32 | + (0.00985468 * x5); 33 | 34 | a / (1.0 + (a * a)).sqrt() 35 | } 36 | ``` 37 | --------------------------------------------------------------------------------