OSSIA
Open Scenario System for Interactive Application
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 
12 #include <libremidi/api.hpp>
13 #include <libremidi/message.hpp>
14 #include <libremidi/observer_configuration.hpp>
15 
16 #include <any>
17 #include <array>
18 #include <atomic>
19 #include <cassert>
20 namespace libremidi
21 {
22 class midi_in;
23 class midi_out;
24 struct input_configuration;
25 struct output_configuration;
26 struct message;
27 }
28 namespace ossia::net::midi
29 {
30 class midi_device;
31 struct OSSIA_EXPORT midi_info
32 {
33  enum class Type
34  {
35  Input,
36  Output
37  };
38 
39  midi_info() = default;
40  midi_info(const libremidi::input_port& p, bool v)
41  : type{Type::Input}
42  , handle{p}
43  , is_virtual{v}
44  {
45  }
46  midi_info(const libremidi::output_port& p, bool v)
47  : type{Type::Output}
48  , handle{p}
49  , is_virtual{v}
50  {
51  }
52 
53  midi_info(Type t, const libremidi::port_information& p, bool v)
54  : type{t}
55  , handle{p}
56  , is_virtual{v}
57  {
58  }
59 
60  Type type{};
61  libremidi::port_information handle{};
62  bool is_virtual{};
63 };
64 
65 class OSSIA_EXPORT midi_protocol final
67  , public Nano::Observer
68 {
69 public:
70  explicit midi_protocol(
71  ossia::net::network_context_ptr, std::string device_name,
72  libremidi::input_configuration&, std::any midi_api);
73  explicit midi_protocol(
74  ossia::net::network_context_ptr, std::string device_name,
75  libremidi::output_configuration&, std::any midi_api);
76  explicit midi_protocol(
77  ossia::net::network_context_ptr, midi_info,
78  libremidi::API api = libremidi::API::UNSPECIFIED);
79  ~midi_protocol();
80 
81  bool set_info(midi_info);
82  midi_info get_info() const;
83 
84  int64_t get_timestamp() const noexcept;
85 
86  static std::string
87  get_midi_port_name(ossia::net::device_base* dev, const midi_info& info);
88 
89  static std::vector<midi_info> scan(libremidi::API = libremidi::API::UNSPECIFIED);
90 
91  void push_value(const libremidi::message&);
92 
93  void enable_registration();
94 
95  bool learning() const;
96  void set_learning(bool);
97 
98  libremidi::midi_in* midi_in() const noexcept { return m_input.get(); }
99 
100  ossia::spsc_queue<libremidi::message> messages;
101 
102 private:
103  ossia::net::network_context_ptr m_context;
104  std::unique_ptr<libremidi::midi_in> m_input;
105  std::unique_ptr<libremidi::midi_out> m_output;
106 
107  std::array<midi_channel, 16> m_channels;
108 
109  midi_info m_info{};
110  midi_device* m_dev{};
111  bool m_registers{};
112  std::atomic_bool m_learning{};
113 
114  friend class midi_device;
115  friend class midi_parameter;
116  bool pull(ossia::net::parameter_base&) override;
117  bool push(const ossia::net::parameter_base&, const ossia::value& v) override;
118  bool push_raw(const ossia::net::full_parameter_data& parameter_base) override;
119  bool observe(ossia::net::parameter_base&, bool) override;
120  bool update(ossia::net::node_base& node_base) override;
121  void set_device(ossia::net::device_base& dev) override;
122 
123  void register_parameter(midi_parameter& adrs);
124  void unregister_parameter(midi_parameter& adrs);
125  void register_parameter_base(const ossia::net::parameter_base& adrs);
126  void unregister_parameter_base(const ossia::net::parameter_base& adrs);
127  void register_node_base(const ossia::net::node_base& adrs);
128  void unregister_node_base(const ossia::net::node_base& adrs);
129  void value_callback(
130  bool observed, ossia::net::parameter_base& param, const ossia::value& val);
131 
132  void midi_callback(const libremidi::message&);
133  void on_learn(const libremidi::message& m);
134 };
135 }
Root of a device tree.
Definition: ossia/network/base/device.hpp:58
The node_base class.
Definition: network/base/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