TrackManager.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2019-2020, William McPherson <willmcpherson2@gmail.com>
  4. * Copyright (c) 2021, JJ Roberts-White <computerfido@gmail.com>
  5. * Copyright (c) 2022, the SerenityOS developers.
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include "TrackManager.h"
  10. #include "Applications/Piano/Music.h"
  11. #include <AK/NonnullRefPtr.h>
  12. TrackManager::TrackManager()
  13. : m_transport(make_ref_counted<DSP::Transport>(120, 4))
  14. , m_keyboard(make_ref_counted<DSP::Keyboard>(m_transport))
  15. {
  16. add_track();
  17. m_tracks[m_current_track]->set_active(true);
  18. }
  19. void TrackManager::time_forward(int amount)
  20. {
  21. int new_value = (static_cast<int>(m_transport->time()) + amount) % roll_length;
  22. if (new_value < 0) { // If the new time value is negative add roll_length to wrap around
  23. m_transport->set_time(roll_length + new_value);
  24. } else {
  25. m_transport->set_time(new_value);
  26. }
  27. }
  28. void TrackManager::fill_buffer(Span<Sample> buffer)
  29. {
  30. memset(buffer.data(), 0, buffer_size);
  31. for (size_t i = 0; i < buffer.size(); ++i) {
  32. for (auto& track : m_tracks)
  33. track->fill_sample(buffer[i]);
  34. m_transport->set_time(m_transport->time() + 1);
  35. // FIXME: This should be handled automatically by Transport.
  36. if (m_transport->time() >= roll_length) {
  37. m_transport->set_time(0);
  38. if (!m_should_loop)
  39. break;
  40. }
  41. }
  42. memcpy(m_current_back_buffer.data(), buffer.data(), buffer_size);
  43. swap(m_current_front_buffer, m_current_back_buffer);
  44. }
  45. void TrackManager::reset()
  46. {
  47. memset(m_front_buffer.data(), 0, buffer_size);
  48. memset(m_back_buffer.data(), 0, buffer_size);
  49. m_current_front_buffer = m_front_buffer.span();
  50. m_current_back_buffer = m_back_buffer.span();
  51. m_transport->set_time(0);
  52. for (auto& track : m_tracks) {
  53. track->reset();
  54. track->set_active(false);
  55. }
  56. m_tracks[m_current_track]->set_active(true);
  57. }
  58. void TrackManager::add_track()
  59. {
  60. m_tracks.append(make<Track>(m_transport, m_keyboard));
  61. }
  62. int TrackManager::next_track_index() const
  63. {
  64. auto next_track_index = m_current_track + 1;
  65. if (next_track_index >= m_tracks.size())
  66. return 0;
  67. else
  68. return next_track_index;
  69. }