Line data Source code
1 : #pragma once
2 :
3 : #include <AH/Error/Error.hpp>
4 :
5 : #include "BLEMIDI/BLEAPI.hpp"
6 : #include "MIDI_Interface.hpp"
7 :
8 : #include <chrono>
9 :
10 : BEGIN_CS_NAMESPACE
11 :
12 : /**
13 : * @brief Bluetooth Low Energy MIDI Interface.
14 : */
15 : template <class Backend>
16 : class GenericBLEMIDI_Interface : public MIDI_Interface {
17 : public:
18 : template <class... Args>
19 29 : GenericBLEMIDI_Interface(Args &&...args)
20 29 : : backend {std::forward<Args>(args)...} {}
21 :
22 : private:
23 : // MIDI send implementations
24 : template <class L, class F>
25 : void sendImpl(L &lck, F add_to_buffer);
26 : void sendChannelMessageImpl(ChannelMessage) override;
27 : void sendSysCommonImpl(SysCommonMessage) override;
28 : void sendSysExImpl(SysExMessage) override;
29 : void sendRealTimeImpl(RealTimeMessage) override;
30 : void sendNowImpl() override;
31 :
32 : private:
33 : #if !DISABLE_PIPES
34 0 : void handleStall() override { MIDI_Interface::handleStall(this); }
35 : #ifdef DEBUG_OUT
36 : const char *getName() const override { return "ble"; }
37 : #endif
38 : #endif
39 :
40 : public:
41 : /// @name Initialization and polling
42 : /// @{
43 :
44 : /// Initialize the BLE hardware and start advertising as a MIDI over BLE
45 : /// peripheral.
46 : void begin() override;
47 : /// @todo Currently not implemented.
48 : void end();
49 : /// Poll the backend (if necessary) and invoke the callbacks for any
50 : /// received MIDI messages, as well as sending them over the pipes connected
51 : /// to this interface.
52 12 : void update() override { MIDI_Interface::updateIncoming(this); }
53 : /// Returns true if a BLE central is currently connected.
54 : /// @note This is useful for e.g. turning on/off an LED or showing a
55 : /// message to the user, but it's not all that useful for anything
56 : /// else, because the connection could be terminated at any moment.
57 : bool isConnected() const { return backend.isConnected(); }
58 :
59 : /// @}
60 :
61 : public:
62 : /// @name Reading incoming MIDI messages
63 : /// @{
64 :
65 : /// Try reading and parsing a single incoming MIDI message.
66 : /// @return Returns the type of the message read, or
67 : /// `MIDIReadEvent::NO_MESSAGE` if no MIDI message was available.
68 : MIDIReadEvent read();
69 :
70 : /// Return the received channel voice message.
71 : ChannelMessage getChannelMessage() const;
72 : /// Return the received system common message.
73 : SysCommonMessage getSysCommonMessage() const;
74 : /// Return the received real-time message.
75 : RealTimeMessage getRealTimeMessage() const;
76 : /// Return the received system exclusive message.
77 : SysExMessage getSysExMessage() const;
78 : /// Get the BLE-MIDI timestamp of the latest MIDI message.
79 : /// @note Invalid for SysEx chunks (except the last chunk of a message).
80 : uint16_t getTimestamp() const;
81 :
82 : /// @}
83 :
84 : private:
85 : /// Incoming message that can be from retrieved using the
86 : /// `getChannelMessage()`, `getSysCommonMessage()`, `getRealTimeMessage()`
87 : /// and `getSysExMessage()` methods.
88 : typename Backend::IncomingMIDIMessage incomingMessage;
89 :
90 : public:
91 : /// @name BLE configuration options
92 : /// @{
93 :
94 : /// Set the BLE device name. Must be called before @ref begin().
95 : /// Length is limited by the size of the BLE advertising packets.
96 : void setName(const char *name);
97 : /// Require encryption of the MIDI characteristic. Must be called before
98 : /// @ref begin(). Currently only supported by the NimBLE backend.
99 : void requireEncryption(bool require = true);
100 : /// Set the timeout, the number of milliseconds to buffer the outgoing MIDI
101 : /// messages. A shorter timeout usually results in lower latency, but also
102 : /// causes more overhead, because more packets might be required.
103 3 : void setTimeout(std::chrono::milliseconds timeout) {
104 3 : backend.setTimeout(timeout);
105 3 : }
106 : /// BLE backend configuration option.
107 : BLESettings ble_settings;
108 :
109 : /// @}
110 :
111 : public:
112 : /// Low-level BLE backend for sending and receiving MIDI over BLE packets.
113 : Backend backend;
114 : };
115 :
116 : END_CS_NAMESPACE
117 :
118 : #include "GenericBLEMIDI_Interface.ipp"
|