examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

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:
Asrc/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); +}