Zrythm v2.0.0-alpha.1
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/enum_utils.h"
11#include "utils/icloneable.h"
12
13namespace zrythm::structure::arrangement
14{
17}
18
19namespace zrythm::structure::tracks
20{
22
29class TrackProcessor final : public QObject, public dsp::ProcessorBase
30{
31 Q_OBJECT
32 QML_ELEMENT
33 QML_UNCREATABLE ("")
34 Q_DISABLE_COPY_MOVE (TrackProcessor)
35
36public:
37 using StereoPortPair = std::pair<std::span<float>, std::span<float>>;
38 using ConstStereoPortPair =
39 std::pair<std::span<const float>, std::span<const float>>;
40 static constexpr auto midi_in_symbol =
41 std::string_view ("track_processor_midi_in");
42
50 using FillEventsCallback = std::function<void (
51 const dsp::ITransport &transport,
52 const dsp::graph::ProcessBlockInfo &time_nfo,
53 dsp::MidiEventBuffer * midi_events,
54 std::optional<StereoPortPair> stereo_ports)>;
55
64 using RecordingCallbackRT = std::function<void (
65 units::sample_t timeline_position,
66 const dsp::ITransport &transport,
67 const dsp::MidiEventBuffer * midi_events,
68 std::optional<ConstStereoPortPair> stereo_ports,
69 units::sample_u32_t nframes)>;
70
80 using AppendMidiInputsToOutputsFunc = std::function<void (
81 dsp::MidiEventBuffer &out_events,
82 const dsp::MidiEventBuffer &in_events,
83 const dsp::graph::ProcessBlockInfo &time_nfo)>;
84
90 using TransformMidiInputsFunc = std::function<void (dsp::MidiEventBuffer &)>;
91
97 using EnabledProvider = std::function<bool ()>;
98
99 using TrackNameProvider = std::function<utils::Utf8String ()>;
100
101 enum class Capabilities : uint8_t
102 {
103 PianoRoll = 1 << 0,
104 AudioTrack = 1 << 1,
105 Recording = 1 << 2,
106 };
107
108 enum class MonitorMode : uint8_t
109 {
110 Off,
111 On,
112 Auto,
113 };
114
115 using MidiEventProviderProcessFunc = std::function<void (
116 const dsp::graph::ProcessBlockInfo &time_nfo,
117 dsp::MidiEventBuffer &output_buffer)>;
118
119 enum class ActiveMidiEventProviders : uint8_t
120 {
121 Timeline = 1 << 0,
122 ClipLauncher = 1 << 1,
123 PianoRoll = 1 << 2,
124 Recording = 1 << 3,
125 Custom = 1 << 4,
126 };
127
128 enum class ActiveAudioProviders : uint8_t
129 {
130 Timeline = 1 << 0,
131 ClipLauncher = 1 << 1,
132 Recording = 1 << 2,
133 Custom = 1 << 3,
134 };
135
142 const dsp::TempoMap &tempo_map,
143 dsp::PortType signal_type,
144 TrackNameProvider track_name_provider,
145 EnabledProvider enabled_provider,
146 Capabilities capabilities,
147 utils::IObjectRegistry &registry,
148 std::optional<FillEventsCallback> fill_events_cb = std::nullopt,
149 std::optional<TransformMidiInputsFunc> transform_midi_inputs_func =
150 std::nullopt,
151 std::optional<AppendMidiInputsToOutputsFunc>
152 append_midi_inputs_to_outputs_func = std::nullopt,
153 RecordingCallbackRT recording_cb =
154 [] (
155 units::sample_t,
156 const dsp::ITransport &,
157 const dsp::MidiEventBuffer *,
158 std::optional<ConstStereoPortPair>,
159 units::sample_u32_t) { },
160 QObject * parent = nullptr);
161 ~TrackProcessor () override;
162
163 bool is_audio () const { return is_audio_; }
164
165 constexpr bool is_midi () const { return is_midi_; }
166
167 utils::Utf8String get_full_designation_for_port (const dsp::Port &port) const;
168
169 // ============================================================================
170 // ProcessorBase Interface
171 // ============================================================================
172
188 const dsp::ITransport &transport,
189 const dsp::TempoMap &tempo_map) noexcept override;
190
191 void custom_prepare_for_processing (
192 const dsp::graph::GraphNode * node,
193 units::sample_rate_t sample_rate,
194 units::sample_u32_t max_block_length) override;
195
196 void custom_release_resources () override;
197
198 // ============================================================================
199
200 dsp::AudioPort &get_stereo_in_port () const
201 {
202 assert (is_audio ());
203 return *get_input_ports ().front ().get_object_as<dsp::AudioPort> ();
204 }
205 dsp::AudioPort &get_stereo_out_port () const
206 {
207 assert (is_audio ());
208 return *get_output_ports ().front ().get_object_as<dsp::AudioPort> ();
209 }
210
211 dsp::ProcessorParameter &get_mono_param () const;
212 dsp::ProcessorParameter &get_input_gain_param () const;
213 dsp::ProcessorParameter &get_output_gain_param () const;
214 dsp::ProcessorParameter &get_monitor_audio_param () const;
215 dsp::ProcessorParameter &get_recording_param () const;
216
217 bool is_recording_armed () const;
218 bool is_recording_armed_rt () const noexcept [[clang::nonblocking]];
219 void set_recording_armed (bool armed);
220
229 dsp::MidiPort &get_midi_in_port () const
230 {
231 assert (is_midi ());
232 return *get_input_ports ().front ().get_object_as<dsp::MidiPort> ();
233 }
234
239 {
240 assert (is_midi ());
241 return *get_output_ports ().front ().get_object_as<dsp::MidiPort> ();
242 }
243
251
260
261 arrangement::AudioTimelineDataProvider &timeline_audio_data_provider ();
262 arrangement::MidiTimelineDataProvider &timeline_midi_data_provider ();
263
264 ClipPlaybackDataProvider &clip_playback_data_provider ();
265
277 void set_hw_midi_channel (int channel);
278
288 ActiveMidiEventProviders event_providers,
289 bool active);
290
299 void
300 set_audio_providers_active (ActiveAudioProviders audio_providers, bool active);
301
305 void
306 set_custom_midi_event_provider (MidiEventProviderProcessFunc process_func);
307
318 const dsp::graph::ProcessBlockInfo &time_nfo,
319 const dsp::ITransport &transport,
320 dsp::MidiEventBuffer &midi_events);
321
331 const dsp::graph::ProcessBlockInfo &time_nfo,
332 const dsp::ITransport &transport,
333 StereoPortPair stereo_ports);
334
335private:
336 friend void to_json (nlohmann::json &j, const TrackProcessor &tp);
337 friend void from_json (const nlohmann::json &j, TrackProcessor &tp);
338
339 friend void init_from (
340 TrackProcessor &obj,
341 const TrackProcessor &other,
342 utils::ObjectCloneType clone_type);
343
347 void set_param_id_caches ();
348
349private:
350 const bool is_midi_;
351 const bool is_audio_;
352 const Capabilities capabilities_;
353
354 const EnabledProvider enabled_provider_;
355 const TrackNameProvider track_name_provider_;
356
357 struct Impl;
358 std::unique_ptr<Impl> impl_;
359};
360}
361
362ENUM_ENABLE_BITSET (
363 zrythm::structure::tracks::TrackProcessor::ActiveMidiEventProviders);
364ENUM_ENABLE_BITSET (
365 zrythm::structure::tracks::TrackProcessor::ActiveAudioProviders);
366ENUM_ENABLE_BITSET (zrythm::structure::tracks::TrackProcessor::Capabilities);
Interface for transport.
Definition itransport.h:47
Packed contiguous buffer for RT MIDI events.
A base class for ports used for connecting processors in the DSP graph.
Definition port.h:37
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:255
Represents a node in a DSP graph.
Definition graph_node.h:180
Track containing AudioClip's.
Definition audio_track.h:14
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 clips) or other so...
dsp::MidiPort & get_midi_out_port() const
MIDI out port, if MIDI.
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.
void set_audio_providers_active(ActiveAudioProviders audio_providers, bool active)
Used to enable or disable audio providers.
std::function< void(dsp::MidiEventBuffer &)> TransformMidiInputsFunc
Function to transform the given MIDI inputs.
std::function< void( const dsp::ITransport &transport, const dsp::graph::ProcessBlockInfo &time_nfo, dsp::MidiEventBuffer * midi_events, std::optional< StereoPortPair > stereo_ports)> FillEventsCallback
Function called during processing to fill events.
std::function< void( units::sample_t timeline_position, const dsp::ITransport &transport, const dsp::MidiEventBuffer * midi_events, std::optional< ConstStereoPortPair > stereo_ports, units::sample_u32_t nframes)> RecordingCallbackRT
Callback to record the given audio or MIDI data.
TrackProcessor(const dsp::TempoMap &tempo_map, dsp::PortType signal_type, TrackNameProvider track_name_provider, EnabledProvider enabled_provider, Capabilities capabilities, utils::IObjectRegistry &registry, 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::MidiEventBuffer *, std::optional< ConstStereoPortPair >, units::sample_u32_t) { }, QObject *parent=nullptr)
Creates a new track processor for the given track.
void fill_midi_events(const dsp::graph::ProcessBlockInfo &time_nfo, const dsp::ITransport &transport, dsp::MidiEventBuffer &midi_events)
Wrapper for MIDI/instrument/chord tracks to fill in MidiEvents from the timeline data.
std::function< void( dsp::MidiEventBuffer &out_events, const dsp::MidiEventBuffer &in_events, const dsp::graph::ProcessBlockInfo &time_nfo)> AppendMidiInputsToOutputsFunc
Custom logic to use when appending the MIDI input events to the output events.
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_hw_midi_in_port() const
Hardware MIDI input port.
void set_hw_midi_channel(int channel)
Sets the hardware MIDI input channel filter for this processor.
dsp::MidiPort & get_midi_in_port() const
MIDI in Port.
Abstract interface for a UUID-keyed object registry.
Lightweight UTF-8 string wrapper with safe conversions.
Definition utf8_string.h:37
Common struct to pass around during processing to avoid repeating the data in function arguments.
Definition graph_node.h:51