ref: b5ce869c17886785ebe2798cc8471fa5a0f1e306
dir: /piper/piano.c/
#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, };