ref: c787e8e5371c91b41172dc985d8e29fd9565f88f
parent: 10d66333fb0f3f6f333bb1bb4802a77d061628a7
author: Sigrid Haflínudóttir <[email protected]>
date: Fri Jan 17 08:56:19 EST 2020
move stuff around
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
At this moment the effort is mostly on getting tooling powered by
[Faust](https://faust.grame.fr) to beep beep boop. Here, watch this:
-![code](kick.png) → ![result](cfg.png)
+![code](kick.jpg) → ![result](cfg.png)
Wow.
@@ -16,7 +16,7 @@
```
cd /tmp && \
hget https://github.com/ftrvxmtrx/neindaw/archive/master.tar.gz | tar xz && \
-cd faust9p-master && mk install
+cd neindaw-master && mk install
ls /bin/daw
```
@@ -73,6 +73,9 @@
## TODO and random notes
+ * buffer computated data and make
+ * use llvm-generated object or asm instead of C? that would be having to
+ add Plan 9 target to llc I guess, or some kind of conversion tool for asm
* renaming/removal of instance IDs and controls via Twstat and Tremove
* GUI needs to support various styles like knobs, drop down menus,
radio buttons etc
@@ -93,6 +96,7 @@
together, should be controllable through daw/cfg. microui will need
a lot of work
* polyphonyfs to manage master/voices automatically for any DSP
+ * mixerfs with channels
* full MIDI support
* OSC support
* port Orca to Plan 9 and use it for testing neindaw
--- a/arch.c
+++ /dev/null
@@ -1,35 +1,0 @@
-/* mydsp Plan 9 C architecture for Faust. */
-
-#include <u.h>
-#include <libc.h>
-#include "uiglue.h"
-
-#define max(x,y) (((x) > (y)) ? (x) : (y))
-#define min(x,y) (((x) < (y)) ? (x) : (y))
-
-<<includeIntrinsic>>
-<<includeclass>>
-
-#define DSP mydsp
-
-#include "dspf.h"
-
-static DSPf dspf = {
- .new = newmydsp,
- .init = instanceInitmydsp,
- .delete = deletemydsp,
- .metadata = metadatamydsp,
- .num_in = getNumInputsmydsp,
- .num_out = getNumOutputsmydsp,
- .clear = instanceClearmydsp,
- .reset_ui = instanceResetUserInterfacemydsp,
- .build_ui = buildUserInterfacemydsp,
- .compute = computemydsp,
-};
-
-void *
-class_init(int rate)
-{
- classInitmydsp(rate);
- return &dspf;
-}
--- a/aux.h
+++ /dev/null
@@ -1,56 +1,0 @@
-typedef enum {
- Xclone,
- Xctl,
- Xmetadata,
-
- Xdsp,
- Xdspctl,
- Xdspdata,
-
- Xui,
- Xuictl,
- Xuimeta,
-}Auxtype;
-
-typedef struct Aux Aux;
-typedef struct Auxdsp Auxdsp;
-typedef struct Meta Meta;
-typedef struct UI UI;
-
-struct Auxdsp {
- void *dsp;
- FAUSTFLOAT **in, **out;
- int numin, numout;
- int inmax, outmax;
-};
-
-struct Aux {
- Auxtype type;
- int id;
- int ctl;
- int data;
- int metadata;
-
- Auxdsp *dsp;
- UI *ui;
-};
-
-struct Meta {
- const char *k;
- const char *v;
-};
-
-struct UI {
- UItype type;
- const char *label;
- FAUSTFLOAT *zone;
- FAUSTFLOAT init;
- FAUSTFLOAT min;
- FAUSTFLOAT max;
- FAUSTFLOAT step;
- char *(*readstr)(UI *ui, int type, char *s, int sz);
- int (*write)(UI *ui, int type, char *s);
-
- Meta *meta;
- int nummeta;
-};
--- /dev/null
+++ b/dsp/arch.c
@@ -1,0 +1,35 @@
+/* mydsp Plan 9 C architecture for Faust. */
+
+#include <u.h>
+#include <libc.h>
+#include "uiglue.h"
+
+#define max(x,y) (((x) > (y)) ? (x) : (y))
+#define min(x,y) (((x) < (y)) ? (x) : (y))
+
+<<includeIntrinsic>>
+<<includeclass>>
+
+#define DSP mydsp
+
+#include "dspf.h"
+
+static DSPf dspf = {
+ .new = newmydsp,
+ .init = instanceInitmydsp,
+ .delete = deletemydsp,
+ .metadata = metadatamydsp,
+ .num_in = getNumInputsmydsp,
+ .num_out = getNumOutputsmydsp,
+ .clear = instanceClearmydsp,
+ .reset_ui = instanceResetUserInterfacemydsp,
+ .build_ui = buildUserInterfacemydsp,
+ .compute = computemydsp,
+};
+
+void *
+class_init(int rate)
+{
+ classInitmydsp(rate);
+ return &dspf;
+}
--- /dev/null
+++ b/dsp/aux.h
@@ -1,0 +1,56 @@
+typedef enum {
+ Xclone,
+ Xctl,
+ Xmetadata,
+
+ Xdsp,
+ Xdspctl,
+ Xdspdata,
+
+ Xui,
+ Xuictl,
+ Xuimeta,
+}Auxtype;
+
+typedef struct Aux Aux;
+typedef struct Auxdsp Auxdsp;
+typedef struct Meta Meta;
+typedef struct UI UI;
+
+struct Auxdsp {
+ void *dsp;
+ FAUSTFLOAT **in, **out;
+ int numin, numout;
+ int inmax, outmax;
+};
+
+struct Aux {
+ Auxtype type;
+ int id;
+ int ctl;
+ int data;
+ int metadata;
+
+ Auxdsp *dsp;
+ UI *ui;
+};
+
+struct Meta {
+ const char *k;
+ const char *v;
+};
+
+struct UI {
+ UItype type;
+ const char *label;
+ FAUSTFLOAT *zone;
+ FAUSTFLOAT init;
+ FAUSTFLOAT min;
+ FAUSTFLOAT max;
+ FAUSTFLOAT step;
+ char *(*readstr)(UI *ui, int type, char *s, int sz);
+ int (*write)(UI *ui, int type, char *s);
+
+ Meta *meta;
+ int nummeta;
+};
--- /dev/null
+++ b/dsp/dspf.h
@@ -1,0 +1,14 @@
+typedef struct {
+ DSP *(*new)(void);
+ void (*init)(DSP *dsp, int sample_rate);
+ void (*delete)(DSP *dsp);
+ void (*metadata)(MetaGlue *glue);
+ int (*num_in)(DSP *dsp);
+ int (*num_out)(DSP *dsp);
+ void (*clear)(DSP *dsp);
+ void (*reset_ui)(DSP *dsp);
+ void (*build_ui)(DSP *dsp, UIGlue *glue);
+ void (*compute)(DSP *dsp, int count, FAUSTFLOAT **in, FAUSTFLOAT **out);
+}DSPf;
+
+void *class_init(int rate);
--- /dev/null
+++ b/dsp/fs.c
@@ -1,0 +1,321 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include "uiglue.h"
+typedef struct DSP DSP;
+#include "dspf.h"
+#include "common.h"
+#include "aux.h"
+
+enum {
+ Inmax = 2048, /* float = 8192 bytes */
+ Outmax = 2048, /* float = 8192 bytes */
+};
+
+static Aux rootaux[] = {
+ [Xctl] = {.type = Xctl},
+ [Xmetadata] = {.type = Xmetadata},
+ [Xclone] = {.type = Xclone},
+};
+static Aux *objs[32];
+static char *meta = nil;
+static int metalen = 0;
+static int rate = 44100;
+static DSPf *dspf;
+extern Srv fs;
+
+static char Elocked[] = "file locked";
+
+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 Aux *
+newobj(char *name)
+{
+ File *f;
+ Aux *o;
+ Auxdsp *dsp;
+ int i;
+
+ for (i = 0, o = nil; o == nil && i < nelem(objs); i++) {
+ if (objs[i] == nil){
+ o = objs[i] = calloc(1, sizeof(*o)+sizeof(Auxdsp));
+ break;
+ }
+ }
+ if (o == nil)
+ return nil;
+
+ o->id = i;
+ o->type = Xdsp;
+ o->ctl = Xdspctl;
+ o->data = Xdspdata;
+ o->dsp = dsp = (Auxdsp*)(o+1);
+ dsp->dsp = dspf->new();
+
+ dsp->in = dsp->out = nil;
+ if ((dsp->numin = dspf->num_in(dsp->dsp)) > 0) {
+ dsp->in = malloc(sizeof(*dsp->in) * dsp->numin);
+ dsp->inmax = Inmax;
+ for (i = 0; i < dsp->numin; i++)
+ dsp->in[i] = malloc(sizeof(**dsp->in) * dsp->inmax);
+ }
+ if ((dsp->numout = dspf->num_out(dsp->dsp)) > 0) {
+ dsp->out = malloc(sizeof(*dsp->out) * dsp->numout);
+ dsp->outmax = Outmax;
+ for (i = 0; i < dsp->numout; i++)
+ dsp->out[i] = malloc(sizeof(**dsp->out) * dsp->outmax);
+ }
+
+ sprint(name, "%d", o->id);
+ if ((f = createfile(fs.tree->root, name, nil, DMDIR|0775, o)) == nil)
+ return nil;
+ closefile(createfile(f, "ctl", nil, 0664, &o->ctl));
+ closefile(createfile(f, "data", nil, 0664, &o->data));
+ closefile(f);
+ dspf->init(dsp->dsp, rate);
+ uiglue.f = f;
+ dspf->build_ui(dsp->dsp, &uiglue);
+
+ return o;
+}
+
+static void
+freeobj(Aux *o)
+{
+ int i;
+
+ if (o == nil)
+ return;
+
+ if (o->type == Xdsp) {
+ objs[o->id] = nil;
+ dspf->delete(o->dsp->dsp);
+ for (i = 0; i < o->dsp->numin; i++)
+ free(o->dsp->in[i]);
+ free(o->dsp->in);
+ for (i = 0; i < o->dsp->numout; i++)
+ free(o->dsp->out[i]);
+ free(o->dsp->out);
+ }
+
+ free(o);
+}
+
+static void
+addmeta(void *metaInterface, const char *k, const char *v)
+{
+ int klen, vlen;
+
+ USED(metaInterface);
+
+ if (strchr(k, '/') != nil) /* ignore library-specific meta */
+ return;
+
+ klen = strlen(k);
+ vlen = strlen(v);
+ meta = realloc(meta, metalen + klen + 1 + vlen + 2);
+ strcpy(meta+metalen, k);
+ metalen += klen;
+ meta[metalen++] = '\t';
+ strcpy(meta+metalen, v);
+ metalen += vlen;
+ meta[metalen++] = '\n';
+ meta[metalen] = 0;
+}
+
+void
+fsopen(Req *r)
+{
+ respond(r, nil);
+}
+
+void
+fsread(Req *r)
+{
+ Aux *a, *o;
+ Auxdsp *dsp;
+ char b[256];
+ FAUSTFLOAT *p;
+ int i, j, n, numframes, framesz;
+
+ a = r->fid->file->aux;
+ switch (a->type) {
+ case Xctl:
+ respond(r, nil);
+ break;
+ case Xmetadata:
+ readstr(r, meta);
+ respond(r, nil);
+ break;
+ case Xclone:
+ if (r->ifcall.offset == 0) {
+ if (newobj(b) != nil) {
+ readstr(r, b);
+ } else {
+ snprint(b, sizeof(b), "no free objects: %r");
+ respond(r, b);
+ break;
+ }
+ }
+ respond(r, nil);
+ break;
+ case Xuictl:
+ case Xuimeta:
+ o = auxtype2obj(&a->type);
+ if (o->ui->readstr != nil)
+ readstr(r, o->ui->readstr(o->ui, a->type, b, sizeof(b)));
+ respond(r, nil);
+ break;
+ case Xdspdata:
+ o = auxtype2obj(&a->type);
+ dsp = o->dsp;
+ if (r->ifcall.offset == 0) /* clear every time the offset is reset */
+ dspf->clear(dsp->dsp);
+ framesz = dsp->numout * sizeof(*p);
+ n = r->ifcall.count;
+ for (p = (FAUSTFLOAT*)r->ofcall.data; n >= framesz;) {
+ numframes = n / framesz;
+ if (numframes > dsp->outmax)
+ numframes = dsp->outmax;
+ dspf->compute(dsp->dsp, numframes, dsp->in, dsp->out);
+ for (i = 0; i < numframes; i++) {
+ for (j = 0; j < dsp->numout; j++)
+ *p++ = dsp->out[j][i];
+ }
+ n -= numframes * framesz;
+ }
+ r->ofcall.count = r->ifcall.count - n;
+ respond(r, nil);
+ break;
+ default:
+ respond(r, "not implemented");
+ break;
+ }
+}
+
+void
+fswrite(Req *r)
+{
+ Aux *a, *o;
+ char b[256];
+ int st;
+
+ if (r->ifcall.count >= sizeof(b)) {
+ respond(r, "can't fit into buffer");
+ return;
+ }
+
+ memmove(b, r->ifcall.data, r->ifcall.count);
+ b[r->ifcall.count] = '\0';
+ r->ofcall.count = r->ifcall.count;
+
+ a = r->fid->file->aux;
+ switch (a->type) {
+ case Xuictl:
+ o = auxtype2obj(&a->type);
+ st = o->ui->write != nil ? o->ui->write(o->ui, a->type, b) : -1;
+ respond(r, st == 0 ? nil : "write failed");
+ break;
+ case Xdspctl: /* FIXME changing sampling rate */
+ o = auxtype2obj(&a->type);
+ if (strncmp(b, "clear", 5) == 0)
+ dspf->clear(o->dsp->dsp);
+ else if (strncmp(b, "reset", 5) == 0)
+ dspf->reset_ui(o->dsp->dsp);
+ else if (strncmp(b, "init", 4) == 0)
+ dspf->init(o->dsp->dsp, rate);
+ respond(r, nil);
+ break;
+ case Xmetadata: /* FIXME should be possible to add new key/value */
+ default:
+ respond(r, "not implemented");
+ break;
+ }
+}
+
+static void
+fsdestroyfile(File *f)
+{
+ Aux *a;
+
+ if ((a = f->aux) == nil)
+ return;
+ switch (a->type) {
+ case Xdsp:
+ case Xui:
+ freeobj(a);
+ f->aux = nil;
+ break;
+ }
+}
+
+Srv fs = {
+ .open = fsopen,
+ .read = fsread,
+ .write = fswrite,
+};
+
+static void
+usage(void)
+{
+ print("usage: %s [-s srv] [-m mtpt] [-r rate]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ char *srv, *mtpt;
+ MetaGlue mg;
+
+ srv = nil;
+ mtpt = nil;
+ ARGBEGIN{
+ case 'D':
+ chatty9p++;
+ break;
+ case 's':
+ srv = EARGF(usage());
+ break;
+ case 'm':
+ mtpt = EARGF(usage());
+ break;
+ case 'r':
+ rate = atoi(EARGF(usage()));
+ break;
+ default:
+ usage();
+ }ARGEND
+
+ if (srv == nil && mtpt == nil)
+ sysfatal("must specify -s or -m option");
+
+ mg.declare = addmeta;
+ dspf = class_init(rate);
+ dspf->metadata(&mg);
+
+ fs.tree = alloctree(nil, nil, DMDIR|0775, fsdestroyfile);
+ closefile(createfile(fs.tree->root, "ctl", nil, 0666, &rootaux[Xctl]));
+ closefile(createfile(fs.tree->root, "metadata", nil, 0444, &rootaux[Xmetadata]));
+ closefile(createfile(fs.tree->root, "clone", nil, 0444, &rootaux[Xclone]));
+ postmountsrv(&fs, srv, mtpt, MREPL);
+ exits(nil);
+}
--- /dev/null
+++ b/dsp/kick_drum.c
@@ -1,0 +1,363 @@
+/* ------------------------------------------------------------
+name: "Kick Drum"
+Code generated with Faust 2.21.5 (https://faust.grame.fr)
+Compilation options: -lang c -scal -ftz 0
+------------------------------------------------------------ */
+
+#ifndef __KickDrum_H__
+#define __KickDrum_H__
+
+/* KickDrum Plan 9 C architecture for Faust. */
+
+#include <u.h>
+#include <libc.h>
+#include "uiglue.h"
+
+#define max(x,y) (((x) > (y)) ? (x) : (y))
+#define min(x,y) (((x) < (y)) ? (x) : (y))
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+
+typedef struct {
+ int iRec0[2];
+} KickDrumSIG0;
+
+static KickDrumSIG0* newKickDrumSIG0(void) { return (KickDrumSIG0*)calloc(1, sizeof(KickDrumSIG0)); }
+static void deleteKickDrumSIG0(KickDrumSIG0* dsp) {
+ USED(dsp); free(dsp); }
+
+int getNumInputsKickDrumSIG0(KickDrumSIG0* dsp) {
+ USED(dsp);
+ return 0;
+}
+int getNumOutputsKickDrumSIG0(KickDrumSIG0* dsp) {
+ USED(dsp);
+ return 1;
+}
+int getInputRateKickDrumSIG0(KickDrumSIG0* dsp, int channel) {
+ USED(dsp);
+ int rate;
+ switch ((channel)) {
+ default: {
+ rate = -1;
+ break;
+ }
+ }
+ return rate;
+}
+int getOutputRateKickDrumSIG0(KickDrumSIG0* dsp, int channel) {
+ USED(dsp);
+ int rate;
+ switch ((channel)) {
+ case 0: {
+ rate = 0;
+ break;
+ }
+ default: {
+ rate = -1;
+ break;
+ }
+ }
+ return rate;
+}
+
+static void instanceInitKickDrumSIG0(KickDrumSIG0* dsp, int sample_rate) {
+ USED(sample_rate);
+ USED(dsp);
+ /* C99 loop */
+ {
+ int l0;
+ for (l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
+ dsp->iRec0[l0] = 0;
+ }
+ }
+}
+
+static void fillKickDrumSIG0(KickDrumSIG0* dsp, int count, float* table) {
+ USED(dsp);
+ /* C99 loop */
+ {
+ int i;
+ for (i = 0; (i < count); i = (i + 1)) {
+ dsp->iRec0[0] = (dsp->iRec0[1] + 1);
+ table[i] = sinf((9.58738019e-05f * (float)(dsp->iRec0[0] + -1)));
+ dsp->iRec0[1] = dsp->iRec0[0];
+ }
+ }
+}
+
+static float ftbl0KickDrumSIG0[65536];
+
+#ifndef FAUSTCLASS
+#define FAUSTCLASS KickDrum
+#endif
+#ifdef __APPLE__
+#define exp10f __exp10f
+#define exp10 __exp10
+#endif
+
+typedef struct {
+ FAUSTFLOAT fHslider0;
+ FAUSTFLOAT fButton0;
+ float fVec0[2];
+ int fSampleRate;
+ float fConst0;
+ float fConst1;
+ FAUSTFLOAT fHslider1;
+ FAUSTFLOAT fHslider2;
+ FAUSTFLOAT fCheckbox0;
+ FAUSTFLOAT fHslider3;
+ int iRec2[2];
+ FAUSTFLOAT fHslider4;
+ float fRec1[2];
+ FAUSTFLOAT fHslider5;
+ FAUSTFLOAT fHslider6;
+} KickDrum;
+
+KickDrum* newKickDrum(void) {
+ KickDrum* dsp = (KickDrum*)calloc(1, sizeof(KickDrum));
+ return dsp;
+}
+
+void deleteKickDrum(KickDrum* dsp) {
+ USED(dsp);
+ free(dsp);
+}
+
+void metadataKickDrum(MetaGlue* m) {
+ m->declare(m->metaInterface, "basics.lib/name", "Faust Basic Element Library");
+ m->declare(m->metaInterface, "basics.lib/version", "0.1");
+ m->declare(m->metaInterface, "envelopes.lib/ar:author", "Yann Orlarey, Stéphane Letz");
+ m->declare(m->metaInterface, "envelopes.lib/author", "GRAME");
+ m->declare(m->metaInterface, "envelopes.lib/copyright", "GRAME");
+ m->declare(m->metaInterface, "envelopes.lib/license", "LGPL with exception");
+ m->declare(m->metaInterface, "envelopes.lib/name", "Faust Envelope Library");
+ m->declare(m->metaInterface, "envelopes.lib/version", "0.0");
+ m->declare(m->metaInterface, "filename", "kick_drum.dsp");
+ m->declare(m->metaInterface, "group", "Synthesis");
+ m->declare(m->metaInterface, "maths.lib/author", "GRAME");
+ m->declare(m->metaInterface, "maths.lib/copyright", "GRAME");
+ m->declare(m->metaInterface, "maths.lib/license", "LGPL with exception");
+ m->declare(m->metaInterface, "maths.lib/name", "Faust Math Library");
+ m->declare(m->metaInterface, "maths.lib/version", "2.1");
+ m->declare(m->metaInterface, "name", "Kick Drum");
+ m->declare(m->metaInterface, "oscillators.lib/name", "Faust Oscillator Library");
+ m->declare(m->metaInterface, "oscillators.lib/version", "0.0");
+}
+
+int getSampleRateKickDrum(KickDrum* dsp) {
+ USED(dsp);
+ return dsp->fSampleRate;
+}
+
+int getNumInputsKickDrum(KickDrum* dsp) {
+ USED(dsp);
+ return 0;
+}
+int getNumOutputsKickDrum(KickDrum* dsp) {
+ USED(dsp);
+ return 1;
+}
+int getInputRateKickDrum(KickDrum* dsp, int channel) {
+ USED(dsp);
+ int rate;
+ switch ((channel)) {
+ default: {
+ rate = -1;
+ break;
+ }
+ }
+ return rate;
+}
+int getOutputRateKickDrum(KickDrum* dsp, int channel) {
+ USED(dsp);
+ int rate;
+ switch ((channel)) {
+ case 0: {
+ rate = 1;
+ break;
+ }
+ default: {
+ rate = -1;
+ break;
+ }
+ }
+ return rate;
+}
+
+void classInitKickDrum(int sample_rate) {
+ USED(sample_rate);
+ KickDrumSIG0* sig0 = newKickDrumSIG0();
+ instanceInitKickDrumSIG0(sig0, sample_rate);
+ fillKickDrumSIG0(sig0, 65536, ftbl0KickDrumSIG0);
+ deleteKickDrumSIG0(sig0);
+}
+
+void instanceResetUserInterfaceKickDrum(KickDrum* dsp) {
+ USED(dsp);
+ dsp->fHslider0 = (FAUSTFLOAT)1.0f;
+ dsp->fButton0 = (FAUSTFLOAT)0.0f;
+ dsp->fHslider1 = (FAUSTFLOAT)100.0f;
+ dsp->fHslider2 = (FAUSTFLOAT)-5.0f;
+ dsp->fCheckbox0 = (FAUSTFLOAT)0.0f;
+ dsp->fHslider3 = (FAUSTFLOAT)0.001f;
+ dsp->fHslider4 = (FAUSTFLOAT)0.001f;
+ dsp->fHslider5 = (FAUSTFLOAT)0.001f;
+ dsp->fHslider6 = (FAUSTFLOAT)0.001f;
+}
+
+void instanceClearKickDrum(KickDrum* dsp) {
+ USED(dsp);
+ /* C99 loop */
+ {
+ int l1;
+ for (l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
+ dsp->fVec0[l1] = 0.0f;
+ }
+ }
+ /* C99 loop */
+ {
+ int l2;
+ for (l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
+ dsp->iRec2[l2] = 0;
+ }
+ }
+ /* C99 loop */
+ {
+ int l3;
+ for (l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
+ dsp->fRec1[l3] = 0.0f;
+ }
+ }
+}
+
+void instanceConstantsKickDrum(KickDrum* dsp, int sample_rate) {
+ USED(sample_rate);
+ USED(dsp);
+ dsp->fSampleRate = sample_rate;
+ dsp->fConst0 = min(192000.0f, max(1.0f, (float)dsp->fSampleRate));
+ dsp->fConst1 = (1.0f / dsp->fConst0);
+}
+
+void instanceInitKickDrum(KickDrum* dsp, int sample_rate) {
+ USED(sample_rate);
+ USED(dsp);
+ instanceConstantsKickDrum(dsp, sample_rate);
+ instanceResetUserInterfaceKickDrum(dsp);
+ instanceClearKickDrum(dsp);
+}
+
+void initKickDrum(KickDrum* dsp, int sample_rate) {
+ USED(sample_rate);
+ USED(dsp);
+ classInitKickDrum(sample_rate);
+ instanceInitKickDrum(dsp, sample_rate);
+}
+
+void buildUserInterfaceKickDrum(KickDrum* dsp, UIGlue* ui_interface) {
+ USED(dsp);
+ ui_interface->openVerticalBox(ui_interface->uiInterface, "Kick Drum");
+ ui_interface->openVerticalBox(ui_interface->uiInterface, "A");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider1, "0", "");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider1, "unit", "Hz");
+ ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Frequency", &dsp->fHslider1, 100.0f, 5.0f, 200.0f, 1.0f);
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider5, "1", "");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider5, "unit", "s");
+ ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Attack", &dsp->fHslider5, 0.00100000005f, 9.99999975e-06f, 0.200000003f, 0.00100000005f);
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider6, "3", "");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider6, "unit", "s");
+ ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Release", &dsp->fHslider6, 0.00100000005f, 9.99999975e-06f, 1.0f, 0.00100000005f);
+ ui_interface->closeBox(ui_interface->uiInterface);
+ ui_interface->openVerticalBox(ui_interface->uiInterface, "B");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider2, "0", "");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider2, "unit", "Hz");
+ ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Frequency", &dsp->fHslider2, -5.0f, -5.0f, 200.0f, 5.0f);
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider3, "1", "");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider3, "unit", "s");
+ ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Attack", &dsp->fHslider3, 0.00100000005f, 9.99999975e-06f, 0.200000003f, 0.00100000005f);
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider4, "2", "");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider4, "unit", "s");
+ ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Release", &dsp->fHslider4, 0.00100000005f, 9.99999975e-06f, 1.0f, 0.00100000005f);
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fCheckbox0, "3", "");
+ ui_interface->addCheckButton(ui_interface->uiInterface, "Enable", &dsp->fCheckbox0);
+ ui_interface->closeBox(ui_interface->uiInterface);
+ ui_interface->openVerticalBox(ui_interface->uiInterface, "Control");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider0, "0", "");
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider0, "style", "knob");
+ ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Gain", &dsp->fHslider0, 1.0f, 0.0f, 1.0f, 0.00999999978f);
+ ui_interface->declare(ui_interface->uiInterface, &dsp->fButton0, "1", "");
+ ui_interface->addButton(ui_interface->uiInterface, "Gate", &dsp->fButton0);
+ ui_interface->closeBox(ui_interface->uiInterface);
+ ui_interface->closeBox(ui_interface->uiInterface);
+}
+
+void computeKickDrum(KickDrum* dsp, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
+ USED(inputs);
+ USED(dsp);
+ FAUSTFLOAT* output0 = outputs[0];
+ float fSlow0 = (float)dsp->fHslider0;
+ float fSlow1 = (float)dsp->fButton0;
+ float fSlow2 = (float)dsp->fHslider1;
+ float fSlow3 = ((float)dsp->fHslider2 * (float)dsp->fCheckbox0);
+ float fSlow4 = max(1.0f, (dsp->fConst0 * (float)dsp->fHslider3));
+ float fSlow5 = (1.0f / fSlow4);
+ float fSlow6 = (1.0f / max(1.0f, (dsp->fConst0 * (float)dsp->fHslider4)));
+ float fSlow7 = max(1.0f, (dsp->fConst0 * (float)dsp->fHslider5));
+ float fSlow8 = (1.0f / fSlow7);
+ float fSlow9 = (1.0f / max(1.0f, (dsp->fConst0 * (float)dsp->fHslider6)));
+ /* C99 loop */
+ {
+ int i;
+ for (i = 0; (i < count); i = (i + 1)) {
+ dsp->fVec0[0] = fSlow1;
+ int iTemp0 = (fSlow1 > dsp->fVec0[1]);
+ dsp->iRec2[0] = (iTemp0 + ((fSlow1 <= dsp->fVec0[1]) * (dsp->iRec2[1] + (dsp->iRec2[1] > 0))));
+ float fTemp1 = (float)dsp->iRec2[0];
+ float fTemp2 = ((dsp->fRec1[1] * (1.0f - (float)(iTemp0 > 0))) + (dsp->fConst1 * (fSlow2 + (fSlow3 * max(0.0f, min((fSlow5 * fTemp1), (1.0f - (fSlow6 * (fTemp1 - fSlow4)))))))));
+ dsp->fRec1[0] = (fTemp2 - floorf(fTemp2));
+ output0[i] = (FAUSTFLOAT)(fSlow0 * (ftbl0KickDrumSIG0[(int)(65536.0f * dsp->fRec1[0])] * max(0.0f, min((fSlow8 * fTemp1), ((fSlow9 * (fSlow7 - fTemp1)) + 1.0f)))));
+ dsp->fVec0[1] = dsp->fVec0[0];
+ dsp->iRec2[1] = dsp->iRec2[0];
+ dsp->fRec1[1] = dsp->fRec1[0];
+ }
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#define DSP KickDrum
+
+#include "dspf.h"
+
+static DSPf dspf = {
+ .new = newKickDrum,
+ .init = instanceInitKickDrum,
+ .delete = deleteKickDrum,
+ .metadata = metadataKickDrum,
+ .num_in = getNumInputsKickDrum,
+ .num_out = getNumOutputsKickDrum,
+ .clear = instanceClearKickDrum,
+ .reset_ui = instanceResetUserInterfaceKickDrum,
+ .build_ui = buildUserInterfaceKickDrum,
+ .compute = computeKickDrum,
+};
+
+void *
+class_init(int rate)
+{
+ classInitKickDrum(rate);
+ return &dspf;
+}
+
+#endif
--- /dev/null
+++ b/dsp/kick_drum.dsp
@@ -1,0 +1,16 @@
+// Simple kick drum
+declare name "Kick Drum";
+declare group "Synthesis";
+import("stdfaust.lib");
+
+aFreq = hslider("v:A/[0]Frequency[unit:Hz]", 100, 5, 200, 1);
+aA = hslider("v:A/[1]Attack[unit:s]", 0.001, 0.00001, 0.2, 0.001);
+aR = hslider("v:A/[3]Release[unit:s]", 0.001, 0.00001, 1.0, 0.001);
+bA = hslider("v:B/[1]Attack[unit:s]", 0.001, 0.00001, 0.2, 0.001);
+bR = hslider("v:B/[2]Release[unit:s]", 0.001, 0.00001, 1, 0.001);
+bFreq = checkbox("v:B/[3]Enable") * hslider("v:B/[0]Frequency[unit:Hz]", -5, -5, 200, 5);
+
+gain = hslider("v:Control/[0]Gain[style:knob]", 1, 0, 1, 0.01);
+gate = button("v:Control/[1]Gate");
+
+process = os.hs_oscsin(aFreq + bFreq*en.ar(bA, bR, gate), gate : ba.impulsify) * gain * en.ar(aA, aR, gate);
--- /dev/null
+++ b/dsp/math.h
@@ -1,0 +1,8 @@
+#define cosf cos
+#define expf exp
+#define fabsf fabs
+#define floorf floor
+#define powf pow
+#define sinf sin
+#define sqrtf sqrt
+#define tanf tan
--- /dev/null
+++ b/dsp/mkfile
@@ -1,0 +1,24 @@
+</$objtype/mkfile
+
+TARG=\
+ kick_drum
+
+OFILES=\
+ common.$O\
+ fs.$O\
+ uiglue.$O\
+
+CFLAGS=$CFLAGS -I..
+
+default:V: all
+
+CLEANFILES=\
+
+</sys/src/cmd/mkmany
+
+$BIN/%: $O.%
+ mkdir -p $BIN
+ cp $O.$stem $BIN/$stem
+
+common.$O: ../common.c
+ $CC $CFLAGS $prereq
--- /dev/null
+++ b/dsp/uiglue.c
@@ -1,0 +1,281 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+#include "uiglue.h"
+#include "common.h"
+#include "aux.h"
+
+static struct {
+ FAUSTFLOAT *zone;
+ Meta *meta;
+ int nummeta;
+}decl;
+
+static char *
+ui_readstr(UI *ui, int type, char *s, int sz)
+{
+ char *x, *t;
+ int i;
+
+ if (type == Xuictl) {
+ if (ui->type < 0 || ui->type >= UInum)
+ sysfatal("unknown ui type %d", ui->type);
+ t = uitypenames[ui->type];
+ switch (ui->type) {
+ case UITGroup:
+ case UIHGroup:
+ case UIVGroup:
+ snprint(s, sz, "%s\n", t);
+ return s;
+ case UIButton:
+ case UICheckBox:
+ snprint(s, sz, "%s\t%g\n", t, *ui->zone);
+ return s;
+ case UIVSlider:
+ case UIHSlider:
+ case UINEntry:
+ snprint(s, sz, "%s\t%g\t%g\t%g\t%g\t%g\n", t, *ui->zone, ui->init, ui->min, ui->max, ui->step);
+ return s;
+ case UIHBarGraph:
+ case UIVBarGraph:
+ snprint(s, sz, "%s\t%g\t%g\t%g\n", t, *ui->zone, ui->min, ui->max);
+ return s;
+ default:
+ sysfatal("readstr not implemented for ui type %d", ui->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 type %d", type);
+ }
+
+ return nil;
+}
+
+static int
+ui_write(UI *ui, int type, char *s)
+{
+ char *e;
+ int failoor;
+ float v;
+
+ if (type != Xuictl)
+ sysfatal("unknown ui file");
+
+ /* FIXME optional argument should specify at which frame to apply the change */
+
+ v = 0.0f;
+ failoor = 0;
+ if (strncmp(s, "reset", 5) == 0) { /* FIXME reset for a box should reset ALL controls inside it */
+ v = ui->init;
+ } else if (strncmp(s, "add", 3) == 0) {
+ if (ui->zone != nil)
+ v = *ui->zone + atof(s+3);
+ } else if (strncmp(s, "sub", 3) == 0) {
+ if (ui->zone != nil)
+ v = *ui->zone - atof(s+3);
+ } else {
+ v = strtod(s, &e);
+ if (*e != 0 && *e != '\n')
+ return -1;
+ failoor = 1;
+ }
+
+ if (ui->zone != nil) {
+ if (ui->type == UIButton || ui->type == UICheckBox) {
+ *ui->zone = v > 0 ? 1 : 0;
+ } else {
+ if (v < ui->min) {
+ if (failoor)
+ return -1;
+ v = ui->min;
+ } else if (v > ui->max) {
+ if (failoor)
+ return -1;
+ v = ui->max;
+ }
+ *ui->zone = v;
+ }
+ }
+
+ return 0;
+}
+
+static UI *
+newui(File *f, const char *label, int type)
+{
+ Aux *a;
+
+ a = calloc(1, sizeof(*a)+sizeof(UI) + sizeof(Meta)*decl.nummeta);
+ a->type = Xui;
+ a->ui = (UI*)(a+1);
+ a->ui->type = type;
+ 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->ui->zone = decl.zone;
+ a->ui->label = label;
+ a->ui->readstr = ui_readstr;
+ a->ui->write = ui_write;
+ if ((uiglue.f = createfile(f, label, nil, DMDIR|0775, a)) == nil)
+ sysfatal("failed to create ui: %r");
+ if ((f = createfile(uiglue.f, "ctl", nil, 0664, &a->ctl)) == nil)
+ sysfatal("failed to create ui ctl: %r");
+ closefile(f);
+ if ((f = createfile(uiglue.f, "metadata", nil, 0664, &a->metadata)) == nil)
+ sysfatal("failed to create ui metadata: %r");
+ closefile(f);
+ closefile(uiglue.f);
+
+ free(decl.meta);
+ decl.zone = nil;
+ decl.meta = nil;
+ decl.nummeta = 0;
+
+ return a->ui;
+}
+
+static void
+ui_tgroup(void *f, const char *label)
+{
+ newui(f, label, UITGroup);
+}
+
+static void
+ui_hgroup(void *f, const char *label)
+{
+ newui(f, label, UIHGroup);
+}
+
+static void
+ui_vgroup(void *f, const char *label)
+{
+ newui(f, label, UIVGroup);
+}
+
+static void
+ui_close_group(void *file)
+{
+ File *f;
+
+ f = file;
+ uiglue.f = f->parent;
+}
+
+static UI *
+ui_define(File *f, int type, const char *label, FAUSTFLOAT *zone)
+{
+ UI *ui;
+
+ if (zone != decl.zone)
+ sysfatal("zone mismatch during definition");
+ ui = newui(f, label, type);
+ uiglue.f = f;
+
+ return ui;
+}
+
+static void
+ui_button(void *f, const char *label, FAUSTFLOAT *zone)
+{
+ ui_define(f, UIButton, label, zone);
+}
+
+static void
+ui_checkbox(void *f, const char *label, FAUSTFLOAT *zone)
+{
+ ui_define(f, UICheckBox, label, zone);
+}
+
+static void
+ui_vslider(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+ UI *ui;
+
+ ui = ui_define(f, UIVSlider, label, zone);
+ ui->init = init;
+ ui->min = min;
+ ui->max = max;
+ ui->step = step;
+}
+
+static void
+ui_hslider(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+ UI *ui;
+
+ ui = ui_define(f, UIHSlider, label, zone);
+ ui->init = init;
+ ui->min = min;
+ ui->max = max;
+ ui->step = step;
+}
+
+static void
+ui_nentry(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+ UI *ui;
+
+ ui = ui_define(f, UINEntry, label, zone);
+ ui->init = init;
+ ui->min = min;
+ ui->max = max;
+ ui->step = step;
+}
+
+static void
+ui_hbargraph(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max)
+{
+ UI *ui;
+
+ ui = ui_define(f, UIHBarGraph, label, zone);
+ ui->min = min;
+ ui->max = max;
+}
+
+static void
+ui_vbargraph(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max)
+{
+ UI *ui;
+
+ ui = ui_define(f, UIVBarGraph, label, zone);
+ ui->min = min;
+ ui->max = max;
+}
+
+static void
+ui_declare(void *f, FAUSTFLOAT *zone, const char *key, const char *value)
+{
+ USED(f);
+
+ 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 = {
+ .openTabBox = ui_tgroup,
+ .openHorizontalBox = ui_hgroup,
+ .openVerticalBox = ui_vgroup,
+ .closeBox = ui_close_group,
+ .addButton = ui_button,
+ .addCheckButton = ui_checkbox,
+ .addVerticalSlider = ui_vslider,
+ .addHorizontalSlider = ui_hslider,
+ .addNumEntry = ui_nentry,
+ .addHorizontalBargraph = ui_hbargraph,
+ .addVerticalBargraph = ui_vbargraph,
+ .declare = ui_declare,
+};
--- /dev/null
+++ b/dsp/uiglue.h
@@ -1,0 +1,34 @@
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+typedef struct UIGlue UIGlue;
+typedef struct MetaGlue MetaGlue;
+
+struct File;
+
+struct UIGlue {
+ union {
+ void *uiInterface;
+ struct File *f;
+ };
+ void (*openTabBox)(void *uiInterface, const char *label);
+ void (*openHorizontalBox)(void *uiInterface, const char *label);
+ void (*openVerticalBox)(void *uiInterface, const char *label);
+ void (*closeBox)(void *uiInterface);
+ void (*addButton)(void *uiInterface, const char *label, FAUSTFLOAT *zone);
+ void (*addCheckButton)(void *uiInterface, const char *label, FAUSTFLOAT *zone);
+ void (*addVerticalSlider)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+ void (*addHorizontalSlider)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+ void (*addNumEntry)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
+ void (*addHorizontalBargraph)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max);
+ void (*addVerticalBargraph)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max);
+ void (*declare)(void *uiInterface, FAUSTFLOAT *zone, const char *key, const char *value);
+};
+
+struct MetaGlue {
+ void *metaInterface;
+ void (*declare)(void *metaInterface, const char *key, const char *value);
+};
+
+extern UIGlue uiglue;
--- a/dspf.h
+++ /dev/null
@@ -1,14 +1,0 @@
-typedef struct {
- DSP *(*new)(void);
- void (*init)(DSP *dsp, int sample_rate);
- void (*delete)(DSP *dsp);
- void (*metadata)(MetaGlue *glue);
- int (*num_in)(DSP *dsp);
- int (*num_out)(DSP *dsp);
- void (*clear)(DSP *dsp);
- void (*reset_ui)(DSP *dsp);
- void (*build_ui)(DSP *dsp, UIGlue *glue);
- void (*compute)(DSP *dsp, int count, FAUSTFLOAT **in, FAUSTFLOAT **out);
-}DSPf;
-
-void *class_init(int rate);
--- a/fs.c
+++ /dev/null
@@ -1,321 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include <9p.h>
-#include "uiglue.h"
-typedef struct DSP DSP;
-#include "dspf.h"
-#include "common.h"
-#include "aux.h"
-
-enum {
- Inmax = 2048, /* float = 8192 bytes */
- Outmax = 2048, /* float = 8192 bytes */
-};
-
-static Aux rootaux[] = {
- [Xctl] = {.type = Xctl},
- [Xmetadata] = {.type = Xmetadata},
- [Xclone] = {.type = Xclone},
-};
-static Aux *objs[32];
-static char *meta = nil;
-static int metalen = 0;
-static int rate = 44100;
-static DSPf *dspf;
-extern Srv fs;
-
-static char Elocked[] = "file locked";
-
-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 Aux *
-newobj(char *name)
-{
- File *f;
- Aux *o;
- Auxdsp *dsp;
- int i;
-
- for (i = 0, o = nil; o == nil && i < nelem(objs); i++) {
- if (objs[i] == nil){
- o = objs[i] = calloc(1, sizeof(*o)+sizeof(Auxdsp));
- break;
- }
- }
- if (o == nil)
- return nil;
-
- o->id = i;
- o->type = Xdsp;
- o->ctl = Xdspctl;
- o->data = Xdspdata;
- o->dsp = dsp = (Auxdsp*)(o+1);
- dsp->dsp = dspf->new();
-
- dsp->in = dsp->out = nil;
- if ((dsp->numin = dspf->num_in(dsp->dsp)) > 0) {
- dsp->in = malloc(sizeof(*dsp->in) * dsp->numin);
- dsp->inmax = Inmax;
- for (i = 0; i < dsp->numin; i++)
- dsp->in[i] = malloc(sizeof(**dsp->in) * dsp->inmax);
- }
- if ((dsp->numout = dspf->num_out(dsp->dsp)) > 0) {
- dsp->out = malloc(sizeof(*dsp->out) * dsp->numout);
- dsp->outmax = Outmax;
- for (i = 0; i < dsp->numout; i++)
- dsp->out[i] = malloc(sizeof(**dsp->out) * dsp->outmax);
- }
-
- sprint(name, "%d", o->id);
- if ((f = createfile(fs.tree->root, name, nil, DMDIR|0775, o)) == nil)
- return nil;
- closefile(createfile(f, "ctl", nil, 0664, &o->ctl));
- closefile(createfile(f, "data", nil, 0664, &o->data));
- closefile(f);
- dspf->init(dsp->dsp, rate);
- uiglue.f = f;
- dspf->build_ui(dsp->dsp, &uiglue);
-
- return o;
-}
-
-static void
-freeobj(Aux *o)
-{
- int i;
-
- if (o == nil)
- return;
-
- if (o->type == Xdsp) {
- objs[o->id] = nil;
- dspf->delete(o->dsp->dsp);
- for (i = 0; i < o->dsp->numin; i++)
- free(o->dsp->in[i]);
- free(o->dsp->in);
- for (i = 0; i < o->dsp->numout; i++)
- free(o->dsp->out[i]);
- free(o->dsp->out);
- }
-
- free(o);
-}
-
-static void
-addmeta(void *metaInterface, const char *k, const char *v)
-{
- int klen, vlen;
-
- USED(metaInterface);
-
- if (strchr(k, '/') != nil) /* ignore library-specific meta */
- return;
-
- klen = strlen(k);
- vlen = strlen(v);
- meta = realloc(meta, metalen + klen + 1 + vlen + 2);
- strcpy(meta+metalen, k);
- metalen += klen;
- meta[metalen++] = '\t';
- strcpy(meta+metalen, v);
- metalen += vlen;
- meta[metalen++] = '\n';
- meta[metalen] = 0;
-}
-
-void
-fsopen(Req *r)
-{
- respond(r, nil);
-}
-
-void
-fsread(Req *r)
-{
- Aux *a, *o;
- Auxdsp *dsp;
- char b[256];
- FAUSTFLOAT *p;
- int i, j, n, numframes, framesz;
-
- a = r->fid->file->aux;
- switch (a->type) {
- case Xctl:
- respond(r, nil);
- break;
- case Xmetadata:
- readstr(r, meta);
- respond(r, nil);
- break;
- case Xclone:
- if (r->ifcall.offset == 0) {
- if (newobj(b) != nil) {
- readstr(r, b);
- } else {
- snprint(b, sizeof(b), "no free objects: %r");
- respond(r, b);
- break;
- }
- }
- respond(r, nil);
- break;
- case Xuictl:
- case Xuimeta:
- o = auxtype2obj(&a->type);
- if (o->ui->readstr != nil)
- readstr(r, o->ui->readstr(o->ui, a->type, b, sizeof(b)));
- respond(r, nil);
- break;
- case Xdspdata:
- o = auxtype2obj(&a->type);
- dsp = o->dsp;
- if (r->ifcall.offset == 0) /* clear every time the offset is reset */
- dspf->clear(dsp->dsp);
- framesz = dsp->numout * sizeof(*p);
- n = r->ifcall.count;
- for (p = (FAUSTFLOAT*)r->ofcall.data; n >= framesz;) {
- numframes = n / framesz;
- if (numframes > dsp->outmax)
- numframes = dsp->outmax;
- dspf->compute(dsp->dsp, numframes, dsp->in, dsp->out);
- for (i = 0; i < numframes; i++) {
- for (j = 0; j < dsp->numout; j++)
- *p++ = dsp->out[j][i];
- }
- n -= numframes * framesz;
- }
- r->ofcall.count = r->ifcall.count - n;
- respond(r, nil);
- break;
- default:
- respond(r, "not implemented");
- break;
- }
-}
-
-void
-fswrite(Req *r)
-{
- Aux *a, *o;
- char b[256];
- int st;
-
- if (r->ifcall.count >= sizeof(b)) {
- respond(r, "can't fit into buffer");
- return;
- }
-
- memmove(b, r->ifcall.data, r->ifcall.count);
- b[r->ifcall.count] = '\0';
- r->ofcall.count = r->ifcall.count;
-
- a = r->fid->file->aux;
- switch (a->type) {
- case Xuictl:
- o = auxtype2obj(&a->type);
- st = o->ui->write != nil ? o->ui->write(o->ui, a->type, b) : -1;
- respond(r, st == 0 ? nil : "write failed");
- break;
- case Xdspctl: /* FIXME changing sampling rate */
- o = auxtype2obj(&a->type);
- if (strncmp(b, "clear", 5) == 0)
- dspf->clear(o->dsp->dsp);
- else if (strncmp(b, "reset", 5) == 0)
- dspf->reset_ui(o->dsp->dsp);
- else if (strncmp(b, "init", 4) == 0)
- dspf->init(o->dsp->dsp, rate);
- respond(r, nil);
- break;
- case Xmetadata: /* FIXME should be possible to add new key/value */
- default:
- respond(r, "not implemented");
- break;
- }
-}
-
-static void
-fsdestroyfile(File *f)
-{
- Aux *a;
-
- if ((a = f->aux) == nil)
- return;
- switch (a->type) {
- case Xdsp:
- case Xui:
- freeobj(a);
- f->aux = nil;
- break;
- }
-}
-
-Srv fs = {
- .open = fsopen,
- .read = fsread,
- .write = fswrite,
-};
-
-static void
-usage(void)
-{
- print("usage: %s [-s srv] [-m mtpt] [-r rate]\n", argv0);
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- char *srv, *mtpt;
- MetaGlue mg;
-
- srv = nil;
- mtpt = nil;
- ARGBEGIN{
- case 'D':
- chatty9p++;
- break;
- case 's':
- srv = EARGF(usage());
- break;
- case 'm':
- mtpt = EARGF(usage());
- break;
- case 'r':
- rate = atoi(EARGF(usage()));
- break;
- default:
- usage();
- }ARGEND
-
- if (srv == nil && mtpt == nil)
- sysfatal("must specify -s or -m option");
-
- mg.declare = addmeta;
- dspf = class_init(rate);
- dspf->metadata(&mg);
-
- fs.tree = alloctree(nil, nil, DMDIR|0775, fsdestroyfile);
- closefile(createfile(fs.tree->root, "ctl", nil, 0666, &rootaux[Xctl]));
- closefile(createfile(fs.tree->root, "metadata", nil, 0444, &rootaux[Xmetadata]));
- closefile(createfile(fs.tree->root, "clone", nil, 0444, &rootaux[Xclone]));
- postmountsrv(&fs, srv, mtpt, MREPL);
- exits(nil);
-}
binary files /dev/null b/kick.jpg differ
binary files a/kick.png /dev/null differ
--- a/kick_drum.c
+++ /dev/null
@@ -1,363 +1,0 @@
-/* ------------------------------------------------------------
-name: "Kick Drum"
-Code generated with Faust 2.21.5 (https://faust.grame.fr)
-Compilation options: -lang c -scal -ftz 0
------------------------------------------------------------- */
-
-#ifndef __KickDrum_H__
-#define __KickDrum_H__
-
-/* KickDrum Plan 9 C architecture for Faust. */
-
-#include <u.h>
-#include <libc.h>
-#include "uiglue.h"
-
-#define max(x,y) (((x) > (y)) ? (x) : (y))
-#define min(x,y) (((x) < (y)) ? (x) : (y))
-
-#ifndef FAUSTFLOAT
-#define FAUSTFLOAT float
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <math.h>
-#include <stdlib.h>
-
-typedef struct {
- int iRec0[2];
-} KickDrumSIG0;
-
-static KickDrumSIG0* newKickDrumSIG0(void) { return (KickDrumSIG0*)calloc(1, sizeof(KickDrumSIG0)); }
-static void deleteKickDrumSIG0(KickDrumSIG0* dsp) {
- USED(dsp); free(dsp); }
-
-int getNumInputsKickDrumSIG0(KickDrumSIG0* dsp) {
- USED(dsp);
- return 0;
-}
-int getNumOutputsKickDrumSIG0(KickDrumSIG0* dsp) {
- USED(dsp);
- return 1;
-}
-int getInputRateKickDrumSIG0(KickDrumSIG0* dsp, int channel) {
- USED(dsp);
- int rate;
- switch ((channel)) {
- default: {
- rate = -1;
- break;
- }
- }
- return rate;
-}
-int getOutputRateKickDrumSIG0(KickDrumSIG0* dsp, int channel) {
- USED(dsp);
- int rate;
- switch ((channel)) {
- case 0: {
- rate = 0;
- break;
- }
- default: {
- rate = -1;
- break;
- }
- }
- return rate;
-}
-
-static void instanceInitKickDrumSIG0(KickDrumSIG0* dsp, int sample_rate) {
- USED(sample_rate);
- USED(dsp);
- /* C99 loop */
- {
- int l0;
- for (l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
- dsp->iRec0[l0] = 0;
- }
- }
-}
-
-static void fillKickDrumSIG0(KickDrumSIG0* dsp, int count, float* table) {
- USED(dsp);
- /* C99 loop */
- {
- int i;
- for (i = 0; (i < count); i = (i + 1)) {
- dsp->iRec0[0] = (dsp->iRec0[1] + 1);
- table[i] = sinf((9.58738019e-05f * (float)(dsp->iRec0[0] + -1)));
- dsp->iRec0[1] = dsp->iRec0[0];
- }
- }
-}
-
-static float ftbl0KickDrumSIG0[65536];
-
-#ifndef FAUSTCLASS
-#define FAUSTCLASS KickDrum
-#endif
-#ifdef __APPLE__
-#define exp10f __exp10f
-#define exp10 __exp10
-#endif
-
-typedef struct {
- FAUSTFLOAT fHslider0;
- FAUSTFLOAT fButton0;
- float fVec0[2];
- int fSampleRate;
- float fConst0;
- float fConst1;
- FAUSTFLOAT fHslider1;
- FAUSTFLOAT fHslider2;
- FAUSTFLOAT fCheckbox0;
- FAUSTFLOAT fHslider3;
- int iRec2[2];
- FAUSTFLOAT fHslider4;
- float fRec1[2];
- FAUSTFLOAT fHslider5;
- FAUSTFLOAT fHslider6;
-} KickDrum;
-
-KickDrum* newKickDrum(void) {
- KickDrum* dsp = (KickDrum*)calloc(1, sizeof(KickDrum));
- return dsp;
-}
-
-void deleteKickDrum(KickDrum* dsp) {
- USED(dsp);
- free(dsp);
-}
-
-void metadataKickDrum(MetaGlue* m) {
- m->declare(m->metaInterface, "basics.lib/name", "Faust Basic Element Library");
- m->declare(m->metaInterface, "basics.lib/version", "0.1");
- m->declare(m->metaInterface, "envelopes.lib/ar:author", "Yann Orlarey, Stéphane Letz");
- m->declare(m->metaInterface, "envelopes.lib/author", "GRAME");
- m->declare(m->metaInterface, "envelopes.lib/copyright", "GRAME");
- m->declare(m->metaInterface, "envelopes.lib/license", "LGPL with exception");
- m->declare(m->metaInterface, "envelopes.lib/name", "Faust Envelope Library");
- m->declare(m->metaInterface, "envelopes.lib/version", "0.0");
- m->declare(m->metaInterface, "filename", "kick_drum.dsp");
- m->declare(m->metaInterface, "group", "Synthesis");
- m->declare(m->metaInterface, "maths.lib/author", "GRAME");
- m->declare(m->metaInterface, "maths.lib/copyright", "GRAME");
- m->declare(m->metaInterface, "maths.lib/license", "LGPL with exception");
- m->declare(m->metaInterface, "maths.lib/name", "Faust Math Library");
- m->declare(m->metaInterface, "maths.lib/version", "2.1");
- m->declare(m->metaInterface, "name", "Kick Drum");
- m->declare(m->metaInterface, "oscillators.lib/name", "Faust Oscillator Library");
- m->declare(m->metaInterface, "oscillators.lib/version", "0.0");
-}
-
-int getSampleRateKickDrum(KickDrum* dsp) {
- USED(dsp);
- return dsp->fSampleRate;
-}
-
-int getNumInputsKickDrum(KickDrum* dsp) {
- USED(dsp);
- return 0;
-}
-int getNumOutputsKickDrum(KickDrum* dsp) {
- USED(dsp);
- return 1;
-}
-int getInputRateKickDrum(KickDrum* dsp, int channel) {
- USED(dsp);
- int rate;
- switch ((channel)) {
- default: {
- rate = -1;
- break;
- }
- }
- return rate;
-}
-int getOutputRateKickDrum(KickDrum* dsp, int channel) {
- USED(dsp);
- int rate;
- switch ((channel)) {
- case 0: {
- rate = 1;
- break;
- }
- default: {
- rate = -1;
- break;
- }
- }
- return rate;
-}
-
-void classInitKickDrum(int sample_rate) {
- USED(sample_rate);
- KickDrumSIG0* sig0 = newKickDrumSIG0();
- instanceInitKickDrumSIG0(sig0, sample_rate);
- fillKickDrumSIG0(sig0, 65536, ftbl0KickDrumSIG0);
- deleteKickDrumSIG0(sig0);
-}
-
-void instanceResetUserInterfaceKickDrum(KickDrum* dsp) {
- USED(dsp);
- dsp->fHslider0 = (FAUSTFLOAT)1.0f;
- dsp->fButton0 = (FAUSTFLOAT)0.0f;
- dsp->fHslider1 = (FAUSTFLOAT)100.0f;
- dsp->fHslider2 = (FAUSTFLOAT)-5.0f;
- dsp->fCheckbox0 = (FAUSTFLOAT)0.0f;
- dsp->fHslider3 = (FAUSTFLOAT)0.001f;
- dsp->fHslider4 = (FAUSTFLOAT)0.001f;
- dsp->fHslider5 = (FAUSTFLOAT)0.001f;
- dsp->fHslider6 = (FAUSTFLOAT)0.001f;
-}
-
-void instanceClearKickDrum(KickDrum* dsp) {
- USED(dsp);
- /* C99 loop */
- {
- int l1;
- for (l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
- dsp->fVec0[l1] = 0.0f;
- }
- }
- /* C99 loop */
- {
- int l2;
- for (l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
- dsp->iRec2[l2] = 0;
- }
- }
- /* C99 loop */
- {
- int l3;
- for (l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
- dsp->fRec1[l3] = 0.0f;
- }
- }
-}
-
-void instanceConstantsKickDrum(KickDrum* dsp, int sample_rate) {
- USED(sample_rate);
- USED(dsp);
- dsp->fSampleRate = sample_rate;
- dsp->fConst0 = min(192000.0f, max(1.0f, (float)dsp->fSampleRate));
- dsp->fConst1 = (1.0f / dsp->fConst0);
-}
-
-void instanceInitKickDrum(KickDrum* dsp, int sample_rate) {
- USED(sample_rate);
- USED(dsp);
- instanceConstantsKickDrum(dsp, sample_rate);
- instanceResetUserInterfaceKickDrum(dsp);
- instanceClearKickDrum(dsp);
-}
-
-void initKickDrum(KickDrum* dsp, int sample_rate) {
- USED(sample_rate);
- USED(dsp);
- classInitKickDrum(sample_rate);
- instanceInitKickDrum(dsp, sample_rate);
-}
-
-void buildUserInterfaceKickDrum(KickDrum* dsp, UIGlue* ui_interface) {
- USED(dsp);
- ui_interface->openVerticalBox(ui_interface->uiInterface, "Kick Drum");
- ui_interface->openVerticalBox(ui_interface->uiInterface, "A");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider1, "0", "");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider1, "unit", "Hz");
- ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Frequency", &dsp->fHslider1, 100.0f, 5.0f, 200.0f, 1.0f);
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider5, "1", "");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider5, "unit", "s");
- ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Attack", &dsp->fHslider5, 0.00100000005f, 9.99999975e-06f, 0.200000003f, 0.00100000005f);
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider6, "3", "");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider6, "unit", "s");
- ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Release", &dsp->fHslider6, 0.00100000005f, 9.99999975e-06f, 1.0f, 0.00100000005f);
- ui_interface->closeBox(ui_interface->uiInterface);
- ui_interface->openVerticalBox(ui_interface->uiInterface, "B");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider2, "0", "");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider2, "unit", "Hz");
- ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Frequency", &dsp->fHslider2, -5.0f, -5.0f, 200.0f, 5.0f);
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider3, "1", "");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider3, "unit", "s");
- ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Attack", &dsp->fHslider3, 0.00100000005f, 9.99999975e-06f, 0.200000003f, 0.00100000005f);
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider4, "2", "");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider4, "unit", "s");
- ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Release", &dsp->fHslider4, 0.00100000005f, 9.99999975e-06f, 1.0f, 0.00100000005f);
- ui_interface->declare(ui_interface->uiInterface, &dsp->fCheckbox0, "3", "");
- ui_interface->addCheckButton(ui_interface->uiInterface, "Enable", &dsp->fCheckbox0);
- ui_interface->closeBox(ui_interface->uiInterface);
- ui_interface->openVerticalBox(ui_interface->uiInterface, "Control");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider0, "0", "");
- ui_interface->declare(ui_interface->uiInterface, &dsp->fHslider0, "style", "knob");
- ui_interface->addHorizontalSlider(ui_interface->uiInterface, "Gain", &dsp->fHslider0, 1.0f, 0.0f, 1.0f, 0.00999999978f);
- ui_interface->declare(ui_interface->uiInterface, &dsp->fButton0, "1", "");
- ui_interface->addButton(ui_interface->uiInterface, "Gate", &dsp->fButton0);
- ui_interface->closeBox(ui_interface->uiInterface);
- ui_interface->closeBox(ui_interface->uiInterface);
-}
-
-void computeKickDrum(KickDrum* dsp, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
- USED(inputs);
- USED(dsp);
- FAUSTFLOAT* output0 = outputs[0];
- float fSlow0 = (float)dsp->fHslider0;
- float fSlow1 = (float)dsp->fButton0;
- float fSlow2 = (float)dsp->fHslider1;
- float fSlow3 = ((float)dsp->fHslider2 * (float)dsp->fCheckbox0);
- float fSlow4 = max(1.0f, (dsp->fConst0 * (float)dsp->fHslider3));
- float fSlow5 = (1.0f / fSlow4);
- float fSlow6 = (1.0f / max(1.0f, (dsp->fConst0 * (float)dsp->fHslider4)));
- float fSlow7 = max(1.0f, (dsp->fConst0 * (float)dsp->fHslider5));
- float fSlow8 = (1.0f / fSlow7);
- float fSlow9 = (1.0f / max(1.0f, (dsp->fConst0 * (float)dsp->fHslider6)));
- /* C99 loop */
- {
- int i;
- for (i = 0; (i < count); i = (i + 1)) {
- dsp->fVec0[0] = fSlow1;
- int iTemp0 = (fSlow1 > dsp->fVec0[1]);
- dsp->iRec2[0] = (iTemp0 + ((fSlow1 <= dsp->fVec0[1]) * (dsp->iRec2[1] + (dsp->iRec2[1] > 0))));
- float fTemp1 = (float)dsp->iRec2[0];
- float fTemp2 = ((dsp->fRec1[1] * (1.0f - (float)(iTemp0 > 0))) + (dsp->fConst1 * (fSlow2 + (fSlow3 * max(0.0f, min((fSlow5 * fTemp1), (1.0f - (fSlow6 * (fTemp1 - fSlow4)))))))));
- dsp->fRec1[0] = (fTemp2 - floorf(fTemp2));
- output0[i] = (FAUSTFLOAT)(fSlow0 * (ftbl0KickDrumSIG0[(int)(65536.0f * dsp->fRec1[0])] * max(0.0f, min((fSlow8 * fTemp1), ((fSlow9 * (fSlow7 - fTemp1)) + 1.0f)))));
- dsp->fVec0[1] = dsp->fVec0[0];
- dsp->iRec2[1] = dsp->iRec2[0];
- dsp->fRec1[1] = dsp->fRec1[0];
- }
- }
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#define DSP KickDrum
-
-#include "dspf.h"
-
-static DSPf dspf = {
- .new = newKickDrum,
- .init = instanceInitKickDrum,
- .delete = deleteKickDrum,
- .metadata = metadataKickDrum,
- .num_in = getNumInputsKickDrum,
- .num_out = getNumOutputsKickDrum,
- .clear = instanceClearKickDrum,
- .reset_ui = instanceResetUserInterfaceKickDrum,
- .build_ui = buildUserInterfaceKickDrum,
- .compute = computeKickDrum,
-};
-
-void *
-class_init(int rate)
-{
- classInitKickDrum(rate);
- return &dspf;
-}
-
-#endif
--- a/kick_drum.dsp
+++ /dev/null
@@ -1,16 +1,0 @@
-// Simple kick drum
-declare name "Kick Drum";
-declare group "Synthesis";
-import("stdfaust.lib");
-
-aFreq = hslider("v:A/[0]Frequency[unit:Hz]", 100, 5, 200, 1);
-aA = hslider("v:A/[1]Attack[unit:s]", 0.001, 0.00001, 0.2, 0.001);
-aR = hslider("v:A/[3]Release[unit:s]", 0.001, 0.00001, 1.0, 0.001);
-bA = hslider("v:B/[1]Attack[unit:s]", 0.001, 0.00001, 0.2, 0.001);
-bR = hslider("v:B/[2]Release[unit:s]", 0.001, 0.00001, 1, 0.001);
-bFreq = checkbox("v:B/[3]Enable") * hslider("v:B/[0]Frequency[unit:Hz]", -5, -5, 200, 5);
-
-gain = hslider("v:Control/[0]Gain[style:knob]", 1, 0, 1, 0.01);
-gate = button("v:Control/[1]Gate");
-
-process = os.hs_oscsin(aFreq + bFreq*en.ar(bA, bR, gate), gate : ba.impulsify) * gain * en.ar(aA, aR, gate);
--- a/math.h
+++ /dev/null
@@ -1,8 +1,0 @@
-#define cosf cos
-#define expf exp
-#define fabsf fabs
-#define floorf floor
-#define powf pow
-#define sinf sin
-#define sqrtf sqrt
-#define tanf tan
--- a/mkfile
+++ b/mkfile
@@ -1,20 +1,27 @@
</$objtype/mkfile
-TARG=\
- kick_drum\
+LIBS=\
+ microui\
+CMDS=\
+ dsp\
+ cfg\
+
BIN=/$objtype/bin/daw
-OFILES=\
- common.$O\
- fs.$O\
- uiglue.$O\
-default:V: all
+none:VQ:
+ echo mk all, install, clean, nuke, or libs
-CLEANFILES=\
+all install clean nuke:VQ:
+ for (i in $LIBS $CMDS) @{
+ cd $i
+ mk $target
+ }
-</sys/src/cmd/mkmany
-
-$BIN/%: $O.%
- mkdir -p $BIN
- cp $O.$stem $BIN/$stem
+libs:V:
+ for (i in $LIBS) @{
+ cd $i
+ mk clean
+ mk install
+ mk clean
+ }
--- /dev/null
+++ b/nix/faust2.nix
@@ -1,0 +1,218 @@
+{ stdenv
+, coreutils
+, cmake
+, fetchgit
+, makeWrapper
+, pkgconfig
+, llvm_9
+, openssl
+, libsndfile
+}:
+
+with stdenv.lib.strings;
+
+let
+ version = "latest";
+
+ src = fetchgit {
+ url = "https://github.com/grame-cncm/faust";
+ rev = "f16a1e4fbfacec2a00f16fa225733b8e4c758ff9";
+ sha256 = "0pj1wazlqw6jhqfj9pf6bbxvs57li8ngh0348n5p4m2gy0mg5xc2";
+ fetchSubmodules = true;
+ };
+
+ meta = with stdenv.lib; {
+ homepage = http://faust.grame.fr/;
+ downloadPage = https://sourceforge.net/projects/faudiostream/files/;
+ license = licenses.gpl2;
+ platforms = platforms.linux;
+ };
+
+ faust = stdenv.mkDerivation {
+
+ pname = "faust";
+ inherit version;
+
+ inherit src;
+
+ nativeBuildInputs = [ makeWrapper pkgconfig cmake ];
+ buildInputs = [ llvm_9 openssl libsndfile ];
+ dontUseCmakeConfigure = true;
+
+ passthru = {
+ inherit wrap wrapWithBuildEnv;
+ };
+
+ preConfigure = ''
+ makeFlags="$makeFlags DESTDIR=/ PREFIX=$out LLVM_CONFIG='${llvm_9}/bin/llvm-config' world"
+
+ # The faust makefiles use 'system ?= $(shell uname -s)' but nix
+ # defines 'system' env var, so undefine that so faust detects the
+ # correct system.
+ unset system
+ '';
+
+ # Remove most faust2appl scripts since they won't run properly
+ # without additional paths setup. See faust.wrap,
+ # faust.wrapWithBuildEnv.
+ postInstall = ''
+ # syntax error when eval'd directly
+ pattern="faust2!(*@(api|atomsnippets|graph|graphviewer|md|plot|sig|sigviewer|svg))"
+ (shopt -s extglob; rm "$out"/bin/$pattern)
+ '';
+
+ postFixup = ''
+ # Set faustpath explicitly.
+ substituteInPlace "$out"/bin/faustpath \
+ --replace "/usr/local /usr /opt /opt/local" "$out"
+
+ # The 'faustoptflags' is 'source'd into other faust scripts and
+ # not used as an executable, so patch 'uname' usage directly
+ # rather than use makeWrapper.
+ substituteInPlace "$out"/bin/faustoptflags \
+ --replace uname "${coreutils}/bin/uname"
+
+ # wrapper for scripts that don't need faust.wrap*
+ for script in "$out"/bin/faust2*; do
+ wrapProgram "$script" \
+ --prefix PATH : "$out"/bin
+ done
+ '';
+
+ meta = meta // {
+ description = "A functional programming language for realtime audio signal processing";
+ longDescription = ''
+ FAUST (Functional Audio Stream) is a functional programming
+ language specifically designed for real-time signal processing
+ and synthesis. FAUST targets high-performance signal processing
+ applications and audio plug-ins for a variety of platforms and
+ standards.
+ The Faust compiler translates DSP specifications into very
+ efficient C++ code. Thanks to the notion of architecture,
+ FAUST programs can be easily deployed on a large variety of
+ audio platforms and plugin formats (jack, alsa, ladspa, maxmsp,
+ puredata, csound, supercollider, pure, vst, coreaudio) without
+ any change to the FAUST code.
+
+ This package has just the compiler, libraries, and headers.
+ Install faust2* for specific faust2appl scripts.
+ '';
+ };
+
+ };
+
+ # Default values for faust2appl.
+ faust2ApplBase =
+ { baseName
+ , dir ? "tools/faust2appls"
+ , scripts ? [ baseName ]
+ , ...
+ }@args:
+
+ args // {
+ name = "${baseName}-${version}";
+
+ inherit src;
+
+ dontBuild = true;
+
+ installPhase = ''
+ runHook preInstall
+
+ mkdir -p "$out/bin"
+ for script in ${concatStringsSep " " scripts}; do
+ cp "${dir}/$script" "$out/bin/"
+ done
+
+ runHook postInstall
+ '';
+
+ postInstall = ''
+ # For the faust2appl script, change 'faustpath' and
+ # 'faustoptflags' to absolute paths.
+ for script in "$out"/bin/*; do
+ substituteInPlace "$script" \
+ --replace ". faustpath" ". '${faust}/bin/faustpath'" \
+ --replace ". faustoptflags" ". '${faust}/bin/faustoptflags'" \
+ --replace " error " "echo"
+ done
+ '';
+
+ meta = meta // {
+ description = "The ${baseName} script, part of faust functional programming language for realtime audio signal processing";
+ };
+ };
+
+ # Some 'faust2appl' scripts, such as faust2alsa, run faust to
+ # generate cpp code, then invoke the c++ compiler to build the code.
+ # This builder wraps these scripts in parts of the stdenv such that
+ # when the scripts are called outside any nix build, they behave as
+ # if they were running inside a nix build in terms of compilers and
+ # paths being configured (e.g. rpath is set so that compiled
+ # binaries link to the libs inside the nix store)
+ #
+ # The function takes two main args: the appl name (e.g.
+ # 'faust2alsa') and an optional list of propagatedBuildInputs. It
+ # returns a derivation that contains only the bin/${appl} script,
+ # wrapped up so that it will run as if it was inside a nix build
+ # with those build inputs.
+ #
+ # The build input 'faust' is automatically added to the
+ # propagatedBuildInputs.
+ wrapWithBuildEnv =
+ { baseName
+ , propagatedBuildInputs ? [ ]
+ , ...
+ }@args:
+
+ stdenv.mkDerivation ((faust2ApplBase args) // {
+
+ nativeBuildInputs = [ pkgconfig ];
+ buildInputs = [ makeWrapper ];
+
+ propagatedBuildInputs = [ faust ] ++ propagatedBuildInputs;
+
+
+ postFixup = ''
+
+ # export parts of the build environment
+ for script in "$out"/bin/*; do
+ wrapProgram "$script" \
+ --set FAUSTLIB "${faust}/share/faust" \
+ --set FAUST_LIB_PATH "${faust}/share/faust" \
+ --set FAUSTINC "${faust}/include/faust" \
+ --prefix PATH : "$PATH" \
+ --prefix PKG_CONFIG_PATH : "$PKG_CONFIG_PATH" \
+ --set NIX_CFLAGS_COMPILE "$NIX_CFLAGS_COMPILE" \
+ --set NIX_LDFLAGS "$NIX_LDFLAGS"
+ done
+ '';
+ });
+
+ # Builder for 'faust2appl' scripts, such as faust2firefox that
+ # simply need to be wrapped with some dependencies on PATH.
+ #
+ # The build input 'faust' is automatically added to the PATH.
+ wrap =
+ { baseName
+ , runtimeInputs ? [ ]
+ , ...
+ }@args:
+
+ let
+
+ runtimePath = concatStringsSep ":" (map (p: "${p}/bin") ([ faust ] ++ runtimeInputs));
+
+ in stdenv.mkDerivation ((faust2ApplBase args) // {
+
+ buildInputs = [ makeWrapper ];
+
+ postFixup = ''
+ for script in "$out"/bin/*; do
+ wrapProgram "$script" --prefix PATH : "${runtimePath}"
+ done
+ '';
+
+ });
+
+in faust
--- /dev/null
+++ b/nix/shell.nix
@@ -1,0 +1,9 @@
+{ pkgs ? import <nixpkgs> {} }:
+
+with pkgs; mkShell {
+ buildInputs = [
+ (callPackage ./faust2.nix {})
+ graphviz
+ gcc
+ ];
+}
--- /dev/null
+++ b/pull_subtree.sh
@@ -1,0 +1,2 @@
+#!/bin/sh
+git subtree pull --prefix microui [email protected]:ftrvxmtrx/microui.git master --squash
--- a/uiglue.c
+++ /dev/null
@@ -1,281 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <thread.h>
-#include <9p.h>
-#include "uiglue.h"
-#include "common.h"
-#include "aux.h"
-
-static struct {
- FAUSTFLOAT *zone;
- Meta *meta;
- int nummeta;
-}decl;
-
-static char *
-ui_readstr(UI *ui, int type, char *s, int sz)
-{
- char *x, *t;
- int i;
-
- if (type == Xuictl) {
- if (ui->type < 0 || ui->type >= UInum)
- sysfatal("unknown ui type %d", ui->type);
- t = uitypenames[ui->type];
- switch (ui->type) {
- case UITGroup:
- case UIHGroup:
- case UIVGroup:
- snprint(s, sz, "%s\n", t);
- return s;
- case UIButton:
- case UICheckBox:
- snprint(s, sz, "%s\t%g\n", t, *ui->zone);
- return s;
- case UIVSlider:
- case UIHSlider:
- case UINEntry:
- snprint(s, sz, "%s\t%g\t%g\t%g\t%g\t%g\n", t, *ui->zone, ui->init, ui->min, ui->max, ui->step);
- return s;
- case UIHBarGraph:
- case UIVBarGraph:
- snprint(s, sz, "%s\t%g\t%g\t%g\n", t, *ui->zone, ui->min, ui->max);
- return s;
- default:
- sysfatal("readstr not implemented for ui type %d", ui->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 type %d", type);
- }
-
- return nil;
-}
-
-static int
-ui_write(UI *ui, int type, char *s)
-{
- char *e;
- int failoor;
- float v;
-
- if (type != Xuictl)
- sysfatal("unknown ui file");
-
- /* FIXME optional argument should specify at which frame to apply the change */
-
- v = 0.0f;
- failoor = 0;
- if (strncmp(s, "reset", 5) == 0) { /* FIXME reset for a box should reset ALL controls inside it */
- v = ui->init;
- } else if (strncmp(s, "add", 3) == 0) {
- if (ui->zone != nil)
- v = *ui->zone + atof(s+3);
- } else if (strncmp(s, "sub", 3) == 0) {
- if (ui->zone != nil)
- v = *ui->zone - atof(s+3);
- } else {
- v = strtod(s, &e);
- if (*e != 0 && *e != '\n')
- return -1;
- failoor = 1;
- }
-
- if (ui->zone != nil) {
- if (ui->type == UIButton || ui->type == UICheckBox) {
- *ui->zone = v > 0 ? 1 : 0;
- } else {
- if (v < ui->min) {
- if (failoor)
- return -1;
- v = ui->min;
- } else if (v > ui->max) {
- if (failoor)
- return -1;
- v = ui->max;
- }
- *ui->zone = v;
- }
- }
-
- return 0;
-}
-
-static UI *
-newui(File *f, const char *label, int type)
-{
- Aux *a;
-
- a = calloc(1, sizeof(*a)+sizeof(UI) + sizeof(Meta)*decl.nummeta);
- a->type = Xui;
- a->ui = (UI*)(a+1);
- a->ui->type = type;
- 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->ui->zone = decl.zone;
- a->ui->label = label;
- a->ui->readstr = ui_readstr;
- a->ui->write = ui_write;
- if ((uiglue.f = createfile(f, label, nil, DMDIR|0775, a)) == nil)
- sysfatal("failed to create ui: %r");
- if ((f = createfile(uiglue.f, "ctl", nil, 0664, &a->ctl)) == nil)
- sysfatal("failed to create ui ctl: %r");
- closefile(f);
- if ((f = createfile(uiglue.f, "metadata", nil, 0664, &a->metadata)) == nil)
- sysfatal("failed to create ui metadata: %r");
- closefile(f);
- closefile(uiglue.f);
-
- free(decl.meta);
- decl.zone = nil;
- decl.meta = nil;
- decl.nummeta = 0;
-
- return a->ui;
-}
-
-static void
-ui_tgroup(void *f, const char *label)
-{
- newui(f, label, UITGroup);
-}
-
-static void
-ui_hgroup(void *f, const char *label)
-{
- newui(f, label, UIHGroup);
-}
-
-static void
-ui_vgroup(void *f, const char *label)
-{
- newui(f, label, UIVGroup);
-}
-
-static void
-ui_close_group(void *file)
-{
- File *f;
-
- f = file;
- uiglue.f = f->parent;
-}
-
-static UI *
-ui_define(File *f, int type, const char *label, FAUSTFLOAT *zone)
-{
- UI *ui;
-
- if (zone != decl.zone)
- sysfatal("zone mismatch during definition");
- ui = newui(f, label, type);
- uiglue.f = f;
-
- return ui;
-}
-
-static void
-ui_button(void *f, const char *label, FAUSTFLOAT *zone)
-{
- ui_define(f, UIButton, label, zone);
-}
-
-static void
-ui_checkbox(void *f, const char *label, FAUSTFLOAT *zone)
-{
- ui_define(f, UICheckBox, label, zone);
-}
-
-static void
-ui_vslider(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
-{
- UI *ui;
-
- ui = ui_define(f, UIVSlider, label, zone);
- ui->init = init;
- ui->min = min;
- ui->max = max;
- ui->step = step;
-}
-
-static void
-ui_hslider(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
-{
- UI *ui;
-
- ui = ui_define(f, UIHSlider, label, zone);
- ui->init = init;
- ui->min = min;
- ui->max = max;
- ui->step = step;
-}
-
-static void
-ui_nentry(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
-{
- UI *ui;
-
- ui = ui_define(f, UINEntry, label, zone);
- ui->init = init;
- ui->min = min;
- ui->max = max;
- ui->step = step;
-}
-
-static void
-ui_hbargraph(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max)
-{
- UI *ui;
-
- ui = ui_define(f, UIHBarGraph, label, zone);
- ui->min = min;
- ui->max = max;
-}
-
-static void
-ui_vbargraph(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max)
-{
- UI *ui;
-
- ui = ui_define(f, UIVBarGraph, label, zone);
- ui->min = min;
- ui->max = max;
-}
-
-static void
-ui_declare(void *f, FAUSTFLOAT *zone, const char *key, const char *value)
-{
- USED(f);
-
- 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 = {
- .openTabBox = ui_tgroup,
- .openHorizontalBox = ui_hgroup,
- .openVerticalBox = ui_vgroup,
- .closeBox = ui_close_group,
- .addButton = ui_button,
- .addCheckButton = ui_checkbox,
- .addVerticalSlider = ui_vslider,
- .addHorizontalSlider = ui_hslider,
- .addNumEntry = ui_nentry,
- .addHorizontalBargraph = ui_hbargraph,
- .addVerticalBargraph = ui_vbargraph,
- .declare = ui_declare,
-};
--- a/uiglue.h
+++ /dev/null
@@ -1,34 +1,0 @@
-#ifndef FAUSTFLOAT
-#define FAUSTFLOAT float
-#endif
-
-typedef struct UIGlue UIGlue;
-typedef struct MetaGlue MetaGlue;
-
-struct File;
-
-struct UIGlue {
- union {
- void *uiInterface;
- struct File *f;
- };
- void (*openTabBox)(void *uiInterface, const char *label);
- void (*openHorizontalBox)(void *uiInterface, const char *label);
- void (*openVerticalBox)(void *uiInterface, const char *label);
- void (*closeBox)(void *uiInterface);
- void (*addButton)(void *uiInterface, const char *label, FAUSTFLOAT *zone);
- void (*addCheckButton)(void *uiInterface, const char *label, FAUSTFLOAT *zone);
- void (*addVerticalSlider)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
- void (*addHorizontalSlider)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
- void (*addNumEntry)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step);
- void (*addHorizontalBargraph)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max);
- void (*addVerticalBargraph)(void *uiInterface, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max);
- void (*declare)(void *uiInterface, FAUSTFLOAT *zone, const char *key, const char *value);
-};
-
-struct MetaGlue {
- void *metaInterface;
- void (*declare)(void *metaInterface, const char *key, const char *value);
-};
-
-extern UIGlue uiglue;