Piano: Add sustain
This commit is contained in:
parent
421a340572
commit
5990b3b2e6
Notes:
sideshowbarker
2024-07-19 09:39:43 +09:00
Author: https://github.com/willmcpherson2 Commit: https://github.com/SerenityOS/serenity/commit/5990b3b2e64 Pull-request: https://github.com/SerenityOS/serenity/pull/1178
5 changed files with 40 additions and 4 deletions
|
@ -31,6 +31,7 @@
|
|||
|
||||
AudioEngine::AudioEngine()
|
||||
{
|
||||
set_sustain_impl(0);
|
||||
set_decay(0);
|
||||
}
|
||||
|
||||
|
@ -48,8 +49,8 @@ void AudioEngine::fill_buffer(FixedArray<Sample>& buffer)
|
|||
continue;
|
||||
|
||||
m_power[note] -= m_decay_step;
|
||||
if (m_power[note] < 0)
|
||||
m_power[note] = 0;
|
||||
if (m_power[note] < m_sustain_level)
|
||||
m_power[note] = m_sustain_level;
|
||||
|
||||
double val = 0;
|
||||
switch (m_wave) {
|
||||
|
@ -212,7 +213,20 @@ void AudioEngine::set_decay(int decay)
|
|||
{
|
||||
ASSERT(decay >= 0);
|
||||
m_decay = decay;
|
||||
m_decay_step = calculate_step(1, m_decay);
|
||||
m_decay_step = calculate_step(1 - m_sustain_level, m_decay);
|
||||
}
|
||||
|
||||
void AudioEngine::set_sustain_impl(int sustain)
|
||||
{
|
||||
ASSERT(sustain >= 0);
|
||||
m_sustain = sustain;
|
||||
m_sustain_level = sustain / 1000.0;
|
||||
}
|
||||
|
||||
void AudioEngine::set_sustain(int sustain)
|
||||
{
|
||||
set_sustain_impl(sustain);
|
||||
set_decay(m_decay);
|
||||
}
|
||||
|
||||
void AudioEngine::set_delay(int delay)
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
int octave_base() const { return (m_octave - octave_min) * 12; }
|
||||
int wave() const { return m_wave; }
|
||||
int decay() const { return m_decay; }
|
||||
int sustain() const { return m_sustain; }
|
||||
int delay() const { return m_delay; }
|
||||
int time() const { return m_time; }
|
||||
int tick() const { return m_tick; }
|
||||
|
@ -55,6 +56,7 @@ public:
|
|||
void set_wave(int wave);
|
||||
void set_wave(Direction);
|
||||
void set_decay(int decay);
|
||||
void set_sustain(int sustain);
|
||||
void set_delay(int delay);
|
||||
|
||||
private:
|
||||
|
@ -64,6 +66,8 @@ private:
|
|||
double triangle(size_t note);
|
||||
double noise() const;
|
||||
|
||||
void set_sustain_impl(int sustain);
|
||||
|
||||
FixedArray<Sample> m_front_buffer { sample_count };
|
||||
FixedArray<Sample> m_back_buffer { sample_count };
|
||||
FixedArray<Sample>* m_front_buffer_ptr { &m_front_buffer };
|
||||
|
@ -79,6 +83,8 @@ private:
|
|||
int m_wave { first_wave };
|
||||
int m_decay;
|
||||
double m_decay_step;
|
||||
int m_sustain;
|
||||
double m_sustain_level;
|
||||
int m_delay { 0 };
|
||||
|
||||
int m_time { 0 };
|
||||
|
|
|
@ -51,6 +51,7 @@ KnobsWidget::KnobsWidget(GUI::Widget* parent, AudioEngine& audio_engine, MainWid
|
|||
m_octave_label = GUI::Label::construct("Octave", m_labels_container);
|
||||
m_wave_label = GUI::Label::construct("Wave", m_labels_container);
|
||||
m_decay_label = GUI::Label::construct("Decay", m_labels_container);
|
||||
m_sustain_label = GUI::Label::construct("Sustain", m_labels_container);
|
||||
m_delay_label = GUI::Label::construct("Delay", m_labels_container);
|
||||
|
||||
m_values_container = GUI::Widget::construct(this);
|
||||
|
@ -61,6 +62,7 @@ KnobsWidget::KnobsWidget(GUI::Widget* parent, AudioEngine& audio_engine, MainWid
|
|||
m_octave_value = GUI::Label::construct(String::number(m_audio_engine.octave()), m_values_container);
|
||||
m_wave_value = GUI::Label::construct(wave_strings[m_audio_engine.wave()], m_values_container);
|
||||
m_decay_value = GUI::Label::construct(String::number(m_audio_engine.decay()), m_values_container);
|
||||
m_sustain_value = GUI::Label::construct(String::number(m_audio_engine.sustain()), m_values_container);
|
||||
m_delay_value = GUI::Label::construct(String::number(m_audio_engine.delay() / m_audio_engine.tick()), m_values_container);
|
||||
|
||||
m_knobs_container = GUI::Widget::construct(this);
|
||||
|
@ -102,6 +104,17 @@ KnobsWidget::KnobsWidget(GUI::Widget* parent, AudioEngine& audio_engine, MainWid
|
|||
m_decay_value->set_text(String::number(new_decay));
|
||||
};
|
||||
|
||||
constexpr int max_sustain = 1000;
|
||||
m_sustain_knob = GUI::Slider::construct(Orientation::Vertical, m_knobs_container);
|
||||
m_sustain_knob->set_range(0, max_sustain);
|
||||
m_sustain_knob->set_value(max_sustain - m_audio_engine.sustain());
|
||||
m_sustain_knob->on_value_changed = [this](int value) {
|
||||
int new_sustain = max_sustain - value;
|
||||
m_audio_engine.set_sustain(new_sustain);
|
||||
ASSERT(new_sustain == m_audio_engine.sustain());
|
||||
m_sustain_value->set_text(String::number(new_sustain));
|
||||
};
|
||||
|
||||
constexpr int max_delay = 8;
|
||||
m_delay_knob = GUI::Slider::construct(Orientation::Vertical, m_knobs_container);
|
||||
m_delay_knob->set_range(0, max_delay);
|
||||
|
|
|
@ -54,18 +54,21 @@ private:
|
|||
RefPtr<GUI::Label> m_octave_label;
|
||||
RefPtr<GUI::Label> m_wave_label;
|
||||
RefPtr<GUI::Label> m_decay_label;
|
||||
RefPtr<GUI::Label> m_sustain_label;
|
||||
RefPtr<GUI::Label> m_delay_label;
|
||||
|
||||
RefPtr<GUI::Widget> m_values_container;
|
||||
RefPtr<GUI::Label> m_octave_value;
|
||||
RefPtr<GUI::Label> m_wave_value;
|
||||
RefPtr<GUI::Label> m_decay_value;
|
||||
RefPtr<GUI::Label> m_sustain_value;
|
||||
RefPtr<GUI::Label> m_delay_value;
|
||||
|
||||
RefPtr<GUI::Widget> m_knobs_container;
|
||||
RefPtr<GUI::Slider> m_octave_knob;
|
||||
RefPtr<GUI::Slider> m_wave_knob;
|
||||
RefPtr<GUI::Slider> m_decay_knob;
|
||||
RefPtr<GUI::Slider> m_sustain_knob;
|
||||
RefPtr<GUI::Slider> m_delay_knob;
|
||||
|
||||
bool m_change_octave { true };
|
||||
|
|
|
@ -60,7 +60,7 @@ MainWidget::MainWidget(AudioEngine& audio_engine)
|
|||
|
||||
m_knobs_widget = KnobsWidget::construct(m_keys_and_knobs_container, audio_engine, *this);
|
||||
m_knobs_widget->set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fill);
|
||||
m_knobs_widget->set_preferred_size(200, 0);
|
||||
m_knobs_widget->set_preferred_size(250, 0);
|
||||
}
|
||||
|
||||
MainWidget::~MainWidget()
|
||||
|
|
Loading…
Add table
Reference in a new issue