Control Surface stm32
MIDI Control Surface library for Arduino
FortySevenEffects.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/Error/Error.hpp>
5
7
9#include <MIDI.h>
11
13
20 private:
21 template <class MidiInterface>
23
25 template <class MidiInterface>
26 void updateChannelMessage(const MidiInterface &interface) {
27 uint8_t channel = interface.getChannel() - 1;
28 this->midimsg.header = interface.getType() | channel;
29 this->midimsg.data1 = interface.getData1();
30 this->midimsg.data2 = interface.getData2();
31 this->midimsg.cable = CABLE_1;
32 }
33
35 template <class MidiInterface>
36 void updateSysExMessage(const MidiInterface &interface) {
37 this->sysex.data = interface.getSysExArray();
38 this->sysex.length = interface.getSysExArrayLength();
39 this->sysex.cable = CABLE_1;
40 }
41
43 template <class MidiInterface>
44 void updateSysCommonMessage(const MidiInterface &interface) {
45 this->midimsg.header = interface.getType();
46 this->midimsg.data1 = interface.getData1();
47 this->midimsg.data2 = interface.getData2();
48 this->midimsg.cable = CABLE_1;
49 }
50
52 template <class MidiInterface>
53 void updateRealTimeMessage(const MidiInterface &interface) {
54 this->rtmsg.message = interface.getType();
55 this->rtmsg.cable = CABLE_1;
56 }
57
59 SysExMessage sysex = {nullptr, 0, CABLE_1};
60
61 public:
63 SysExMessage getSysExMessage() const { return sysex; }
64};
65
86template <class MidiInterface>
88 public:
90 : midi(std::forward<MidiInterface>(midi)) {}
91
92 void begin() override { midi.begin(MIDI_CHANNEL_OMNI); }
93
95 if (!midi.read()) // Update the MIDI input and check if there's
96 return MIDIReadEvent::NO_MESSAGE; // a new message available
97 auto type = midi.getType();
98 if (type <= uint8_t(MIDIMessageType::PITCH_BEND)) { // Channel
101 } else if (type == uint8_t(MIDIMessageType::SYSEX_START)) { // SysEx
104 } else if (type <= uint8_t(MIDIMessageType::TUNE_REQUEST)) { // SysComm
107 } else if (type == uint8_t(MIDIMessageType::SYSEX_END)) { // SysEx
108 // ignore
109 } else { // Real-Time
112 }
114 }
115
118 return parser.getChannelMessage();
119 }
122 return parser.getRealTimeMessage();
123 }
127 }
130
131 void update() override {
132 MIDIReadEvent event = read();
133 while (event != MIDIReadEvent::NO_MESSAGE) { // As long as there are
134 // incoming messages
135 dispatchMIDIEvent(event);
136 event = read();
137 }
138 // TODO: check if we should block the pipe
139 }
140
141 protected:
143 switch (event) {
144 case MIDIReadEvent::NO_MESSAGE: break;
147 break;
150 break;
153 break;
156 break;
157 default: break;
158 }
159 }
160
161 protected:
163 midi.send(static_cast<MIDI_NAMESPACE::MidiType>(msg.getMessageType()),
164 msg.getData1(), msg.getData2(),
165 msg.getChannel().getOneBased());
166 // channel is zero-based in Control Surface, one-based in MIDI 47 Fx
167 }
169 midi.sendCommon(
170 static_cast<MIDI_NAMESPACE::MidiType>(msg.getMessageType()),
171 msg.getData14bit());
172 }
174 midi.sendSysEx(msg.length, msg.data, true);
175 // true indicates that the array contains the SysEx start and stop bytes
176 }
178 midi.sendRealTime(static_cast<MIDI_NAMESPACE::MidiType>(msg.message));
179 }
180 void sendNowImpl() override { /* TODO */
181 }
182
183 private:
184 void handleStall() override {
185 auto stallername = MIDIStaller::getNameNull(getStaller());
186 ERROR(F("Not implemented (stalled by ") << stallername << ')', 0x1349);
187 (void)stallername;
188 }
189
190 private:
192 MidiInterface midi;
193};
194
196
constexpr Cable CABLE_1
Definition: Cable.hpp:118
#define ERROR(msg, errc)
Definition: Error.hpp:22
MIDIReadEvent
Values returned by the MIDI reading functions.
@ CHANNEL_MESSAGE
A MIDI Channel message was received.
@ SYSCOMMON_MESSAGE
A MIDI System Common message was received.
@ NO_MESSAGE
No new messages were received.
@ SYSEX_MESSAGE
A MIDI System Exclusive message was received.
@ REALTIME_MESSAGE
A MIDI Real-Time message was received.
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
#define AH_DIAGNOSTIC_EXTERNAL_HEADER()
Definition: Warnings.hpp:38
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:37
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:36
constexpr uint8_t getOneBased() const
Get the channel as an integer.
Definition: Channel.hpp:36
Class that wraps the FortySevenEffects MIDI library.
ChannelMessage getChannelMessage() const
Return the received channel voice message.
RealTimeMessage getRealTimeMessage() const
Return the received real-time message.
void sendRealTimeImpl(RealTimeMessage msg) override
Low-level function for sending a MIDI real-time message.
void dispatchMIDIEvent(MIDIReadEvent event)
FortySevenEffectsMIDI_Parser parser
FortySevenEffectsMIDI_Interface(MidiInterface &&midi)
void handleStall() override
Call back that should finish any MIDI messages that are in progress, and un-stall the pipe or MIDI so...
void update() override
Read the MIDI interface and call the callback if a message was received.
void sendSysCommonImpl(SysCommonMessage msg) override
Low-level function for sending a MIDI system common message.
void sendSysExImpl(SysExMessage msg)
Low-level function for sending a system exclusive MIDI message.
void sendNowImpl() override
Low-level function for sending any buffered outgoing MIDI messages.
SysCommonMessage getSysCommonMessage() const
Return the received system common message.
void begin() override
Initialize the MIDI Interface.
SysExMessage getSysExMessage() const
Return the received system exclusive message.
void sendChannelMessageImpl(ChannelMessage msg) override
Low-level function for sending a MIDI channel voice message.
Wrapper class for the FortySevenEffects MIDI parser.
void updateChannelMessage(const MidiInterface &interface)
Get the latest channel message from the given MIDI interface.
void updateRealTimeMessage(const MidiInterface &interface)
Get the latest real-time message from the given MIDI interface.
void updateSysCommonMessage(const MidiInterface &interface)
Get the latest system common message from the given MIDI interface.
void updateSysExMessage(const MidiInterface &interface)
Get the latest system exclusive message from the given MIDI interface.
SysExMessage getSysExMessage() const
Get the latest SysEx message.
An abstract class for MIDI interfaces.
void onSysCommonMessage(SysCommonMessage message)
Call the System Common message callback and send the message to the sink pipe.
void onSysExMessage(SysExMessage message)
Call the SysEx message callback and send the message to the sink pipe.
void onRealTimeMessage(RealTimeMessage message)
Call the real-time message callback and send the message to the sink pipe.
void onChannelMessage(ChannelMessage message)
Call the channel message callback and send the message to the sink pipe.
Base class for MIDI parsers.
Definition: MIDI_Parser.hpp:16
ChannelMessage getChannelMessage() const
Get the latest MIDI channel voice message.
Definition: MIDI_Parser.hpp:19
RealTimeMessage getRealTimeMessage() const
Get the latest MIDI real-time message.
Definition: MIDI_Parser.hpp:25
SysCommonMessage getSysCommonMessage() const
Get the latest MIDI system common message.
Definition: MIDI_Parser.hpp:21
MIDIStaller * getStaller() const
Get a pointer to whatever is causing this MIDI source to be stalled.
Definition: MIDI_Pipes.cpp:173
MIDIMessageType getMessageType() const
Get the MIDI message type.
Channel getChannel() const
Get the MIDI channel of the message.
uint8_t getData1() const
Get the first data byte.
uint16_t getData14bit() const
If Data 1 and Data 2 represent a single 14-bit number, you can use this method to retrieve that numbe...
uint8_t getData2() const
Get the second data byte.
static const char * getNameNull(MIDIStaller *s)
Get the staller's name for debugging purposes.
Definition: MIDI_Pipes.cpp:354
MIDIMessageType getMessageType() const
Get the MIDI message type.
const uint8_t * data