shithub: neindaw

Download patch

ref: 262fbae1b70df3a7883a5c2b8df05e486622559b
parent: 8606ddf48890de2de0f25b771f9ca60ce4ede412
author: Sigrid Haflínudóttir <[email protected]>
date: Sun May 10 15:48:41 EDT 2020

piper: some more ideas

--- /dev/null
+++ b/piper/ay.c
@@ -1,0 +1,65 @@
+#include <u.h>
+#include <libc.h>
+#include "piper.h"
+
+typedef struct AY AY;
+
+struct AY {
+	struct {
+		int freq;
+		int enable;
+		int noise;
+		int env;
+	}abc[3];
+	struct {
+		int period;
+		int alter;
+		int attack;
+		int cont;
+		int hold;
+		int hit;
+	}env;
+	int noisefreq;
+	int volume;
+	char path[1];
+};
+
+static void
+cmd(void *aux, Cmd *c)
+{
+}
+
+static void *
+alloc(char *path)
+{
+	AY *ay;
+	int i;
+
+	if ((ay = calloc(1, sizeof(*ay) + strlen(path) + 1)) != nil) {
+		for (i = 0; i < 3; i++) {
+			ay->abc[i].freq = pathopen(path, "%c/Tone/Frequency/ctl", 'A'+i);
+			ay->abc[i].enable = pathopen(path, "%c/Tone/Enable/ctl", 'A'+i);
+			ay->abc[i].enable = pathopen(path, "%c/Noise/ctl", 'A'+i);
+			ay->abc[i].enable = pathopen(path, "%c/Envelope/ctl", 'A'+i);
+		}
+
+		ay->env.period = pathopen(path, "Envelope/Period/ctl");
+		ay->env.alter = pathopen(path, "Envelope/Alternate/ctl");
+		ay->env.attack = pathopen(path, "Envelope/Attack/ctl");
+		ay->env.cont = pathopen(path, "Envelope/Continue/ctl");
+		ay->env.hold = pathopen(path, "Envelope/Hold/ctl");
+		ay->env.hit = pathopen(path, "Envelope/Hit/ctl");
+		ay->noisefreq = pathopen(path, "Noise/ctl");
+		ay->volume = pathopen(path, "Volume/ctl");
+
+		strcpy(ay->path, path);
+	}
+
+	return ay;
+}
+
+Synth ay_3_8910 = {
+	.name = "AY-3-8910",
+	.cmd = cmd,
+	.alloc = alloc,
+};
--- /dev/null
+++ b/piper/kick.c
@@ -1,0 +1,55 @@
+#include <u.h>
+#include <libc.h>
+#include "piper.h"
+
+typedef struct Kick Kick;
+
+struct Kick {
+	struct {
+		int freq;
+		int attack;
+		int release;
+	}a;
+	struct {
+		int freq;
+		int attack;
+		int release;
+		int enable;
+	}b;
+	int gate;
+	int volume;
+	char path[1];
+};
+
+static void
+cmd(void *aux, Cmd *c)
+{
+}
+
+static void *
+alloc(char *path)
+{
+	Kick *k;
+
+	if ((k = calloc(1, sizeof(*k) + strlen(path) + 1)) != nil) {
+		k->a.freq = pathopen(path, "A/Frequency/ctl");
+		k->a.attack = pathopen(path, "A/Attack/ctl");
+		k->a.release = pathopen(path, "A/Release/ctl");
+		k->b.freq = pathopen(path, "B/Frequency/ctl");
+		k->b.attack = pathopen(path, "B/Attack/ctl");
+		k->b.release = pathopen(path, "B/Release/ctl");
+		k->b.enable = pathopen(path, "B/Enable/ctl");
+		k->gate = pathopen(path, "Control/Gate/ctl");
+		k->volume = pathopen(path, "Control/Gain/ctl");
+
+		strcpy(k->path, path);
+	}
+
+	return k;
+}
+
+Synth kick_drum = {
+	.name = "Kick Drum",
+	.cmd = cmd,
+	.alloc = alloc,
+};
--- a/piper/mkfile
+++ b/piper/mkfile
@@ -4,10 +4,14 @@
 BIN=/$objtype/bin/daw
 
 OFILES=\
+	ay.$O\
+	kick.$O\
 	piper.$O\
+	util.$O\
 
 HFILES=\
 	a440.h\
+	piper.h
 
 %.h: %.txt
 	./notegen <$stem.txt >$stem.h
--- a/piper/piper.c
+++ b/piper/piper.c
@@ -1,26 +1,12 @@
 #include <u.h>
 #include <libc.h>
 #include <thread.h>
+#include "piper.h"
 
-static int b2i[] = {
-	['0'] =  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
-	['a'] = 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-	['k'] = 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
-	['u'] = 30, 31, 32, 33, 34, 35,
+static Synth *synths[] = {
+	&ay_3_8910,
+	&kick_drum,
 };
-
-static float notes[/* octave */]['g'-'A'+1 /* note */] = {
-#include "a440.h"
-};
-
-static float
-note2freq(int octave, char note)
-{
-	note -= 'A';
-	if(octave < 0 || octave >= nelem(notes) || note >= nelem(notes[0]))
-		return 0.0;
-	return notes[octave][note];
-}
 
 static void
 usage(void)
--- /dev/null
+++ b/piper/piper.h
@@ -1,0 +1,29 @@
+typedef struct Cmd Cmd;
+typedef struct Synth Synth;
+
+enum {
+	CmdNote,
+};
+
+struct Cmd {
+	int type;
+	union {
+		struct {
+			float freq;
+			int len;
+		}note[3];
+	};
+	int numnotes;
+};
+
+struct Synth {
+	char *name;
+	void (*cmd)(void *aux, Cmd *c);
+	void *(*alloc)(char *path);
+};
+
+extern Synth ay_3_8910;
+extern Synth kick_drum;
+
+float note2freq(int octave, char note);
+int pathopen(char *path, char *fmt, ...);
--- /dev/null
+++ b/piper/util.c
@@ -1,0 +1,44 @@
+#include <u.h>
+#include <libc.h>
+#include "piper.h"
+
+static int b2i[] = {
+	['0'] =  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+	['a'] = 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+	['k'] = 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+	['u'] = 30, 31, 32, 33, 34, 35,
+};
+
+static float notes[/* octave */]['g'-'A'+1 /* note */] = {
+#include "a440.h"
+};
+
+float
+note2freq(int octave, char note)
+{
+	note -= 'A';
+	if (octave < 0 || octave >= nelem(notes) || note >= nelem(notes[0]))
+		return 0.0;
+	return notes[octave][note];
+}
+
+int
+pathopen(char *path, char *fmt, ...)
+{
+	va_list arg;
+	char *s;
+	int fd;
+
+	va_start(arg, fmt);
+	s = vsmprint(fmt, arg);
+	va_end(arg);
+
+	if (s == nil || (path = smprint("%s/%s", path, s)) == nil)
+		sysfatal("memory");
+	free(s);
+	if ((fd = open(path, OWRITE)) < 0)
+		fprint(2, "%s: %r\n", path);
+	free(path);
+
+	return fd;
+}