stew

a monorepo of some sort
Log | Files | Refs

commit 33a4d7ac6a987fb463649f51cdeb144f7d8cea5d
parent 7d8214845af801b7e5e8f7390a26cdeca73316e2
Author: rpa <rpa@laika>
Date:   Sat, 14 Jan 2023 19:39:56 +0000

wave: refacttorink

Diffstat:
Msrc/wave/inst.c | 42++++++++++++++++++++++++++++--------------
Msrc/wave/notes | 41+++++++++++++++++++++++++++++++++++++++++
Msrc/wave/sampler.c | 112+------------------------------------------------------------------------------
Msrc/wave/smoke.c | 24+-----------------------
Msrc/wave/util.c | 2+-
Msrc/wave/util.h | 15+++++++--------
Msrc/wave/wavetable.h | 30++++++++++++++++++++++++++++--
7 files changed, 107 insertions(+), 159 deletions(-)

diff --git a/src/wave/inst.c b/src/wave/inst.c @@ -178,15 +178,19 @@ usage(void) void threadsynth(void *) { + + Phasor phasor; + Synth synth; + synth.table[0] = (s16int *)wavetable.p; + synth.flag = 0; Channel *c = synthc; Inter inter; inter.progstart = prog.p; - int i, audio, note = 0, newnote, freq = 0, flag = 0; - double t = 0, f; + int audiofd, note = 0, newnote, freq = 0, flag = 0; Rune r; s16int *buf; - audio = open("/dev/audio", OWRITE); - if (audio < 0) { + audiofd = open("/dev/audio", OWRITE); + if (audiofd < 0) { fprint(2, "threadsynth: %r\n"); return; } @@ -194,10 +198,10 @@ threadsynth(void *) if (buf == nil) { sysfatal("threadsynth failed to allocate buffer: %r"); } - fprint(2, "threadsynth online\n"); - while (write(audio, buf, OutBufSize * sizeof(s16int)) > 0) { - interstep(&inter, flag); + long n = 1; + while (n > 0) { + if (nbrecv(c, &r) != 0) { if (r == L'\0') { flag = 0; @@ -208,17 +212,29 @@ threadsynth(void *) interreset(&inter); flag |= FHold; note = newnote; - t = 0; + phasor.t = 0; freq = note2freq(note); } } } + + interstep(&inter, flag); + + synth.mod.wtsel = 0; + synth.mod.freq = freq; + synth.mod.phase = 0; + synth.mod.mod = inter.mod[1]; + synth.mod.vol = inter.mod[0]; + synth.mod.pan = 0; + + int i; for (i = 0; i < OutBufSize - 1; i += 2) { - f = wtosc((s16int *)wavetable.p, inter.mod[1], t) * inter.mod[0]; - t += freq / 44100.0; - buf[i] = f / (double)0x7fff; - buf[i+1] = buf[i]; + union { u32int i; s16int s[2]; } out; + out.i = wtstep(&synth, &phasor); + buf[i] = out.s[0]; + buf[i + 1] = out.s[1]; } + n = write(audiofd, buf, OutBufSize * sizeof(s16int)); } free(buf); } @@ -238,8 +254,6 @@ threadkbd(void *) } memset(kbuf, 0, KbdBufSize); - fprint(2, "threadkbd online\n"); - while ((read(kbd, kbuf, KbdBufSize)) > 0) { n = runesnprint(rbuf, KbdBufSize, "%s", kbuf + 1); switch (kbuf[0]) { diff --git a/src/wave/notes b/src/wave/notes @@ -17,3 +17,44 @@ instrument: voice: instrument state (osc_t, pos on every envelope) + +------ +# note control commands + +1 byte is enough, I guess + + 0 → no command + 1-12? → note + ????? → ??? + 0xFE → note release + 0xFF → note off + +# base volume commands + +would like to fit into 1 byte as well + + no command (can be combined with something else???) + volume + volume, relative + volume, relative, repeat latest ??? + pan ??? + pan, relative ??? + pan, relative, repeat latest ??? + +# modifier commands + +[modifier index] [operation] [argument] +argument must be 2 bytes. + + no command ??? + value + value relative + value relative repeat ??? + +???? + +---- +# synth input + + wtsynth: table freq phase mod volume pan + channel: note prog volume diff --git a/src/wave/sampler.c b/src/wave/sampler.c @@ -3,118 +3,8 @@ #include <bio.h> #include <thread.h> -#include "util.h" -#include "wavetable.h" - -#define BufSize 256 -#define BufSizeInBytes (BufSize * 2 * sizeof(s16int)) - -Inst inst; -s16int buf[BufSize * 2]; -int audio, fid; -Channel *ctl; - -void synth(void *); - void -usage(void) +threadmain(int , char **) { - fprint(2, "usage: %s wavetable\n", argv0); - threadexitsall("usage"); -} - -void -threadmain(int argc, char **argv) -{ - ARGBEGIN { - default: - usage(); - } ARGEND - if (argc != 1) usage(); - - inst.wt = mallocz(sizeof(s16int) * WFSize * WTSize, 1); - inst.ampenv.n = 3; - inst.ampenv.val[0] = 256; - inst.ampenv.val[1] = 128; - inst.ampenv.val[2] = 0; - inst.ampenv.len[0] = 441 * 25; - inst.ampenv.len[1] = 441 * 50; - inst.ampenv.flags = EFHold; - inst.ampenv.hold[0] = 1; - inst.ampenv.hold[1] = 1; - - - inst.wtenv.n = 3; - inst.wtenv.val[0] = 0; - inst.wtenv.val[1] = 3; - inst.wtenv.val[2] = 0; - inst.wtenv.len[0] = 441 * 50; - inst.wtenv.len[1] = 441 * 50; - inst.wtenv.flags = EFLoop; - inst.wtenv.loop[0] = 0; - inst.wtenv.loop[1] = 2; - - fid = open(argv[0], OREAD); - if (fid <= 0) sysfatal("%r"); - long n; - s16int *wp = inst.wt; - while ((n = read(fid, wp, WFSize * sizeof(s16int))) > 0) { - wp += n/sizeof(s16int); - } - close(fid); - - audio = open("/dev/audio", OWRITE); - if (audio <= 0) sysfatal("%r"); - - ctl = chancreate(sizeof(double), 8); - proccreate(synth, nil, 64 * 1024); - Biobuf *bp; - bp = Bfdopen(0, OREAD); - for (;;) { - // TODO: use Brdstr or Brdline and extract double from it's output instead of this. - double in; - Bgetd(bp, &in); - send(ctl, &in); - if (Bgetc(bp) == Beof) break; - } - chanclose(ctl); - threadexitsall(nil); -} - -void -synth(void *) -{ - int i, n, as[2] = {0, 0}, ws[2] = {0, 0}, hold = 0; - double f, t, freq, v, lfo; - freq = 0; - t = 0; - lfo = 0; - for(n = 0; n >= 0; n = nbrecv(ctl, &v)){ - if (n > 0) { - if (v == 0) { - hold = 0; - } - else { - freq = v; - hold = 1; - t = 0; - as[0] = 0, as[1] = 0; - ws[0] = 0, ws[1] = 0; - } - } - for (i = 0; i < BufSize; i++) { - f = wtosc(inst.wt, envget(&inst.wtenv, &ws[0], &ws[1], hold), t); - f *= envget(&inst.ampenv, &as[0], &as[1], hold) / 256.0 * 0x7fff; - as[1]++; - ws[1]++; - buf[i * 2] = f; - buf[1 + i * 2] = buf[i * 2]; - t += freq / 44100.0; - lfo += 1.0 / 44100.0; - } - if (write(audio, buf, BufSizeInBytes) < BufSizeInBytes) { - sysfatal("synth: write to /dev/audio failed, %r"); - } - } } diff --git a/src/wave/smoke.c b/src/wave/smoke.c @@ -4,31 +4,9 @@ #include "wavetable.h" #include "prog.h" -s16int prog[128 * 8] = { - 0x0001, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xff01, 0x0001, 0x00ff, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, - - 0x0101, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0101, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xff01, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xff01, 0x0002, 0x01ff, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000, - - 0xff01, 0x000f, 0x00ff, 0x000f, 0x0000, 0x0000, 0x0000, 0x0000, - - 0x0001, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, -}; void main(void) { - int i, j; - Inter I = {(char *)prog}; - interreset(&I); - i = 0; - while (I.state != InHalt) { - interstep(&I, i < 16); - print("<< [%04d] ", i++); - for (j = 0; j < 4; j++) print("%04d ", I.mod[j]); - print(">>\n"); - }; + } diff --git a/src/wave/util.c b/src/wave/util.c @@ -56,7 +56,7 @@ int note2freq(int n) }; int s = sizeof(freq) / sizeof(double); - int fo = 1 + (n / s); + // int fo = 1 + (n / s); int fn = n % s; double f = freq[fn];// / 16 * fo; return f; diff --git a/src/wave/util.h b/src/wave/util.h @@ -5,16 +5,15 @@ enum { MaxLength = (44100 * 10) }; -typedef struct Frame Frame; +typedef union Frame Frame; typedef struct Aud Aud; -struct Frame { - union { - s16int c[2]; - struct { - s16int c1; - s16int c2; - }; +union Frame { + u32int i; + s16int c[2]; + struct { + s16int c1; + s16int c2; }; }; diff --git a/src/wave/wavetable.h b/src/wave/wavetable.h @@ -1,7 +1,33 @@ enum { WFSize = 2048, WTSize = 256, + + ModWtSel = 0, + ModFreq, + ModPhase, + ModMod, + ModVolume, + ModPan, +}; + +typedef struct Synth Synth; +typedef struct Phasor Phasor; + +struct Phasor { + u64int t; +}; + +struct Synth { + s16int *table[64]; + union { + int p[6]; + struct { + int wtsel, freq, phase, mod, vol, pan; + }; + } mod; + int flag; }; -double wfosc(s16int *, double); -double wtosc(s16int *, int, double); +u32int wtfunc(s16int *wtp, int phase, int mod, int vol, int pan); +int pstep(Phasor *, int, int, int); +u32int wtstep(Synth *, Phasor *);