-
Notifications
You must be signed in to change notification settings - Fork 1
/
Oscillators.h
189 lines (168 loc) · 5.37 KB
/
Oscillators.h
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#ifndef OSCILLATORS_H
#define OSCILLATORS_H
#include <cmath> // for sin(), powf()
#include <JuceHeader.h> // for jassert()
/// Base phasor class.
/// A class is used as a base for building different oscillator forms.
/// A class method process() processes phase value to output oscillator sample
/// at that time. This method accounts for phase offset, amplitude, direct current
/// and power which are specified using setter functions.
class Phasor
{
public:
/// update the phase and output the next sample from the oscillator
/// @return float, oscillator sample (with applied phase offset, amplitude,
/// direct current and power which are specified using setter functions)
float process()
{
phase += phaseDelta;
if (phase > 1.0f)
phase -= 1.0f;
return (amplitude + amplitudeOffset) * powf (output (phase + phaseOffset), power) + dc;
}
/// placeholder function to specify output of an oscillator
/// @param float, phase
/// @return float, raw oscillator sample
virtual float output (float p)
{
return p;
}
/// set sample rate
/// @param float, sample rate in Hz
void setSampleRate (float _sampleRate)
{
jassert (_sampleRate > 0.0f); // check sample rate value
sampleRate = _sampleRate;
}
/// set oscillator frequency
/// @param float, frequency value in Hz
void setFrequency (float _frequency)
{
jassert (sampleRate > 0.0f); // check if sample rate is set (the default value on initialization is 0)
if (fabs(_frequency) >= 0.5f * sampleRate)
frequency = 0.5f * sampleRate;
else
frequency = fabs(_frequency);
phaseDelta = frequency / sampleRate;
}
/// set phase offset (useful for phase modulation)
/// @param float, phase offset
void setPhaseOffset (float _phaseOffset)
{
phaseOffset = _phaseOffset;
}
/// set amplitude (useful for amplitude modulation and LFOs)
/// @param float, amplitude
void setAmplitude (float _amplitude)
{
amplitude = _amplitude;
}
/// set amplitude offset (useful for LFOs)
/// @param float, amplitude offset
void setAmplitudeOffset (float _amplitudeOffset)
{
amplitudeOffset = _amplitudeOffset;
}
/// set direct current (useful for LFOs)
/// @param float, phase offset
void setDC (float _dc)
{
dc = _dc;
}
/// set power value for oscillator output (useful for amplitude modulation and LFOs)
/// @param float, power (assumed to be positive)
void setPower (float _power)
{
_power = std::round (_power); // fractional powers are excluded
jassert (_power >= 1.0f); // negative values excluded so we don't have division by zero; for zero value we have no oscillation
power = _power;
}
/// set oscillator phase (useful to reset phase)
/// @param float, phase (from 0 to 1)
void setPhase (float _phase)
{
phase = _phase;
}
/// get oscillator current phase
/// @return float, phase
float getPhase()
{
return phase;
}
private:
// base parameters
float frequency = 0.0f; // frequency [Hz]
float sampleRate = 0.0f; // sample rate [Hz]
float phase = 0.0f; // phase
float phaseDelta = 0.0f; // phase delta
float amplitude = 1.0f; // amplitude
// modulation parameters
float phaseOffset = 0.0f; // phase offset
float amplitudeOffset = 0.0f; // amplitude offset
float dc = 0.0f; // direct current
float power = 1.0f; // power
};
/// Triangle oscillator which has zero amplitude points at phase = 0, 0.5, 1.
class TriOsc : public Phasor
{
public:
/// get triangle oscillator output
/// @param float, phase
/// @return float, triangle oscillator output in range [-1,1]
float output(float p) override
{
// the following function is used: 1 - 4*abs(1/2 - frac(1/2*p+1/4))
// the reason for this form is that the waveshape has zero amplitude points
// at p = 0, 1/2, 1 (the same as in sine oscillator)
float frac = (0.5f * p + 0.25f - (int)(0.5f * p + 0.25f));
return 1.0f - 4.0f * fabsf(0.5f - frac);
}
};
/// Sine oscillator
class SinOsc : public Phasor
{
public:
/// get sine oscillator output
/// @param float, phase
/// @return float, sine oscillator output in range [-1,1]
float output(float p) override
{
return sin(p * 2 * 3.1415926535897932384626433832795f);
}
};
/// Square oscillator
class SqrOsc : public Phasor
{
public:
/// get square oscillator output
/// @param float, phase
/// @return float, square oscillator output in range [-1,1]
float output(float p) override
{
float outVal = 1.0f;
if (p > pulseWidth)
outVal = -1.0f;
return outVal;
}
/// set square wave pulse width
/// @param float, pulse width in range [0,1]
void setPulseWidth(float _pulseWidth)
{
pulseWidth = _pulseWidth;
}
private:
float pulseWidth = 0.5f;
};
/// Saw oscillator
class SawOsc : public Phasor
{
public:
/// get saw oscillator output
/// @param float, phase
/// @return float, saw oscillator output in range [-1,1]
float output(float p) override
{
return 2.0f * p - 1.0f;
}
};
#endif // OSCILLATORS_H