shithub: prismriver

Download patch

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);