Advertisement
Kaelygon

ukaelWaceC.h

Jul 7th, 2023 (edited)
601
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.23 KB | None | 0 0
  1. #pragma once
  2.  
  3. //waveform functions
  4. #include <stdint.h>
  5.  
  6. #include "ukaelTypedefC.h"
  7.  
  8. static uint64_t rdtsc(){
  9.     uint32_t lo,hi;
  10.     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
  11.     return ((uint64_t)hi << 32) | lo;
  12. }
  13.  
  14. /*
  15. static uint64_t rdrand(){
  16.         uint64_t rnum;
  17.         __asm__ __volatile__ ("rdrand %0"  : "=r" (rnum));
  18.     return rnum;
  19. }
  20. */
  21.  
  22. //refresh random seed     00000000000000000000000000000000
  23. static uint32_t ENTROPY=4091831291;
  24. void reseed(){
  25.     ENTROPY^=ENTROPY<<15;
  26.     ENTROPY^=ENTROPY>>13;
  27.     return;
  28. }
  29.  
  30.  
  31. //sine approximation.
  32. static inline uint8_t ukaelSine(WaveArg *arg) {
  33.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;  //n=floor(n)
  34.     uint8_t secondHalf = time8 & 0b10000000;            //s=floor(n%255/128)
  35.     time8 <<= 1;                                        //2*n%255
  36.     uint16_t buf = ((uint16_t)(time8)<<1) - UINT8_MAX;  //(2*n-255)%65536
  37.     time8 = (uint8_t)((buf * buf) >> 9);                //(floor(n^2%65536)/512)%255
  38.     time8 = secondHalf ? time8 : ~time8;                //n = s ? n : 255-n
  39.     return time8;
  40. }
  41.  
  42.  
  43. //Crunchy Sine
  44. static inline uint8_t ukaelCSine(WaveArg *arg) {
  45.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;
  46.  
  47.     uint8_t secondHalf = time8 & 0b10000000;
  48.     time8 = !(time8 & 0b01000000) ? ~time8 : time8; //invert even quarters
  49.     time8 <<= 2;    //2 period saw
  50.     time8 >>= 4;    //square root. Crunchy precision
  51.     time8*=time8;   //square
  52.     time8 >>= 1;    //divide by 2
  53.     time8 = secondHalf ? time8 : ~time8;    //invert 2nd half
  54.     return time8;
  55. }
  56.  
  57.  
  58. //triangle
  59. static inline uint8_t ukaelTriangle(WaveArg *arg) {
  60.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;
  61.    
  62.     time8+=63;
  63.     uint8_t secondHalf = time8&0b10000000;
  64.     time8 <<= 1;
  65.     time8 = secondHalf ? ~time8 : time8;    //invert 2nd half
  66.     return time8;
  67. }
  68.  
  69. //Saw
  70. static inline uint8_t ukaelSaw(WaveArg *arg) {
  71.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;
  72.  
  73.     time8+=127; //add UINT_MAX/2
  74.     return time8;
  75. }
  76.  
  77.  
  78. //Square
  79. static inline uint8_t ukaelSquare(WaveArg *arg) {
  80.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;
  81.  
  82.     time8 = ( time8>>7 ) ? UINT8_MAX : 0; //hi if 0 to 0.5, low if 0.5 to 1.0
  83.     return time8 ;
  84. }
  85.  
  86.  
  87. //Pulse square 2 arguments
  88. static inline uint8_t ukaelPulse(WaveArg *arg) {
  89.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;
  90.  
  91.     time8 = (time8 >= arg->u8arg[0]) ? UINT8_MAX : 0;   //same as square but dutyCycle sets treshold
  92.     return time8 ;
  93. }
  94.  
  95.  
  96. //Time dependent noise
  97. static inline uint8_t ukaelNoise(WaveArg *arg) {
  98.     uint16_t time16 = arg->time*arg->freq.a/arg->freq.b;
  99.     reseed();
  100.     time16^=ENTROPY<<9;
  101.     time16^=ENTROPY>>7;
  102.     return time16;
  103. }
  104.  
  105.  
  106. //White noise
  107. static inline uint8_t ukaelWNoise(WaveArg *arg) {
  108.     reseed();
  109.     return ENTROPY;
  110. }
  111.  
  112.  
  113. //White noise
  114. static inline uint8_t ukaelWNoiseOLD(uint16_t num) {
  115.     reseed();
  116.     num*=3083*ENTROPY;
  117.     return num;
  118. }
  119.  
  120.  
  121. //random walk
  122. static inline uint8_t ukaelRWalk(WaveArg *arg) {
  123.     uint8_t prevSample = arg->u8arg[1];
  124.     uint8_t random = ukaelWNoise( &((WaveArg){ .freq=arg->freq} ) )>>(arg->u8arg[0]&6); //(0 to 255) / 3
  125.     uint8_t sign = random&1; //add=0 subtract=1
  126.     random>>=1;
  127.     random=prevSample+(1-sign)*random-(sign)*random; //add or subtract random/2 and reuse random as result
  128.     if(sign==1 && random>prevSample){ //underflow
  129.         return 0;
  130.     }
  131.     if(sign==0 && random<prevSample){ //overflow
  132.         return 255;
  133.     }
  134.     arg->u8arg[1]=random;
  135.     return random;
  136. }
  137.  
  138.  
  139. #include <math.h>
  140. //accurate sine very slow
  141. static inline uint8_t ukaelSinef(WaveArg *arg){
  142.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;
  143.     return (sin((float)time8/40.7436654)*128+128);
  144. }
  145.  
  146.  
  147.  
  148.  
  149. /*
  150. // Input: x (angle in radians, represented as fixed-point)
  151. // Output: sin(x) approximation (represented as uint8_t)
  152. uint8_t testing(WaveArg *arg) {
  153.     uint8_t time8 = arg->time*arg->freq.a/arg->freq.b;
  154.     const uint8_t lut[] = {
  155.         0, 25, 49, 74, 98, 120, 141, 160, 177, 191, 202, 210, 215, 218,
  156.         218, 215, 210, 202, 191, 177, 160, 141, 120, 98, 74, 49, 25
  157.     };
  158.  
  159.     // Ensure x is within the range of one period
  160.     time8 &= UINT8_MAX;
  161.  
  162.     // Map x to the lookup table index
  163.     uint8_t index = (time8 * sizeof(lut)) >> 8;
  164.  
  165.     return lut[index];
  166. }
  167. */
  168.  
  169.     static const uint8_t sineLut[] = {128,131,134,137,140,143,146,149,152,156,159,162,165,168,171,174,176,179,182,185,188,191,193,196,199,201,204,206,209,211,213,216,218,220,222,224,226,228,230,232,234,236,237,239,240,242,243,245,246,247,248,249,250,251,252,252,253,254,254,255,255,255,255,255,255,255,255,255,255,255,254,254,253,252,252,251,250,249,248,247,246,245,243,242,240,239,237,236,234,232,230,228,226,224,222,220,218,216,213,211,209,206,204,201,199,196,193,191,188,185,182,179,176,174,171,168,165,162,159,156,152,149,146,143,140,137,134,131,127,124,121,118,115,112,109,106,103,99,96,93,90,87,84,81,79,76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,19,18,16,15,13,12,10,9,8,7,6,5,4,3,3,2,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,2,3,3,4,5,6,7,8,9,10,12,13,15,16,18,19,21,23,25,27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,79,81,84,87,90,93,96,99,103,107,110,113,116,119,122,125};
  170.  
  171. static inline uint8_t ukaeLSine(WaveArg *arg) {
  172.     uint8_t time8 = arg->time * arg->freq.a / arg->freq.b;
  173.         time8=sineLut[time8];
  174.     return time8;
  175. }
  176.  
  177. static inline uint8_t testing(WaveArg *arg) {
  178.     uint8_t time8 = arg->time * arg->freq.a / arg->freq.b;
  179.    
  180.     return time8;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement