You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
2.8 KiB
113 lines
2.8 KiB
#pragma once
|
|
#ifndef DSY_OSCILLATOR_H
|
|
#define DSY_OSCILLATOR_H
|
|
#include <stdint.h>
|
|
#include "Utility/dsp.h"
|
|
#ifdef __cplusplus
|
|
|
|
namespace daisysp
|
|
{
|
|
/** Synthesis of several waveforms, including polyBLEP bandlimited waveforms.
|
|
*/
|
|
class Oscillator
|
|
{
|
|
public:
|
|
Oscillator() {}
|
|
~Oscillator() {}
|
|
/** Choices for output waveforms, POLYBLEP are appropriately labeled. Others are naive forms.
|
|
*/
|
|
enum
|
|
{
|
|
WAVE_SIN,
|
|
WAVE_TRI,
|
|
WAVE_SAW,
|
|
WAVE_RAMP,
|
|
WAVE_SQUARE,
|
|
WAVE_POLYBLEP_TRI,
|
|
WAVE_POLYBLEP_SAW,
|
|
WAVE_POLYBLEP_SQUARE,
|
|
WAVE_LAST,
|
|
};
|
|
|
|
|
|
/** Initializes the Oscillator
|
|
|
|
\param sample_rate - sample rate of the audio engine being run, and the frequency that the Process function will be called.
|
|
|
|
Defaults:
|
|
- freq_ = 100 Hz
|
|
- amp_ = 0.5
|
|
- waveform_ = sine wave.
|
|
*/
|
|
void Init(float sample_rate)
|
|
{
|
|
sr_ = sample_rate;
|
|
sr_recip_ = 1.0f / sample_rate;
|
|
freq_ = 100.0f;
|
|
amp_ = 0.5f;
|
|
phase_ = 0.0f;
|
|
phase_inc_ = CalcPhaseInc(freq_);
|
|
waveform_ = WAVE_SIN;
|
|
eoc_ = true;
|
|
eor_ = true;
|
|
}
|
|
|
|
|
|
/** Changes the frequency of the Oscillator, and recalculates phase increment.
|
|
*/
|
|
inline void SetFreq(const float f)
|
|
{
|
|
freq_ = f;
|
|
phase_inc_ = CalcPhaseInc(f);
|
|
}
|
|
|
|
|
|
/** Sets the amplitude of the waveform.
|
|
*/
|
|
inline void SetAmp(const float a) { amp_ = a; }
|
|
/** Sets the waveform to be synthesized by the Process() function.
|
|
*/
|
|
inline void SetWaveform(const uint8_t wf)
|
|
{
|
|
waveform_ = wf < WAVE_LAST ? wf : WAVE_SIN;
|
|
}
|
|
|
|
/** Returns true if cycle is at end of rise. Set during call to Process.
|
|
*/
|
|
inline bool IsEOR() { return eor_; }
|
|
|
|
/** Returns true if cycle is at end of cycle. Set during call to Process.
|
|
*/
|
|
inline bool IsEOC() { return eoc_; }
|
|
|
|
/** Returns true if cycle rising.
|
|
*/
|
|
inline bool IsRising() { return phase_ < PI_F; }
|
|
|
|
/** Returns true if cycle falling.
|
|
*/
|
|
inline bool IsFalling() { return phase_ >= PI_F; }
|
|
|
|
/** Processes the waveform to be generated, returning one sample. This should be called once per sample period.
|
|
*/
|
|
float Process();
|
|
|
|
|
|
/** Adds a value 0.0-1.0 (mapped to 0.0-TWO_PI) to the current phase. Useful for PM and "FM" synthesis.
|
|
*/
|
|
void PhaseAdd(float _phase) { phase_ += (_phase * TWOPI_F); }
|
|
/** Resets the phase to the input argument. If no argumeNt is present, it will reset phase to 0.0;
|
|
*/
|
|
void Reset(float _phase = 0.0f) { phase_ = _phase; }
|
|
|
|
private:
|
|
float CalcPhaseInc(float f);
|
|
uint8_t waveform_;
|
|
float amp_, freq_;
|
|
float sr_, sr_recip_, phase_, phase_inc_;
|
|
float last_out_, last_freq_;
|
|
bool eor_, eoc_;
|
|
};
|
|
} // namespace daisysp
|
|
#endif
|
|
#endif
|
|
|