ref: e93003292b1c6bceed680831cffeae5329bb0104
parent: 1110500359d75192a9e224f90fe6cc679a6e0a25
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Mon Dec 30 07:34:59 EST 2019
proper ui metadata handling
--- a/aux.h
+++ b/aux.h
@@ -16,10 +16,12 @@
UIHBarGraph,
UIVBarGraph,
Xuictl,
+ Xuimeta,
};
typedef struct Aux Aux;
typedef struct Auxdsp Auxdsp;
+typedef struct Meta Meta;
typedef struct UI UI;
struct Auxdsp {
@@ -35,12 +37,16 @@
Auxdsp dsp;
int ctl;
int data;
+ int metadata;
UI *ui;
};
+struct Meta {
+ const char *k;
+ const char *v;
+};
+
struct UI {
- const char *key;
- const char *value;
const char *label;
FAUSTFLOAT *zone;
FAUSTFLOAT init;
@@ -49,4 +55,7 @@
FAUSTFLOAT step;
char *(*readstr)(Aux *a, UI *ui, int type, char *s, int sz);
int (*write)(Aux *a, UI *ui, int type, char *s);
+
+ Meta *meta;
+ int nummeta;
};
--- a/fs.c
+++ b/fs.c
@@ -36,6 +36,8 @@
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);
}
@@ -160,9 +162,10 @@
respond(r, nil);
break;
case Xuictl:
+ case Xuimeta:
o = auxtype2obj(&a->type);
if (o->ui->readstr != nil)
- readstr(r, o->ui->readstr(o, o->ui, Xuictl, b, sizeof(b)));
+ readstr(r, o->ui->readstr(o, o->ui, a->type, b, sizeof(b)));
respond(r, nil);
break;
case Xdspdata:
--- a/kick_drum.dsp
+++ b/kick_drum.dsp
@@ -3,13 +3,13 @@
declare group "synthesis";
import("stdfaust.lib");
-aFreq = vslider("h:a/[0]frequency", 100, 10, 200, 5);
-aA = vslider("h:a/[1]attack", 0.001, 0.00001, 0.2, 0.001);
-aD = vslider("h:a/[2]delay", 0.01, 0.00001, 1.0, 0.001);
-aR = vslider("h:a/[3]release", 0.001, 0.00001, 1.0, 0.001);
-bA = vslider("h:b/[0]attack", 0.001, 0.00001, 0.2, 0.001);
+aFreq = vslider("h:a/[0]frequency[unit:Hz]", 100, 10, 200, 5);
+aA = vslider("h:a/[1]attack[unit:s]", 0.001, 0.00001, 0.2, 0.001);
+aD = vslider("h:a/[2]delay[unit:s]", 0.01, 0.00001, 1.0, 0.001);
+aR = vslider("h:a/[3]release[unit:s]", 0.001, 0.00001, 1.0, 0.001);
+bA = vslider("h:b/[0]attack[unit:s]", 0.001, 0.00001, 0.2, 0.001);
bFreq = checkbox("h:control/[1]b enable") * vslider("h:b/[1]frequency", 200, -400, 400, 5);
-bR = vslider("h:b/[2]release", 0.001, 0.00001, 0.2, 0.001);
+bR = vslider("h:b/[2]release[unit:s]", 0.001, 0.00001, 0.2, 0.001);
gate = button("h:control/[0]gate");
process = os.oscsin(aFreq + bFreq*en.ar(bA, bR, gate)) * en.adsr(aA, aD, 0.000001, aR, gate) <: _, _;
--- a/uiglue.c
+++ b/uiglue.c
@@ -6,29 +6,42 @@
#include "uiglue.h"
#include "aux.h"
-static FAUSTFLOAT *declzone;
-static const char *declkey;
-static const char *declvalue;
+static struct {
+ FAUSTFLOAT *zone;
+ Meta *meta;
+ int nummeta;
+}decl;
static char *
ui_readstr(Aux *a, UI *ui, int type, char *s, int sz)
{
- if (type != Xuictl)
- sysfatal("unknown ui file");
+ char *x;
+ int i;
- switch (a->type) {
- case UITBox: snprint(s, sz, "tbox\n"); return s;
- case UIHBox: snprint(s, sz, "hbox\n"); return s;
- case UIVBox: snprint(s, sz, "vbox\n"); return s;
- case UIButton: snprint(s, sz, "button\t%s\t%d\n", ui->key, !!*ui->zone); return s;
- case UICheck: snprint(s, sz, "check\t%s\t%d\n", ui->key, !!*ui->zone); return s;
- case UIVSlider: snprint(s, sz, "vslider\t%s\t%f\t%f\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->init, ui->min, ui->max, ui->step); return s;
- case UIHSlider: snprint(s, sz, "hslider\t%s\t%f\t%f\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->init, ui->min, ui->max, ui->step); return s;
- case UINum: snprint(s, sz, "num\t%s\t%f\t%f\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->init, ui->min, ui->max, ui->step); return s;
- case UIHBarGraph: snprint(s, sz, "hbargraph\t%s\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->min, ui->max); return s;
- case UIVBarGraph: snprint(s, sz, "vbargraph\t%s\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->min, ui->max); return s;
+ if (type == Xuictl) {
+ switch (a->type) {
+ case UITBox: snprint(s, sz, "tbox\n"); return s;
+ case UIHBox: snprint(s, sz, "hbox\n"); return s;
+ case UIVBox: snprint(s, sz, "vbox\n"); return s;
+ case UIButton: snprint(s, sz, "button\t%d\n", !!*ui->zone); return s;
+ case UICheck: snprint(s, sz, "check\t%d\n", !!*ui->zone); return s;
+ case UIVSlider: snprint(s, sz, "vslider\t%f\t%f\t%f\t%f\t%f\n", *ui->zone, ui->init, ui->min, ui->max, ui->step); return s;
+ case UIHSlider: snprint(s, sz, "hslider\t%f\t%f\t%f\t%f\t%f\n", *ui->zone, ui->init, ui->min, ui->max, ui->step); return s;
+ case UINum: snprint(s, sz, "num\t%f\t%f\t%f\t%f\t%f\n", *ui->zone, ui->init, ui->min, ui->max, ui->step); return s;
+ case UIHBarGraph: snprint(s, sz, "hbargraph\t%f\t%f\t%f\n", *ui->zone, ui->min, ui->max); return s;
+ case UIVBarGraph: snprint(s, sz, "vbargraph\t%f\t%f\t%f\n", *ui->zone, ui->min, ui->max); return s;
+ default: sysfatal("unknown ui type %d", a->type);
+ }
+ } else if (type == Xuimeta) {
+ x = s;
+ *x = 0;
+ for (i = 0; i < ui->nummeta; i++)
+ x = seprint(x, s+sz-1, "%s\t%s\n", ui->meta[i].k, ui->meta[i].v);
+ return s;
+ } else {
+ sysfatal("unknown ui file");
}
- sysfatal("unknown ui type %d", a->type);
+
return nil;
}
@@ -73,9 +86,13 @@
{
Aux *a;
- a = calloc(1, sizeof(*a)+sizeof(UI));
+ a = calloc(1, sizeof(*a)+sizeof(UI) + sizeof(Meta)*decl.nummeta);
a->ui = (UI*)(a+1);
+ a->ui->meta = (Meta*)(a->ui+1);
+ a->ui->nummeta = decl.nummeta;
+ memmove(a->ui->meta, decl.meta, sizeof(Meta)*decl.nummeta);
a->ctl = Xuictl;
+ a->metadata = Xuimeta;
a->type = type;
a->ui->label = label;
a->ui->readstr = ui_readstr;
@@ -84,7 +101,14 @@
sysfatal("failed to create ui: %r");
if (createfile(uiglue.uiInterface, "ctl", nil, 0664, &a->ctl) == nil)
sysfatal("failed to create ui ctl: %r");
+ if (createfile(uiglue.uiInterface, "metadata", nil, 0664, &a->metadata) == nil)
+ sysfatal("failed to create ui metadata: %r");
+ free(decl.meta);
+ decl.zone = nil;
+ decl.meta = nil;
+ decl.nummeta = 0;
+
return a->ui;
}
@@ -120,12 +144,10 @@
{
UI *ui;
- if (zone != declzone)
- sysfatal("zone mismatch");
+ if (zone != decl.zone)
+ sysfatal("zone mismatch during definition");
ui = newui(f, label, type);
- ui->zone = declzone;
- ui->key = declkey;
- ui->value = declvalue;
+ ui->zone = decl.zone;
uiglue.uiInterface = f;
return ui;
@@ -204,9 +226,13 @@
{
USED(f);
- declzone = zone;
- declkey = key;
- declvalue = value;
+ if (decl.zone != nil && decl.zone != zone)
+ sysfatal("zone mismatch during declaration");
+ decl.zone = zone;
+ decl.meta = realloc(decl.meta, sizeof(Meta)*(decl.nummeta+1));
+ decl.meta[decl.nummeta].k = key;
+ decl.meta[decl.nummeta].v = value;
+ decl.nummeta++;
}
UIGlue uiglue = {