-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathWaveSawtooth.cpp
More file actions
66 lines (57 loc) · 1.69 KB
/
WaveSawtooth.cpp
File metadata and controls
66 lines (57 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
MINI VIRTUAL ANALOG SYNTHESIZER
Copyright 2014 Kenneth D. Miller III
Sawtooth Wave
*/
#include "StdAfx.h"
#include "Wave.h"
#include "Oscillator.h"
#include "PolyBLEP.h"
#include "Math.h"
// sawtooth wave
// - 2/pi sum k=1..infinity sin(k*2*pi*phase)/n
// - smoothed transition to reduce aliasing
static __forceinline float GetSawtoothValue(float const phase)
{
return 1 - phase - phase;
}
float OscillatorSawtooth(OscillatorConfig const &config, OscillatorState &state, float step)
{
if (step > 0.5f)
return 0.0f;
float phase = state.phase;
float value = GetSawtoothValue(phase);
#if ANTIALIAS == ANTIALIAS_POLYBLEP
if (use_antialias)
{
float const w = Min(step * POLYBLEP_WIDTH, 0.5f);
// up edge nearest the current phase
float up_nearest = float(phase >= 0.5f);
if (config.sync_enable)
{
int const index = state.index;
phase += index;
up_nearest += index;
float const sync_fraction = config.sync_phase - float(FloorInt(config.sync_phase));
// handle last integer phase before sync from the previous wave cycle
float const up_before_zero = -sync_fraction;
value += PolyBLEP(phase - up_before_zero, w);
// handle discontinuity at integer phases
if (up_nearest > 0 && up_nearest <= config.sync_phase)
value += PolyBLEP(phase - up_nearest, w);
// handle discontituity at sync phase
float const sync_value = GetSawtoothValue(sync_fraction);
if (sync_value < 0.999969482421875f)
{
value += PolyBLEP(phase, w, 1 - sync_value);
value += PolyBLEP(phase - config.sync_phase, w, 1 - sync_value);
}
}
else
{
value += PolyBLEP(phase - up_nearest, w);
}
}
#endif
return value;
}