commit 33a4d7ac6a987fb463649f51cdeb144f7d8cea5d
parent 7d8214845af801b7e5e8f7390a26cdeca73316e2
Author: rpa <rpa@laika>
Date: Sat, 14 Jan 2023 19:39:56 +0000
wave: refacttorink
Diffstat:
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 *);