shithub: neindaw

ref: ced961be3380556f92801b92973cb90a4a95b799
dir: /piper/ay.c/

View raw version
#include <u.h>
#include <libc.h>
#include "piper.h"
#include "util.h"

typedef struct AY AY;

struct AY {
	struct {
		int freq;
		int enable;
		int noise;
		int env;
		int vol;
	}abc[3];
	struct {
		int period;
		int alter;
		int attack;
		int cont;
		int hold;
		int hit;
	}env;
	int noisefreq;
	int volume;
	char path[1];
};

static int
cmd(void *aux, Cmd *c)
{
	AY *ay;
	int i;
	float dur;

	ay = aux;
	switch (c->type) {
	case CmdNote:
		fprint(ay->env.hit, "0");
		for (i = 0; i < 3; i++)
			fprint(ay->abc[i].enable, "0");

		dur = 0.0;
		for (i = 0; i < c->numnotes; i++) {
			fprint(ay->abc[i].enable, "1");
			fprint(ay->abc[i].freq, "%g", c->note[i].freq);
			fprint(ay->abc[i].vol, "%g", c->note[i].vel);
			if (dur < c->note[i].dur)
				dur = c->note[i].dur;
		}

		fprint(ay->env.period, "%g", dur);
		fprint(ay->env.hit, "1");
		break;

	case CmdRaw:
		break;
	}

	return 0;
}

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].noise = pathopen(path, "%c/Noise/ctl", 'A'+i);
			ay->abc[i].env = pathopen(path, "%c/Envelope/ctl", 'A'+i);
			ay->abc[i].vol = pathopen(path, "%c/Volume/ctl", 'A'+i);
			fprint(ay->abc[i].env, "1");
		}

		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,
};