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 "gui/dsp/ext_port.h"
7#include "gui/dsp/port.h"
8#include "utils/icloneable.h"
9
10using WrappedObjectWithChangeSignal = struct _WrappedObjectWithChangeSignal;
11
17
18#define MIDI_MAPPINGS (PROJECT->midi_mappings_)
19
23class MidiMapping final : public QObject, public ICloneable<MidiMapping>
24{
25 Q_OBJECT
26 QML_ELEMENT
27
28public:
29 using PortIdentifier = zrythm::dsp::PortIdentifier;
30
31 MidiMapping (QObject * parent = nullptr);
32
33public:
34 void init_after_cloning (const MidiMapping &other, ObjectCloneType clone_type)
35 override;
36
37 void set_enabled (bool enabled) { enabled_.store (enabled); }
38
39 void apply (std::array<midi_byte_t, 3> buf);
40
41private:
42 static constexpr auto kKeyKey = "key"sv;
43 static constexpr auto kDevicePortKey = "devicePort"sv;
44 static constexpr auto kDestIdKey = "destId"sv;
45 static constexpr auto kEnabledKey = "enabled"sv;
46 friend void to_json (nlohmann::json &j, const MidiMapping &mapping)
47 {
48 j = nlohmann::json{
49 { kKeyKey, mapping.key_ },
50 { kDevicePortKey, mapping.device_port_ },
51 { kDestIdKey, mapping.dest_id_ },
52 { kEnabledKey, mapping.enabled_.load () },
53 };
54 }
55 friend void from_json (const nlohmann::json &j, MidiMapping &mapping)
56 {
57 j.at (kKeyKey).get_to (mapping.key_);
58 j.at (kDevicePortKey).get_to (mapping.device_port_);
59 j.at (kDestIdKey).get_to (mapping.dest_id_);
60 mapping.enabled_.store (j.at (kEnabledKey).get<bool> ());
61 }
62
63public:
65 std::array<midi_byte_t, 3> key_ = {};
66
68 std::unique_ptr<ExtPort> device_port_;
69
71 std::optional<PortIdentifier::PortUuid> dest_id_;
72
78 Port * dest_ = nullptr;
79
81 /* TODO: check if really should be atomic */
82 std::atomic<bool> enabled_ = false;
83};
84
88class MidiMappings final : public ICloneable<MidiMappings>
89{
90public:
91 void init_loaded ();
92
101 void bind_at (
102 std::array<midi_byte_t, 3> buf,
103 ExtPort * device_port,
104 Port &dest_port,
105 int idx,
106 bool fire_events);
107
114 void unbind (int idx, bool fire_events);
115
116 void bind_device (
117 std::array<midi_byte_t, 3> buf,
118 ExtPort * dev_port,
119 Port &dest_port,
120 bool fire_events)
121 {
122 bind_at (
123 buf, dev_port, dest_port, static_cast<int> (mappings_.size ()),
124 fire_events);
125 }
126
127 void
128 bind_track (std::array<midi_byte_t, 3> buf, Port &dest_port, bool fire_events)
129 {
130 bind_at (
131 buf, nullptr, dest_port, static_cast<int> (mappings_.size ()),
132 fire_events);
133 }
134
135 int get_mapping_index (const MidiMapping &mapping) const;
136
145
149 void apply (const midi_byte_t * buf);
150
158 int
159 get_for_port (const Port &dest_port, std::vector<MidiMapping *> * arr) const;
160
161 void
163 override
164 {
165 clone_unique_ptr_container (mappings_, other.mappings_);
166 }
167
168private:
169 static constexpr auto kMappingsKey = "mappings"sv;
170 friend void to_json (nlohmann::json &j, const MidiMappings &mappings)
171 {
172 j[kMappingsKey] = mappings.mappings_;
173 }
174 friend void from_json (const nlohmann::json &j, MidiMappings &mappings);
175
176public:
177 std::vector<std::unique_ptr<MidiMapping>> mappings_;
178};
179
External port.
Definition ext_port.h:41
A lock-free thread-safe vector of MidiEvents.
Definition midi_event.h:93
A mapping from a MIDI CC value to a destination ControlPort.
std::optional< PortIdentifier::PortUuid > dest_id_
Destination.
std::unique_ptr< ExtPort > device_port_
The device that this connection will be mapped for.
std::array< midi_byte_t, 3 > key_
Raw MIDI signal.
Port * dest_
Destination pointer, for convenience.
void init_after_cloning(const MidiMapping &other, ObjectCloneType clone_type) override
Initializes the cloned object.
std::atomic< bool > enabled_
Whether this binding is enabled.
All MIDI mappings in Zrythm.
void apply(const midi_byte_t *buf)
Applies the given buffer to the matching ports.
void apply_from_cc_events(MidiEventVector &events)
Applies the events to the appropriate mapping.
void unbind(int idx, bool fire_events)
Unbinds the given binding.
int get_for_port(const Port &dest_port, std::vector< MidiMapping * > *arr) const
Get MIDI mappings for the given port.
void bind_at(std::array< midi_byte_t, 3 > buf, ExtPort *device_port, Port &dest_port, int idx, bool fire_events)
Binds the CC represented by the given raw buffer (must be size 3) to the given Port.
void init_after_cloning(const MidiMappings &other, ObjectCloneType clone_type) override
Initializes the cloned object.
The Port class represents a port in the audio processing graph.
Definition port.h:181
Struct used to identify Ports in the project.
External ports.
ObjectCloneType
Definition icloneable.h:25
void clone_unique_ptr_container(Container &dest, const Container &src, ObjectCloneType clone_type=ObjectCloneType::Snapshot)
Clones the elements of a container of std::unique_ptr into the destination container.
Definition icloneable.h:342
uint8_t midi_byte_t
MIDI byte.
Definition types.h:59