1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:57:45 +00:00

Piano: Allow multiple tracks internally

This commit adds multi-track functionality without exposing it to the
user.

All I really did was rename AudioEngine to Track and allow more than one
Track in TrackManager. A lot of the changes are just changing widgets to
take a TrackManager and use current_track().

The TrackManager creates Tracks and gives them a read-only reference to
the global time value. When the TrackManager wants to fill a sample in
the buffer (in fill_buffer()), it calls fill_sample() on each Track.

The delay code is slightly different - a Track will fill its
m_delay_buffer with the sample it just created rather than the most
recent sample in the buffer (which used to be the same thing).

TrackManager manages the current octave.

Other than those few things, this is a pretty basic separation of
concerns.
This commit is contained in:
William McPherson 2020-06-15 15:33:53 +10:00 committed by Andreas Kling
parent db5b28b78e
commit ee52572ca1
18 changed files with 371 additions and 247 deletions

View file

@ -26,14 +26,14 @@
*/
#include "KnobsWidget.h"
#include "AudioEngine.h"
#include "MainWidget.h"
#include "TrackManager.h"
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Label.h>
#include <LibGUI/Slider.h>
KnobsWidget::KnobsWidget(AudioEngine& audio_engine, MainWidget& main_widget)
: m_audio_engine(audio_engine)
KnobsWidget::KnobsWidget(TrackManager& track_manager, MainWidget& main_widget)
: m_track_manager(track_manager)
, m_main_widget(main_widget)
{
set_layout<GUI::VerticalBoxLayout>();
@ -57,13 +57,13 @@ KnobsWidget::KnobsWidget(AudioEngine& audio_engine, MainWidget& main_widget)
m_values_container->set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
m_values_container->set_preferred_size(0, 10);
m_octave_value = m_values_container->add<GUI::Label>(String::number(m_audio_engine.octave()));
m_wave_value = m_values_container->add<GUI::Label>(wave_strings[m_audio_engine.wave()]);
m_attack_value = m_values_container->add<GUI::Label>(String::number(m_audio_engine.attack()));
m_decay_value = m_values_container->add<GUI::Label>(String::number(m_audio_engine.decay()));
m_sustain_value = m_values_container->add<GUI::Label>(String::number(m_audio_engine.sustain()));
m_release_value = m_values_container->add<GUI::Label>(String::number(m_audio_engine.release()));
m_delay_value = m_values_container->add<GUI::Label>(String::number(m_audio_engine.delay()));
m_octave_value = m_values_container->add<GUI::Label>(String::number(m_track_manager.octave()));
m_wave_value = m_values_container->add<GUI::Label>(wave_strings[m_track_manager.current_track().wave()]);
m_attack_value = m_values_container->add<GUI::Label>(String::number(m_track_manager.current_track().attack()));
m_decay_value = m_values_container->add<GUI::Label>(String::number(m_track_manager.current_track().decay()));
m_sustain_value = m_values_container->add<GUI::Label>(String::number(m_track_manager.current_track().sustain()));
m_release_value = m_values_container->add<GUI::Label>(String::number(m_track_manager.current_track().release()));
m_delay_value = m_values_container->add<GUI::Label>(String::number(m_track_manager.current_track().delay()));
m_knobs_container = add<GUI::Widget>();
m_knobs_container->set_layout<GUI::HorizontalBoxLayout>();
@ -73,82 +73,82 @@ KnobsWidget::KnobsWidget(AudioEngine& audio_engine, MainWidget& main_widget)
m_octave_knob = m_knobs_container->add<GUI::VerticalSlider>();
m_octave_knob->set_tooltip("Z: octave down, X: octave up");
m_octave_knob->set_range(octave_min - 1, octave_max - 1);
m_octave_knob->set_value((octave_max - 1) - (m_audio_engine.octave() - 1));
m_octave_knob->set_value((octave_max - 1) - (m_track_manager.octave() - 1));
m_octave_knob->on_value_changed = [this](int value) {
int new_octave = octave_max - value;
if (m_change_octave)
m_main_widget.set_octave_and_ensure_note_change(new_octave == m_audio_engine.octave() + 1 ? Up : Down);
ASSERT(new_octave == m_audio_engine.octave());
m_main_widget.set_octave_and_ensure_note_change(new_octave == m_track_manager.octave() + 1 ? Up : Down);
ASSERT(new_octave == m_track_manager.octave());
m_octave_value->set_text(String::number(new_octave));
};
m_wave_knob = m_knobs_container->add<GUI::VerticalSlider>();
m_wave_knob->set_tooltip("C: cycle through waveforms");
m_wave_knob->set_range(0, last_wave);
m_wave_knob->set_value(last_wave - m_audio_engine.wave());
m_wave_knob->set_value(last_wave - m_track_manager.current_track().wave());
m_wave_knob->on_value_changed = [this](int value) {
int new_wave = last_wave - value;
m_audio_engine.set_wave(new_wave);
ASSERT(new_wave == m_audio_engine.wave());
m_track_manager.current_track().set_wave(new_wave);
ASSERT(new_wave == m_track_manager.current_track().wave());
m_wave_value->set_text(wave_strings[new_wave]);
};
constexpr int max_attack = 1000;
m_attack_knob = m_knobs_container->add<GUI::VerticalSlider>();
m_attack_knob->set_range(0, max_attack);
m_attack_knob->set_value(max_attack - m_audio_engine.attack());
m_attack_knob->set_value(max_attack - m_track_manager.current_track().attack());
m_attack_knob->set_step(100);
m_attack_knob->on_value_changed = [this](int value) {
int new_attack = max_attack - value;
m_audio_engine.set_attack(new_attack);
ASSERT(new_attack == m_audio_engine.attack());
m_track_manager.current_track().set_attack(new_attack);
ASSERT(new_attack == m_track_manager.current_track().attack());
m_attack_value->set_text(String::number(new_attack));
};
constexpr int max_decay = 1000;
m_decay_knob = m_knobs_container->add<GUI::VerticalSlider>();
m_decay_knob->set_range(0, max_decay);
m_decay_knob->set_value(max_decay - m_audio_engine.decay());
m_decay_knob->set_value(max_decay - m_track_manager.current_track().decay());
m_decay_knob->set_step(100);
m_decay_knob->on_value_changed = [this](int value) {
int new_decay = max_decay - value;
m_audio_engine.set_decay(new_decay);
ASSERT(new_decay == m_audio_engine.decay());
m_track_manager.current_track().set_decay(new_decay);
ASSERT(new_decay == m_track_manager.current_track().decay());
m_decay_value->set_text(String::number(new_decay));
};
constexpr int max_sustain = 1000;
m_sustain_knob = m_knobs_container->add<GUI::VerticalSlider>();
m_sustain_knob->set_range(0, max_sustain);
m_sustain_knob->set_value(max_sustain - m_audio_engine.sustain());
m_sustain_knob->set_value(max_sustain - m_track_manager.current_track().sustain());
m_sustain_knob->set_step(100);
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_track_manager.current_track().set_sustain(new_sustain);
ASSERT(new_sustain == m_track_manager.current_track().sustain());
m_sustain_value->set_text(String::number(new_sustain));
};
constexpr int max_release = 1000;
m_release_knob = m_knobs_container->add<GUI::VerticalSlider>();
m_release_knob->set_range(0, max_release);
m_release_knob->set_value(max_release - m_audio_engine.release());
m_release_knob->set_value(max_release - m_track_manager.current_track().release());
m_release_knob->set_step(100);
m_release_knob->on_value_changed = [this](int value) {
int new_release = max_release - value;
m_audio_engine.set_release(new_release);
ASSERT(new_release == m_audio_engine.release());
m_track_manager.current_track().set_release(new_release);
ASSERT(new_release == m_track_manager.current_track().release());
m_release_value->set_text(String::number(new_release));
};
constexpr int max_delay = 8;
m_delay_knob = m_knobs_container->add<GUI::VerticalSlider>();
m_delay_knob->set_range(0, max_delay);
m_delay_knob->set_value(max_delay - m_audio_engine.delay());
m_delay_knob->set_value(max_delay - m_track_manager.current_track().delay());
m_delay_knob->on_value_changed = [this](int value) {
int new_delay = max_delay - value;
m_audio_engine.set_delay(new_delay);
ASSERT(new_delay == m_audio_engine.delay());
m_track_manager.current_track().set_delay(new_delay);
ASSERT(new_delay == m_track_manager.current_track().delay());
m_delay_value->set_text(String::number(new_delay));
};
}
@ -159,12 +159,12 @@ KnobsWidget::~KnobsWidget()
void KnobsWidget::update_knobs()
{
m_wave_knob->set_value(last_wave - m_audio_engine.wave());
m_wave_knob->set_value(last_wave - m_track_manager.current_track().wave());
// FIXME: This is needed because when the slider is changed directly, it
// needs to change the octave, but if the octave was changed elsewhere, we
// need to change the slider without changing the octave.
m_change_octave = false;
m_octave_knob->set_value(octave_max - m_audio_engine.octave());
m_octave_knob->set_value(octave_max - m_track_manager.octave());
m_change_octave = true;
}