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/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 static constexpr auto midi_in_symbol =
40 std::string_view ("track_processor_midi_in");
41
49 using FillEventsCallback = std::function<void (
50 const dsp::ITransport &transport,
51 const dsp::graph::ProcessBlockInfo &time_nfo,
52 dsp::MidiEventVector * midi_events,
53 std::optional<StereoPortPair> stereo_ports)>;
54
63 using RecordingCallbackRT = std::function<void (
64 units::sample_t timeline_position,
65 const dsp::ITransport &transport,
66 std::optional<std::span<const dsp::MidiEvent>> midi_events,
67 std::optional<ConstStereoPortPair> stereo_ports,
68 units::sample_u32_t nframes)>;
69
79 using AppendMidiInputsToOutputsFunc = std::function<void (
80 dsp::MidiEventVector &out_events,
81 const dsp::MidiEventVector &in_events,
82 const dsp::graph::ProcessBlockInfo &time_nfo)>;
83
89 using TransformMidiInputsFunc = std::function<void (dsp::MidiEventVector &)>;
90
96 using EnabledProvider = std::function<bool ()>;
97
98 using TrackNameProvider = std::function<utils::Utf8String ()>;
99
100 enum class Capabilities : uint8_t
101 {
102 PianoRoll = 1 << 0,
103 AudioTrack = 1 << 1,
104 Recording = 1 << 2,
105 };
106
107 enum class MonitorMode : uint8_t
108 {
109 Off,
110 On,
111 Auto,
112 };
113
114 using MidiEventProviderProcessFunc = std::function<void (
115 const dsp::graph::ProcessBlockInfo &time_nfo,
116 dsp::MidiEventVector &output_buffer)>;
117
118 enum class ActiveMidiEventProviders : uint8_t
119 {
120 Timeline = 1 << 0,
121 ClipLauncher = 1 << 1,
122 PianoRoll = 1 << 2,
123 Recording = 1 << 3,
124 Custom = 1 << 4,
125 };
126
127 enum class ActiveAudioProviders : uint8_t
128 {
129 Timeline = 1 << 0,
130 ClipLauncher = 1 << 1,
131 Recording = 1 << 2,
132 Custom = 1 << 3,
133 };
134
141 const dsp::TempoMap &tempo_map,
142 dsp::PortType signal_type,
143 TrackNameProvider track_name_provider,
144 EnabledProvider enabled_provider,
145 Capabilities capabilities,
146 utils::IObjectRegistry &registry,
147 std::optional<FillEventsCallback> fill_events_cb = std::nullopt,
148 std::optional<TransformMidiInputsFunc> transform_midi_inputs_func =
149 std::nullopt,
150 std::optional<AppendMidiInputsToOutputsFunc>
151 append_midi_inputs_to_outputs_func = std::nullopt,
152 RecordingCallbackRT recording_cb =
153 [] (
154 units::sample_t,
155 const dsp::ITransport &,
156 std::optional<std::span<const dsp::MidiEvent>>,
157 std::optional<ConstStereoPortPair>,
158 units::sample_u32_t) { },
159 QObject * parent = nullptr);
160 ~TrackProcessor () override;
161
162 bool is_audio () const { return is_audio_; }
163
164 constexpr bool is_midi () const { return is_midi_; }
165
166 utils::Utf8String get_full_designation_for_port (const dsp::Port &port) const;
167
168 // ============================================================================
169 // ProcessorBase Interface
170 // ============================================================================
171
187 const dsp::ITransport &transport,
188 const dsp::TempoMap &tempo_map) noexcept override;
189
190 void custom_prepare_for_processing (
191 const dsp::graph::GraphNode * node,
192 units::sample_rate_t sample_rate,
193 units::sample_u32_t max_block_length) override;
194
195 void custom_release_resources () override;
196
197 // ============================================================================
198
199 dsp::AudioPort &get_stereo_in_port () const
200 {
201 assert (is_audio ());
202 return *get_input_ports ().front ().get_object_as<dsp::AudioPort> ();
203 }
204 dsp::AudioPort &get_stereo_out_port () const
205 {
206 assert (is_audio ());
207 return *get_output_ports ().front ().get_object_as<dsp::AudioPort> ();
208 }
209
210 dsp::ProcessorParameter &get_mono_param () const;
211 dsp::ProcessorParameter &get_input_gain_param () const;
212 dsp::ProcessorParameter &get_output_gain_param () const;
213 dsp::ProcessorParameter &get_monitor_audio_param () const;
214 dsp::ProcessorParameter &get_recording_param () const;
215
216 bool is_recording_armed () const;
217 bool is_recording_armed_rt () const noexcept [[clang::nonblocking]];
218 void set_recording_armed (bool armed);
219
228 dsp::MidiPort &get_midi_in_port () const
229 {
230 assert (is_midi ());
231 return *get_input_ports ().front ().get_object_as<dsp::MidiPort> ();
232 }
233
238 {
239 assert (is_midi ());
240 return *get_output_ports ().front ().get_object_as<dsp::MidiPort> ();
241 }
242
250
259
260 arrangement::AudioTimelineDataProvider &timeline_audio_data_provider ();
261 arrangement::MidiTimelineDataProvider &timeline_midi_data_provider ();
262
263 ClipPlaybackDataProvider &clip_playback_data_provider ();
264
276 void set_hw_midi_channel (int channel);
277
287 ActiveMidiEventProviders event_providers,
288 bool active);
289
298 void
299 set_audio_providers_active (ActiveAudioProviders audio_providers, bool active);
300
304 void
305 set_custom_midi_event_provider (MidiEventProviderProcessFunc process_func);
306
317 const dsp::graph::ProcessBlockInfo &time_nfo,
318 const dsp::ITransport &transport,
319 dsp::MidiEventVector &midi_events);
320
330 const dsp::graph::ProcessBlockInfo &time_nfo,
331 const dsp::ITransport &transport,
332 StereoPortPair stereo_ports);
333
334private:
335 friend void to_json (nlohmann::json &j, const TrackProcessor &tp);
336 friend void from_json (const nlohmann::json &j, TrackProcessor &tp);
337
338 friend void init_from (
339 TrackProcessor &obj,
340 const TrackProcessor &other,
341 utils::ObjectCloneType clone_type);
342
346 void set_param_id_caches ();
347
348private:
349 const bool is_midi_;
350 const bool is_audio_;
351 const Capabilities capabilities_;
352
353 const EnabledProvider enabled_provider_;
354 const TrackNameProvider track_name_provider_;
355
356 struct Impl;
357 std::unique_ptr<Impl> impl_;
358};
359}
360
361ENUM_ENABLE_BITSET (
362 zrythm::structure::tracks::TrackProcessor::ActiveMidiEventProviders);
363ENUM_ENABLE_BITSET (zrythm::structure::tracks::TrackProcessor::Capabilities);
Audio port specifics.
Definition audio_port.h:25
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:21
A base class for ports used for connecting processors in the DSP graph.
Definition port.h:34
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: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.
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 &, std::optional< std::span< const dsp::MidiEvent > >, std::optional< ConstStereoPortPair >, units::sample_u32_t) { }, QObject *parent=nullptr)
Creates a new track processor for the given track.
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::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_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.
std::function< void( units::sample_t timeline_position, const dsp::ITransport &transport, std::optional< std::span< const dsp::MidiEvent > > midi_events, std::optional< ConstStereoPortPair > stereo_ports, units::sample_u32_t nframes)> RecordingCallbackRT
Callback to record the given audio or MIDI data.
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.
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