mystran polyblep

This commit is contained in:
Gordon JC Pearce 2024-09-06 21:44:41 +01:00
parent f527691deb
commit e3add1d306
2 changed files with 75 additions and 16 deletions

View File

@ -19,6 +19,7 @@
#include "voice.hpp"
#include <math.h>
#include <cstdio>
static float blep(float p, float theta) {
@ -26,18 +27,18 @@ static float blep(float p, float theta) {
// low (late) side of step
if (p < theta) {
//printf("phase < theta, %f %f\n", p, theta);
printf("phase < theta, %f %f\n", p, theta);
t = p / theta;
return (2 * t) - (t * t) - 1;
}
// high (early) side of step
if (p > (1 - theta)) {
//printf("phase > 1-theta %f %f \n", p, theta);
printf("phase > 1-theta %f %f \n", p, theta);
t = (p - 1) / theta;
return (2 * t) + (t * t) + 1;
}
//printf("no action\n");
// printf("no action\n");
return 0;
}
@ -53,7 +54,6 @@ void Voice::on(uint32_t key, bool reset = 0) {
omega = (261.63 * powf(2, (note - 60) / 12.0f)) / 48000.0f;
target = 1;
env = 1;
}
void Voice::off() {
@ -76,20 +76,78 @@ void Voice::gate() {
}
*/
env = ((target - env) * 0.005f) + env;
if (env < 0.001) env = 0;
}
static inline float poly3blep0(float t) {
// these are just sanity checks
// correct code doesn't need them
if (t < 0) return 0;
if (t > 1) return 1;
float t2 = t * t;
return t * t2 - 0.5f * t2 * t2;
}
// And second sample as wrapper, optimize if you want.
static inline float poly3blep1(float t) {
return -poly3blep0(1 - t);
}
void Voice::run(Synth &s, float *buffer, uint32_t samples) {
float y, offset, pw = 0;
float y, out, pw = 0, t;
s.p.sqr = 1;
s.p.saw = 1;
float mix = 1;
for (uint32_t i = 0; i < samples; i++) {
#if 1
y = delay;
delay = 0;
phase += omega;
float pulseWidth = 0.5; // pwm[i];
// if(pulseWidth > 1) pulseWidth = 1;
// if(pulseWidth < 0) pulseWidth = 0;
while (true) {
if (pulseStage == 0) {
if (phase < pulseWidth) break;
#if 1
float t = (phase - pulseWidth) / omega;
#else
float t = (phase - pulseWidth) / (widthDelay - pulseWidth + freq);
#endif
y += mix * poly3blep0(t);
delay += mix * poly3blep1(t);
pulseStage = 1;
}
if (pulseStage == 1) {
if (phase < 1) break;
float t = (phase - 1) / omega;
y -= poly3blep0(t);
delay -= poly3blep1(t);
pulseStage = 0;
phase -= 1;
subosc = (1-subosc);
}
}
delay += (1 - mix) * phase + mix * (pulseStage ? 1.f : 0.f);
delay += subosc;
out = (2 * y) - 1;
// widthDelay = pulseWidth;
#else
// sawtooth
y = 1 - (2 * phase);
// y += blep(phase, omega);
y += blep(phase, omega);
// need this if either saw or square is on;
y *= (s.p.saw + s.p.sqr);
@ -103,7 +161,7 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
if (offset > 1) offset -= 1;
y -= (1 - (2 * offset)) * s.p.sqr;
// y -= blep(offset, omega) * s.p.sqr;
y -= blep(offset, omega) * s.p.sqr;
// s.lastpw = pw_rc;
phase += omega;
@ -111,9 +169,7 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
// printf("step\n");
phase -= 1;
}
buffer[i] += (0.125 * y * env);
#endif
buffer[i] += (0.25 * out * env);
}
}

View File

@ -51,8 +51,11 @@ class Voice {
K_ON,
K_SUSTAIN } keyState = K_OFF;
float phase = 0, omega = 260 / 48000.0;
float phase = 0, omega = 260 / 48000.0, subosc = 0;
float env, target;
float delay;
uint8_t pulseStage = 0;
float pw_rc = 0;
};