[refactor]: rearrange code

This commit is contained in:
2023-09-07 17:46:27 +04:00
parent f9ad4d844b
commit 868a59da0e
10 changed files with 34 additions and 99 deletions

View File

@@ -30,8 +30,6 @@ class ADSR : public Effect {
~ADSR(); ~ADSR();
void Trigger() override; void Trigger() override;
void Release() override; void Release() override;
// void RetriggerState() override;
void Process(std::vector<float>& samples) override; void Process(std::vector<float>& samples) override;
void Reset();
void SetParameters(float attack, float decay, float sustain, float release); void SetParameters(float attack, float decay, float sustain, float release);
}; };

View File

@@ -8,11 +8,7 @@
struct Adder { struct Adder {
static void SumOscillators(const std::vector<Oscillator*>& oscillators, static void SumOscillators(const std::vector<Oscillator*>& oscillators,
std::vector<float>& signal) { std::vector<float>& signal) {
size_t sample_count = size_t sample_count = STREAM_BUFFER_SIZE;
STREAM_BUFFER_SIZE; //(size_t)(1.f/FPS * SAMPLE_RATE);
// std::vector<float>* output = new std::vector<float>();
// output->reserve(sample_count);
for (size_t i = 0; i < sample_count; i++) { for (size_t i = 0; i < sample_count; i++) {
float sample = 0.0f; float sample = 0.0f;

View File

@@ -8,6 +8,5 @@ class Effect {
~Effect(){}; ~Effect(){};
virtual void Trigger(){}; virtual void Trigger(){};
virtual void Release(){}; virtual void Release(){};
// virtual void RetriggerState(){};
virtual void Process(std::vector<float>& samples){}; virtual void Process(std::vector<float>& samples){};
}; };

View File

@@ -7,7 +7,6 @@
class KeyBoard { class KeyBoard {
private: private:
/* data */
static int get_semitone_shift_internal(const char* root_note, static int get_semitone_shift_internal(const char* root_note,
char* target_note) { char* target_note) {
const char* pitch_classes[12] = {"C", "C#", "D", "D#", "E", "F", const char* pitch_classes[12] = {"C", "C#", "D", "D#", "E", "F",

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "cstdio" #include "cstdio"
#define write_log(format,args...) do { \ #define write_log(format, args...) \
printf(format, ## args); \ do { \
} while(0) printf(format, ##args); \
} while (0)

View File

@@ -8,8 +8,6 @@
class Renderer { class Renderer {
private: private:
void draw_main_panel(const Rectangle& panel_bounds); void draw_main_panel(const Rectangle& panel_bounds);
void draw_add_oscillator_button(Synth& synth, SynthGuiState& synth_gui,
Rectangle panel_bounds);
float draw_oscillators_panels( float draw_oscillators_panels(
const std::vector<Oscillator*>& oscillators, const std::vector<Oscillator*>& oscillators,
const std::vector<OscillatorGuiState*>& gui_oscillators, const std::vector<OscillatorGuiState*>& gui_oscillators,

View File

@@ -13,14 +13,13 @@ class Synth {
bool is_note_triggered; bool is_note_triggered;
std::vector<Oscillator*> m_oscillators; std::vector<Oscillator*> m_oscillators;
std::vector<Effect*> m_effects; std::vector<Effect*> m_effects;
// OscillatorUI* ui_oscillators;
// Note m_current_note;
std::vector<float> m_out_signal; std::vector<float> m_out_signal;
void zero_signal(); void zero_signal();
void get_note(); void get_note();
void trigger_note_on_effects(); void trigger_note_on_effects();
void untrigger_note_on_effects(); void untrigger_note_on_effects();
void apply_effects(); void apply_effects();
void add_oscillator();
public: public:
Synth(/* args */); Synth(/* args */);
@@ -28,7 +27,6 @@ class Synth {
void Trigger(Note input); void Trigger(Note input);
void Process(); void Process();
void Release(); void Release();
void AddOscillator();
void AddEffect(Effect* fx); void AddEffect(Effect* fx);
const std::vector<float>& GetOutSignal() { return m_out_signal; } const std::vector<float>& GetOutSignal() { return m_out_signal; }
const std::vector<Oscillator*>& GetOscillators() { return m_oscillators; } const std::vector<Oscillator*>& GetOscillators() { return m_oscillators; }

View File

@@ -32,11 +32,10 @@ void Application::init_audio() {
} }
void Application::init_synth() { void Application::init_synth() {
// todo: move that variables to Synth declaration
std::string* nameString = new std::string(std::string(new char[3])); std::string* nameString = new std::string(std::string(new char[3]));
m_current_note = new Note{.length = 1, .name = (*nameString)}; m_current_note = new Note{.length = 1, .name = (*nameString)};
m_current_note->name.assign("G4"); m_current_note->name.assign("G4");
// todo: move somewhere in initialization
std::vector<Oscillator*> oscillators = m_synth.GetOscillators(); std::vector<Oscillator*> oscillators = m_synth.GetOscillators();
m_synth_gui_state.oscillators.reserve(oscillators.size()); m_synth_gui_state.oscillators.reserve(oscillators.size());
for (size_t i = 0; i < oscillators.size(); i++) { for (size_t i = 0; i < oscillators.size(); i++) {
@@ -86,20 +85,15 @@ bool Application::detect_note_pressed(Note* note) {
} }
bool is_note_up() { bool is_note_up() {
return IsKeyUp(KEY_A) || IsKeyUp(KEY_B) || return IsKeyUp(KEY_A) || IsKeyUp(KEY_B) || IsKeyUp(KEY_C) ||
IsKeyUp(KEY_C) || IsKeyUp(KEY_D) || IsKeyUp(KEY_D) || IsKeyUp(KEY_E) || IsKeyUp(KEY_F) || IsKeyUp(KEY_G);
IsKeyUp(KEY_E) || IsKeyUp(KEY_F) || IsKeyUp(KEY_G);
} }
// Update On Input
void Application::update_on_note_input() { void Application::update_on_note_input() {
if (detect_note_pressed(m_current_note)) { if (detect_note_pressed(m_current_note)) {
if (!m_synth.GetIsNoteTriggered()) { if (!m_synth.GetIsNoteTriggered()) {
m_synth.Trigger((*m_current_note)); m_synth.Trigger((*m_current_note));
} }
// m_sound_played_count = 0;
write_log("Note played: %s\n", m_current_note->name.c_str()); write_log("Note played: %s\n", m_current_note->name.c_str());
} else if (is_note_up() && m_synth.GetIsNoteTriggered()) { } else if (is_note_up() && m_synth.GetIsNoteTriggered()) {
m_synth.Release(); m_synth.Release();
@@ -111,14 +105,9 @@ void Application::update_on_note_input() {
// Play ring-buffered audio // Play ring-buffered audio
void Application::play_buffered_audio() { void Application::play_buffered_audio() {
if (IsAudioStreamProcessed(m_synth_stream)) { if (IsAudioStreamProcessed(m_synth_stream)) {
// const float audio_frame_start_time = GetTime();
update_on_note_input(); update_on_note_input();
UpdateAudioStream(m_synth_stream, m_synth.GetOutSignal().data(), UpdateAudioStream(m_synth_stream, m_synth.GetOutSignal().data(),
STREAM_BUFFER_SIZE); STREAM_BUFFER_SIZE);
// const float audio_freme_duration = GetTime() -
// audio_frame_start_time; write_log("Frame time: %.3f%% \n", 100.0f /
// ((1.0f / audio_freme_duration) /
// ((float)SAMPLE_RATE/STREAM_BUFFER_SIZE)));
} }
} }

View File

@@ -19,13 +19,10 @@ Renderer::~Renderer() {}
void Renderer::Draw(Synth& synth, SynthGuiState& synth_gui) { void Renderer::Draw(Synth& synth, SynthGuiState& synth_gui) {
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
// todo: implement renderer
draw_ui(synth, synth_gui); draw_ui(synth, synth_gui);
draw_signal(synth, synth_gui); draw_signal(synth, synth_gui);
// DrawText("Congrats! You created your first window!", 190, 200, 20,
// LIGHTGRAY); DrawFPS(0,0);
EndDrawing(); EndDrawing();
} }
@@ -122,21 +119,6 @@ float Renderer::draw_oscillators_panels(
// Defer shape drop-down box. // Defer shape drop-down box.
ui_osc->shape_dropdown_rect = el_rect; ui_osc->shape_dropdown_rect = el_rect;
el_rect.y += el_rect.height + el_spacing; el_rect.y += el_rect.height + el_spacing;
Rectangle delete_button_rect = el_rect;
delete_button_rect.x = osc_panel_x + 5;
delete_button_rect.y -= el_rect.height + el_spacing;
delete_button_rect.width = 30;
bool is_delete_button_pressed = GuiButton(delete_button_rect, "X");
if (is_delete_button_pressed) {
// memmove(
// synth->ui_oscillator + ui_osc_i,
// synth->ui_oscillator + ui_osc_i + 1,
// (synth->ui_oscillator_count - ui_osc_i) *
// sizeof(UiOscillator)
// );
// synth->ui_oscillator_count -= 1;
}
} }
return panel_y_offset; return panel_y_offset;
@@ -146,47 +128,6 @@ void Renderer::draw_main_panel(const Rectangle& panel_bounds) {
GuiPanel(panel_bounds, ""); GuiPanel(panel_bounds, "");
} }
void Renderer::draw_add_oscillator_button(Synth& synth,
SynthGuiState& synth_gui,
Rectangle panel_bounds) {
//clang-format off
bool click_add_oscillator =
GuiButton((Rectangle){panel_bounds.x + 10, panel_bounds.y + 10,
panel_bounds.width - 20, 25.f},
"Add Oscillator");
//clang-format on
if (click_add_oscillator) {
synth.AddOscillator();
Oscillator* osc = synth.GetOscillators().back();
OscillatorGuiState* ui =
new OscillatorGuiState{.freq = osc->GetFreq(),
.waveshape = osc->GetType(),
.volume = osc->GetVolume()};
synth_gui.oscillators.push_back(ui);
}
}
void Renderer::draw_ui(Synth& synth, SynthGuiState& synth_gui) {
Rectangle panel_bounds = {.x = 0,
.y = 0,
.width = OSCILLATOR_PANEL_WIDTH,
.height = WINDOW_HEIGHT};
draw_main_panel(panel_bounds);
draw_add_oscillator_button(synth, synth_gui, panel_bounds);
// Draw Oscillators
std::vector<Oscillator*> oscillators = synth.GetOscillators();
std::vector<OscillatorGuiState*> gui_oscillators = synth_gui.oscillators;
float panel_y_offset =
draw_oscillators_panels(oscillators, gui_oscillators, panel_bounds);
draw_oscillators_shape_inputs(oscillators, gui_oscillators);
draw_adsr_panel(synth.GetADSR(), synth_gui.adsr, panel_bounds,
panel_y_offset);
}
void Renderer::draw_adsr_panel(ADSR* adsr, ADSRGuiState& gui_adsr, void Renderer::draw_adsr_panel(ADSR* adsr, ADSRGuiState& gui_adsr,
const Rectangle& panel_bounds, const Rectangle& panel_bounds,
float panel_y_offset) { float panel_y_offset) {
@@ -243,3 +184,20 @@ void Renderer::draw_adsr_panel(ADSR* adsr, ADSRGuiState& gui_adsr,
adsr->SetParameters(gui_adsr.attack, gui_adsr.decay, gui_adsr.sustain, adsr->SetParameters(gui_adsr.attack, gui_adsr.decay, gui_adsr.sustain,
gui_adsr.release); gui_adsr.release);
} }
void Renderer::draw_ui(Synth& synth, SynthGuiState& synth_gui) {
Rectangle panel_bounds = {.x = 0,
.y = 0,
.width = OSCILLATOR_PANEL_WIDTH,
.height = WINDOW_HEIGHT};
draw_main_panel(panel_bounds);
std::vector<Oscillator*> oscillators = synth.GetOscillators();
std::vector<OscillatorGuiState*> gui_oscillators = synth_gui.oscillators;
float panel_y_offset =
draw_oscillators_panels(oscillators, gui_oscillators, panel_bounds);
draw_adsr_panel(synth.GetADSR(), synth_gui.adsr, panel_bounds,
panel_y_offset);
draw_oscillators_shape_inputs(oscillators, gui_oscillators);
}

View File

@@ -6,7 +6,8 @@
#include "Settings.h" #include "Settings.h"
Synth::Synth(/* args */) { Synth::Synth(/* args */) {
AddOscillator(); add_oscillator();
add_oscillator();
AddEffect(new ADSR()); AddEffect(new ADSR());
for (size_t i = 0; i < STREAM_BUFFER_SIZE; i++) { for (size_t i = 0; i < STREAM_BUFFER_SIZE; i++) {
float sample = 0.0f; float sample = 0.0f;
@@ -51,11 +52,15 @@ void Synth::untrigger_note_on_effects() {
} }
} }
void Synth::add_oscillator() {
m_oscillators.push_back(
new Oscillator(OscillatorType::Sine, 440.f, VOLUME));
}
void Synth::Trigger(Note input) { void Synth::Trigger(Note input) {
int semitone_shift = KeyBoard::GetSemitoneShift(input.name); int semitone_shift = KeyBoard::GetSemitoneShift(input.name);
float hz = KeyBoard::GetHzBySemitone(semitone_shift); float hz = KeyBoard::GetHzBySemitone(semitone_shift);
// will change after oscillator starts to be more autonomous
for (Oscillator* osc : m_oscillators) { for (Oscillator* osc : m_oscillators) {
osc->SetFreq(hz); osc->SetFreq(hz);
} }
@@ -68,16 +73,10 @@ void Synth::Process() {
apply_effects(); apply_effects();
} }
// todo: rename to something like untrigger note
void Synth::Release() { void Synth::Release() {
zero_signal(); zero_signal();
is_note_triggered = false; is_note_triggered = false;
untrigger_note_on_effects(); untrigger_note_on_effects();
} }
void Synth::AddOscillator() {
m_oscillators.push_back(
new Oscillator(OscillatorType::Sine, 440.f, VOLUME));
}
void Synth::AddEffect(Effect* fx) { m_effects.push_back(fx); } void Synth::AddEffect(Effect* fx) { m_effects.push_back(fx); }