Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
midi_mapping.h
1// SPDX-FileCopyrightText: © 2019-2022, 2024-2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include "dsp/port.h"
7#include "utils/icloneable.h"
8
9#define MIDI_MAPPINGS (PROJECT->midi_mappings_)
10
11namespace zrythm::engine::session
12{
16class MidiMapping : public QObject
17{
18 Q_OBJECT
19 QML_ELEMENT
20 QML_UNCREATABLE ("")
21
22public:
23 MidiMapping (
24 dsp::ProcessorParameterRegistry &param_registry,
25 QObject * parent = nullptr);
26 Z_DISABLE_COPY_MOVE (MidiMapping)
27
28public:
29 friend void init_from (
30 MidiMapping &obj,
31 const MidiMapping &other,
32 utils::ObjectCloneType clone_type);
33
34 void set_enabled (bool enabled) { enabled_.store (enabled); }
35
36 void apply (std::array<midi_byte_t, 3> buf);
37
38private:
39 static constexpr auto kKeyKey = "key"sv;
40 static constexpr auto kDeviceIdKey = "deviceIdentifier"sv;
41 static constexpr auto kDestIdKey = "destId"sv;
42 static constexpr auto kEnabledKey = "enabled"sv;
43 friend void to_json (nlohmann::json &j, const MidiMapping &mapping)
44 {
45 j[kKeyKey] = mapping.key_;
46 j[kDeviceIdKey] = mapping.device_id_;
47 if (mapping.dest_id_)
48 {
49 j[kDestIdKey] = *mapping.dest_id_;
50 }
51 j[kEnabledKey] = mapping.enabled_.load ();
52 }
53 friend void from_json (const nlohmann::json &j, MidiMapping &mapping)
54 {
55 j.at (kKeyKey).get_to (mapping.key_);
56 j.at (kDeviceIdKey).get_to (mapping.device_id_);
57 if (j.contains (kDestIdKey))
58 {
59 mapping.dest_id_.emplace (mapping.param_registry_);
60 j.at (kDestIdKey).get_to (*mapping.dest_id_);
61 }
62 mapping.enabled_.store (j.at (kEnabledKey).get<bool> ());
63 }
64
65public:
66 dsp::ProcessorParameterRegistry &param_registry_;
67
69 std::array<midi_byte_t, 3> key_ = {};
70
76 std::optional<utils::Utf8String> device_id_;
77
79 std::optional<dsp::ProcessorParameterUuidReference> dest_id_;
80
82 /* TODO: check if really should be atomic */
83 std::atomic<bool> enabled_ = false;
84};
85
89class MidiMappings final
90{
91public:
92 MidiMappings (dsp::ProcessorParameterRegistry &param_registry);
93
102 void bind_at (
103 std::array<midi_byte_t, 3> buf,
104 std::optional<utils::Utf8String> device_id,
105 dsp::ProcessorParameterUuidReference dest_port,
106 int idx,
107 bool fire_events);
108
115 void unbind (int idx, bool fire_events);
116
117 void bind_device (
118 std::array<midi_byte_t, 3> buf,
119 std::optional<utils::Utf8String> device_id,
120 dsp::ProcessorParameterUuidReference dest_port,
121 bool fire_events)
122 {
123 bind_at (
124 buf, device_id, dest_port, static_cast<int> (mappings_.size ()),
125 fire_events);
126 }
127
128 void bind_track (
129 std::array<midi_byte_t, 3> buf,
130 dsp::ProcessorParameterUuidReference dest_port,
131 bool fire_events)
132 {
133 bind_at (
134 buf, std::nullopt, dest_port, static_cast<int> (mappings_.size ()),
135 fire_events);
136 }
137
138 int get_mapping_index (const MidiMapping &mapping) const;
139
148
152 void apply (const midi_byte_t * buf);
153
162 const dsp::ProcessorParameter &dest_port,
163 std::vector<MidiMapping *> * arr) const;
164
165 friend void init_from (
166 MidiMappings &obj,
167 const MidiMappings &other,
168 utils::ObjectCloneType clone_type)
169 {
170 // TODO
171 // utils::clone_unique_ptr_container (obj.mappings_, other.mappings_);
172 }
173
174private:
175 static constexpr auto kMappingsKey = "mappings"sv;
176 friend void to_json (nlohmann::json &j, const MidiMappings &mappings)
177 {
178 j[kMappingsKey] = mappings.mappings_;
179 }
180 friend void from_json (const nlohmann::json &j, MidiMappings &mappings);
181
182public:
183 std::vector<std::unique_ptr<MidiMapping>> mappings_;
184
185private:
186 dsp::ProcessorParameterRegistry &param_registry_;
187};
188
189}
A lock-free thread-safe vector of MidiEvents.
Definition midi_event.h:78
Wrapper over a Uuid registry that provides (slow) lookup by unique ID.
Definition parameter.h:523
Processor parameter that accepts automation and modulation sources and integrates with QML and the DS...
Definition parameter.h:225
std::optional< dsp::ProcessorParameterUuidReference > dest_id_
Destination.
std::array< midi_byte_t, 3 > key_
Raw MIDI signal.
std::optional< utils::Utf8String > device_id_
The device that this connection will be mapped for.
std::atomic< bool > enabled_
Whether this binding is enabled.
All MIDI mappings in Zrythm.
int get_for_port(const dsp::ProcessorParameter &dest_port, std::vector< MidiMapping * > *arr) const
Get MIDI mappings for the given port.
void unbind(int idx, bool fire_events)
Unbinds the given binding.
void apply_from_cc_events(const dsp::MidiEventVector &events)
Applies the events to the appropriate mapping.
void apply(const midi_byte_t *buf)
Applies the given buffer to the matching ports.
void bind_at(std::array< midi_byte_t, 3 > buf, std::optional< utils::Utf8String > device_id, dsp::ProcessorParameterUuidReference dest_port, int idx, bool fire_events)
Binds the CC represented by the given raw buffer (must be size 3) to the given Port.
uint8_t midi_byte_t
MIDI byte.
Definition types.h:55