mystran polyblep
This commit is contained in:
parent
f527691deb
commit
e3add1d306
@ -19,6 +19,7 @@
|
|||||||
#include "voice.hpp"
|
#include "voice.hpp"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
static float blep(float p, float theta) {
|
static float blep(float p, float theta) {
|
||||||
@ -26,18 +27,18 @@ static float blep(float p, float theta) {
|
|||||||
|
|
||||||
// low (late) side of step
|
// low (late) side of step
|
||||||
if (p < theta) {
|
if (p < theta) {
|
||||||
//printf("phase < theta, %f %f\n", p, theta);
|
printf("phase < theta, %f %f\n", p, theta);
|
||||||
t = p / theta;
|
t = p / theta;
|
||||||
return (2 * t) - (t * t) - 1;
|
return (2 * t) - (t * t) - 1;
|
||||||
}
|
}
|
||||||
// high (early) side of step
|
// high (early) side of step
|
||||||
if (p > (1 - theta)) {
|
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;
|
t = (p - 1) / theta;
|
||||||
return (2 * t) + (t * t) + 1;
|
return (2 * t) + (t * t) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("no action\n");
|
// printf("no action\n");
|
||||||
return 0;
|
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;
|
omega = (261.63 * powf(2, (note - 60) / 12.0f)) / 48000.0f;
|
||||||
target = 1;
|
target = 1;
|
||||||
env = 1;
|
env = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::off() {
|
void Voice::off() {
|
||||||
@ -76,20 +76,78 @@ void Voice::gate() {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
env = ((target - env) * 0.005f) + env;
|
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) {
|
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.sqr = 1;
|
||||||
s.p.saw = 1;
|
s.p.saw = 1;
|
||||||
|
|
||||||
|
float mix = 1;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < samples; i++) {
|
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
|
// sawtooth
|
||||||
|
|
||||||
y = 1 - (2 * phase);
|
y = 1 - (2 * phase);
|
||||||
// y += blep(phase, omega);
|
y += blep(phase, omega);
|
||||||
|
|
||||||
// need this if either saw or square is on;
|
// need this if either saw or square is on;
|
||||||
y *= (s.p.saw + s.p.sqr);
|
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;
|
if (offset > 1) offset -= 1;
|
||||||
|
|
||||||
y -= (1 - (2 * offset)) * s.p.sqr;
|
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;
|
// s.lastpw = pw_rc;
|
||||||
|
|
||||||
phase += omega;
|
phase += omega;
|
||||||
@ -111,9 +169,7 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
|
|||||||
// printf("step\n");
|
// printf("step\n");
|
||||||
phase -= 1;
|
phase -= 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
buffer[i] += (0.125 * y * env);
|
buffer[i] += (0.25 * out * env);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,11 @@ class Voice {
|
|||||||
K_ON,
|
K_ON,
|
||||||
K_SUSTAIN } keyState = K_OFF;
|
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 env, target;
|
||||||
|
float delay;
|
||||||
|
uint8_t pulseStage = 0;
|
||||||
|
|
||||||
|
|
||||||
float pw_rc = 0;
|
float pw_rc = 0;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user