dsp.c (2066B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 5 void die(char const* msg) 6 { 7 if (errno) 8 perror(msg); 9 else 10 fprintf(stderr, "%s: Unknown failure\n", msg); 11 exit(EXIT_FAILURE); 12 } 13 14 void usage(int err) 15 { 16 fputs("lol", err ? stderr : stdout); 17 exit(err); 18 } 19 20 static unsigned in_len, out_len; 21 static float *in_kernel, *out_kernel; 22 static float *in_history, *out_history; 23 24 void do_history(unsigned len, float* history, float new) 25 { 26 for (unsigned i = len - 1; i; --i) 27 history[i] = history[i-1]; 28 history[0] = new; 29 } 30 31 float dsp(float in) 32 { 33 float out = in; 34 if (in_len) 35 { 36 out *= in_kernel[0]; 37 for (unsigned i = 1; i < in_len; ++i) 38 out += in_kernel[i] * in_history[i-1]; 39 40 do_history(in_len, in_history, in); 41 } 42 43 if (out_len) 44 { 45 for (unsigned i = 0; i < out_len; ++i) 46 out += out_kernel[i] * out_history[i]; 47 48 do_history(out_len, out_history, out); 49 } 50 return out; 51 } 52 53 float* fmalloc_or_die(unsigned n) 54 { 55 if (!n) 56 return NULL; 57 58 float* p = malloc(n * sizeof(float)); 59 if (!p) 60 die("malloc"); 61 62 for (unsigned i = 0; i < n; ++i) 63 p[i] = 0; 64 return p; 65 } 66 67 void graph(float signal, float out) 68 { 69 unsigned unseen = 7; 70 for (int i = -20; unseen && i < 100; ++i) 71 { 72 unsigned seen = 0; 73 if (!i) 74 seen |= 1; 75 if (unseen & 4) 76 if (i >= signal) 77 seen |= 4; 78 if (unseen & 2) 79 if (i >= out) 80 seen |= 2; 81 82 switch(seen) 83 { 84 case 1: 85 putchar('|'); 86 break; 87 case 2: 88 putchar('-'); 89 break; 90 case 3: 91 case 6: 92 case 7: 93 putchar('+'); 94 break; 95 case 4: 96 case 5: 97 putchar('.'); 98 break; 99 100 default: 101 putchar(' '); 102 } 103 104 unseen &= ~seen; 105 } 106 putchar('\n'); 107 } 108 109 int main() 110 { 111 in_len = 2; 112 out_len = 2; 113 in_history = fmalloc_or_die(in_len); 114 in_kernel = fmalloc_or_die(in_len); 115 out_history = fmalloc_or_die(out_len); 116 out_kernel = fmalloc_or_die(out_len); 117 118 in_kernel[0] = .4f; 119 in_kernel[1] = -.2f; 120 out_kernel[0] = 1.55f; 121 out_kernel[1] = -.75f; 122 123 float signal; 124 float out; 125 for (int i = 0; i < 50; ++i) 126 { 127 signal = i > 2 ? 50 : 0; 128 129 out = dsp(signal); 130 graph(signal, out); 131 } 132 printf("%.0f = %.0f\n", signal, out); 133 }