Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<cstdint>
- //compiled with gcc flag -O3
- //approx -UIMAX/2*sin((2*x*pi)/UIMAX)+UIMAX/2 https://www.desmos.com/calculator/lyyy678gdw
- //sine both input [0.0,2pi] and output [-1.0,1.0] are mapped to [0,4294967295]
- //Convert VALUE[0,4294967295] to range[-1.0,1.0] using (-1.0)*((float)VALUE/(UIMAX/2)-1)
- //2.8% error, 3-6x faster than sin() with num=rand()%(1+i++), up to ~20x faster with num=i++
- //Fast sine approximation.
- uint32_t u32kaelSin(uint32_t num) {
- bool secondHalf = (num>>31); //second half of uint
- num<<=1; //2x input for 2 parabola period
- uint64_t buf = (static_cast<uint64_t>(num)<<1)-UINT32_MAX; //<cast>64b-32b and flip vertically
- num = (buf * buf) >> 33; //compute parabola
- num = secondHalf ? ~num : num; //flip horizontally if past mid point
- return num;
- }
- uint16_t u16kaelSin(uint16_t num) {
- bool secondHalf = (num>>15);
- num<<=1;
- uint32_t buf = (static_cast<uint32_t>(num)<<1)-UINT16_MAX;
- num = (buf * buf) >> 17;
- num = secondHalf ? ~num : num;
- return num;
- }
- uint8_t u8kaelSin(uint8_t num) {
- bool secondHalf = (num>>7);
- num<<=1;
- uint16_t buf = (static_cast<uint16_t>(num)<<1)-UINT8_MAX;
- num = (buf * buf) >> 9;
- num = secondHalf ? ~num : num;
- return num;
- }
- //Triangle wave
- template <typename T>
- T ukaelTriangle(T num) {
- bool flip = num>>(sizeof(num)<<3-2)==0 | num>>(sizeof(num)<<3-2)==3; //first and last quarters
- num<<=1;
- num+=~T(0)>>1;
- return flip ? ~num : num;
- }
- //Saw wave
- template <typename T>
- T ukaelSaw(T num){
- return num<<=1;
- }
- //Square wave
- template <typename T>
- T ukaelSquare(T num){
- return ( num>>(sizeof(num)<<3-1) ) ? 0 : ~T(0);
- }
- //Pulse square wave
- template <typename T>
- T ukaelPulse(T num, T dutyCycle) {
- return (num > dutyCycle) ? 0 : ~T(0);
- }
- //noise function
- template <typename T>
- T ukaelNoise(T num) {
- uint sz=sizeof(num)<<1;
- num^=num>>(num&sz)+4;
- num*=4763;
- num^=num<<(num&sz)+4;
- return num;
- }
- //helps making 8bit noise less repetitive when input is linear. Small as 32 wroks
- const uint8_t u8randomTable[]{
- 33, 138,142,237,100,84, 241,4, 139,149,159,233,64, 201,75, 235,
- 116,248,10, 116,247,112,214,245,221,58, 158,124,196,227,255,39,
- 51, 238,5, 253,76, 6, 65, 104,106,81, 230,171,55, 245,21, 244,
- 99, 162,98, 34, 78, 28, 195,184,229,205,14, 154,57, 224,249,45,
- 226,233,77, 124,10, 50, 81, 103,26, 30, 18, 18, 185,98, 214,48,
- 244,118,214,17, 67, 215,209,34, 134,100,177,206,190,70, 133,219,
- 194,66, 123,57, 26, 129,5, 64, 36, 59, 237,122,207,87, 22, 164,
- 133,200,191,47, 15, 54, 194,223,129,166,52, 8, 49, 193,235,254,
- 62, 122,55, 93, 190,241,171,91, 25, 101,233,151,224,113,69, 71,
- 235,253,55, 247,143,240,205,52, 229,223,229,229,211,244,252,2,
- 159,141,91, 4, 46, 233,78, 127,236,237,167,248,37, 253,140,89,
- 155,138,185,162,65, 115,117,196,57, 195,107,39, 205,189,216,73,
- 57, 243,10, 107,193,226,182,204,200,165,234,253,208,185,137,151,
- 238,49, 18, 189,98, 185,169,67, 94, 77, 73, 165,127,121,65, 202,
- 148,165,101,186,131,207,252,86, 204,225,108,82, 129,133,184,179,
- 236,17, 223,163,11, 1, 60, 251,118,243,105,190,74, 52, 200,235
- };
- //8-bit noise function. actually slower than ukaelNoise()
- uint8_t u8kaelNoise(uint16_t num) {
- num^=num<<7;
- num*=17;
- num^=num>>7;
- num^=u8randomTable[(num>>8)]; //num>>8 for 256 table
- return num;
- }
- /* too slow for random generation, seeding maybe
- uint64_t rdtsc(){
- unsigned int lo,hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return ((uint64_t)hi << 32) | lo;
- }
- */
- /*
- Time warmup() 0.67921 seconds
- For loop overhead 0.10994 seconds
- Time ukaelNoi() 2.45002 seconds
- Time u32kaelSin() 1.62207 seconds
- Time ukaelTri() 0.61627 seconds
- Time ukaelSqu() 1.02044 seconds
- Time ukaelSaw() 0.41214 seconds
- Time ukaelPul() 0.61336 seconds
- Time math.h sin() 13.2384 seconds
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement