libDaisy
Hardware Library for Daisy
Loading...
Searching...
No Matches
midi.h
Go to the documentation of this file.
1#pragma once
2#ifndef DSY_MIDI_H
3#define DSY_MIDI_H
4
5#include <stdint.h>
6#include <stdlib.h>
7#include <algorithm>
8#include <functional>
9#include "per/uart.h"
10#include "util/ringbuffer.h"
11#include "util/FIFO.h"
12#include "hid/midi_parser.h"
13#include "hid/usb_midi.h"
14#include "sys/dma.h"
15#include "sys/system.h"
16
17namespace daisy
18{
26{
27 public:
28 typedef void (*MidiRxParseCallback)(uint8_t* data,
29 size_t size,
30 void* context);
31
34
61
63 inline void Init(Config config)
64 {
65 UartHandler::Config uart_config;
66
67 //defaults
68 uart_config.baudrate = 31250;
73
74 //user settings
75 uart_config.periph = config.periph;
76 uart_config.pin_config.rx = config.rx;
77 uart_config.pin_config.tx = config.tx;
78
79 rx_buffer = config.rx_buffer;
80 rx_buffer_size = config.rx_buffer_size;
81
83 std::fill(rx_buffer, rx_buffer + rx_buffer_size, 0);
84
85 uart_.Init(uart_config);
86 }
87
90 inline void StartRx(MidiRxParseCallback parse_callback, void* context)
91 {
92 parse_context_ = context;
93 parse_callback_ = parse_callback;
94 dsy_dma_clear_cache_for_buffer((uint8_t*)this,
95 sizeof(MidiUartTransport));
96 uart_.DmaListenStart(
97 rx_buffer, rx_buffer_size, MidiUartTransport::rxCallback, this);
98 }
99
101 inline bool RxActive() { return uart_.IsListening(); }
102
104 inline void FlushRx() {}
105
107 inline void Tx(uint8_t* buff, size_t size) { uart_.PollTx(buff, size); }
108
109 private:
110 UartHandler uart_;
111 uint8_t* rx_buffer;
112 size_t rx_buffer_size;
113 void* parse_context_;
114 MidiRxParseCallback parse_callback_;
115
125 static void rxCallback(uint8_t* data,
126 size_t size,
127 void* context,
129 {
131 MidiUartTransport* transport
132 = reinterpret_cast<MidiUartTransport*>(context);
133 if(res == UartHandler::Result::OK)
134 {
135 if(transport->parse_callback_)
136 {
137 transport->parse_callback_(
138 data, size, transport->parse_context_);
139 }
140 }
141 }
142};
143
152template <typename Transport>
154{
155 public:
156 using MidiEventCallback = std::function<void(MidiEvent&)>;
157
160
161 struct Config
162 {
163 typename Transport::Config transport_config;
164 };
165
169 void Init(Config config)
170 {
171 config_ = config;
172 transport_.Init(config_.transport_config);
173 parser_.Init();
174 }
175
179 {
180 transport_.StartRx(MidiHandler::ParseCallback, this);
181 }
182
187 void StartReceiveRt(MidiEventCallback callback_for_rt_messages)
188 {
189 realtime_callback_ = callback_for_rt_messages;
190 transport_.StartRx(MidiHandler::ParseCallback, this);
191 }
192
194 void Listen()
195 {
196 // In case of UART Error, (particularly
197 // overrun error), UART disables itself.
198 // Flush the buff, and restart.
199 if(!transport_.RxActive())
200 {
201 parser_.Reset();
202 transport_.FlushRx();
203 StartReceive();
204 }
205 }
206
210 bool HasEvents() const { return event_q_.GetNumElements() > 0; }
211
212 bool RxActive() { return transport_.RxActive(); }
213
217 MidiEvent PopEvent() { return event_q_.PopFront(); }
218
222 void SendMessage(uint8_t* bytes, size_t size)
223 {
224 transport_.Tx(bytes, size);
225 }
226
233 void Parse(uint8_t byte)
234 {
235 MidiEvent event;
236 if(parser_.Parse(byte, &event))
237 {
239 {
240 if(realtime_callback_)
241 {
242 realtime_callback_(event);
243 return;
244 }
245 }
246 event_q_.PushBack(event);
247 return;
248 }
249 }
250
251 private:
252 Config config_;
253 Transport transport_;
254 MidiParser parser_;
255 FIFO<MidiEvent, 256> event_q_;
256 MidiEventCallback realtime_callback_;
257
258 static void ParseCallback(uint8_t* data, size_t size, void* context)
259 {
260 MidiHandler* handler = reinterpret_cast<MidiHandler*>(context);
261 for(size_t i = 0; i < size; i++)
262 {
263 handler->Parse(data[i]);
264 }
265 }
266};
267
276} // namespace daisy
277#endif
Definition FIFO.h:299
Simple MIDI Handler Parses bytes from an input into valid MidiEvents. The MidiEvents fill a FIFO qu...
Definition midi.h:154
std::function< void(MidiEvent &)> MidiEventCallback
Definition midi.h:156
void StartReceive()
Definition midi.h:178
MidiEvent PopEvent()
Definition midi.h:217
void Listen()
Definition midi.h:194
void SendMessage(uint8_t *bytes, size_t size)
Definition midi.h:222
MidiHandler()
Definition midi.h:158
bool RxActive()
Definition midi.h:212
void Parse(uint8_t byte)
Definition midi.h:233
bool HasEvents() const
Definition midi.h:210
void Init(Config config)
Definition midi.h:169
void StartReceiveRt(MidiEventCallback callback_for_rt_messages)
Definition midi.h:187
~MidiHandler()
Definition midi.h:159
Utility class for parsing raw byte streams into MIDI messages.
Definition midi_parser.h:16
void Reset()
Reset parser to default state.
bool Parse(uint8_t byte, MidiEvent *event_out)
Parse one MIDI byte. If the byte completes a parsed event, its value will be assigned to the derefere...
void Init()
Definition midi_parser.h:21
Transport layer for sending and receiving MIDI data over UART.
Definition midi.h:26
void StartRx(MidiRxParseCallback parse_callback, void *context)
Start the UART peripheral in listening mode. This will fill an internal data structure in the backgro...
Definition midi.h:90
void Tx(uint8_t *buff, size_t size)
sends the buffer of bytes out of the UART peripheral
Definition midi.h:107
~MidiUartTransport()
Definition midi.h:33
void FlushRx()
This is a no-op for UART transport - Rx is via DMA callback with circular buffer.
Definition midi.h:104
void(*) MidiRxParseCallback(uint8_t *data, size_t size, void *context)
Definition midi.h:28
MidiUartTransport()
Definition midi.h:32
bool RxActive()
returns whether the UART peripheral is actively listening in the background or not
Definition midi.h:101
void Init(Config config)
Initialization of UART using config struct.
Definition midi.h:63
Definition uart.h:27
bool IsListening() const
Result DmaListenStart(uint8_t *buff, size_t size, CircularRxCallbackFunctionPtr cb, void *callback_context)
Result PollTx(uint8_t *buff, size_t size)
Result Init(const Config &config)
Result
Definition uart.h:103
@ SystemRealTime
Definition MidiEvent.h:30
void dsy_dma_clear_cache_for_buffer(uint8_t *buffer, size_t size)
Hardware defines and helpers for daisy field platform.
Definition index.h:2
Definition MidiEvent.h:240
MidiMessageType type
Definition MidiEvent.h:242
Definition midi.h:162
Transport::Config transport_config
Definition midi.h:163
Configuration structure for UART MIDI.
Definition midi.h:37
Pin tx
Definition midi.h:40
Pin rx
Definition midi.h:39
UartHandler::Config::Peripheral periph
Definition midi.h:38
size_t rx_buffer_size
Definition midi.h:57
uint8_t * rx_buffer
Definition midi.h:49
representation of hardware port/pin combination
Definition daisy_core.h:193
Definition uart.h:30
Pin rx
Definition uart.h:76
Pin tx
Definition uart.h:75
Mode mode
Definition uart.h:91
StopBits stopbits
Definition uart.h:89
WordLength wordlength
Definition uart.h:92
Peripheral periph
Definition uart.h:88
struct daisy::UartHandler::Config::@20 pin_config
uint32_t baudrate
Definition uart.h:93
Parity parity
Definition uart.h:90
Peripheral
Definition uart.h:32