ref: 7adfd4ca6b951bcc17d3c636bb810876c159950a
parent: b00b726e8f50ce92a60909bced989177bc028c73
author: Tevo <[email protected]>
date: Sat Nov 28 13:11:18 EST 2020
WIP
--- a/demo/keyboard/main.c
+++ b/demo/keyboard/main.c
@@ -50,7 +50,7 @@
initdraw(nil, nil, "Prismsynth");
einit(Ekeyboard);
- w = waveform(sine, 1.0, 0);
+ w = unison(waveform(sine, 1.0, 0), 7, 0.5, 0.3);
while(cont)
switch(e = ekbd())
@@ -70,6 +70,7 @@
}
}
+ destroywavegen(w);
close(out);
exits(0);
}
--- a/p-wavegen.c
+++ b/p-wavegen.c
@@ -126,3 +126,49 @@
p->buf = buf;
return p;
}
+
+/** Unison **/
+
+typedef struct
+{
+ Wavegen;
+ Wavegen *gen;
+ uint voices;
+ double pitchΔ, phaseΔ;
+} Unisonprops;
+
+Stuple
+unisonfn(Wavegen *w, double freq, ulong t)
+{
+ Unisonprops *p = (Unisonprops*)w;
+ Stuple ret = (Stuple) { 0, 0 };
+ int voices = p->voices;
+ for(int c = 0; c < voices; c++)
+ {
+ Stuple r = p->gen->fn(p->gen, freq * p->pitchΔ * c, t);
+ ret.l += r.l/voices;
+ ret.r += r.r/voices;
+ }
+ return ret;
+}
+
+void
+unisoncleanup(Wavegen *w)
+{
+ Unisonprops *p = (Unisonprops*)w;
+ destroywavegen(p->gen);
+ free(p);
+}
+
+Wavegen*
+unison(Wavegen *gen, uint voices, double pitchvar, double phasevar)
+{
+ Unisonprops *p = emallocz(sizeof(*p));
+ p->fn = unisonfn;
+ p->destroy = unisoncleanup;
+ p->gen = gen;
+ p->voices = voices;
+ p->pitchΔ = pitchvar;
+ p->phaseΔ = phasevar;
+ return p;
+}
--- a/prismriver.h
+++ b/prismriver.h
@@ -1,9 +1,9 @@
#pragma lib "libprismriver.a"
-typedef short sample;
+typedef double sample;
-static const ulong SAMPLE_MAX = 32767;
-static const ulong SAMPLE_MIN = -32768;
+static const ulong SAMPLE_MAX = 1;
+static const ulong SAMPLE_MIN = -1;
static const ulong SAMPLE_RATE = 44100;
typedef struct
@@ -37,8 +37,10 @@
Buffer* buffermap(Buffer *buf, Wavegen *gen, double freq, ulong *clock, int d, ulong s, ulong sz);
-Wavegen* waveform(double (*fn)(double), double amp, double φ);
+Wavegen* waveform(double (*fn)(double), double amp, double phase);
Wavegen* pcm(Buffer *buf);
+
+Wavegen* unison(Wavegen *gen, uint voices, double pitchvar, double phasevar);
double sine(double);
double saw(double);