ref: beb274816e4ac1c0910e8c7297f2a38c29f8fe37
parent: 72ed94b46fa454fce4edfc2396cb0becee5bdb00
author: Tevo <[email protected]>
date: Sun Aug 30 21:26:16 EDT 2020
Frequency as a generation time argument, PCM-backed generator The PCM-backed generator is currently untested
--- a/p-pcm.c
+++ b/p-pcm.c
@@ -12,7 +12,7 @@
*/
Buffer *b = emallocz(sizeof(Buffer));
b->size = s;
- b->data = emallocz(s * sizeof(STuple));
+ b->data = emallocz(s * sizeof(Stuple));
return b;
}
@@ -19,7 +19,7 @@
Buffer*
resizebuffer(Buffer *b, ulong ns)
{
- b->data = erealloc(b->data, ns * sizeof(STuple));
+ b->data = erealloc(b->data, ns * sizeof(Stuple));
b->size = ns;
return b;
}
@@ -34,5 +34,5 @@
void
play(Buffer *b, int fd)
{
- write(fd, b->data, b->size * sizeof(STuple));
+ write(fd, b->data, b->size * sizeof(Stuple));
}
--- a/p-wavegen.c
+++ b/p-wavegen.c
@@ -11,17 +11,20 @@
}
Buffer*
-buffermap(Buffer *buf, Wavegen *gen, int d, ulong s, ulong sz)
+buffermap(Buffer *buf, Wavegen *gen, double freq, ulong *pc, int d, ulong s, ulong sz)
{
if(buf == nil)
buf = createbuffer(s + sz);
for(ulong c = s; c < sz; c++)
- buf->data[c] = gen->fn(gen, c);
+ buf->data[c] = gen->fn(gen, freq, c + (pc == nil ? 0 : *pc));
if(d)
destroywavegen(gen);
+ if(pc != nil)
+ *pc += sz;
+
return buf;
}
@@ -31,16 +34,16 @@
{
Wavegen;
double (*wavefn)(double);
- double amp, freq, phase;
+ double amp, phase;
} Waveprops;
-STuple
-waveformfn(Wavegen *w, ulong t)
+Stuple
+waveformfn(Wavegen *w, double freq, ulong t)
{
Waveprops *p = (Waveprops*)w;
- double v = p->amp * p->wavefn(s2d(t) * p->freq + p->phase);
+ double v = p->amp * p->wavefn(s2d(t) * freq + p->phase);
sample val = truncate(v);
- return (STuple)
+ return (Stuple)
{
val, val
};
@@ -47,7 +50,7 @@
}
Wavegen*
-waveform(double (*fn)(double), double amp, double freq, double φ)
+waveform(double (*fn)(double), double amp, double φ)
{
Waveprops *p = emallocz(sizeof(Waveprops));
p->fn = waveformfn;
@@ -54,7 +57,6 @@
p->destroy = (void(*)(Wavegen*))free;
p->wavefn = fn;
p->amp = amp;
- p->freq = freq;
p->phase = φ;
return p;
}
@@ -87,4 +89,40 @@
triangle(double num)
{
return 2 * fabs(saw(num)) - 1;
+}
+
+/** PCM-backed wave "generators" **/
+
+typedef struct
+{
+ Wavegen;
+ Buffer *buf;
+} Pcmprops;
+
+Stuple
+pcmfn(Wavegen *w, double freq, ulong t)
+{
+ (void)freq;
+ Pcmprops *p = (Pcmprops*)w;
+ if(t < p->buf->size)
+ return p->buf->data[t];
+ return (Stuple) { 0, 0 };
+}
+
+void
+pcmdestroy(Wavegen *w)
+{
+ Pcmprops *p = (Pcmprops*)w;
+ destroybuffer(p->buf);
+ free(p);
+}
+
+Wavegen*
+pcm(Buffer *buf)
+{
+ Pcmprops *p = emallocz(sizeof(*p));
+ p->fn = pcmfn;
+ p->destroy = pcmdestroy;
+ p->buf = buf;
+ return p;
}
--- a/prismriver.h
+++ b/prismriver.h
@@ -9,7 +9,7 @@
typedef struct
{
sample l, r;
-} STuple;
+} Stuple;
/** PCM API **/
@@ -16,7 +16,7 @@
typedef struct
{
ulong size;
- STuple *data;
+ Stuple *data;
} Buffer;
Buffer* createbuffer(ulong size);
@@ -29,15 +29,16 @@
typedef struct Wavegen
{
- STuple (*fn)(struct Wavegen*, ulong);
+ Stuple (*fn)(struct Wavegen*, double, ulong);
void (*destroy)(struct Wavegen*);
} Wavegen;
void destroywavegen(Wavegen *gen);
-Buffer* buffermap(Buffer *buf, Wavegen *gen, int d, ulong s, ulong sz);
+Buffer* buffermap(Buffer *buf, Wavegen *gen, double freq, ulong *clock, int d, ulong s, ulong sz);
-Wavegen* waveform(double (*fn)(double), double amp, double freq, double φ);
+Wavegen* waveform(double (*fn)(double), double amp, double φ);
+Wavegen* pcm(Buffer *buf);
double sine(double);
double saw(double);