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 <string_view>
7
8#include "dsp/midi_event.h"
9#include "utils/icloneable.h"
10
11#include <QtQmlIntegration/qqmlintegration.h>
12
13#include <nlohmann/json_fwd.hpp>
14
15using std::literals::string_view_literals::operator""sv;
16
17namespace zrythm::structure::tracks
18{
22class PianoRollTrackMixin : public QObject
23{
24 Q_OBJECT
25 Q_PROPERTY (
26 bool drumMode READ drumMode WRITE setDrumMode NOTIFY drumModeChanged)
27 Q_PROPERTY (
28 bool passthroughMidiInput READ passthroughMidiInput WRITE
29 setPassthroughMidiInput NOTIFY passthroughMidiInputChanged)
30 Q_PROPERTY (
31 std::uint8_t midiChannel READ midiChannel WRITE setMidiChannel NOTIFY
32 midiChannelChanged)
33 QML_ELEMENT
34 QML_UNCREATABLE ("")
35public:
36 PianoRollTrackMixin (QObject * parent = nullptr);
37 Q_DISABLE_COPY_MOVE (PianoRollTrackMixin)
38 ~PianoRollTrackMixin () override = default;
39
40 // ========================================================================
41 // QML Interface
42 // ========================================================================
43
44 std::uint8_t midiChannel () const { return midi_ch_; }
45 void setMidiChannel (std::uint8_t midi_ch)
46 {
47 midi_ch = std::clamp (
48 midi_ch, static_cast<std::uint8_t> (1), static_cast<std::uint8_t> (16));
49 if (midi_ch_ == midi_ch)
50 return;
51
52 midi_ch_ = midi_ch;
53 Q_EMIT midiChannelChanged (midi_ch);
54 }
55 Q_SIGNAL void midiChannelChanged (std::uint8_t midi_ch);
56
57 bool passthroughMidiInput () const { return passthrough_midi_input_; }
58 void setPassthroughMidiInput (bool passthrough)
59 {
60 if (passthrough_midi_input_ == passthrough)
61 return;
62
63 passthrough_midi_input_ = passthrough;
64 Q_EMIT passthroughMidiInputChanged (passthrough);
65 }
66 Q_SIGNAL void passthroughMidiInputChanged (bool passthrough);
67
68 bool drumMode () const { return drum_mode_; }
69 void setDrumMode (bool drum_mode)
70 {
71 if (drum_mode_ == drum_mode)
72 return;
73
74 drum_mode_ = drum_mode;
75 Q_EMIT drumModeChanged (drum_mode);
76 }
77 Q_SIGNAL void drumModeChanged (bool drum_mode);
78
79 // ========================================================================
80
81 bool allow_only_specific_midi_channels () const
82 {
83 return midi_channels_.has_value ();
84 }
85 auto &midi_channels_to_allow () const { return midi_channels_.value (); }
86
91 {
92 // change the MIDI channel on the midi input to the channel set on the track
93 if (!passthrough_midi_input_)
94 {
95 events.set_channel (midi_ch_);
96 }
97 }
98
99private:
100 static constexpr auto kDrumModeKey = "drumMode"sv;
101 static constexpr auto kMidiChKey = "midiChannel"sv;
102 static constexpr auto kPassthroughMidiInputKey = "passthroughMidiInput"sv;
103 static constexpr auto kMidiChannelsKey = "midiChannels"sv;
104 friend void to_json (nlohmann::json &j, const PianoRollTrackMixin &track);
105 friend void from_json (const nlohmann::json &j, PianoRollTrackMixin &track);
106
107 friend void init_from (
108 PianoRollTrackMixin &obj,
109 const PianoRollTrackMixin &other,
110 utils::ObjectCloneType clone_type);
111
112private:
116 bool drum_mode_ = false;
117
119 midi_byte_t midi_ch_ = 1;
120
128 std::atomic_bool passthrough_midi_input_ = false;
129
135 std::optional<std::array<bool, 16>> midi_channels_;
136};
137}
A lock-free thread-safe vector of MidiEvents.
Definition midi_event.h:74
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.
std::uint8_t midi_byte_t
MIDI byte.
Definition midi.h:43