3#include <ossia/network/base/osc_address.hpp>
4#include <ossia/network/domain/domain.hpp>
5#include <ossia/network/value/value.hpp>
6#include <ossia/protocols/midi/detail/channel.hpp>
7#include <ossia/protocols/midi/midi_device.hpp>
8#include <ossia/protocols/midi/midi_node.hpp>
9#include <ossia/protocols/midi/midi_parameter.hpp>
10#include <ossia/protocols/midi/midi_protocol.hpp>
12namespace ossia::net::midi
14const std::string& midi_node_name(midi_size_t i);
16class generic_node final
18 ,
public midi_parameter
23 , midi_parameter{addr, *this}
25 using namespace std::literals;
28 case address_info::Type::NoteOn:
31 case address_info::Type::NoteOn_N:
32 m_name = midi_node_name(addr.note);
34 case address_info::Type::NoteOff:
37 case address_info::Type::NoteOff_N:
38 m_name = midi_node_name(addr.note);
40 case address_info::Type::CC:
43 case address_info::Type::CC_N:
44 m_name = midi_node_name(addr.note);
46 case address_info::Type::PC:
49 case address_info::Type::PC_N:
50 m_name = midi_node_name(addr.note);
52 case address_info::Type::PB:
53 m_name =
"pitchbend"s;
55 case address_info::Type::Any:
63 m_parameter.reset(
this);
66 std::unique_ptr<node_base> make_child(
const std::string& name)
override
72 num = std::stoi(name);
83 address_info ai{m_info.channel, {}, midi_size_t(num)};
86 case address_info::Type::NoteOn:
87 ai.type = address_info::Type::NoteOn_N;
89 case address_info::Type::NoteOff:
90 ai.type = address_info::Type::NoteOff_N;
92 case address_info::Type::CC:
93 ai.type = address_info::Type::CC_N;
95 case address_info::Type::PC:
96 ai.type = address_info::Type::PC_N;
102 return std::make_unique<generic_node>(ai, m_device, *
this);
111 m_device.on_parameter_removing(*
this);
112 m_device.get_protocol().observe(*
this,
false);
114 m_parameter.release();
118class note_on_N_node final
120 ,
public midi_parameter
124 midi_size_t channel, midi_size_t note, midi_device& aDevice,
126 : midi_node{aDevice, aParent}
127 , midi_parameter{address_info{channel, address_info::Type::NoteOn_N, note}, *this}
129 m_name = midi_node_name(note);
131 m_parameter.reset(
this);
140 m_device.on_parameter_removing(*
this);
141 m_device.get_protocol().observe(*
this,
false);
143 m_parameter.release();
147class note_off_N_node final
149 ,
public midi_parameter
153 midi_size_t channel, midi_size_t note, midi_device& aDevice,
155 : midi_node{aDevice, aParent}
156 , midi_parameter{address_info{channel, address_info::Type::NoteOff_N, note}, *this}
158 m_name = midi_node_name(note);
160 m_parameter.reset(
this);
169 m_device.on_parameter_removing(*
this);
170 m_device.get_protocol().observe(*
this,
false);
172 m_parameter.release();
176class control_N_node final
178 ,
public midi_parameter
182 midi_size_t channel, midi_size_t param, midi_device& aDevice,
184 : midi_node{aDevice, aParent}
185 , midi_parameter{address_info{channel, address_info::Type::CC_N, param}, *this}
187 m_name = midi_node_name(param);
189 m_parameter.reset(
this);
198 m_device.on_parameter_removing(*
this);
199 m_device.get_protocol().observe(*
this,
false);
201 m_parameter.release();
205class program_N_node final
207 ,
public midi_parameter
211 midi_size_t channel, midi_size_t param, midi_device& aDevice,
213 : midi_node{aDevice, aParent}
214 , midi_parameter{address_info{channel, address_info::Type::PC_N, param}, *this}
216 m_name = midi_node_name(param);
218 m_parameter.reset(
this);
227 m_device.on_parameter_removing(*
this);
228 m_device.get_protocol().observe(*
this,
false);
230 m_parameter.release();
234class program_node final
236 ,
public midi_parameter
240 : midi_node(aDevice, aParent)
241 , midi_parameter{address_info{channel, address_info::Type::PC, 0}, *this}
243 using namespace std::literals;
246 m_parameter.reset(
this);
247 m_children.reserve(128);
248 for(
int i = 0; i < 128; i++)
250 auto ptr = std::make_unique<program_N_node>(channel, i, m_device, *
this);
251 m_children.push_back(std::move(ptr));
261 m_device.on_parameter_removing(*
this);
262 m_device.get_protocol().observe(*
this,
false);
264 m_parameter.release();
268class note_on_node final
270 ,
public midi_parameter
274 : midi_node(aDevice, aParent)
275 , midi_parameter{address_info{channel, address_info::Type::NoteOn, 0}, *this}
277 using namespace std::literals;
280 m_parameter.reset(
this);
281 m_children.reserve(128);
282 for(
int i = 0; i < 128; i++)
284 auto ptr = std::make_unique<note_on_N_node>(channel, i, m_device, *
this);
285 m_children.push_back(std::move(ptr));
295 m_device.on_parameter_removing(*
this);
296 m_device.get_protocol().observe(*
this,
false);
298 m_parameter.release();
302class note_off_node final
304 ,
public midi_parameter
309 : midi_node(aDevice, aParent)
310 , midi_parameter{address_info{channel, address_info::Type::NoteOff, 0}, *this}
312 using namespace std::literals;
315 m_parameter.reset(
this);
317 m_children.reserve(128);
318 for(
int i = 0; i < 128; i++)
320 auto ptr = std::make_unique<note_off_N_node>(channel, i, m_device, *
this);
321 m_children.push_back(std::move(ptr));
331 m_device.on_parameter_removing(*
this);
332 m_device.get_protocol().observe(*
this,
false);
334 m_parameter.release();
338class control_node final
340 ,
public midi_parameter
344 : midi_node(aDevice, aParent)
345 , midi_parameter{address_info{channel, address_info::Type::CC, 0}, *this}
347 using namespace std::literals;
350 m_parameter.reset(
this);
352 m_children.reserve(128);
353 for(
int i = 0; i < 128; i++)
355 auto ptr = std::make_unique<control_N_node>(channel, i, m_device, *
this);
356 m_children.push_back(std::move(ptr));
366 m_device.on_parameter_removing(*
this);
367 m_device.get_protocol().observe(*
this,
false);
369 m_parameter.release();
373class pitch_bend_node final
375 ,
public midi_parameter
380 : midi_node(aDevice, aParent)
381 , midi_parameter{address_info{channel, address_info::Type::PB, 0}, *this}
383 using namespace std::literals;
384 m_name =
"pitchbend"s;
386 m_parameter.reset(
this);
395 m_device.on_parameter_removing(*
this);
396 m_device.get_protocol().observe(*
this,
false);
398 m_parameter.release();
402class channel_node final :
public midi_node
405 const midi_size_t channel;
408 bool init, midi_size_t channel, midi_device& aDevice,
410 : midi_node(aDevice, aParent)
413 m_name = midi_node_name(channel);
415 m_children.reserve(5);
419 m_children.push_back(std::make_unique<note_on_node>(channel, m_device, *
this));
421 m_children.push_back(std::make_unique<note_off_node>(channel, m_device, *
this));
423 m_children.push_back(std::make_unique<control_node>(channel, m_device, *
this));
425 m_children.push_back(std::make_unique<program_node>(channel, m_device, *
this));
427 m_children.push_back(std::make_unique<pitch_bend_node>(channel, m_device, *
this));
438 std::array<ossia::message, 2> note_on(midi_size_t note, midi_size_t vel)
440 const auto& c = children();
443 *c[0]->get_parameter(),
444 value{std::vector<ossia::value>{int32_t{note}, int32_t{vel}}}},
445 ossia::message{*c[0]->children()[note]->get_parameter(), int32_t{vel}}}};
448 std::array<ossia::message, 2> note_off(midi_size_t note, midi_size_t vel)
450 const auto& c = children();
453 *c[1]->get_parameter(),
454 value{std::vector<ossia::value>{int32_t{note}, int32_t{vel}}}},
455 ossia::message{*c[1]->children()[note]->get_parameter(), int32_t{vel}}}};
458 std::unique_ptr<node_base> make_child(
const std::string& name)
override
460 address_info ai{channel, {}, 0};
463 ai.type = address_info::Type::NoteOn;
465 else if(name ==
"off")
467 ai.type = address_info::Type::NoteOff;
469 else if(name ==
"control")
471 ai.type = address_info::Type::CC;
473 else if(name ==
"program")
475 ai.type = address_info::Type::PC;
477 else if(name ==
"pitchbend")
479 ai.type = address_info::Type::PB;
486 return std::make_unique<generic_node>(ai, m_device, *
this);
The node_base class.
Definition node.hpp:48
Nano::Signal< void(const node_base &)> about_to_be_deleted
The node subclasses must call this in their destructor.
Definition node.hpp:204
The message struct.
Definition message.hpp:29