diff options
-rw-r--r-- | Applications/Piano/AudioEngine.cpp | 30 | ||||
-rw-r--r-- | Applications/Piano/AudioEngine.h | 9 | ||||
-rw-r--r-- | Applications/Piano/MainWidget.cpp | 2 | ||||
-rw-r--r-- | Applications/Piano/Music.h | 2 | ||||
-rw-r--r-- | Applications/Piano/RollWidget.cpp | 35 | ||||
-rw-r--r-- | Applications/Piano/RollWidget.h | 7 |
6 files changed, 47 insertions, 38 deletions
diff --git a/Applications/Piano/AudioEngine.cpp b/Applications/Piano/AudioEngine.cpp index 11c4a4e109..d91d0180ee 100644 --- a/Applications/Piano/AudioEngine.cpp +++ b/Applications/Piano/AudioEngine.cpp @@ -113,8 +113,10 @@ void AudioEngine::fill_buffer(FixedArray<Sample>& buffer) m_delay_buffers.enqueue(move(delay_buffer)); } - if (++m_time == m_tick) + if (++m_time == m_tick) { m_time = 0; + update_roll(); + } memcpy(m_back_buffer_ptr->data(), buffer.data(), buffer_size); swap(m_front_buffer_ptr, m_back_buffer_ptr); @@ -205,6 +207,32 @@ void AudioEngine::set_note_current_octave(int note, Switch switch_note) set_note(note + octave_base(), switch_note); } +void AudioEngine::set_roll_note(int y, int x, Switch switch_note) +{ + ASSERT(x >= 0 && x < horizontal_notes); + ASSERT(y >= 0 && y < note_count); + + m_roll_notes[y][x] = switch_note; + + if (x == m_current_column && switch_note == Off) // If you turn off a note that is playing. + set_note((note_count - 1) - y, Off); +} + +void AudioEngine::update_roll() +{ + if (++m_current_column == horizontal_notes) + m_current_column = 0; + if (++m_previous_column == horizontal_notes) + m_previous_column = 0; + + for (int note = 0; note < note_count; ++note) { + if (m_roll_notes[note][m_previous_column] == On) + set_note((note_count - 1) - note, Off); + if (m_roll_notes[note][m_current_column] == On) + set_note((note_count - 1) - note, On); + } +} + void AudioEngine::set_octave(Direction direction) { if (direction == Up) { diff --git a/Applications/Piano/AudioEngine.h b/Applications/Piano/AudioEngine.h index 8e1a048234..229c365f1a 100644 --- a/Applications/Piano/AudioEngine.h +++ b/Applications/Piano/AudioEngine.h @@ -40,6 +40,8 @@ public: ~AudioEngine(); const FixedArray<Sample>& buffer() const { return *m_front_buffer_ptr; } + Switch roll_note(int y, int x) const { return m_roll_notes[y][x]; } + int current_column() const { return m_current_column; } int octave() const { return m_octave; } int octave_base() const { return (m_octave - octave_min) * 12; } int wave() const { return m_wave; } @@ -54,6 +56,7 @@ public: void fill_buffer(FixedArray<Sample>& buffer); void set_note(int note, Switch); void set_note_current_octave(int note, Switch); + void set_roll_note(int y, int x, Switch); void set_octave(Direction); void set_wave(int wave); void set_wave(Direction); @@ -70,6 +73,8 @@ private: double triangle(size_t note); double noise() const; + void update_roll(); + void set_sustain_impl(int sustain); FixedArray<Sample> m_front_buffer { sample_count }; @@ -98,4 +103,8 @@ private: int m_time { 0 }; int m_tick { 8 }; + + Switch m_roll_notes[note_count][horizontal_notes] { { Off } }; + int m_current_column { 0 }; + int m_previous_column { horizontal_notes - 1 }; }; diff --git a/Applications/Piano/MainWidget.cpp b/Applications/Piano/MainWidget.cpp index d64850fca7..de3b908741 100644 --- a/Applications/Piano/MainWidget.cpp +++ b/Applications/Piano/MainWidget.cpp @@ -75,7 +75,7 @@ void MainWidget::custom_event(Core::CustomEvent&) m_wave_widget->update(); if (m_audio_engine.time() == 0) - m_roll_widget->update_roll(); + m_roll_widget->update(); } void MainWidget::keydown_event(GUI::KeyEvent& event) diff --git a/Applications/Piano/Music.h b/Applications/Piano/Music.h index cdd787cce8..2a0a030cf8 100644 --- a/Applications/Piano/Music.h +++ b/Applications/Piano/Music.h @@ -116,6 +116,8 @@ constexpr int black_keys_per_octave = 5; constexpr int octave_min = 1; constexpr int octave_max = 7; +constexpr int horizontal_notes = 32; + // Equal temperament, A = 440Hz // We calculate note frequencies relative to A4: // 440.0 * pow(pow(2.0, 1.0 / 12.0), N) diff --git a/Applications/Piano/RollWidget.cpp b/Applications/Piano/RollWidget.cpp index 8b2a8f93cd..12e5e9a9db 100644 --- a/Applications/Piano/RollWidget.cpp +++ b/Applications/Piano/RollWidget.cpp @@ -53,7 +53,7 @@ RollWidget::~RollWidget() void RollWidget::paint_event(GUI::PaintEvent& event) { int roll_width = widget_inner_rect().width(); - double note_width = static_cast<double>(roll_width) / m_horizontal_notes; + double note_width = static_cast<double>(roll_width) / horizontal_notes; set_content_size({ roll_width, roll_height }); @@ -74,7 +74,7 @@ void RollWidget::paint_event(GUI::PaintEvent& event) for (int y = 0; y < notes_to_paint; ++y) { int y_pos = y * note_height; - for (int x = 0; x < m_horizontal_notes; ++x) { + for (int x = 0; x < horizontal_notes; ++x) { // This is needed to avoid rounding errors. You can't just use // note_width as the width. int x_pos = x * note_width; @@ -82,9 +82,9 @@ void RollWidget::paint_event(GUI::PaintEvent& event) int distance_to_next_x = next_x_pos - x_pos; Gfx::Rect rect(x_pos, y_pos, distance_to_next_x, note_height); - if (m_roll_notes[y + note_offset][x] == On) + if (m_audio_engine.roll_note(y + note_offset, x) == On) painter.fill_rect(rect, note_pressed_color); - else if (x == m_current_column) + else if (x == m_audio_engine.current_column()) painter.fill_rect(rect, column_playing_color); else if (key_pattern[key_pattern_index] == Black) painter.fill_rect(rect, Color::LightGray); @@ -108,7 +108,7 @@ void RollWidget::mousedown_event(GUI::MouseEvent& event) return; int roll_width = widget_inner_rect().width(); - double note_width = static_cast<double>(roll_width) / m_horizontal_notes; + double note_width = static_cast<double>(roll_width) / horizontal_notes; int y = (event.y() + vertical_scrollbar().value()) - frame_thickness(); y /= note_height; @@ -125,30 +125,7 @@ void RollWidget::mousedown_event(GUI::MouseEvent& event) ++x; x /= note_width; - if (m_roll_notes[y][x] == On) { - if (x == m_current_column) // If you turn off a note that is playing. - m_audio_engine.set_note((note_count - 1) - y, Off); - m_roll_notes[y][x] = Off; - } else { - m_roll_notes[y][x] = On; - } - - update(); -} - -void RollWidget::update_roll() -{ - if (++m_current_column == m_horizontal_notes) - m_current_column = 0; - if (++m_previous_column == m_horizontal_notes) - m_previous_column = 0; - - for (int note = 0; note < note_count; ++note) { - if (m_roll_notes[note][m_previous_column] == On) - m_audio_engine.set_note((note_count - 1) - note, Off); - if (m_roll_notes[note][m_current_column] == On) - m_audio_engine.set_note((note_count - 1) - note, On); - } + m_audio_engine.set_roll_note(y, x, m_audio_engine.roll_note(y, x) == On ? Off : On); update(); } diff --git a/Applications/Piano/RollWidget.h b/Applications/Piano/RollWidget.h index 7eea45bf76..dfbef95300 100644 --- a/Applications/Piano/RollWidget.h +++ b/Applications/Piano/RollWidget.h @@ -37,8 +37,6 @@ class RollWidget final : public GUI::ScrollableWidget { public: virtual ~RollWidget() override; - void update_roll(); - private: RollWidget(GUI::Widget* parent, AudioEngine&); @@ -46,9 +44,4 @@ private: virtual void mousedown_event(GUI::MouseEvent& event) override; AudioEngine& m_audio_engine; - - int m_horizontal_notes { 32 }; - Switch m_roll_notes[note_count][32] { { Off } }; - int m_current_column { 0 }; - int m_previous_column { m_horizontal_notes - 1 }; }; |