ref: 66fa8ef996ffb3ded8ad1f9b6eb756727e0aa705
parent: 0f82143ee0b59de717f556ae7b873e2de9af2e79
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed May 13 11:45:22 EDT 2020
piper: add a dumb piano handler
--- a/piper/mkfile
+++ b/piper/mkfile
@@ -7,6 +7,7 @@
OFILES=\
ay.$O\
kick.$O\
+ piano.$O\
piper.$O\
util.$O\
--- /dev/null
+++ b/piper/piano.c
@@ -1,0 +1,93 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include "piper.h"
+#include "util.h"
+
+typedef struct Piano Piano;
+
+struct Piano {
+ int freq;
+ int gain;
+ int gate;
+ Channel *offc;
+ char path[1];
+};
+
+static void
+gateoff(void *aux)
+{
+ uvlong t, n;
+ Piano *p;
+
+ threadsetname("piper/gateoff");
+ p = aux;
+ for (;;) {
+ if (recv(p->offc, &t) != 1)
+ break;
+next:
+ while (1) {
+ n = nanosec();
+ if (n >= t)
+ break;
+ n = t - n;
+ if (n > 750000000LL)
+ sleep(70);
+ else if (n > 25000000LL)
+ sleep(20);
+ else if (n > 10000000LL)
+ sleep(1);
+ }
+ if (nbrecv(p->offc, &t) != 0)
+ goto next;
+ fprint(p->gate, "0");
+ }
+
+ threadexits(nil);
+}
+
+static int
+cmd(void *aux, Cmd *c)
+{
+ Piano *p;
+ uvlong off;
+
+ p = aux;
+ switch (c->type) {
+ case CmdNote:
+ off = nanosec() + 1000000000ULL*c->note[0].dur;
+ send(p->offc, &off);
+ fprint(p->gain, "%g", c->note[0].vel);
+ fprint(p->freq, "%g", c->note[0].freq);
+ fprint(p->gate, "1");
+ break;
+
+ case CmdRaw:
+ break;
+ }
+
+ return 0;
+}
+
+static void *
+alloc(char *path)
+{
+ Piano *p;
+
+ if ((p = calloc(1, sizeof(*p) + strlen(path) + 1)) != nil) {
+ p->freq = pathopen(path, "Basic/Freq/ctl");
+ p->gain = pathopen(path, "Basic/Gain/ctl");
+ p->gate = pathopen(path, "Basic/Gate/ctl");
+ p->offc = chancreate(sizeof(uvlong), 10);
+ strcpy(p->path, path);
+ proccreate(gateoff, p, 4096);
+ }
+
+ return p;
+}
+
+Synth piano = {
+ .name = "Piano",
+ .cmd = cmd,
+ .alloc = alloc,
+};
--- a/piper/piper.c
+++ b/piper/piper.c
@@ -34,6 +34,7 @@
static Synth *synths[] = {
&ay_3_8910,
&kick_drum,
+ &piano,
};
static void
--- a/piper/piper.h
+++ b/piper/piper.h
@@ -29,7 +29,4 @@
extern Synth ay_3_8910;
extern Synth kick_drum;
-
-int i36(uchar c);
-float note2freq(uchar note, uchar octave);
-int pathopen(char *path, char *fmt, ...);
+extern Synth piano;