ref: 262fbae1b70df3a7883a5c2b8df05e486622559b
parent: 8606ddf48890de2de0f25b771f9ca60ce4ede412
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
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;
+}