shithub: neindaw

Download patch

ref: 8b1426f03a09a3c4c99c3d12c194edd87fbccd93
parent: 8b0c34fef29634833180f62135c3f8b33cc0be04
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Thu Mar 19 16:05:27 EDT 2020

ay: apply every change separately

--- a/ay/ay.c
+++ b/ay/ay.c
@@ -10,16 +10,6 @@
 #include "uiglue.h"
 #include "aux.h"
 
-/*
-FIXME just a note, remove later
-	ay = aynew(1.0);
-	amp(ay, 0, Levelenv | 4);
-	envp(ay, ms2ep(500));
-	envsc(ay, Continue|Attack);
-	toneon(ay, 0);
-	tone(ay, 0, 500);
-*/
-
 #define MIN(a,b) ((a)<=(b)?(a):(b))
 #define MAX(a,b) ((a)>=(b)?(a):(b))
 
@@ -42,8 +32,8 @@
 		float enable;
 	}chan[3];
 	float hold, alternate, attack, cont;
-	float volume;
 	float noise;
+	float envelope;
 };
 
 static Aux rootaux[] = {
@@ -101,95 +91,92 @@
 	return v;
 }
 
-static int
-hz2tp(int hz)
+static float
+tone(ay38910_t *ay, int chan, float hz)
 {
-	return MAX(1, MIN(4095, tickhz / (MAX(1, hz) * 16)));
-}
+	int tp;
 
-static int
-tp2hz(int tp)
-{
-	return tickhz / tp / 16;
-}
+	tp = MAX(1, MIN(4095, tickhz / (MAX(1, hz) * 16)));
+	regw(ay, AY38910_REG_PERIOD_A_FINE + 2*chan, tp & 0xff);
+	regw(ay, AY38910_REG_PERIOD_A_COARSE + 2*chan, (tp>>8) & 0x0f);
 
-static int
-hz2ep(int hz)
-{
-	return MAX(1, MIN(65535, tickhz / (MAX(1, hz) * 256)));
+	return tickhz/tp/16;
 }
 
 static int
-ms2ep(int ms)
+writeay(UI *ui, int auxtype, char *s)
 {
-	return MAX(1, MIN(65535, (tickhz / 1000) * ms / 256));
-}
+	Auxdsp *dsp;
+	ay38910_t *ay;
+	int r, i, level;
+	vlong pd;
 
-static void
-toneon(ay38910_t *ay, int chan)
-{
-	regw(ay, AY38910_REG_ENABLE, regr(ay, AY38910_REG_ENABLE) & ~(1<<chan));
-}
+	if ((r = ui_writestr(ui, auxtype, s)) < 0)
+		return r;
 
-static void
-toneoff(ay38910_t *ay, int chan)
-{
-	regw(ay, AY38910_REG_ENABLE, regr(ay, AY38910_REG_ENABLE) | 1<<chan);
-}
+	dsp = ui->userdata;
+	ay = &dsp->ay;
+	for (i = 0; i < nelem(dsp->chan); i++) {
+		if (ui->zone == &dsp->chan[i].freq) {
+			*ui->zone = tone(ay, i, *ui->zone);
+			return 0;
+		}
+		if (ui->zone == &dsp->chan[i].enable) {
+			r = regr(ay, AY38910_REG_ENABLE) | 1<<i;
+			if (*ui->zone)
+				r &= ~(1<<i);
+			regw(ay, AY38910_REG_ENABLE, r);
+			return 0;
+		}
+		if (ui->zone == &dsp->chan[i].noise) {
+			r = regr(ay, AY38910_REG_ENABLE) | 1<<(3+i);
+			if (*ui->zone)
+				r &= ~(1<<(3+i));
+			regw(ay, AY38910_REG_ENABLE, r);
+			return 0;
+		}
+		if (ui->zone == &dsp->chan[i].envelope) {
+			r = regr(ay, AY38910_REG_AMP_A+i) & ~(1<<4);
+			if (*ui->zone)
+				r |= 1<<4;
+			regw(ay, AY38910_REG_AMP_A+i, r);
+			return 0;
+		}
+		if (ui->zone == &dsp->chan[i].amp) {
+			level = MAX(0, MIN(15, *ui->zone * 15));
+			level |= regr(ay, AY38910_REG_AMP_A+i) & (1<<4);
+			regw(ay, AY38910_REG_AMP_A+i, level);
+			*ui->zone = (float)(level&0xf) / 15.0f;
+			return 0;
+		}
+	}
 
-static void
-envp(ay38910_t *ay, int p)
-{
-	regw(ay, AY38910_REG_ENV_PERIOD_FINE, p & 0xff);
-	regw(ay, AY38910_REG_ENV_PERIOD_COARSE, p>>8);
-}
+	if (ui->zone == &dsp->envelope) {
+		pd = MAX(1, MIN(65535, (tickhz / 1000) * (*ui->zone) / 256));
+		regw(ay, AY38910_REG_ENV_PERIOD_FINE, pd&0xff);
+		regw(ay, AY38910_REG_ENV_PERIOD_COARSE, pd>>8);
+		*ui->zone = MAX(1, pd*256000LL/tickhz);
+		return 0;
+	}
 
-static void
-envsc(ay38910_t *ay, int v)
-{
-	regw(ay, AY38910_REG_ENV_SHAPE_CYCLE, v & 0xf);
-}
-
-static void
-amp(ay38910_t *ay, int chan, int level)
-{
-	regw(ay, AY38910_REG_AMP_A+chan, level);
-}
-
-static void *
-auxtype2obj(int *type)
-{
-	switch (*type) {
-	case Xdspctl:
-	case Xuictl:
-		return (uchar*)type - offsetof(Aux, ctl);
-	case Xdspdata:
-		return (uchar*)type - offsetof(Aux, data);
-	case Xuimeta:
-		return (uchar*)type - offsetof(Aux, metadata);
-	default:
-		sysfatal("trying to get aux out of type %d", *type);
+	if (ui->zone == &dsp->noise) {
+		r = MAX(1, MIN(31, tickhz/(16 * (*ui->zone))));
+		regw(ay, AY38910_REG_PERIOD_NOISE, r);
+		*ui->zone = tickhz/16/r;
+		return 0;
 	}
 
-	return nil;
-}
+	r = 0;
+	if (dsp->hold)
+		r |= 1<<0;
+	if (dsp->alternate)
+		r |= 1<<1;
+	if (dsp->attack)
+		r |= 1<<2;
+	if (dsp->cont)
+		r |= 1<<3;
+	regw(ay, AY38910_REG_ENV_SHAPE_CYCLE, r);
 
-static int
-writefreq(UI *ui, int auxtype, char *s)
-{
-	Auxdsp *dsp;
-	int r, chan, tp;
-
-	if ((r = ui_writestr(ui, auxtype, s)) != 0)
-		return r;
-
-	dsp = ui->userdata;
-	for (chan = 0; ui->zone != &dsp->chan[chan].freq; chan++);
-	tp = hz2tp(*ui->zone);
-	regw(&dsp->ay, chan*2+0, tp & 0xff); /* fine */
-	regw(&dsp->ay, chan*2+1, (tp>>8) & 0x0f); /* coarse */
-	*ui->zone = tp2hz(tp);
-
 	return 0;
 }
 
@@ -205,55 +192,56 @@
 	step = MAX(1, ceil(tickhz/65504 - tickhz/65520));
 
 	ui->userdata = dsp;
+	ui->writestr = writeay;
 	ui->openVerticalBox(ui->f, "AY-3-8910");
+	ui->addHorizontalSlider(ui->f, "Volume", &dsp->ay.mag, 1.0f, 0.0f, 1.0f, 0.001f);
 
-	ui->openVerticalBox(ui->f, "Tone");
 	for (i = 0; i < nelem(dsp->chan); i++) {
 		sprint(s, "%c", 'A'+i);
 		ui->openVerticalBox(ui->f, s);
 
+		ui->openHorizontalBox(ui->f, "Tone");
 		ui->declare(ui->f, &dsp->chan[i].freq, "0", "");
 		ui->declare(ui->f, &dsp->chan[i].freq, "unit", "Hz");
-		ui->writestr = writefreq;
-		ui->addHorizontalSlider(ui->f, "Tone", &dsp->chan[i].freq, min, min, max, step);
+		ui->addHorizontalSlider(ui->f, "Frequency", &dsp->chan[i].freq, min, min, max, step);
+		ui->declare(ui->f, &dsp->chan[i].enable, "1", "");
+		ui->addCheckButton(ui->f, "Enable", &dsp->chan[i].enable);
+		ui->closeBox(ui->f);
 
-		ui->writestr = nil;
-		ui->declare(ui->f, &dsp->chan[i].amp, "1", "");
+		ui->declare(ui->f, &dsp->chan[i].amp, "0", "");
 		ui->addHorizontalSlider(ui->f, "Volume", &dsp->chan[i].amp, 1.0f, 0.0f, 1.0f, 1.0f/15.0f);
 
-		ui->declare(ui->f, &dsp->chan[i].enable, "2", "");
-		ui->addCheckButton(ui->f, "Enable", &dsp->chan[i].enable);
-
-		ui->declare(ui->f, &dsp->chan[i].envelope, "3", "");
+		ui->declare(ui->f, &dsp->chan[i].envelope, "1", "");
 		ui->addCheckButton(ui->f, "Envelope", &dsp->chan[i].envelope);
 
-		ui->declare(ui->f, &dsp->chan[i].noise, "4", "");
+		ui->declare(ui->f, &dsp->chan[i].noise, "2", "");
 		ui->addCheckButton(ui->f, "Noise", &dsp->chan[i].noise);
 
 		ui->closeBox(ui->f);
 	}
-	ui->closeBox(ui->f);
 
 	min = ceil(tickhz/496);
 	max = floor(tickhz/16);
 	step = MAX(1, tickhz/480 - tickhz/496);
-
 	ui->declare(ui->f, &dsp->noise, "unit", "Hz");
-	ui->addHorizontalSlider(ui->f, "Noise", &dsp->noise, 4000, min, max, step);
+	ui->addHorizontalSlider(ui->f, "Noise", &dsp->noise, min, min, max, step);
 
 	ui->openVerticalBox(ui->f, "Envelope");
-	ui->declare(ui->f, &dsp->hold, "0", "");
+	min = MAX(1, 256000/tickhz);
+	max = floor(16776960000LL/tickhz);
+	ui->declare(ui->f, &dsp->envelope, "0", "");
+	ui->declare(ui->f, &dsp->envelope, "unit", "ms");
+	ui->addHorizontalSlider(ui->f, "Period", &dsp->envelope, 500, min, max, 1);
+	ui->declare(ui->f, &dsp->hold, "1", "");
 	ui->addCheckButton(ui->f, "Hold", &dsp->hold);
-	ui->declare(ui->f, &dsp->alternate, "1", "");
+	ui->declare(ui->f, &dsp->alternate, "2", "");
 	ui->addCheckButton(ui->f, "Alternate", &dsp->alternate);
-	ui->declare(ui->f, &dsp->attack, "2", "");
+	ui->declare(ui->f, &dsp->attack, "3", "");
 	ui->addCheckButton(ui->f, "Attack", &dsp->attack);
-	ui->declare(ui->f, &dsp->cont, "3", "");
+	ui->declare(ui->f, &dsp->cont, "4", "");
 	ui->addCheckButton(ui->f, "Continue", &dsp->cont);
 	ui->closeBox(ui->f);
 
-	ui->addHorizontalSlider(ui->f, "Volume", &dsp->volume, 1.0f, 0.0f, 1.0f, 0.001f);
-
 	ui->closeBox(ui->f);
 }
 
@@ -273,7 +261,7 @@
 
 	for (i = 0, o = nil; o == nil && i < nelem(objs); i++) {
 		if (objs[i] == nil){
-			o = objs[i] = calloc(1, sizeof(*o)+sizeof(Auxdsp));
+			o = objs[i] = calloc(1, sizeof(*o) + sizeof(Auxdsp));
 			break;
 		}
 	}
@@ -299,6 +287,24 @@
 	buildui(dsp, &uiglue);
 
 	return o;
+}
+
+static void *
+auxtype2obj(int *type)
+{
+	switch (*type) {
+	case Xdspctl:
+	case Xuictl:
+		return (uchar*)type - offsetof(Aux, ctl);
+	case Xdspdata:
+		return (uchar*)type - offsetof(Aux, data);
+	case Xuimeta:
+		return (uchar*)type - offsetof(Aux, metadata);
+	default:
+		sysfatal("trying to get aux out of type %d", *type);
+	}
+
+	return nil;
 }
 
 static void