commit f357d93a8859b6ff598392d2fe138550df92e5c6
parent 76401de43d3ec54c3a4f9635f1da340611496782
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Fri, 10 Dec 2021 14:41:28 +0000
Add DSP processing kernel example
Diffstat:
A | src/dsp.c | | | 133 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 133 insertions(+), 0 deletions(-)
diff --git a/src/dsp.c b/src/dsp.c
@@ -0,0 +1,133 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+void die(char const* msg)
+{
+ if (errno)
+ perror(msg);
+ else
+ fprintf(stderr, "%s: Unknown failure\n", msg);
+ exit(EXIT_FAILURE);
+}
+
+void usage(int err)
+{
+ fputs("lol", err ? stderr : stdout);
+ exit(err);
+}
+
+static unsigned in_len, out_len;
+static float *in_kernel, *out_kernel;
+static float *in_history, *out_history;
+
+void do_history(unsigned len, float* history, float new)
+{
+ for (unsigned i = len - 1; i; --i)
+ history[i] = history[i-1];
+ history[0] = new;
+}
+
+float dsp(float in)
+{
+ float out = in;
+ if (in_len)
+ {
+ out *= in_kernel[0];
+ for (unsigned i = 1; i < in_len; ++i)
+ out += in_kernel[i] * in_history[i-1];
+
+ do_history(in_len, in_history, in);
+ }
+
+ if (out_len)
+ {
+ for (unsigned i = 0; i < out_len; ++i)
+ out += out_kernel[i] * out_history[i];
+
+ do_history(out_len, out_history, out);
+ }
+ return out;
+}
+
+float* fmalloc_or_die(unsigned n)
+{
+ if (!n)
+ return NULL;
+
+ float* p = malloc(n * sizeof(float));
+ if (!p)
+ die("malloc");
+
+ for (int i = 0; i < n; ++i)
+ p[i] = 0;
+ return p;
+}
+
+void graph(float signal, float out)
+{
+ unsigned unseen = 7;
+ for (int i = -20; unseen && i < 100; ++i)
+ {
+ unsigned seen = 0;
+ if (!i)
+ seen |= 1;
+ if (unseen & 4)
+ if (i >= signal)
+ seen |= 4;
+ if (unseen & 2)
+ if (i >= out)
+ seen |= 2;
+
+ switch(seen)
+ {
+ case 1:
+ putchar('|');
+ break;
+ case 2:
+ putchar('-');
+ break;
+ case 3:
+ case 6:
+ case 7:
+ putchar('+');
+ break;
+ case 4:
+ case 5:
+ putchar('.');
+ break;
+
+ default:
+ putchar(' ');
+ }
+
+ unseen &= ~seen;
+ }
+ putchar('\n');
+}
+
+int main(int argc, char const* argv[])
+{
+ in_len = 2;
+ out_len = 2;
+ in_history = fmalloc_or_die(in_len);
+ in_kernel = fmalloc_or_die(in_len);
+ out_history = fmalloc_or_die(out_len);
+ out_kernel = fmalloc_or_die(out_len);
+
+ in_kernel[0] = .4f;
+ in_kernel[1] = -.2f;
+ out_kernel[0] = 1.55f;
+ out_kernel[1] = -.75f;
+
+ float signal;
+ float out;
+ for (int i = 0; i < 50; ++i)
+ {
+ signal = i > 2 ? 50 : 0;
+
+ out = dsp(signal);
+ graph(signal, out);
+ }
+ printf("%.0f = %.0f\n", signal, out);
+}