OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
midi_protocol.hpp
1#pragma once
2#include <ossia/detail/lockfree_queue.hpp>
3#include <ossia/network/base/device.hpp>
4#include <ossia/network/base/parameter.hpp>
5#include <ossia/network/base/protocol.hpp>
6#include <ossia/network/common/parameter_properties.hpp>
7#include <ossia/network/context_functions.hpp>
8#include <ossia/network/domain/domain.hpp>
9#include <ossia/network/value/value.hpp>
10#include <ossia/protocols/midi/detail/channel.hpp>
11#include <ossia/protocols/midi/midi_stream.hpp>
12
13#include <libremidi/api.hpp>
14#include <libremidi/configurations.hpp>
15#include <libremidi/detail/conversion.hpp>
16#include <libremidi/message.hpp>
17#include <libremidi/observer_configuration.hpp>
18#include <libremidi/ump.hpp>
19
20#include <array>
21#include <atomic>
22#include <cassert>
23namespace libremidi
24{
25class midi_in;
26class midi_out;
27struct input_configuration;
28struct output_configuration;
29struct message;
30}
31namespace ossia::net::midi
32{
33class midi_device;
34struct OSSIA_EXPORT midi_info
35{
36 enum class Type
37 {
38 Input,
39 Output
40 };
41
42 midi_info() = default;
43 midi_info(const libremidi::input_port& p, bool v)
44 : type{Type::Input}
45 , handle{p}
46 , is_virtual{v}
47 {
48 }
49 midi_info(const libremidi::output_port& p, bool v)
50 : type{Type::Output}
51 , handle{p}
52 , is_virtual{v}
53 {
54 }
55
56 midi_info(Type t, const libremidi::port_information& p, bool v)
57 : type{t}
58 , handle{p}
59 , is_virtual{v}
60 {
61 }
62
63 Type type{};
64 libremidi::port_information handle{};
65 bool is_virtual{};
66};
67
68struct midi_protocol_configuration
69{
70 std::string device_name;
71 bool velocity_zero_is_note_off{};
72};
73
74class OSSIA_EXPORT midi_protocol final
76 , public Nano::Observer
77 , public midi_stream
78{
79public:
80 explicit midi_protocol(
81 ossia::net::network_context_ptr, midi_protocol_configuration,
82 libremidi::input_configuration&, libremidi::input_api_configuration midi_api);
83 explicit midi_protocol(
84 ossia::net::network_context_ptr, midi_protocol_configuration,
85 libremidi::output_configuration&, libremidi::output_api_configuration midi_api);
86 // Convenience overload: builds a midi_protocol from a midi_info
87 // and immediately opens the described port.
88 explicit midi_protocol(ossia::net::network_context_ptr, midi_info);
89 ~midi_protocol();
90
91 bool set_info(midi_info);
92 midi_info get_info() const;
93
94 int64_t get_timestamp() const noexcept;
95
96 static std::string
97 get_midi_port_name(ossia::net::device_base* dev, const midi_info& info);
98
99 static std::vector<midi_info> scan(libremidi::API = libremidi::API::UNSPECIFIED);
100
101 void push_value(const libremidi::message&) override;
102 void push_value(const libremidi::ump&) override;
103
104 void enable_registration() override;
105
106 bool learning() const;
107 void set_learning(bool);
108
109 libremidi::midi_in* midi_in() const noexcept override { return m_input.get(); }
110
113 std::optional<int> stream_channel(const node_base& n) const noexcept override;
114
115private:
116 ossia::net::network_context_ptr m_context;
117 std::unique_ptr<libremidi::midi_in> m_input;
118 std::unique_ptr<libremidi::midi_out> m_output;
119
120 std::array<midi_channel, 16> m_channels;
121
122 midi_protocol_configuration m_config{};
123 midi_info m_info{};
124 midi_device* m_dev{};
125 bool m_registers{};
126 std::atomic_bool m_learning{};
127
128 friend class midi_device;
129 friend class midi_parameter;
130 bool pull(ossia::net::parameter_base&) override;
131 bool push(const ossia::net::parameter_base&, const ossia::value& v) override;
132 bool push_raw(const ossia::net::full_parameter_data& parameter_base) override;
133 bool observe(ossia::net::parameter_base&, bool) override;
134 bool update(ossia::net::node_base& node_base) override;
135 void set_device(ossia::net::device_base& dev) override;
136
137 void register_parameter(midi_parameter& adrs);
138 void unregister_parameter(midi_parameter& adrs);
139 void register_parameter_base(const ossia::net::parameter_base& adrs);
140 void unregister_parameter_base(const ossia::net::parameter_base& adrs);
141 void register_node_base(const ossia::net::node_base& adrs);
142 void unregister_node_base(const ossia::net::node_base& adrs);
143 void value_callback(
144 bool observed, ossia::net::parameter_base& param, const ossia::value& val);
145
146 void midi_callback(libremidi::message&&);
147 void on_learn(const libremidi::message& m);
148
149 libremidi::midi1_to_midi2 to_midi2;
150};
151}
Root of a device tree.
Definition ossia/network/base/device.hpp:58
The node_base class.
Definition node.hpp:48
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The protocol_base class.
Definition protocol.hpp:40
The value class.
Definition value.hpp:173
void(* value_callback)(void *, const opp::value &)
container for a value callback
Definition ossia-cpp98.hpp:474
Definition git_info.h:7
Full information about a parameter.
Definition parameter_data.hpp:61