From 7e04560af45304677d4ea0caeb352121af6806f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Fri, 13 May 2022 23:32:44 +0200 Subject: [PATCH] Piano: Use a real transport in the TrackManager This is technically only a stepping stone but needed to happen at some point anyways. Now, there's no more integer time stored in Piano's legacy datastructures directly. --- .../Applications/Piano/AudioPlayerLoop.cpp | 2 +- Userland/Applications/Piano/RollWidget.cpp | 2 +- Userland/Applications/Piano/Track.cpp | 23 ++++++++----------- Userland/Applications/Piano/Track.h | 7 +++--- Userland/Applications/Piano/TrackManager.cpp | 18 +++++++++------ Userland/Applications/Piano/TrackManager.h | 5 ++-- 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Userland/Applications/Piano/AudioPlayerLoop.cpp b/Userland/Applications/Piano/AudioPlayerLoop.cpp index 801179177f..1bbaaf01ad 100644 --- a/Userland/Applications/Piano/AudioPlayerLoop.cpp +++ b/Userland/Applications/Piano/AudioPlayerLoop.cpp @@ -64,7 +64,7 @@ void AudioPlayerLoop::enqueue_audio() do { m_track_manager.fill_buffer(m_buffer); m_wav_writer.write_samples(reinterpret_cast(m_buffer.data()), buffer_size); - } while (m_track_manager.time()); + } while (m_track_manager.transport()->time()); m_track_manager.reset(); m_track_manager.set_should_loop(true); m_wav_writer.finalize(); diff --git a/Userland/Applications/Piano/RollWidget.cpp b/Userland/Applications/Piano/RollWidget.cpp index a705b6412f..6132b5cb61 100644 --- a/Userland/Applications/Piano/RollWidget.cpp +++ b/Userland/Applications/Piano/RollWidget.cpp @@ -160,7 +160,7 @@ void RollWidget::paint_event(GUI::PaintEvent& event) painter.draw_text(note_name_rect, String::formatted("{}", note / notes_per_octave + 1), Gfx::TextAlignment::CenterLeft); } - int x = m_roll_width * (static_cast(m_track_manager.time()) / roll_length); + int x = m_roll_width * (static_cast(m_track_manager.transport()->time()) / roll_length); if (x > x_offset && x <= x_offset + widget_inner_rect().width()) painter.draw_line({ x, 0 }, { x, roll_height }, Gfx::Color::Black); diff --git a/Userland/Applications/Piano/Track.cpp b/Userland/Applications/Piano/Track.cpp index 7d006670d3..7953b634e4 100644 --- a/Userland/Applications/Piano/Track.cpp +++ b/Userland/Applications/Piano/Track.cpp @@ -16,29 +16,26 @@ #include #include -Track::Track(u32 const& time) - : m_time(time) - , m_temporary_transport(make_ref_counted(120, 4)) - , m_delay(make_ref_counted(m_temporary_transport)) - , m_synth(make_ref_counted(m_temporary_transport)) +Track::Track(NonnullRefPtr transport) + : m_transport(move(transport)) + , m_delay(make_ref_counted(m_transport)) + , m_synth(make_ref_counted(m_transport)) { set_volume(volume_max); } void Track::fill_sample(Sample& sample) { - m_temporary_transport->set_time(m_time); - auto playing_notes = LibDSP::RollNotes {}; for (size_t i = 0; i < note_count; ++i) { auto& notes_at_pitch = m_roll_notes[i]; for (auto& note : notes_at_pitch) { - if (note.is_playing(m_time)) + if (note.is_playing(m_transport->time())) playing_notes.set(i, note); } auto& key_at_pitch = m_keyboard_notes[i]; - if (key_at_pitch.has_value() && key_at_pitch.value().is_playing(m_time)) + if (key_at_pitch.has_value() && key_at_pitch.value().is_playing(m_transport->time())) playing_notes.set(i, key_at_pitch.value()); // No need to keep non-playing keyboard notes around. else @@ -70,7 +67,7 @@ void Track::reset() void Track::sync_roll(int note) { - auto it = m_roll_notes[note].find_if([&](auto& roll_note) { return roll_note.off_sample > m_time; }); + auto it = m_roll_notes[note].find_if([&](auto& roll_note) { return roll_note.off_sample > m_transport->time(); }); if (it.is_end()) m_roll_iterators[note] = m_roll_notes[note].begin(); else @@ -115,15 +112,15 @@ void Track::set_keyboard_note(int note, Switch state) // If the note is playing, we need to start releasing it, otherwise just delete if (auto& maybe_roll_note = m_keyboard_notes[note]; maybe_roll_note.has_value()) { auto& roll_note = maybe_roll_note.value(); - if (roll_note.is_playing(m_time)) - roll_note.off_sample = m_time; + if (roll_note.is_playing(m_transport->time())) + roll_note.off_sample = m_transport->time(); else m_keyboard_notes[note] = {}; } } else // FIXME: The end time needs to be far in the future. m_keyboard_notes[note] - = RollNote { m_time, m_time + static_cast(sample_rate) * 10'000, static_cast(note), 0 }; + = RollNote { m_transport->time(), m_transport->time() + static_cast(sample_rate) * 10'000, static_cast(note), 0 }; } void Track::set_volume(int volume) diff --git a/Userland/Applications/Piano/Track.h b/Userland/Applications/Piano/Track.h index 9c239cd75a..a78e6fb37e 100644 --- a/Userland/Applications/Piano/Track.h +++ b/Userland/Applications/Piano/Track.h @@ -16,6 +16,7 @@ #include #include #include +#include using LibDSP::RollNote; using RollIter = AK::SinglyLinkedListIterator, RollNote>; @@ -25,7 +26,7 @@ class Track { AK_MAKE_NONMOVABLE(Track); public: - explicit Track(u32 const& time); + Track(NonnullRefPtr); ~Track() = default; Vector const& recorded_sample() const { return m_recorded_sample; } @@ -50,9 +51,7 @@ private: int m_volume; - u32 const& m_time; - - NonnullRefPtr m_temporary_transport; + NonnullRefPtr m_transport; NonnullRefPtr m_delay; NonnullRefPtr m_synth; diff --git a/Userland/Applications/Piano/TrackManager.cpp b/Userland/Applications/Piano/TrackManager.cpp index 37accde048..f8427fd2b7 100644 --- a/Userland/Applications/Piano/TrackManager.cpp +++ b/Userland/Applications/Piano/TrackManager.cpp @@ -9,20 +9,22 @@ #include "TrackManager.h" #include "Applications/Piano/Music.h" +#include TrackManager::TrackManager() + : m_transport(make_ref_counted(120, 4)) { add_track(); } void TrackManager::time_forward(int amount) { - int new_value = (static_cast(m_time) + amount) % roll_length; + int new_value = (static_cast(m_transport->time()) + amount) % roll_length; if (new_value < 0) { // If the new time value is negative add roll_length to wrap around - m_time = roll_length + new_value; + m_transport->set_time(roll_length + new_value); } else { - m_time = new_value; + m_transport->set_time(new_value); } } @@ -34,8 +36,10 @@ void TrackManager::fill_buffer(Span buffer) for (auto& track : m_tracks) track->fill_sample(buffer[i]); - if (++m_time >= roll_length) { - m_time = 0; + m_transport->set_time(m_transport->time() + 1); + // FIXME: This should be handled automatically by Transport. + if (m_transport->time() >= roll_length) { + m_transport->set_time(0); if (!m_should_loop) break; } @@ -53,7 +57,7 @@ void TrackManager::reset() m_current_front_buffer = m_front_buffer.span(); m_current_back_buffer = m_back_buffer.span(); - m_time = 0; + m_transport->set_time(0); for (auto& track : m_tracks) track->reset(); @@ -84,7 +88,7 @@ void TrackManager::set_octave(int octave) void TrackManager::add_track() { - m_tracks.append(make(m_time)); + m_tracks.append(make(m_transport)); } int TrackManager::next_track_index() diff --git a/Userland/Applications/Piano/TrackManager.h b/Userland/Applications/Piano/TrackManager.h index 3bbc09862b..f45dae6f27 100644 --- a/Userland/Applications/Piano/TrackManager.h +++ b/Userland/Applications/Piano/TrackManager.h @@ -35,7 +35,8 @@ public: m_current_track = track_index; } - int time() const { return m_time; } + NonnullRefPtr transport() const { return m_transport; } + // Legacy API, do not add new users. void time_forward(int amount); void fill_buffer(Span); @@ -58,7 +59,7 @@ private: int m_octave { 4 }; - u32 m_time { 0 }; + NonnullRefPtr m_transport; bool m_should_loop { true }; };