OpenWareLaboratory
Oscillator.h
Go to the documentation of this file.
1 #ifndef __Oscillator_h
2 #define __Oscillator_h
3 
4 #include "basicmaths.h"
5 #include "FloatArray.h"
6 #include "SignalGenerator.h"
7 
12 class Oscillator : public SignalGenerator {
13 public:
15  virtual ~Oscillator(){}
20  virtual void setSampleRate(float value){}
24  virtual void setFrequency(float value) = 0;
28  virtual float getFrequency() = 0;
33  virtual void setPhase(float phase) = 0;
38  virtual float getPhase() = 0;
42  virtual void reset() = 0;
46  virtual float generate(float fm) = 0;
50  virtual void generate(FloatArray output, FloatArray fm){
51  for(size_t i=0; i<output.getSize(); ++i)
52  output[i] = generate(fm[i]);
53  }
54  [[deprecated("use generate() instead.")]]
55  float getNextSample(){ return generate(); }
56  [[deprecated("use generate() instead.")]]
57  float getNextSample(float fm){ return generate(fm); }
58  [[deprecated("use generate() instead.")]]
59  void getSamples(FloatArray output){
60  generate(output);
61  }
62  [[deprecated("use generate() instead.")]]
63  void getSamples(FloatArray output, FloatArray fm){
64  generate(output, fm);
65  }
66 };
67 
68 template<class T, class BaseOscillator=Oscillator, typename Sample=float>
69 class OscillatorTemplate : public BaseOscillator {
70 protected:
71  float mul = 1; // Prevent having NaN as default getFrequency result
72  float phase = 0;
73  float incr = 0;
74 public:
75  void setSampleRate(float sr){
76  float freq = getFrequency();
77  mul = (T::end_phase - T::begin_phase)/sr;
78  setFrequency(freq);
79  }
80  float getSampleRate(){
81  return (T::end_phase - T::begin_phase)/mul;
82  }
83  void setFrequency(float freq){
84  incr = freq*mul;
85  }
86  float getFrequency(){
87  return incr/mul;
88  }
89  void setPhase(float ph){
90  phase = (T::end_phase - T::begin_phase)*ph/(2*M_PI) + T::begin_phase;
91  }
92  float getPhase(){
93  // return phase 0 to 2*pi
94  return (phase - T::begin_phase)*2*M_PI/(T::end_phase - T::begin_phase);
95  }
96  void reset(){
97  phase = T::begin_phase;
98  }
99  Sample generate() {
100  Sample sample = static_cast<T*>(this)->getSample();
101  phase += incr;
102  if(phase >= T::end_phase)
103  phase -= (T::end_phase - T::begin_phase);
104  return sample;
105  }
106  Sample generate(float fm) {
107  Sample sample = static_cast<T*>(this)->getSample();
108  // phase += incr * (1 + fm);
109  phase += incr + (T::end_phase - T::begin_phase)*fm;
110  if(phase >= T::end_phase)
111  phase -= (T::end_phase - T::begin_phase);
112  return sample;
113  }
114  using BaseOscillator::generate;
115  static T* create(float sr){
116  T* obj = new T();
117  obj->setSampleRate(sr);
118  return obj;
119  }
120  static void destroy(T* osc){
121  delete osc;
122  }
123 protected:
128  static float polyblep(float t, float dt){
129  // PolyBLEP by various
130  // http://research.spa.aalto.fi/publications/papers/smc2010-phaseshaping/
131  // https://www.kvraudio.com/forum/viewtopic.php?t=375517
132  // http://www.martin-finke.de/blog/articles/audio-plugins-018-polyblep-oscillator/
133  // https://www.metafunction.co.uk/post/all-about-digital-oscillators-part-2-blits-bleps
134  if(t < dt){
135  t /= dt;
136  return t+t - t*t - 1;
137  }else if(t + dt > 1){
138  t = (t - 1) / dt;
139  return t*t + t+t + 1;
140  }
141  return 0;
142  }
143 };
144 
145 template<class Osc>
146 class PhaseShiftOscillator : public Osc {
147 protected:
148  float phaseshift;
149 public:
150  template <typename... Args>
151  PhaseShiftOscillator(float phaseshift, Args&&... args) :
152  Osc(std::forward<Args>(args)...), phaseshift(phaseshift) {}
153  void setPhase(float phase){
154  Osc::setPhase(phase + phaseshift);
155  }
156  float getPhase(){
157  return Osc::getPhase() - phaseshift;
158  }
159  void reset(){
160  Osc::setPhase(phaseshift);
161  }
165  template <typename... Args>
166  static PhaseShiftOscillator<Osc>* create(float phaseshift, Args&&... args){
167  return new PhaseShiftOscillator<Osc>(phaseshift, std::forward<Args>(args)...);
168  }
170  Osc::destroy(obj);
171  }
172 };
173 
174 #endif /* __Oscillator_h */
#define M_PI
Definition: basicmaths.h:52
This class contains useful methods for manipulating arrays of floats.
Definition: FloatArray.h:12
void setFrequency(float freq)
Set oscillator frequency in Hertz.
Definition: Oscillator.h:83
static float polyblep(float t, float dt)
Calculate poly blep antialiasing compensation on normalised (to range [0, 1]) phase and phase increme...
Definition: Oscillator.h:128
Sample generate(float fm)
Produce a sample with frequency modulation.
Definition: Oscillator.h:106
void setPhase(float ph)
Set current oscillator phase in radians.
Definition: Oscillator.h:89
float getFrequency()
Get oscillator frequency in Hertz.
Definition: Oscillator.h:86
void reset()
Reset oscillator (typically resets phase)
Definition: Oscillator.h:96
static T * create(float sr)
Definition: Oscillator.h:115
void setSampleRate(float sr)
Set oscillator sample rate.
Definition: Oscillator.h:75
float getPhase()
Get current oscillator phase in radians.
Definition: Oscillator.h:92
static void destroy(T *osc)
Definition: Oscillator.h:120
float getSampleRate()
Definition: Oscillator.h:80
Sample generate()
Produce the next consecutive sample.
Definition: Oscillator.h:99
An Oscillator is a SignalGenerator that operates at a given frequency and that can be frequency modul...
Definition: Oscillator.h:12
virtual void reset()=0
Reset oscillator (typically resets phase)
void getSamples(FloatArray output, FloatArray fm)
Definition: Oscillator.h:63
virtual float getFrequency()=0
Get oscillator frequency in Hertz.
virtual ~Oscillator()
Definition: Oscillator.h:15
virtual void generate(FloatArray output, FloatArray fm)
Produce a block of samples with frequency modulation.
Definition: Oscillator.h:50
virtual float generate(float fm)=0
Produce a sample with frequency modulation.
virtual void setPhase(float phase)=0
Set current oscillator phase in radians.
float getNextSample(float fm)
Definition: Oscillator.h:57
float getNextSample()
Definition: Oscillator.h:55
void getSamples(FloatArray output)
Definition: Oscillator.h:59
virtual void setFrequency(float value)=0
Set oscillator frequency in Hertz.
virtual float generate()
Produce the next consecutive sample.
virtual void setSampleRate(float value)
Set oscillator sample rate.
Definition: Oscillator.h:20
virtual float getPhase()=0
Get current oscillator phase in radians.
void setPhase(float phase)
Definition: Oscillator.h:153
PhaseShiftOscillator(float phaseshift, Args &&... args)
Definition: Oscillator.h:151
static PhaseShiftOscillator< Osc > * create(float phaseshift, Args &&... args)
Definition: Oscillator.h:166
static void destroy(PhaseShiftOscillator< Osc > *obj)
Definition: Oscillator.h:169
Base class for signal generators such as Oscillators.
virtual float generate()
Produce the next consecutive sample.
size_t getSize() const
Definition: SimpleArray.h:31