shithub: neindaw

Download patch

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;