Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
track_processor.h
1// SPDX-FileCopyrightText: © 2019-2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <memory>
7
8#include "dsp/port.h"
9#include "dsp/processor_base.h"
10#include "utils/icloneable.h"
11
12namespace zrythm::structure::arrangement
13{
16}
17
18namespace zrythm::structure::tracks
19{
21
28class TrackProcessor final : public QObject, public dsp::ProcessorBase
29{
30 Q_OBJECT
31 QML_ELEMENT
32 QML_UNCREATABLE ("")
33 Q_DISABLE_COPY_MOVE (TrackProcessor)
34
35public:
36 using StereoPortPair = std::pair<std::span<float>, std::span<float>>;
37 using ConstStereoPortPair =
38 std::pair<std::span<const float>, std::span<const float>>;
39
47 using FillEventsCallback = std::function<void (
48 const dsp::ITransport &transport,
49 const dsp::graph::ProcessBlockInfo &time_nfo,
50 dsp::MidiEventVector * midi_events,
51 std::optional<StereoPortPair> stereo_ports)>;
52
61 using RecordingCallbackRT = std::function<void (
62 units::sample_t timeline_position,
63 const dsp::ITransport &transport,
64 const dsp::MidiEventVector * midi_events,
65 std::optional<ConstStereoPortPair> stereo_ports)>;
66
76 using AppendMidiInputsToOutputsFunc = std::function<void (
77 dsp::MidiEventVector &out_events,
78 const dsp::MidiEventVector &in_events,
79 const dsp::graph::ProcessBlockInfo &time_nfo)>;
80
86 using TransformMidiInputsFunc = std::function<void (dsp::MidiEventVector &)>;
87
93 using EnabledProvider = std::function<bool ()>;
94
95 using TrackNameProvider = std::function<utils::Utf8String ()>;
96
97 enum class Capabilities : uint8_t
98 {
99 PianoRoll = 1 << 0,
100 MidiCC = 1 << 1,
101 AudioTrack = 1 << 2,
102 Recording = 1 << 3,
103 };
104
105 enum class MonitorMode : uint8_t
106 {
107 Off,
108 On,
109 Auto,
110 };
111
112 using MidiEventProviderProcessFunc = std::function<void (
113 const dsp::graph::ProcessBlockInfo &time_nfo,
114 dsp::MidiEventVector &output_buffer)>;
115
116 enum class ActiveMidiEventProviders : uint8_t
117 {
118 Timeline = 1 << 0,
119 ClipLauncher = 1 << 1,
120 PianoRoll = 1 << 2,
121 Recording = 1 << 3,
122 Custom = 1 << 4,
123 };
124
125 enum class ActiveAudioProviders : uint8_t
126 {
127 Timeline = 1 << 0,
128 ClipLauncher = 1 << 1,
129 Recording = 1 << 2,
130 Custom = 1 << 3,
131 };
132
139 const dsp::TempoMap &tempo_map,
140 dsp::PortType signal_type,
141 TrackNameProvider track_name_provider,
142 EnabledProvider enabled_provider,
143 Capabilities capabilities,
144 ProcessorBaseDependencies dependencies,
145 std::optional<FillEventsCallback> fill_events_cb = std::nullopt,
146 std::optional<TransformMidiInputsFunc> transform_midi_inputs_func =
147 std::nullopt,
148 std::optional<AppendMidiInputsToOutputsFunc>
149 append_midi_inputs_to_outputs_func = std::nullopt,
150 RecordingCallbackRT recording_cb =
151 [] (
152 units::sample_t,
153 const dsp::ITransport &,
154 const dsp::MidiEventVector *,
155 std::optional<ConstStereoPortPair>) { },
156 QObject * parent = nullptr);
157 ~TrackProcessor () override;
158
159 bool is_audio () const { return is_audio_; }
160
161 constexpr bool is_midi () const { return is_midi_; }
162
163 utils::Utf8String get_full_designation_for_port (const dsp::Port &port) const;
164
165 // ============================================================================
166 // ProcessorBase Interface
167 // ============================================================================
168
184 const dsp::ITransport &transport,
185 const dsp::TempoMap &tempo_map) noexcept override;
186
187 void custom_prepare_for_processing (
188 const dsp::graph::GraphNode * node,
189 units::sample_rate_t sample_rate,
190 units::sample_u32_t max_block_length) override;
191
192 void custom_release_resources () override;
193
194 // ============================================================================
195
196 dsp::AudioPort &get_stereo_in_port () const
197 {
198 assert (is_audio ());
199 return *get_input_ports ().front ().get_object_as<dsp::AudioPort> ();
200 }
201 dsp::AudioPort &get_stereo_out_port () const
202 {
203 assert (is_audio ());
204 return *get_output_ports ().front ().get_object_as<dsp::AudioPort> ();
205 }
206
207 dsp::ProcessorParameter &get_mono_param () const;
208 dsp::ProcessorParameter &get_input_gain_param () const;
209 dsp::ProcessorParameter &get_output_gain_param () const;
210 dsp::ProcessorParameter &get_monitor_audio_param () const;
211 dsp::ProcessorParameter &get_recording_param () const;
212
213 bool is_recording_armed () const;
214 bool is_recording_armed_rt () const noexcept [[clang::nonblocking]];
215 void set_recording_armed (bool armed);
216
223 dsp::ProcessorParameter &
225
234 dsp::MidiPort &get_midi_in_port () const
235 {
236 assert (is_midi ());
237 return *get_input_ports ().front ().get_object_as<dsp::MidiPort> ();
238 }
239
244 {
245 assert (is_midi ());
246 return *get_output_ports ().front ().get_object_as<dsp::MidiPort> ();
247 }
248
256 {
257 return *get_input_ports ().at (1).get_object_as<dsp::MidiPort> ();
258 }
259
260 arrangement::AudioTimelineDataProvider &timeline_audio_data_provider ();
261 arrangement::MidiTimelineDataProvider &timeline_midi_data_provider ();
262
263 ClipPlaybackDataProvider &clip_playback_data_provider ();
264
274 ActiveMidiEventProviders event_providers,
275 bool active);
276
285 void
286 set_audio_providers_active (ActiveAudioProviders audio_providers, bool active);
287
291 void
292 set_custom_midi_event_provider (MidiEventProviderProcessFunc process_func);
293
304 const dsp::graph::ProcessBlockInfo &time_nfo,
305 const dsp::ITransport &transport,
306 dsp::MidiEventVector &midi_events);
307
317 const dsp::graph::ProcessBlockInfo &time_nfo,
318 const dsp::ITransport &transport,
319 StereoPortPair stereo_ports);
320
321private:
322 friend void to_json (nlohmann::json &j, const TrackProcessor &tp);
323 friend void from_json (const nlohmann::json &j, TrackProcessor &tp);
324
325 friend void init_from (
326 TrackProcessor &obj,
327 const TrackProcessor &other,
328 utils::ObjectCloneType clone_type);
329
333 [[gnu::hot]] void add_events_from_midi_cc_control_ports (
334 dsp::MidiEventVector &events,
335 units::sample_u32_t local_offset);
336
340 void set_param_id_caches ();
341
342// TODO
343#if 0
344 void set_midi_mappings ();
345#endif
346
347private:
348 const bool is_midi_;
349 const bool is_audio_;
350 const Capabilities capabilities_;
351
352 const EnabledProvider enabled_provider_;
353 const TrackNameProvider track_name_provider_;
354
355 struct Impl;
356 std::unique_ptr<Impl> impl_;
357};
358}
359
360ENUM_ENABLE_BITSET (
361 zrythm::structure::tracks::TrackProcessor::ActiveMidiEventProviders);
362ENUM_ENABLE_BITSET (zrythm::structure::tracks::TrackProcessor::Capabilities);
Audio port specifics.
Definition audio_port.h:26
Interface for transport.
Definition itransport.h:16
A lock-free thread-safe vector of MidiEvents.
Definition midi_event.h:74
MIDI port specifics.
Definition midi_port.h:22
A base class for ports used for connecting processors in the DSP graph.
Definition port.h:29
A base class for processors in the DSP graph.
Processor parameter that accepts automation and modulation sources and integrates with QML and the DS...
Definition parameter.h:252
Represents a node in a DSP graph.
Definition graph_node.h:173
Track containing AudioRegion's.
Definition audio_track.h:15
Event provider for clip launcher-based MIDI and audio events.
A TrackProcessor is a standalone processor that is used as the first step when processing a track in ...
dsp::MidiPort & get_piano_roll_port() const
MIDI input for receiving MIDI signals from the piano roll (i.e., MIDI notes inside regions) or other ...
std::function< void( const dsp::ITransport &transport, const dsp::graph::ProcessBlockInfo &time_nfo, dsp::MidiEventVector * midi_events, std::optional< StereoPortPair > stereo_ports)> FillEventsCallback
Function called during processing to fill events.
dsp::MidiPort & get_midi_out_port() const
MIDI out port, if MIDI.
void fill_midi_events(const dsp::graph::ProcessBlockInfo &time_nfo, const dsp::ITransport &transport, dsp::MidiEventVector &midi_events)
Wrapper for MIDI/instrument/chord tracks to fill in MidiEvents from the timeline data.
void fill_audio_events(const dsp::graph::ProcessBlockInfo &time_nfo, const dsp::ITransport &transport, StereoPortPair stereo_ports)
Wrapper for audio tracks to fill in StereoPorts from the timeline data.
TrackProcessor(const dsp::TempoMap &tempo_map, dsp::PortType signal_type, TrackNameProvider track_name_provider, EnabledProvider enabled_provider, Capabilities capabilities, ProcessorBaseDependencies dependencies, std::optional< FillEventsCallback > fill_events_cb=std::nullopt, std::optional< TransformMidiInputsFunc > transform_midi_inputs_func=std::nullopt, std::optional< AppendMidiInputsToOutputsFunc > append_midi_inputs_to_outputs_func=std::nullopt, RecordingCallbackRT recording_cb=[](units::sample_t, const dsp::ITransport &, const dsp::MidiEventVector *, std::optional< ConstStereoPortPair >) { }, QObject *parent=nullptr)
Creates a new track processor for the given track.
void set_audio_providers_active(ActiveAudioProviders audio_providers, bool active)
Used to enable or disable audio providers.
std::function< void( units::sample_t timeline_position, const dsp::ITransport &transport, const dsp::MidiEventVector * midi_events, std::optional< ConstStereoPortPair > stereo_ports)> RecordingCallbackRT
Callback to record the given audio or MIDI data.
dsp::ProcessorParameter & get_midi_cc_param(midi_byte_t channel, midi_byte_t control_no)
std::function< void(dsp::MidiEventVector &)> TransformMidiInputsFunc
Function to transform the given MIDI inputs.
void set_midi_providers_active(ActiveMidiEventProviders event_providers, bool active)
Used to enable or disable MIDI event providers.
void set_custom_midi_event_provider(MidiEventProviderProcessFunc process_func)
Replaces the "Custom" MIDI event provider.
std::function< bool()> EnabledProvider
Function that returns if the track for this processor is enabled.
void custom_process_block(dsp::graph::ProcessBlockInfo time_nfo, const dsp::ITransport &transport, const dsp::TempoMap &tempo_map) noexcept override
Process the TrackProcessor.
dsp::MidiPort & get_midi_in_port() const
MIDI in Port.
std::function< void( dsp::MidiEventVector &out_events, const dsp::MidiEventVector &in_events, const dsp::graph::ProcessBlockInfo &time_nfo)> AppendMidiInputsToOutputsFunc
Custom logic to use when appending the MIDI input events to the output events.
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:37
std::uint8_t midi_byte_t
MIDI byte.
Definition midi.h:43
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition graph_node.h:51