Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdint.h>
- #include <stdio.h>
- /*
- Sine approximation of 127.5*sin(pi*x/2^7)+127.5
- Based on quadratic (3x-x^3)/2 [0,0.25]
- Detailed functions: https://desmos.com/calculator/sqllbjao14
- Max error = ~1.8%. Identical to sine at 0,64,128,192,255
- */
- uint8_t kaelAudio_sine(uint8_t n){
- uint8_t q = n>>6; //quarter phase 0b00=1st 0b01=2nd 0b10=3rd 0b11=4th
- n = n&0b00111111; //repeat quarters
- n = q&0b01 ? 64-n : n; //mirror 2nd and 4th quarters by x-axis
- uint16_t p = (((uint16_t)n*n)>>6)+1; //calculate 6x-n^3/2^11 cube in two parts to prevent overflow //+1 compensates flooring
- p = 6*n - (((uint16_t)n*p)>>5);
- uint8_t o = (p>>1)+128; //scale and offset to match sine wave
- o = q&0b10 ? ~o : o; //mirror 3rd and 4th quarters by y-axis
- return o;
- }
- /*
- Sine approximation of sin(2pi*x/128)*128
- Based on parabola 2x-x^2 [0,0.5]
- Detailed functions: https://desmos.com/calculator/fuhb4xzejt
- max error 3.6%. Identical to sine at 0,64,128,192,255
- */
- uint8_t kaelAudio_sineParabola(uint8_t phase){
- uint8_t secondHalf = phase & 0b10000000;
- phase <<= 1;
- uint16_t buf = ((uint16_t)(phase) << 1) - UINT8_MAX;
- phase = (uint8_t)((buf * buf) >> 9);
- phase = secondHalf ? phase : ~phase;
- return phase;
- }
- int main() {
- //printf("print raw PCM unsigned 8-bit little endian");
- //printf("(3x-x^3)/2\n");
- for(uint16_t i=0;i!=65535;i++){
- uint8_t o = kaelAudio_sine(i);
- fwrite(&o, sizeof(uint8_t), 1, stdout);
- }
- for(uint16_t i=0;i!=65535;i++){
- uint8_t o = kaelAudio_sineParabola(i);
- fwrite(&o, sizeof(uint8_t), 1, stdout);
- }
- //printf("\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement