Skip to content

Commit 590ad12

Browse files
author
Martin Klang
committed
fixed polyblep/antialiased oscillator issues
1 parent c6a8ff2 commit 590ad12

5 files changed

Lines changed: 28 additions & 26 deletions

File tree

LibSource/Oscillator.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,20 +121,21 @@ class OscillatorTemplate : public BaseOscillator {
121121
delete osc;
122122
}
123123
protected:
124+
/**
125+
* Calculate poly blep antialiasing compensation on normalised (to range [0, 1])
126+
* phase and phase increment (angular rate) values.
127+
*/
124128
static float polyblep(float t, float dt){
125129
// PolyBLEP by various
126130
// http://research.spa.aalto.fi/publications/papers/smc2010-phaseshaping/
127131
// https://www.kvraudio.com/forum/viewtopic.php?t=375517
128132
// http://www.martin-finke.de/blog/articles/audio-plugins-018-polyblep-oscillator/
129133
// https://www.metafunction.co.uk/post/all-about-digital-oscillators-part-2-blits-bleps
130-
// if t and dt are normalised before call then end/begin phase are not needed
131-
if(t < T::begin_phase + dt){
132-
dt = dt / (T::end_phase - T::begin_phase); // normalise phase increment
133-
t = (t - T::begin_phase) / dt; // distance from discontinuity
134+
if(t < dt){
135+
t /= dt;
134136
return t+t - t*t - 1;
135-
}else if(t > T::end_phase - dt){
136-
dt = dt / (T::end_phase - T::begin_phase); // normalise phase increment
137-
t = (t - T::end_phase) / dt; // distance from discontinuity
137+
}else if(t > 1 - dt){
138+
t = (t - 1) / dt;
138139
return t*t + t+t + 1;
139140
}
140141
return 0;

LibSource/RampOscillator.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ class InvertedRampOscillator : public OscillatorTemplate<InvertedRampOscillator>
3535
}
3636
};
3737

38-
class AntialisedRampOscillator : public OscillatorTemplate<AntialisedRampOscillator> {
38+
class AntialiasedRampOscillator : public OscillatorTemplate<AntialiasedRampOscillator> {
3939
public:
40-
static constexpr float begin_phase = -1;
40+
static constexpr float begin_phase = 0;
4141
static constexpr float end_phase = 1;
4242
float getSample(){
43-
return phase - polyblep(phase, incr);
43+
float sample = 2*phase-1; // naive ramp
44+
sample -= polyblep(phase, incr);
45+
return sample;
4446
}
4547
};
4648

LibSource/SquareWaveOscillator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ class AntialiasedSquareWaveOscillator : public OscillatorTemplate<AntialiasedSqu
5555
}
5656
float getSample(){
5757
float sample = phase < pw ? 1 : -1;
58-
sample += polyblep(incr, phase);
59-
sample -= polyblep(incr, fmod(phase + 1 + pw, 2));
58+
sample += polyblep(phase, incr);
59+
sample -= polyblep(fmod(phase + 1 - pw, 1), incr);
6060
return sample;
6161
}
6262
};

LibSource/TapTempo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,20 @@ class AdjustableTapTempo : public TapTempo {
115115
public:
116116
AdjustableTapTempo(float sr, size_t min, size_t max) :
117117
TapTempo(sr, min, max), speed(scale(0.5f)) {}
118+
[[deprecated("use resetSpeed() instead.")]]
119+
void resetAdjustment(uint16_t s){
120+
resetSpeed(s/4096.0f);
121+
}
118122
void resetSpeed(float s){
119123
speed = scale(s);
120124
}
121125
void setRange(float value){
122126
range = value*0.75f;
123127
}
128+
[[deprecated("use adjustSpeed() instead.")]]
129+
void adjust(uint16_t s){
130+
adjustSpeed(s/4096.0f);
131+
}
124132
/**
125133
* Adjust the tap tempo period.
126134
* @param speed should be in the range [0, 1]

LibSource/TriangleOscillator.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,17 @@ class TriangleOscillator : public OscillatorTemplate<TriangleOscillator> {
1818

1919
class AntialiasedTriangleOscillator : public OscillatorTemplate<AntialiasedTriangleOscillator> {
2020
protected:
21-
float pw = 0.5f;
2221
float previousSample = 0;
2322
public:
2423
static constexpr float begin_phase = 0;
2524
static constexpr float end_phase = 1;
26-
/**
27-
* Set pulse width to a value between 0 and 1
28-
*/
29-
void setPulseWidth(float value){
30-
pw = value;
31-
}
3225
float getSample(){
33-
float sample = phase < pw ? 1 : -1;
34-
sample += polyblep(incr, phase);
35-
sample -= polyblep(incr, fmod(phase + 1 + pw, 2));
26+
float sample = phase < 0.5f ? 1 : -1; // naive square wave
27+
sample += polyblep(phase, incr);
28+
sample -= polyblep(fmod(phase + 0.5f, 1), incr); // polyblep square wave
3629
// Leaky integrator: y[n] = A * x[n] + (1 - A) * y[n-1] = A * (x[n] - y[n-1]) + y[n-1]
37-
float lambda = incr;
38-
// float lambda = incr*2*M_PI;
39-
sample = lambda * sample + (1 - lambda) * previousSample;
40-
// sample = lambda * (sample - previousSample) + previousSample;
30+
float lambda = incr*2*M_PI;
31+
sample = lambda * (sample - previousSample) + previousSample;
4132
previousSample = sample;
4233
return sample;
4334
}

0 commit comments

Comments
 (0)