MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MIDINode.cpp
Go to the documentation of this file.
1#include "MIDINode.hpp"
2
4
6 : m_config(std::move(config))
7{
8}
9
11{
13 return m_last_output;
14 }
15
16 const auto& midi = value.as_midi();
18
19 if (!matches_filters(value)) {
20 return m_last_output;
21 }
22
23 uint8_t msg_type = midi.type();
24
25 switch (msg_type) {
26 case 0x90:
28 return m_last_output;
29 }
30 // Velocity 0 is actually Note Off
31 if (midi.data2 == 0 && m_config.note_on_only) {
32 return m_last_output;
33 }
34
36 ? m_config.velocity_curve(midi.data2)
37 : static_cast<double>(midi.data2) / 127.0;
38
39 case 0x80: // Note Off
41 return m_last_output;
42 }
43 return 0.0;
44
45 case 0xB0: { // Control Change
46 double value = static_cast<double>(midi.data2) / 127.0;
47 return m_config.invert_cc ? (1.0 - value) : value;
48 }
49
50 case 0xE0: {
51 // Pitch bend is 14-bit: combine data1 and data2
52 int bend_value = (midi.data2 << 7) | midi.data1;
53 return (static_cast<double>(bend_value) - 8192.0) / 8192.0;
54 }
55
56 case 0xD0: // Channel Pressure (Aftertouch)
57 case 0xC0: // Program Change
58 default:
59 return static_cast<double>(midi.data1) / 127.0;
60 }
61}
62
64{
65 const auto& midi = value.as_midi();
66
67 if (m_config.channel.has_value() && midi.channel() != m_config.channel.value()) {
68 return false;
69 }
70
71 if (m_config.message_type.has_value() && midi.type() != m_config.message_type.value()) {
72 return false;
73 }
74
75 uint8_t msg_type = midi.type();
76
77 if (m_config.note_number.has_value() && (msg_type == 0x90 || msg_type == 0x80)) {
78 if (midi.data1 != m_config.note_number.value()) {
79 return false;
80 }
81 }
82
83 if (m_config.cc_number.has_value() && msg_type == 0xB0) {
84 if (midi.data1 != m_config.cc_number.value()) {
85 return false;
86 }
87 }
88
89 return true;
90}
91
99
101{
102 uint8_t msg_type = midi.type();
103
104 switch (msg_type) {
105 case 0x90:
106 for (const auto& cb : m_note_callbacks) {
107 bool is_on = midi.data2 > 0; // velocity 0 = note off
108 cb(midi.data1, midi.data2, is_on);
109 }
110 break;
111
112 case 0x80:
113 for (const auto& cb : m_note_callbacks) {
114 cb(midi.data1, 0, false);
115 }
116 break;
117
118 case 0xB0:
119 for (const auto& cb : m_cc_callbacks) {
120 cb(midi.data1, midi.data2);
121 }
122 break;
123
124 case 0xE0:
125 for (const auto& cb : m_pitch_bend_callbacks) {
126 int16_t bend = ((midi.data2 << 7) | midi.data1) - 8192;
127 cb(bend);
128 }
129 break;
130
131 default:
132 break;
133 }
134}
135
136} // namespace MayaFlux::Nodes::Input
void notify_tick(double value) override
Notify callbacks (minimal for InputNode)
void fire_midi_callbacks(const Core::InputValue::MIDIMessage &midi)
Definition MIDINode.cpp:100
MIDINode(MIDIConfig config={})
Definition MIDINode.cpp:5
std::vector< PitchBendCallback > m_pitch_bend_callbacks
Definition MIDINode.hpp:188
double extract_value(const Core::InputValue &value) override
Extract a scalar value from an InputValue.
Definition MIDINode.cpp:10
std::optional< Core::InputValue::MIDIMessage > m_last_midi_message
Definition MIDINode.hpp:184
void notify_tick(double value) override
Notify callbacks (minimal for InputNode)
Definition MIDINode.cpp:92
std::vector< CC_Callback > m_cc_callbacks
Definition MIDINode.hpp:187
std::vector< NoteCallback > m_note_callbacks
Definition MIDINode.hpp:186
bool matches_filters(const Core::InputValue &value) const
Definition MIDINode.cpp:63
double m_last_output
The most recent sample value generated by this oscillator.
Definition Node.hpp:377
uint8_t data2
Second data byte (may be unused)
@ MIDI
Structured MIDI message.
const MIDIMessage & as_midi() const
Generic input value container.
std::optional< uint8_t > channel
MIDI channel filter (0-15)
Definition MIDINode.hpp:11
std::function< double(uint8_t)> velocity_curve
Custom velocity mapping.
Definition MIDINode.hpp:19
bool invert_cc
Flip CC 127→0.
Definition MIDINode.hpp:20
std::optional< uint8_t > cc_number
CC number filter (0-127)
Definition MIDINode.hpp:13
std::optional< uint8_t > message_type
Message type filter (0x80-0xF0)
Definition MIDINode.hpp:14
bool note_on_only
Only respond to Note On.
Definition MIDINode.hpp:16
std::optional< uint8_t > note_number
Note number filter (0-127)
Definition MIDINode.hpp:12
bool note_off_only
Only respond to Note Off.
Definition MIDINode.hpp:17
MIDI input node configuration.
Definition MIDINode.hpp:10