[feat]: Oscillator fine-tune (#22)

closes #19

Reviewed-on: #22
This commit is contained in:
2023-09-17 02:26:44 +03:00
parent bb3ccc296a
commit 2b4e3cb573
16 changed files with 209 additions and 132 deletions

View File

@@ -1,9 +1,9 @@
#pragma once
#include "Effect.h"
#include "IEffect.h"
#include "Ramp.h"
#include <cstddef>
class ADSR : public Effect {
class ADSR : public IEffect {
enum ADSRState { sOff, sAttack, sDecay, sSustain, sRelease };
private:
@@ -14,11 +14,11 @@ class ADSR : public Effect {
ADSRState m_state;
Ramp* m_ramp;
void process_sample(float* sample);
bool is_attack_elapsed();
bool is_decay_elapsed();
bool is_release_elapsed();
void recheck_state();
void ProcessSample(float* sample);
bool IsAttackElapsed();
bool IsDecayElapsed();
bool IsReleaseElapsed();
void RecheckState();
public:
ADSR(/* args */);

View File

@@ -1,12 +0,0 @@
#pragma once
#include <vector>
class Effect {
private:
/* data */
public:
Effect(/* args */){};
~Effect(){};
virtual void Trigger(){};
virtual void Release(){};
virtual void Process(std::vector<float>& samples){};
};

View File

@@ -1,5 +1,5 @@
#pragma once
#include "Effect.h"
#include "IEffect.h"
enum FilterType {
LowPass,
@@ -7,7 +7,7 @@ enum FilterType {
HighPass
};
class Filter : public Effect {
class Filter : public IEffect {
protected:
float m_freq; // cutoff frequency
float m_q; // filter quantity (resonance)
@@ -23,10 +23,10 @@ class Filter : public Effect {
public:
Filter(/* args */);
virtual ~Filter();
void Trigger() override;
void Release() override;
void Trigger() override final;
void Release() override final;
float Process(float in);
void Process(std::vector<float>& samples) override;
void Process(std::vector<float>& samples) override final;
void SetParameters(float freq, float res, float q);
float GetFreq() { return m_freq; }
float GetRes() { return m_q; }

10
inc/IEffect.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include <vector>
class IEffect {
private:
/* data */
public:
virtual void Trigger() = 0;
virtual void Release() = 0;
virtual void Process(std::vector<float>& samples) = 0;
};

View File

@@ -54,10 +54,9 @@ class KeyBoard {
}
public:
KeyBoard(/* args */);
~KeyBoard();
static float GetHzBySemitone(int semitone) {
static float GetHzBySemitone(float semitone) {
//440 * Math.Pow(2, (note - 69) / 12.0) would it be better?
return PITCH_STANDARD * powf(powf(2.f, (1.f / 12.f)), semitone);
}
@@ -71,7 +70,3 @@ class KeyBoard {
return result;
}
};
KeyBoard::KeyBoard(/* args */) {}
KeyBoard::~KeyBoard() {}

20
inc/LFO.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include "Oscillator.h"
class LFO: public Oscillator
{
private:
/* data */
public:
LFO(/* args */);
~LFO();
void SetFreq(float freq) { m_phase_dt = (this->*m_dt_function)(freq); }
};
LFO::LFO(/* args */): Oscillator(Sine, 0.f, 0.5f)
{
}
LFO::~LFO()
{
}

View File

@@ -5,31 +5,41 @@
class Oscillator {
private:
OscillatorType m_osc;
float m_freq;
float m_fine;
float m_key;
float m_volume;
float m_phase;
float m_phase_dt;
float (Oscillator::*m_osc_function)(void);
void SineOscPhaseIncr();
void SawOscPhaseIncr();
float CalcSawPhaseDelta(float freq);
float CalcSinePhaseDelta(float freq);
float SawOsc();
float TriangleOsc();
float SquareOsc();
float Sign(float v);
float SineOsc();
protected:
float m_phase_dt;
float (Oscillator::*m_dt_function)(float freq);
void sine_osc_phase_incr();
void saw_osc_phase_incr();
float calc_saw_phase_delta(float freq);
float calc_sine_phase_delta(float freq);
float sawosc();
float triangleosc();
float squareosc();
float sign(float v);
float sineosc();
public:
Oscillator(OscillatorType osc, float freq, float volume);
Oscillator(OscillatorType osc, float fine, float volume);
~Oscillator();
OscillatorType GetType() { return m_osc; }
void SetType(OscillatorType osc);
float GetVolume() { return m_volume; }
void SetVolume(float volume) { m_volume = volume; }
float GetFreq() { return m_freq; }
void SetFreq(float freq);
float GetKey() { return m_key; }
void SetKey(float key);
float GetFine() { return m_fine; }
void SetFine(float fine) {
if (fine != m_fine) {
assert(fine >= -2.f && fine <= 2.f);
m_fine = fine;
}
}
void Reset();
float Process();
};

View File

@@ -3,7 +3,7 @@
#include "ADSR.h"
#include "Filter.h"
#include "Adder.h"
#include "Effect.h"
#include "IEffect.h"
#include "Note.h"
#include "Oscillator.h"
#include "Settings.h"
@@ -13,23 +13,23 @@ class Synth {
private:
bool is_note_triggered;
std::vector<Oscillator*> m_oscillators;
std::vector<Effect*> m_effects;
std::vector<IEffect*> m_effects;
std::vector<float> m_out_signal;
Oscillator* m_lfo;
void zero_signal();
void get_note();
void trigger_note_on_effects();
void untrigger_note_on_effects();
void apply_effects();
void add_oscillator();
void apply_filter_lfo();
void ZeroSignal();
void GetNote();
void TriggerNoteOnEffects();
void UntriggerNoteOnEffects();
void ApplyEffects();
void AddOscillator();
void ApplyFilterLfo();
public:
Synth(/* args */);
~Synth();
void Trigger(Note input);
void Process();
void Release();
void AddEffect(Effect* fx);
void AddEffect(IEffect* fx);
const std::vector<float>& GetOutSignal() { return m_out_signal; }
const std::vector<Oscillator*>& GetOscillators() { return m_oscillators; }
const bool& GetIsNoteTriggered() { return is_note_triggered; }

View File

@@ -6,7 +6,7 @@
struct OscillatorGuiState {
float volume;
float freq; // todo: remove or change to pitch shift
float fine;
OscillatorType waveshape;
bool is_dropdown_open;
Rectangle shape_dropdown_rect;