[feat]: Oscillator fine-tune #22
@@ -32,7 +32,12 @@ class Oscillator {
|
|||||||
float GetKey() { return m_key; }
|
float GetKey() { return m_key; }
|
||||||
void SetKey(float key);
|
void SetKey(float key);
|
||||||
float GetFine() { return m_fine; }
|
float GetFine() { return m_fine; }
|
||||||
void SetFine(float fine) { assert(fine >= -2.f && fine <= 2.f); m_fine = fine; }
|
void SetFine(float fine) {
|
||||||
|
if (fine != m_fine) {
|
||||||
|
assert(fine >= -2.f && fine <= 2.f);
|
||||||
|
m_fine = fine;
|
||||||
|
}
|
||||||
|
}
|
||||||
void Reset();
|
void Reset();
|
||||||
float Process();
|
float Process();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#define TWO_PI 2 * SYNTH_PI
|
#define TWO_PI 2 * SYNTH_PI
|
||||||
|
|
||||||
Oscillator::Oscillator(OscillatorType osc, float fine, float volume) {
|
Oscillator::Oscillator(OscillatorType osc, float fine, float volume) {
|
||||||
|
assert(fine >= -2.f && fine <= 2.f);
|
||||||
|
assert(volume >= 0.f && volume <= 1.f);
|
||||||
SetType(osc);
|
SetType(osc);
|
||||||
m_fine = fine;
|
m_fine = fine;
|
||||||
m_volume = volume;
|
m_volume = volume;
|
||||||
@@ -42,8 +44,8 @@ void Oscillator::SetType(OscillatorType osc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Oscillator::SetKey(float key) {
|
void Oscillator::SetKey(float key) {
|
||||||
float freq = KeyBoard::GetHzBySemitone(key + m_fine);
|
m_key = key;
|
||||||
write_log("Frequency: %.1f\n", freq);
|
float freq = KeyBoard::GetHzBySemitone(m_key + m_fine);
|
||||||
m_phase = 0;
|
m_phase = 0;
|
||||||
m_phase_dt = (this->*m_dt_function)(freq);
|
m_phase_dt = (this->*m_dt_function)(freq);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ float Renderer::draw_oscillators_panels(
|
|||||||
|
|
||||||
// Draw Oscillator Panel
|
// Draw Oscillator Panel
|
||||||
const int osc_panel_width = panel_bounds.width - 20;
|
const int osc_panel_width = panel_bounds.width - 20;
|
||||||
const int osc_panel_height = has_shape_param ? 130 : 100;
|
const int osc_panel_height = has_shape_param ? 150 : 120;
|
||||||
const int osc_panel_x = panel_bounds.x + 10;
|
const int osc_panel_x = panel_bounds.x + 10;
|
||||||
const int osc_panel_y = panel_bounds.y + 50 + panel_y_offset;
|
const int osc_panel_y = panel_bounds.y + 50 + panel_y_offset;
|
||||||
panel_y_offset += osc_panel_height + 5;
|
panel_y_offset += osc_panel_height + 5;
|
||||||
@@ -112,13 +112,23 @@ float Renderer::draw_oscillators_panels(
|
|||||||
decibels =
|
decibels =
|
||||||
GuiSlider(el_rect, amp_slider_label, "", decibels, -60.0f, 0.0f);
|
GuiSlider(el_rect, amp_slider_label, "", decibels, -60.0f, 0.0f);
|
||||||
ui_osc->volume = powf(10.f, decibels * (1.f / 20.f));
|
ui_osc->volume = powf(10.f, decibels * (1.f / 20.f));
|
||||||
osc->SetVolume(ui_osc->volume);
|
el_rect.y += el_rect.height + el_spacing;
|
||||||
|
|
||||||
|
// Fine slider
|
||||||
|
float fine = osc->GetFine();
|
||||||
|
char fine_slider_label[10];
|
||||||
|
snprintf(fine_slider_label, 9, "%.3f u", fine);
|
||||||
|
fine = GuiSlider(el_rect, fine_slider_label, "", fine, -2.f, 2.f);
|
||||||
|
ui_osc->fine = fine;
|
||||||
el_rect.y += el_rect.height + el_spacing;
|
el_rect.y += el_rect.height + el_spacing;
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
|
// Apply values to real
|
||||||
|
osc->SetVolume(ui_osc->volume);
|
||||||
|
osc->SetFine(ui_osc->fine);
|
||||||
}
|
}
|
||||||
|
|
||||||
return panel_y_offset;
|
return panel_y_offset;
|
||||||
@@ -191,7 +201,7 @@ void Renderer::draw_second_panel(Rectangle& bounds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float Renderer::DrawFilterPanel(Synth& synth, FilterGuiState& gui_filter,
|
float Renderer::DrawFilterPanel(Synth& synth, FilterGuiState& gui_filter,
|
||||||
const Rectangle& panel_bounds) {
|
const Rectangle& panel_bounds) {
|
||||||
#define FILTER_TYPE_OPTIONS "LP;BP;HP"
|
#define FILTER_TYPE_OPTIONS "LP;BP;HP"
|
||||||
Filter* filter = synth.GetFilter();
|
Filter* filter = synth.GetFilter();
|
||||||
float panel_y_offset = 0;
|
float panel_y_offset = 0;
|
||||||
@@ -221,20 +231,20 @@ float Renderer::DrawFilterPanel(Synth& synth, FilterGuiState& gui_filter,
|
|||||||
gui_filter.freq = powf(10.f, freq);
|
gui_filter.freq = powf(10.f, freq);
|
||||||
el_rect.y += el_rect.height + el_spacing;
|
el_rect.y += el_rect.height + el_spacing;
|
||||||
|
|
||||||
//todo: implement that when Res will be fixed
|
// todo: implement that when Res will be fixed
|
||||||
// Resonance slider
|
// Resonance slider
|
||||||
// float res = gui_filter.res;
|
// float res = gui_filter.res;
|
||||||
// char res_slider_label[32];
|
// char res_slider_label[32];
|
||||||
// snprintf(res_slider_label, 7, "%.1f u", res);
|
// snprintf(res_slider_label, 7, "%.1f u", res);
|
||||||
// res = GuiSlider(el_rect, res_slider_label, "", res, 0.0f, 1.0f);
|
// res = GuiSlider(el_rect, res_slider_label, "", res, 0.0f, 1.0f);
|
||||||
// gui_filter.res = res;
|
// gui_filter.res = res;
|
||||||
// el_rect.y += el_rect.height + el_spacing;
|
// el_rect.y += el_rect.height + el_spacing;
|
||||||
|
|
||||||
// Shape select
|
// Shape select
|
||||||
int shape_index = (int)(gui_filter.type);
|
int shape_index = (int)(gui_filter.type);
|
||||||
bool is_dropdown_click =
|
bool is_dropdown_click =
|
||||||
GuiDropdownBox(el_rect, FILTER_TYPE_OPTIONS,
|
GuiDropdownBox(el_rect, FILTER_TYPE_OPTIONS, &shape_index,
|
||||||
&shape_index, gui_filter.is_dropdown_open);
|
gui_filter.is_dropdown_open);
|
||||||
|
|
||||||
if (is_dropdown_click) {
|
if (is_dropdown_click) {
|
||||||
write_log("Dropdown clicked!\n");
|
write_log("Dropdown clicked!\n");
|
||||||
@@ -247,7 +257,8 @@ float Renderer::DrawFilterPanel(Synth& synth, FilterGuiState& gui_filter,
|
|||||||
// apply values to real one
|
// apply values to real one
|
||||||
// todo: thrid (order) parameter
|
// todo: thrid (order) parameter
|
||||||
// todo: why resonance changing does not work?
|
// todo: why resonance changing does not work?
|
||||||
filter->SetParameters(gui_filter.freq, filter->GetRes(), filter->GetPeakGain());
|
filter->SetParameters(gui_filter.freq, filter->GetRes(),
|
||||||
|
filter->GetPeakGain());
|
||||||
|
|
||||||
return panel_y_offset;
|
return panel_y_offset;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "FilterFactory.h"
|
#include "FilterFactory.h"
|
||||||
|
|
||||||
Synth::Synth(/* args */) {
|
Synth::Synth(/* args */) {
|
||||||
m_lfo = new Oscillator(OscillatorType::Sine, 5.f, VOLUME);
|
m_lfo = new Oscillator(OscillatorType::Sine, 0.f, VOLUME);
|
||||||
AddOscillator();
|
AddOscillator();
|
||||||
AddOscillator();
|
AddOscillator();
|
||||||
AddEffect(new ADSR());
|
AddEffect(new ADSR());
|
||||||
|
|||||||
Reference in New Issue
Block a user