ref: 9b3691b57b3fc854f77cffb8b9000efc13ee2087
dir: /piper/piper.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include "piper.h"
typedef struct Inst Inst;
typedef struct Group Group;
struct Inst {
void *aux;
int data;
};
struct Group {
char *path;
Synth *synth;
Inst *inst;
int numinst;
int clone;
};
static Group *groups;
static int numgroups;
static Synth *synths[] = {
&ay_3_8910,
&kick_drum,
};
static void
usage(void)
{
print("usage: %s DIR...\n", argv0);
threadexitsall("usage");
}
static char *
parse(char *s, Group *g)
{
Cmd c;
char *e, *path, tmp[8];
void *aux;
int i, n;
for (i = 1; s[i] != 0 && s[i] != ';'; i++);
e = s[i] == 0 ? nil : s + i + 1;
s[i] = 0;
if (g != nil) {
s++;
i = i36(*s);
aux = nil;
while (i >= g->numinst) { /* instance needs to be created */
seek(g->clone, 0, 0);
if ((n = read(g->clone, tmp, sizeof(tmp))) < 1)
sysfatal("clone failed");
tmp[n] = 0;
if ((path = smprint("%s/%s/%s", g->path, tmp, g->synth->name)) == nil)
sysfatal("memory");
if ((aux = g->synth->alloc(path)) == nil)
return e;
if ((g->inst = realloc(g->inst, sizeof(Inst)*(g->numinst+1))) == nil)
sysfatal("memory");
if ((path = smprint("%s/%s/data", g->path, tmp)) == nil)
sysfatal("memory");
if ((g->inst[g->numinst].data = open(path, OREAD)) < 0)
sysfatal("couldn't open data: %r");
g->inst[g->numinst++].aux = aux;
free(path);
}
memset(&c, 0, sizeof(c));
g->synth->cmd(aux, &c);
}
return e;
}
void
threadmain(int argc, char **argv)
{
char *s, t[256];
Synth *synth;
Biobuf *b;
int i, j, n;
ARGBEGIN{
default:
usage();
}ARGEND;
if (argc < 1)
usage();
quotefmtinstall();
/* go through all groups */
for (i = 0; i < argc; i++) {
/* search for specific synth handler by its name */
s = smprint("%s/metadata", argv[i]);
if ((b = Bopen(s, OREAD)) == nil)
sysfatal("%r");
free(s);
synth = nil;
while ((s = Brdline(b, '\n')) != nil) {
if (strncmp(s, "name\t", 5) == 0) {
s[Blinelen(b)-1] = 0;
for (j = 0; j < nelem(synths) && strcmp(synths[j]->name, s+5) != 0; j++);
if (j >= nelem(synths))
sysfatal("unknown synth %q\n", s+5);
if ((groups = realloc(groups, sizeof(Group)*(numgroups+1))) == nil)
sysfatal("memory");
synth = synths[j];
memset(&groups[numgroups], 0, sizeof(Group));
if ((s = smprint("%s/clone", argv[i])) == nil)
sysfatal("memory");
if ((groups[numgroups].clone = open(s, OREAD)) < 0)
sysfatal("%r");
free(s);
groups[numgroups].path = argv[i];
groups[numgroups++].synth = synth;
break;
}
}
Bterm(b);
if (synth == nil)
sysfatal("no name set in %s/metadata", argv[i]);
}
for (;;) {
if ((n = read(0, t, sizeof(t)-1)) < 1)
break;
t[n] = 0;
for (s = t; s != nil && *s;) {
i = i36(s[0]);
s = parse(s, i < numgroups ? &groups[i] : nil);
}
}
threadexitsall(nil);
}