Control Surface  1.2.0
MIDI Control Surface library for Arduino
USBMIDI_Interface.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "MIDI_Interface.hpp"
4 #include "USBMIDI/USBMIDI.hpp"
5 #include <AH/Error/Error.hpp>
8 
10 
11 #if defined(TEENSYDUINO) && !defined(TEENSY_MIDIUSB_ENABLED)
12 #warning \
13  "Teensy: USB MIDI not enabled. Enable it from the Tools > USB Type menu."
14 #endif
15 
16 #ifndef ARDUINO
17 #include <gmock-wrapper.h>
18 #endif
19 
20 // If the main MCU has a USB connection or is a Teensy with MIDI USB type
21 #if defined(USBCON) || defined(TEENSY_MIDIUSB_ENABLED) || !defined(ARDUINO)
22 
24 
42  public:
47 
49 
50  private:
52 
53 #ifndef ARDUINO
54  public:
55  MOCK_METHOD(void, writeUSBPacket,
56  (uint8_t, uint8_t, uint8_t, uint8_t, uint8_t));
57  MOCK_METHOD(MIDIUSBPacket_t, readUSBPacket, ());
58  void flushUSB() {}
59 
60  private:
61 #else
62  void writeUSBPacket(uint8_t cn, uint8_t cin, uint8_t d0, uint8_t d1,
63  uint8_t d2) {
64  USBMIDI::write(cn, cin, d0, d1, d2);
65  }
67  void flushUSB() { USBMIDI::flush(); }
68 #endif
69 
70  void sendImpl(uint8_t header, uint8_t d1, uint8_t d2, uint8_t cn) override {
71  writeUSBPacket(cn, header >> 4, // CN|CIN
72  header, // status
73  d1, // data 1
74  d2); // data 2
75  flushUSB();
76  }
77 
78  void sendImpl(uint8_t header, uint8_t d1, uint8_t cn) override {
79  sendImpl(header, d1, 0, cn);
80  }
81 
82  void sendImpl(const uint8_t *data, size_t length, uint8_t cn) override {
83  while (length > 3) {
84  writeUSBPacket(cn, 0x4, data[0], data[1], data[2]);
85  data += 3;
86  length -= 3;
87  }
88  switch (length) {
89  case 3: writeUSBPacket(cn, 0x7, data[0], data[1], data[2]); break;
90  case 2: writeUSBPacket(cn, 0x6, data[0], data[1], 0); break;
91  case 1: writeUSBPacket(cn, 0x5, data[0], 0, 0); break;
92  default: break;
93  }
94  flushUSB();
95  }
96 
97  void sendImpl(uint8_t rt, uint8_t cn) override {
98  writeUSBPacket(cn, 0xF, // CN|CIN
99  rt, // single byte
100  0, // no data
101  0); // no data
102  flushUSB();
103  }
104 
105  public:
106  MIDIReadEvent read() override {
107  for (uint8_t i = 0; i < (SYSEX_BUFFER_SIZE + 2) / 3; ++i) {
108  MIDIUSBPacket_t midi_packet = readUSBPacket();
109  if (midi_packet.data[0] == 0)
110  return MIDIReadEvent::NO_MESSAGE;
111 
112  MIDIReadEvent parseResult = parser.parse(midi_packet.data);
113 
114  if (parseResult != MIDIReadEvent::NO_MESSAGE)
115  return parseResult;
116  }
117  return MIDIReadEvent::NO_MESSAGE;
118  }
119 };
120 
122 
123 // If the main MCU doesn't have a USB connection:
124 // Fall back on Serial connection at the hardware MIDI baud rate.
125 // (Can be used with HIDUINO or USBMidiKliK.)
126 #else
127 
128 #include "SerialMIDI_Interface.hpp"
129 
131 
141  public:
146 };
147 
149 
150 #endif
151 
USBMIDI_Interface
A class for MIDI interfaces sending MIDI messages over a USB MIDI connection.
Definition: USBMIDI_Interface.hpp:41
MIDI_BAUD
constexpr auto MIDI_BAUD
Definition: MIDI_Interface.hpp:11
USBMIDI_Interface::sendImpl
void sendImpl(uint8_t header, uint8_t d1, uint8_t cn) override
Low-level function for sending a 2-byte MIDI message.
Definition: USBMIDI_Interface.hpp:78
Error.hpp
USBMIDI_Parser::parse
MIDIReadEvent parse(uint8_t *packet)
Definition: USBMIDI_Parser.cpp:7
Parsing_MIDI_Interface
An abstract class for MIDI interfaces.
Definition: MIDI_Interface.hpp:232
SerialMIDI_Interface.hpp
USBMIDI.hpp
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
AH_DIAGNOSTIC_POP
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:36
USBMIDI_Parser.hpp
USBSerialMIDI_Interface
A class for MIDI interfaces sending and receiving MIDI messages over the Serial port of the USB conne...
Definition: SerialMIDI_Interface.hpp:160
USBMIDI_Interface::flushUSB
void flushUSB()
Definition: USBMIDI_Interface.hpp:67
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
USBMIDI_Parser
Definition: USBMIDI_Parser.hpp:19
AH::Array
An array wrapper for easy copying, comparing, and iterating.
Definition: Array.hpp:36
TeensyUSBTypes.hpp
USBMIDI::flush
void flush()
Definition: USBMIDI_MIDIUSB.ipp:24
USBMIDI_Interface::sendImpl
void sendImpl(const uint8_t *data, size_t length, uint8_t cn) override
Low-level function for sending a system exclusive MIDI message.
Definition: USBMIDI_Interface.hpp:82
USBMIDI::MIDIUSBPacket_t
AH::Array< uint8_t, 4 > MIDIUSBPacket_t
Definition: USBMIDI.hpp:8
USBMIDI_Interface::sendImpl
void sendImpl(uint8_t header, uint8_t d1, uint8_t d2, uint8_t cn) override
Low-level function for sending a 3-byte MIDI message.
Definition: USBMIDI_Interface.hpp:70
SYSEX_BUFFER_SIZE
constexpr size_t SYSEX_BUFFER_SIZE
The length of the maximum System Exclusive message that can be received.
Definition: Settings/Settings.hpp:54
USBMIDI_Interface::read
MIDIReadEvent read() override
Try reading and parsing a single incoming MIDI message.
Definition: USBMIDI_Interface.hpp:106
USBMIDI_Interface::sendImpl
void sendImpl(uint8_t rt, uint8_t cn) override
Low-level function for sending a single-byte MIDI message.
Definition: USBMIDI_Interface.hpp:97
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
MIDIReadEvent
MIDIReadEvent
Result of the MIDI interface read methods.
Definition: MIDI_Parser.hpp:15
AH::Array::data
T data[N]
Definition: Array.hpp:37
USBMIDI_Interface::parser
USBMIDI_Parser parser
Definition: USBMIDI_Interface.hpp:51
MIDI_Interface.hpp
USBMIDI_Interface::USBMIDI_Interface
USBMIDI_Interface()
Construct a new USBMIDI_Interface.
Definition: USBMIDI_Interface.hpp:46
USBMIDI::read
MIDIUSBPacket_t read()
Definition: USBMIDI_MIDIUSB.ipp:8
USBMIDI_Interface::writeUSBPacket
void writeUSBPacket(uint8_t cn, uint8_t cin, uint8_t d0, uint8_t d1, uint8_t d2)
Definition: USBMIDI_Interface.hpp:62
USBMIDI::write
void write(uint8_t cn, uint8_t cin, uint8_t d0, uint8_t d1, uint8_t d2)
Definition: USBMIDI_MIDIUSB.ipp:14
USBMIDI_Interface::readUSBPacket
MIDIUSBPacket_t readUSBPacket()
Definition: USBMIDI_Interface.hpp:66