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