Skip to content

Commit 0e4402e

Browse files
committed
Some more docs and quadrature oscillator with complex feedback
1 parent 4719232 commit 0e4402e

3 files changed

Lines changed: 72 additions & 12 deletions

File tree

LibSource/ComplexOscillator.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ class ComplexOscillator : public ComplexSignalGenerator {
4545
/**
4646
* Produce a sample with frequency modulation.
4747
*/
48-
virtual ComplexFloat generate() {
49-
return generate(0.f);
50-
}
5148
virtual ComplexFloat generate(float fm) = 0;
52-
virtual void generate(ComplexFloatArray output) {
53-
for(size_t i=0; i<output.getSize(); ++i) {
54-
output[i]= generate();
55-
}
49+
/**
50+
* Produce a block of samples with frequency modulation.
51+
*/
52+
virtual void generate(ComplexFloatArray output, FloatArray fm){
53+
for(size_t i=0; i<output.getSize(); ++i)
54+
output[i] = generate(fm[i]);
5655
}
56+
5757
};
5858

5959
template<typename OscillatorClass>

LibSource/QuadratureSineOscillator.h

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
#include "ComplexOscillator.h"
55

6+
/**
7+
* Oscillator outputs complex numbers on unit cycle. This means that axis are
8+
* 90 degrees out of phase at any point of time and oscillator's magnitude is
9+
* always equal to 1.0
10+
**/
611
class QuadratureSineOscillator : public ComplexOscillatorTemplate<QuadratureSineOscillator> {
712
public:
813
static constexpr float begin_phase = 0;
@@ -19,7 +24,7 @@ class QuadratureSineOscillator : public ComplexOscillatorTemplate<QuadratureSine
1924
}
2025
phase = fmodf(phase, end_phase);
2126
}
22-
void generate(ComplexFloatArray output, FloatArray fm) {
27+
void generate(ComplexFloatArray output, FloatArray fm) override {
2328
size_t len = output.getSize();
2429
for (size_t i = 0; i < len; ++i) {
2530
output[i].re = cosf(phase);
@@ -32,13 +37,21 @@ class QuadratureSineOscillator : public ComplexOscillatorTemplate<QuadratureSine
3237
using ComplexOscillatorTemplate<QuadratureSineOscillator>::generate;
3338
};
3439

40+
/**
41+
* An oscillator similar to QuadratureSineOscillator class that also includes
42+
* feedback control. Feedback value is a scalar value, meaning that both real and
43+
* imaginary axis get the same amount of feeback
44+
**/
3545
class FeedbackQuadratureSineOscillator : public ComplexOscillatorTemplate<FeedbackQuadratureSineOscillator> {
3646
public:
3747
static constexpr float begin_phase = 0;
3848
static constexpr float end_phase = 2 * M_PI;
3949
void setFeedback(float feedback) {
4050
this->feedback = feedback;
4151
}
52+
float getFeedback() const {
53+
return feedback;
54+
}
4255
ComplexFloat getSample() {
4356
last_sample = ComplexFloat(
4457
cosf(phase + last_sample.re * feedback), sinf(phase + last_sample.im * feedback));
@@ -54,7 +67,7 @@ class FeedbackQuadratureSineOscillator : public ComplexOscillatorTemplate<Feedba
5467
}
5568
phase = fmodf(phase, end_phase);
5669
}
57-
void generate(ComplexFloatArray output, FloatArray fm) {
70+
void generate(ComplexFloatArray output, FloatArray fm) override {
5871
size_t len = output.getSize();
5972
for (size_t i = 0; i < len; ++i) {
6073
output[i].re = cosf(phase + last_sample.re * feedback);
@@ -71,4 +84,52 @@ class FeedbackQuadratureSineOscillator : public ComplexOscillatorTemplate<Feedba
7184
ComplexFloat last_sample = 0;
7285
};
7386

87+
88+
/**
89+
* An oscillator similar to QuadratureSineOscillator class that also includes
90+
* feedback control. Feedback value is a complex number, this allows controlling
91+
* feedback direction.
92+
**/
93+
class ComplexFeedbackQuadratureSineOscillator : public ComplexOscillatorTemplate<ComplexFeedbackQuadratureSineOscillator> {
94+
public:
95+
static constexpr float begin_phase = 0;
96+
static constexpr float end_phase = 2 * M_PI;
97+
void setFeedback(ComplexFloat feedback) {
98+
this->feedback = feedback;
99+
}
100+
ComplexFloat getFeedback() const {
101+
return feedback;
102+
}
103+
ComplexFloat getSample() {
104+
last_sample = ComplexFloat(
105+
cosf(phase + last_sample.re * feedback.re), sinf(phase + last_sample.im * feedback.im));
106+
return last_sample;
107+
}
108+
void generate(ComplexFloatArray output) override {
109+
size_t len = output.getSize();
110+
for (size_t i = 0; i < len; ++i) {
111+
output[i].re = cosf(phase + last_sample.re * feedback.re);
112+
output[i].im = sinf(phase + last_sample.im * feedback.im);
113+
last_sample = output[i];
114+
phase += incr; // allow phase to overrun
115+
}
116+
phase = fmodf(phase, end_phase);
117+
}
118+
void generate(ComplexFloatArray output, FloatArray fm) override {
119+
size_t len = output.getSize();
120+
for (size_t i = 0; i < len; ++i) {
121+
output[i].re = cosf(phase + last_sample.re * feedback.re);
122+
output[i].im = sinf(phase + last_sample.im * feedback.im);
123+
last_sample = output[i];
124+
phase += incr * (1 + fm[i]);
125+
// allow phase to overrun
126+
}
127+
phase = fmodf(phase, end_phase);
128+
}
129+
using ComplexOscillatorTemplate<ComplexFeedbackQuadratureSineOscillator>::generate;
130+
protected:
131+
ComplexFloat feedback = 0;
132+
ComplexFloat last_sample = 0;
133+
};
134+
74135
#endif /* QUADRATURE_SINE_OSCILLATOR_H */

LibSource/SignalGenerator.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ class MultiSignalGenerator {
3636

3737
/**
3838
* Base class for stereo signal generators such as Oscillators.
39-
* A ComplexSignalGenerator produces complex numbers with parts
40-
* in [-1..1] range unless
41-
* otherwise stated.
39+
* A ComplexSignalGenerator produces complex numbers with each channel
40+
* containing samples in [-1..1] range unless otherwise stated.
4241
*/
4342
class ComplexSignalGenerator {
4443
public:

0 commit comments

Comments
 (0)