Track.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (c) 2021-2022, kleines Filmröllchen <filmroellchen@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/DisjointChunks.h>
  8. #include <AK/FixedArray.h>
  9. #include <AK/NonnullRefPtr.h>
  10. #include <AK/RefCounted.h>
  11. #include <AK/Weakable.h>
  12. #include <LibDSP/Clip.h>
  13. #include <LibDSP/Effects.h>
  14. #include <LibDSP/Keyboard.h>
  15. #include <LibDSP/Music.h>
  16. #include <LibDSP/Processor.h>
  17. #include <LibDSP/Synthesizers.h>
  18. namespace DSP {
  19. // A track is also known as a channel and serves as a container for the audio pipeline: clips -> processors -> mixing & output
  20. class Track : public RefCounted<Track>
  21. , public Weakable<Track> {
  22. public:
  23. virtual ~Track() = default;
  24. virtual bool check_processor_chain_valid() const = 0;
  25. bool add_processor(NonnullRefPtr<Processor> new_processor);
  26. // Creates the current signal of the track by processing current note or audio data through the processing chain.
  27. void current_signal(FixedArray<Sample>& output_signal);
  28. void write_cached_signal_to(Span<Sample> output_signal);
  29. // We are informed of an audio buffer size change. This happens off-audio-thread so we can allocate.
  30. ErrorOr<void> resize_internal_buffers_to(size_t buffer_size);
  31. Vector<NonnullRefPtr<Processor>> const& processor_chain() const { return m_processor_chain; }
  32. NonnullRefPtr<Transport const> transport() const { return m_transport; }
  33. NonnullRefPtr<DSP::Effects::Mastering> track_mastering() { return m_track_mastering; }
  34. // FIXME: These two getters are temporary until we have dynamic processor UI
  35. NonnullRefPtr<Synthesizers::Classic> synth();
  36. NonnullRefPtr<Effects::Delay> delay();
  37. protected:
  38. Track(NonnullRefPtr<Transport> transport, NonnullRefPtr<Keyboard> keyboard)
  39. : m_transport(move(transport))
  40. , m_track_mastering(make_ref_counted<Effects::Mastering>(m_transport))
  41. , m_keyboard(move(keyboard))
  42. {
  43. }
  44. bool check_processor_chain_valid_with_initial_type(SignalType initial_type) const;
  45. // Subclasses override to provide the base signal to the processing chain
  46. virtual void compute_current_clips_signal() = 0;
  47. Vector<NonnullRefPtr<Processor>> m_processor_chain;
  48. NonnullRefPtr<Transport> m_transport;
  49. NonnullRefPtr<Effects::Mastering> m_track_mastering;
  50. NonnullRefPtr<Keyboard> m_keyboard;
  51. // The current signal is stored here, to prevent unnecessary reallocation.
  52. Signal m_current_signal { FixedArray<Sample> {} };
  53. // These are so that we don't have to allocate a secondary buffer in current_signal().
  54. // A sample buffer possibly used by the processor chain.
  55. Signal m_secondary_sample_buffer { FixedArray<Sample> {} };
  56. // A note buffer possibly used by the processor chain.
  57. Signal m_secondary_note_buffer { RollNotes {} };
  58. private:
  59. Atomic<bool> m_sample_lock;
  60. FixedArray<Sample> m_cached_sample_buffer = {};
  61. };
  62. class NoteTrack final : public Track {
  63. public:
  64. virtual ~NoteTrack() override = default;
  65. NoteTrack(NonnullRefPtr<Transport> transport, NonnullRefPtr<Keyboard> keyboard)
  66. : Track(move(transport), move(keyboard))
  67. {
  68. m_current_signal = RollNotes {};
  69. }
  70. bool check_processor_chain_valid() const override;
  71. ReadonlySpan<NonnullRefPtr<NoteClip>> notes() const { return m_clips.span(); }
  72. Optional<RollNote> note_at(u32 time, u8 pitch) const;
  73. void set_note(RollNote note);
  74. void remove_note(RollNote note);
  75. void add_clip(u32 start_time, u32 end_time);
  76. protected:
  77. void compute_current_clips_signal() override;
  78. private:
  79. Vector<NonnullRefPtr<NoteClip>> m_clips;
  80. };
  81. class AudioTrack final : public Track {
  82. public:
  83. virtual ~AudioTrack() override = default;
  84. AudioTrack(NonnullRefPtr<Transport> transport, NonnullRefPtr<Keyboard> keyboard)
  85. : Track(move(transport), move(keyboard))
  86. {
  87. }
  88. bool check_processor_chain_valid() const override;
  89. Vector<NonnullRefPtr<AudioClip>> const& clips() const { return m_clips; }
  90. protected:
  91. void compute_current_clips_signal() override;
  92. private:
  93. Vector<NonnullRefPtr<AudioClip>> m_clips;
  94. };
  95. }