Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
piano_roll_track.h
1// SPDX-FileCopyrightText: © 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "dsp/midi_event.h"
7#include "utils/types.h"
8
9#include <QtQmlIntegration>
10
11namespace zrythm::structure::tracks
12{
16class PianoRollTrackMixin : public QObject
17{
18 Q_OBJECT
19 Q_PROPERTY (
20 bool drumMode READ drumMode WRITE setDrumMode NOTIFY drumModeChanged)
21 Q_PROPERTY (
22 bool passthroughMidiInput READ passthroughMidiInput WRITE
23 setPassthroughMidiInput NOTIFY passthroughMidiInputChanged)
24 Q_PROPERTY (
25 std::uint8_t midiChannel READ midiChannel WRITE setMidiChannel NOTIFY
26 midiChannelChanged)
27 QML_ELEMENT
28 QML_UNCREATABLE ("")
29public:
30 PianoRollTrackMixin (QObject * parent = nullptr);
31 Z_DISABLE_COPY_MOVE (PianoRollTrackMixin)
32 ~PianoRollTrackMixin () override = default;
33
34 // ========================================================================
35 // QML Interface
36 // ========================================================================
37
38 std::uint8_t midiChannel () const { return midi_ch_; }
39 void setMidiChannel (std::uint8_t midi_ch)
40 {
41 midi_ch = std::clamp (
42 midi_ch, static_cast<std::uint8_t> (1), static_cast<std::uint8_t> (16));
43 if (midi_ch_ == midi_ch)
44 return;
45
46 midi_ch_ = midi_ch;
47 Q_EMIT midiChannelChanged (midi_ch);
48 }
49 Q_SIGNAL void midiChannelChanged (std::uint8_t midi_ch);
50
51 bool passthroughMidiInput () const { return passthrough_midi_input_; }
52 void setPassthroughMidiInput (bool passthrough)
53 {
54 if (passthrough_midi_input_ == passthrough)
55 return;
56
57 passthrough_midi_input_ = passthrough;
58 Q_EMIT passthroughMidiInputChanged (passthrough);
59 }
60 Q_SIGNAL void passthroughMidiInputChanged (bool passthrough);
61
62 bool drumMode () const { return drum_mode_; }
63 void setDrumMode (bool drum_mode)
64 {
65 if (drum_mode_ == drum_mode)
66 return;
67
68 drum_mode_ = drum_mode;
69 Q_EMIT drumModeChanged (drum_mode);
70 }
71 Q_SIGNAL void drumModeChanged (bool drum_mode);
72
73 // ========================================================================
74
75 bool allow_only_specific_midi_channels () const
76 {
77 return midi_channels_.has_value ();
78 }
79 auto &midi_channels_to_allow () const { return midi_channels_.value (); }
80
85 {
86 // change the MIDI channel on the midi input to the channel set on the track
87 if (!passthrough_midi_input_)
88 {
89 events.set_channel (midi_ch_);
90 }
91 }
92
93private:
94 static constexpr auto kDrumModeKey = "drumMode"sv;
95 static constexpr auto kMidiChKey = "midiCh"sv;
96 static constexpr auto kPassthroughMidiInputKey = "passthroughMidiInput"sv;
97 static constexpr auto kMidiChannelsKey = "midiChannels"sv;
98 friend void to_json (nlohmann::json &j, const PianoRollTrackMixin &track)
99 {
100 j[kDrumModeKey] = track.drum_mode_;
101 j[kMidiChKey] = track.midi_ch_;
102 j[kPassthroughMidiInputKey] = track.passthrough_midi_input_.load ();
103 j[kMidiChannelsKey] = track.midi_channels_;
104 }
105 friend void from_json (const nlohmann::json &j, PianoRollTrackMixin &track)
106 {
107 j.at (kDrumModeKey).get_to (track.drum_mode_);
108 j.at (kMidiChKey).get_to (track.midi_ch_);
109 bool passthrough_midi_input{};
110 j.at (kPassthroughMidiInputKey).get_to (passthrough_midi_input);
111 track.passthrough_midi_input_.store (passthrough_midi_input);
112 if (j.contains (kMidiChannelsKey))
113 {
114 j.at (kMidiChannelsKey).get_to (track.midi_channels_);
115 }
116 }
117
118 friend void init_from (
119 PianoRollTrackMixin &obj,
120 const PianoRollTrackMixin &other,
121 utils::ObjectCloneType clone_type);
122
123private:
127 bool drum_mode_ = false;
128
130 midi_byte_t midi_ch_ = 1;
131
139 std::atomic_bool passthrough_midi_input_ = false;
140
146 std::optional<std::array<bool, 16>> midi_channels_;
147};
148}
A lock-free thread-safe vector of MidiEvents.
Definition midi_event.h:78
void set_channel(midi_byte_t channel)
Sets the given MIDI channel on all applicable MIDI events.
void transform_midi_inputs_func(dsp::MidiEventVector &events) const
Callback to be used as TrackProcessor's transform function.
uint8_t midi_byte_t
MIDI byte.
Definition types.h:55