Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
FortySevenEffects.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/Error/Error.hpp>
5
7#include <MIDI.h>
9
11
18 private:
19 template <class MidiInterface>
21
23 template <class MidiInterface>
24 void updateChannelMessage(const MidiInterface &interface) {
25 uint8_t channel = interface.getChannel() - 1;
26 this->midimsg.header = interface.getType() | channel;
27 this->midimsg.data1 = interface.getData1();
28 this->midimsg.data2 = interface.getData2();
29 this->midimsg.cable = Cable_1;
30 }
31
33 template <class MidiInterface>
34 void updateSysExMessage(const MidiInterface &interface) {
35 this->sysex.data = interface.getSysExArray();
36 this->sysex.length = interface.getSysExArrayLength();
37 this->sysex.cable = Cable_1;
38 }
39
41 template <class MidiInterface>
42 void updateSysCommonMessage(const MidiInterface &interface) {
43 this->midimsg.header = interface.getType();
44 this->midimsg.data1 = interface.getData1();
45 this->midimsg.data2 = interface.getData2();
46 this->midimsg.cable = Cable_1;
47 }
48
50 template <class MidiInterface>
51 void updateRealTimeMessage(const MidiInterface &interface) {
52 this->rtmsg.message = interface.getType();
53 this->rtmsg.cable = Cable_1;
54 }
55
57 SysExMessage sysex = {nullptr, 0, Cable_1};
58
59 public:
61 SysExMessage getSysExMessage() const { return sysex; }
62};
63
84template <class MidiInterface>
86 public:
88 : midi(std::forward<MidiInterface>(midi)) {}
89
90 void begin() override { midi.begin(MIDI_CHANNEL_OMNI); }
91
93 if (!midi.read()) // Update the MIDI input and check if there's
94 return MIDIReadEvent::NO_MESSAGE; // a new message available
95 auto type = midi.getType();
96 if (type <= uint8_t(MIDIMessageType::PitchBend)) { // Channel
99 } else if (type == uint8_t(MIDIMessageType::SysExStart)) { // SysEx
102 } else if (type <= uint8_t(MIDIMessageType::TuneRequest)) { // SysComm
105 } else if (type == uint8_t(MIDIMessageType::SysExEnd)) { // SysEx
106 // ignore
107 } else { // Real-Time
110 }
112 }
113
128
129 void update() override {
130 MIDIReadEvent event = read();
131 while (event != MIDIReadEvent::NO_MESSAGE) { // As long as there are
132 // incoming messages
133 dispatchMIDIEvent(event);
134 event = read();
135 }
136 // TODO: check if we should block the pipe
137 }
138
139 protected:
141 switch (event) {
142 case MIDIReadEvent::NO_MESSAGE: break;
145 break;
148 break;
151 break;
154 break;
155 default: break;
156 }
157 }
158
159 protected:
161 midi.send(static_cast<MIDI_NAMESPACE::MidiType>(msg.getMessageType()),
162 msg.getData1(), msg.getData2(),
163 msg.getChannel().getOneBased());
164 // channel is zero-based in Control Surface, one-based in MIDI 47 Fx
165 }
167 midi.sendCommon(
168 static_cast<MIDI_NAMESPACE::MidiType>(msg.getMessageType()),
169 msg.getData14bit());
170 }
172 midi.sendSysEx(msg.length, msg.data, true);
173 // true indicates that the array contains the SysEx start and stop bytes
174 }
176 midi.sendRealTime(static_cast<MIDI_NAMESPACE::MidiType>(msg.message));
177 }
178 void sendNowImpl() override { /* TODO */
179 }
180
181 private:
182#if !DISABLE_PIPES
183 void handleStall() override {
184 auto stallername = MIDIStaller::getNameNull(getStaller());
185 ERROR(F("Not implemented (stalled by ") << stallername << ')', 0x1349);
186 (void)stallername;
187 }
188#ifdef DEBUG_OUT
189 const char *getName() const override { return "47fx"; }
190#endif
191#endif
192
193 private:
195 MidiInterface midi;
196};
197
constexpr Cable Cable_1
Definition Cable.hpp:118
#define ERROR(msg, errc)
Definition Error.hpp:19
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.
@ SysExStart
Start of System Exclusive.
@ TuneRequest
Tune Request System Common message (1B).
@ SysExEnd
End of System Exclusive.
@ PitchBend
Pitch Bend Channel Voice message (3B).
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
#define AH_DIAGNOSTIC_EXTERNAL_HEADER()
Definition Warnings.hpp:51
#define AH_DIAGNOSTIC_POP()
Definition Warnings.hpp:50
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.
const char * getName() const override
Get the staller's name for debugging purposes.
void begin() override
Initialize this updatable.
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.
ChannelMessage getChannelMessage() const
Get the latest MIDI channel voice message.
RealTimeMessage getRealTimeMessage() const
Get the latest MIDI real-time message.
SysCommonMessage getSysCommonMessage() const
Get the latest MIDI system common message.
MIDIStaller * getStaller() const
Get a pointer to whatever is causing this MIDI source to be stalled.
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.
MIDIMessageType getMessageType() const
Get the MIDI message type.
const uint8_t * data