BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

oscillator.hpp (9819B)


      1 #pragma once
      2 
      3 #include <stdlib.h>
      4 #include <stdint.h>
      5 #include <math.h>
      6 #include <vector>
      7 
      8 #include "base.hpp"
      9 #include "math.hpp"
     10 #include "table.hpp"
     11 
     12 namespace bogaudio {
     13 namespace dsp {
     14 
     15 struct Oscillator {
     16 	float _sampleRate;
     17 	float _frequency;
     18 
     19 	Oscillator(
     20 		float sampleRate = 1000.0f,
     21 		float frequency = 100.0f
     22 	)
     23 	: _sampleRate(sampleRate > 1.0 ? sampleRate : 1.0)
     24 	, _frequency(frequency)
     25 	{
     26 	}
     27 	virtual ~Oscillator() {}
     28 
     29 	void setSampleRate(float sampleRate) {
     30 		if (_sampleRate != sampleRate && sampleRate >= 1.0) {
     31 			_sampleRate = sampleRate;
     32 			_sampleRateChanged();
     33 		}
     34 	}
     35 
     36 	virtual void _sampleRateChanged() {}
     37 
     38 	void setFrequency(float frequency) {
     39 		if (_frequency != frequency) {
     40 			_frequency = frequency;
     41 			_frequencyChanged();
     42 		}
     43 	}
     44 
     45 	virtual void _frequencyChanged() {}
     46 };
     47 
     48 struct OscillatorGenerator : Oscillator, Generator {
     49 	OscillatorGenerator(
     50 		float sampleRate = 1000.0f,
     51 		float frequency = 100.0f
     52 	)
     53 	: Oscillator(sampleRate, frequency)
     54 	{
     55 	}
     56 };
     57 
     58 struct Phasor : OscillatorGenerator {
     59 	typedef uint64_t phase_t;
     60 	typedef int64_t phase_delta_t;
     61 	static constexpr phase_t cyclePhase = UINT32_MAX;
     62 	static constexpr float twoPI = 2.0f * M_PI;
     63 	static constexpr float maxSampleWidth = 0.25f;
     64 
     65 	phase_delta_t _delta;
     66 	phase_t _phase = 0;
     67 	float _sampleWidth = 0.0f;
     68 	phase_t _samplePhase = 0;
     69 
     70 	Phasor(
     71 		float sampleRate = 1000.0f,
     72 		float frequency = 100.0f,
     73 		float initialPhase = 0.0f
     74 	)
     75 	: OscillatorGenerator(sampleRate, frequency)
     76 	{
     77 		setPhase(initialPhase);
     78 		_update();
     79 	}
     80 
     81 	void _sampleRateChanged() override {
     82 		_update();
     83 	}
     84 
     85 	void _frequencyChanged() override {
     86 		_update();
     87 	}
     88 
     89 	void setSampleWidth(float sw);
     90 	virtual void resetPhase();
     91 	void setPhase(float radians);
     92 	void syncPhase(const Phasor& phasor);
     93 	float nextFromPhasor(const Phasor& phasor, phase_delta_t offset = 0);
     94 	virtual float nextForPhase(phase_t phase);
     95 	virtual void _update();
     96 	inline void advancePhase() { _phase += _delta; }
     97 	inline void advancePhase(int n) { assert(n > 0); _phase += n * _delta; }
     98 	float _next() override final;
     99 
    100 	inline static phase_delta_t radiansToPhase(float radians) { return (radians / twoPI) * cyclePhase; }
    101 	inline static float phaseToRadians(phase_t phase) { return (phase / (float)cyclePhase) * twoPI; }
    102 };
    103 
    104 struct TablePhasor : Phasor {
    105 	enum Interpolation {
    106 		INTERPOLATION_DEFAULT,
    107 		INTERPOLATION_ON,
    108 		INTERPOLATION_OFF
    109 	};
    110 
    111 	const Table& _table;
    112 	int _tableLength;
    113 	Interpolation _interpolation;
    114 
    115 	TablePhasor(
    116 		const Table& table,
    117 		double sampleRate = 1000.0f,
    118 		double frequency = 100.0f,
    119 		Interpolation interpolation = INTERPOLATION_DEFAULT
    120 	)
    121 	: Phasor(sampleRate, frequency)
    122 	, _table(table)
    123 	, _tableLength(table.length())
    124 	, _interpolation(interpolation)
    125 	{
    126 	}
    127 
    128 	void setInterpolation(Interpolation interpolation);
    129 
    130 	float nextForPhase(phase_t phase) override;
    131 };
    132 
    133 struct SineOscillator : OscillatorGenerator {
    134 	double _k1, _k2;
    135 	double _x;
    136 	double _y;
    137 
    138 	SineOscillator(
    139 		double sampleRate = 1000.0f,
    140 		double frequency = 100.0f,
    141 		double initialPhase = 0.0
    142 	)
    143 	: OscillatorGenerator(sampleRate, frequency)
    144 	{
    145 		setPhase(initialPhase);
    146 		update();
    147 	}
    148 
    149 	void _sampleRateChanged() override {
    150 		update();
    151 	}
    152 
    153 	void _frequencyChanged() override {
    154 		update();
    155 	}
    156 
    157 	void setPhase(double phase);
    158 	void update();
    159 	float _next() override;
    160 };
    161 
    162 struct SineTableOscillator : TablePhasor {
    163 	SineTableOscillator(
    164 		float sampleRate = 1000.0f,
    165 		float frequency = 100.0f,
    166 		Interpolation interpolation = INTERPOLATION_ON
    167 	)
    168 	: TablePhasor(StaticSineTable::table(), sampleRate, frequency, interpolation)
    169 	{
    170 	}
    171 };
    172 
    173 struct SawOscillator : Phasor {
    174 	SawOscillator(
    175 		float sampleRate = 1000.0f,
    176 		float frequency = 100.0f
    177 	)
    178 	: Phasor(sampleRate, frequency)
    179 	{
    180 	}
    181 
    182 	float nextForPhase(phase_t phase) override;
    183 };
    184 
    185 struct SaturatingSawOscillator : SawOscillator {
    186 	float _saturation;
    187 	float _saturationNormalization;
    188 	FastTanhf _tanhf;
    189 
    190 	SaturatingSawOscillator(
    191 		float sampleRate = 1000.0f,
    192 		float frequency = 100.0f
    193 	)
    194 	: SawOscillator(sampleRate, frequency)
    195 	, _saturation(0.0f)
    196 	, _saturationNormalization(1.0f)
    197 	{
    198 	}
    199 
    200 	void setSaturation(float saturation);
    201 	float nextForPhase(phase_t phase) override;
    202 };
    203 
    204 struct BandLimitedSawOscillator : SaturatingSawOscillator {
    205 	int _quality;
    206 	const Table& _table;
    207 	phase_t _qd = 0;
    208 	float _halfTableLen;
    209 
    210 	BandLimitedSawOscillator(
    211 		float sampleRate = 1000.0f,
    212 		float frequency = 100.0f,
    213 		int quality = 5,
    214 		const Table& table = StaticBlepTable::table()
    215 	)
    216 	: SaturatingSawOscillator(sampleRate, frequency)
    217 	, _quality(quality)
    218 	, _table(table)
    219 	, _halfTableLen(_table.length() / 2)
    220 	{
    221 		setQuality(quality);
    222 	}
    223 
    224 	void setQuality(int quality);
    225 	void _update() override;
    226 	float nextForPhase(phase_t phase) override;
    227 };
    228 
    229 struct SquareOscillator : Phasor {
    230 	static constexpr float minPulseWidth = 0.03f;
    231 	static constexpr float maxPulseWidth = 1.0f - minPulseWidth;
    232 	static constexpr float defaultPulseWidth = 0.5f;
    233 	float _pulseWidthInput = -1.0f;
    234 	phase_t _lastCycle = -1;
    235 	phase_t _pulseWidth = cyclePhase * defaultPulseWidth, _nextPulseWidth = cyclePhase * defaultPulseWidth;
    236 	bool positive = true;
    237 
    238 	SquareOscillator(
    239 		float sampleRate = 1000.0f,
    240 		float frequency = 100.0f
    241 	)
    242 	: Phasor(sampleRate, frequency)
    243 	{
    244 	}
    245 
    246 	void setPulseWidth(float pw);
    247 	float nextForPhase(phase_t phase) override;
    248 };
    249 
    250 struct BandLimitedSquareOscillator : BandLimitedSawOscillator {
    251 	const float minPulseWidth = 0.03f;
    252 	const float maxPulseWidth = 1.0f - minPulseWidth;
    253 	float _pulseWidthInput = -1.0f;
    254 	bool _dcCorrection = false;
    255 	phase_t _lastCycle = -1;
    256 	phase_delta_t _pulseWidth = 0, _nextPulseWidth = 0;
    257 	float _offset = 0.0f, _nextOffset = 0.0f;
    258 	float _dcOffset = 0.0f, _nextDcOffset = 0.0f;
    259 
    260 	BandLimitedSquareOscillator(
    261 		float sampleRate = 1000.0f,
    262 		float frequency = 100.0f,
    263 		int quality = 5,
    264 		const Table& table = StaticBlepTable::table()
    265 	)
    266 	: BandLimitedSawOscillator(sampleRate, frequency, quality, table)
    267 	{
    268 		setPulseWidth(0.5f);
    269 	}
    270 
    271 	void setPulseWidth(float pw, bool dcCorrection = true);
    272 	float nextForPhase(phase_t phase) override;
    273 };
    274 
    275 struct TriangleOscillator : Phasor {
    276 	const phase_t quarterCyclePhase = cyclePhase * 0.25f;
    277 	const phase_t threeQuartersCyclePhase = cyclePhase * 0.75f;
    278 
    279 	TriangleOscillator(
    280 		float sampleRate = 1000.0f,
    281 		float frequency = 100.0f
    282 	)
    283 	: Phasor(sampleRate, frequency)
    284 	{
    285 	}
    286 
    287 	float nextForPhase(phase_t phase) override;
    288 };
    289 
    290 struct SteppedRandomOscillator : Phasor {
    291 	const phase_t _n;
    292 	const phase_t _k;
    293 	float* _t = NULL;
    294 	phase_t _seed;
    295 
    296 	SteppedRandomOscillator(
    297 		float sampleRate = 1000.0f,
    298 		float frequency = 100.0f,
    299 		phase_t seed = 0
    300 	);
    301 	~SteppedRandomOscillator();
    302 
    303 	void resetPhase() override;
    304 	float nextForPhase(phase_t phase) override;
    305 };
    306 
    307 struct SineBankOscillator : Oscillator {
    308 	struct Partial {
    309 		float frequency;
    310 		float frequencyRatio;
    311 		float amplitude;
    312 		float amplitudeTarget;
    313 		float amplitudeStepDelta;
    314 		int amplitudeSteps;
    315 		SineTableOscillator sine;
    316 
    317 		Partial()
    318 		: frequency(0.0)
    319 		, frequencyRatio(0.0)
    320 		, amplitude(0.0)
    321 		, amplitudeTarget(0.0)
    322 		, amplitudeStepDelta(0.0)
    323 		, amplitudeSteps(0)
    324 		, sine(0.0, 0.0)
    325 		{}
    326 	};
    327 
    328 	const float _maxPartialFrequencySRRatio = 0.48;
    329 	float _maxPartialFrequency = 0.0;
    330 	const int _amplitudeEnvelopeMS = 10;
    331 	int _amplitudeEnvelopeSamples = 0;
    332 	std::vector<Partial> _partials;
    333 
    334 	SineBankOscillator(
    335 		float sampleRate = 1000.0f,
    336 		float frequency = 100.0f,
    337 		int partialCount = 20
    338 	)
    339 	: Oscillator(sampleRate, frequency)
    340 	, _partials(partialCount)
    341 	{
    342 		_sampleRateChanged();
    343 		_frequencyChanged();
    344 	}
    345 
    346 	int partialCount() {
    347 		return _partials.size();
    348 	}
    349 
    350 	// one-based indexes.
    351 	void setPartial(int i, float frequencyRatio, float amplitude);
    352 	bool setPartialFrequencyRatio(int i, float frequencyRatio);
    353 	void setPartialAmplitude(int i, float amplitude, bool envelope = false);
    354 
    355 	void syncToPhase(float phase);
    356 	void syncTo(const SineBankOscillator& other);
    357 
    358 	void _sampleRateChanged() override;
    359 	void _frequencyChanged() override;
    360 	float next(Phasor::phase_t phaseOffset = 0.0f);
    361 };
    362 
    363 struct ChirpOscillator : OscillatorGenerator {
    364 	static constexpr float minFrequency = 1.0f;
    365 	static constexpr float minTimeSeconds = 0.01f;
    366 
    367 	SineTableOscillator _oscillator;
    368 	float _f1 = -1.0f;
    369 	float _f2 = -1.0f;
    370 	float _Time = -1.0f;
    371 	bool _linear = false;
    372 
    373 	float _sampleTime = 0.0f;
    374 	float _time = 0.0f;
    375 	bool _complete = false;
    376 	double _k = 0.0;
    377 
    378 	ChirpOscillator(
    379 		float sampleRate = 1000.0f,
    380 		float frequency1 = 100.0f,
    381 		float frequency2 = 300.0f,
    382 		float time = 1.0f,
    383 		bool linear = true
    384 	)
    385 	: _oscillator(sampleRate)
    386 	{
    387 		setParams(frequency1, frequency2, time, linear);
    388 	}
    389 
    390 	inline bool isCycleComplete() { return _complete; }
    391 	inline bool isCycleNearlyComplete(float seconds) { return _time > _Time - seconds; }
    392 	void setParams(float frequency1, float frequency2, float time, bool linear);
    393 	void _sampleRateChanged() override;
    394 	float _next() override;
    395 	void reset();
    396 };
    397 
    398 struct PureChirpOscillator : OscillatorGenerator {
    399 	static constexpr float minFrequency = 1.0f;
    400 	static constexpr float minTimeSeconds = 0.01f;
    401 
    402 	float _f1 = -1.0f;
    403 	float _f2 = -1.0f;
    404 	double _Time = -1.0;
    405 	bool _linear = false;
    406 
    407 	double _sampleTime = 0.0f;
    408 	double _time = 0.0f;
    409 	bool _complete = false;
    410 	double _c = 0.0;
    411 	double _k = 0.0;
    412 	double _invlogk = 0.0;
    413 
    414 	PureChirpOscillator(
    415 		float sampleRate = 1000.0f,
    416 		float frequency1 = 100.0f,
    417 		float frequency2 = 300.0f,
    418 		float time = 1.0f,
    419 		bool linear = true
    420 	)
    421 	{
    422 		setParams(frequency1, frequency2, time, linear);
    423 	}
    424 
    425 	inline bool isCycleComplete() { return _complete; }
    426 	inline bool isCycleNearlyComplete(float seconds) { return _time > _Time - seconds; }
    427 	void setParams(float frequency1, float frequency2, double time, bool linear);
    428 	void _sampleRateChanged() override;
    429 	void update();
    430 	float _next() override;
    431 	void reset();
    432 };
    433 
    434 } // namespace dsp
    435 } // namespace bogaudio