[refactor]: rearrange code
This commit is contained in:
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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){};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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); }
|
||||||
|
|||||||
Reference in New Issue
Block a user