ref: 72ed94b46fa454fce4edfc2396cb0becee5bdb00
dir: /p-wavegen.c/
#include <u.h> #include <libc.h> #include "prismriver.h" #include "p-internal.h" void destroywavegen(Wavegen *gen) { gen->destroy(gen); } Buffer* buffermap(Buffer *buf, Wavegen *gen, int d, ulong s, ulong sz) { if(buf == nil) buf = createbuffer(s + sz); for(ulong c = s; c < sz; c++) buf->data[c] = gen->fn(gen, c); if(d) destroywavegen(gen); return buf; } /** Simple Waveforms **/ typedef struct { Wavegen; double (*wavefn)(double); double amp, freq, phase; } Waveprops; STuple waveformfn(Wavegen *w, ulong t) { Waveprops *p = (Waveprops*)w; double v = p->amp * p->wavefn(s2d(t) * p->freq + p->phase); sample val = truncate(v); return (STuple) { val, val }; } Wavegen* waveform(double (*fn)(double), double amp, double freq, double φ) { Waveprops *p = emallocz(sizeof(Waveprops)); p->fn = waveformfn; p->destroy = (void(*)(Wavegen*))free; p->wavefn = fn; p->amp = amp; p->freq = freq; p->phase = φ; return p; } double sine(double num) { return sin(2 * π * num); } double saw(double num) { return 2 * (num - (int)num) - 1; } double pulse(double num, double threshold) { return saw(num) < threshold ? -1.0 : 1.0; } double square(double num) { return pulse(num, 0); } double triangle(double num) { return 2 * fabs(saw(num)) - 1; }