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 "per/uart.h"
9#include "util/ringbuffer.h"
10#include "util/FIFO.h"
11#include "hid/midi_parser.h"
12#include "hid/usb_midi.h"
13#include "sys/dma.h"
14#include "sys/system.h"
15
16namespace daisy
17{
25{
26 public:
28 size_t size,
29 void* context);
30
33
60
62 inline void Init(Config config)
63 {
65
66 //defaults
67 uart_config.baudrate = 31250;
72
73 //user settings
74 uart_config.periph = config.periph;
75 uart_config.pin_config.rx = config.rx;
76 uart_config.pin_config.tx = config.tx;
77
78 rx_buffer = config.rx_buffer;
79 rx_buffer_size = config.rx_buffer_size;
80
82 std::fill(rx_buffer, rx_buffer + rx_buffer_size, 0);
83
84 uart_.Init(uart_config);
85 }
86
89 inline void StartRx(MidiRxParseCallback parse_callback, void* context)
90 {
91 parse_context_ = context;
92 parse_callback_ = parse_callback;
94 sizeof(MidiUartTransport));
95 uart_.DmaListenStart(
96 rx_buffer, rx_buffer_size, MidiUartTransport::rxCallback, this);
97 }
98
100 inline bool RxActive() { return uart_.IsListening(); }
101
103 inline void FlushRx() {}
104
106 inline void Tx(uint8_t* buff, size_t size) { uart_.PollTx(buff, size); }
107
108 private:
109 UartHandler uart_;
110 uint8_t* rx_buffer;
111 size_t rx_buffer_size;
112 void* parse_context_;
113 MidiRxParseCallback parse_callback_;
114
124 static void rxCallback(uint8_t* data,
125 size_t size,
126 void* context,
128 {
130 MidiUartTransport* transport
131 = reinterpret_cast<MidiUartTransport*>(context);
133 {
134 if(transport->parse_callback_)
135 {
136 transport->parse_callback_(
137 data, size, transport->parse_context_);
138 }
139 }
140 }
141};
142
151template <typename Transport>
153{
154 public:
157
158 struct Config
159 {
160 typename Transport::Config transport_config;
161 };
162
167 {
168 config_ = config;
169 transport_.Init(config_.transport_config);
170 parser_.Init();
171 }
172
176 {
177 transport_.StartRx(MidiHandler::ParseCallback, this);
178 }
179
181 void Listen()
182 {
183 // In case of UART Error, (particularly
184 // overrun error), UART disables itself.
185 // Flush the buff, and restart.
186 if(!transport_.RxActive())
187 {
188 parser_.Reset();
189 transport_.FlushRx();
190 StartReceive();
191 }
192 }
193
197 bool HasEvents() const { return event_q_.GetNumElements() > 0; }
198
199 bool RxActive() { return transport_.RxActive(); }
200
204 MidiEvent PopEvent() { return event_q_.PopFront(); }
205
210 {
211 transport_.Tx(bytes, size);
212 }
213
220 void Parse(uint8_t byte)
221 {
223 if(parser_.Parse(byte, &event))
224 {
225 event_q_.PushBack(event);
226 }
227 }
228
229 private:
230 Config config_;
231 Transport transport_;
232 MidiParser parser_;
233 FIFO<MidiEvent, 256> event_q_;
234
235 static void ParseCallback(uint8_t* data, size_t size, void* context)
236 {
237 MidiHandler* handler = reinterpret_cast<MidiHandler*>(context);
238 for(size_t i = 0; i < size; i++)
239 {
240 handler->Parse(data[i]);
241 }
242 }
243};
244
253} // namespace daisy
254#endif
Definition leddriver.h:33
void Init(I2CHandle i2c, const uint8_t(&addresses)[numDrivers], DmaBuffer dma_buffer_a, DmaBuffer dma_buffer_b, Pin oe_pin=Pin(PORTX, 0))
Definition leddriver.h:65
Simple MIDI Handler Parses bytes from an input into valid MidiEvents. The MidiEvents fill a FIFO qu...
Definition midi.h:153
void StartReceive()
Definition midi.h:175
MidiEvent PopEvent()
Definition midi.h:204
void Listen()
Definition midi.h:181
void SendMessage(uint8_t *bytes, size_t size)
Definition midi.h:209
MidiHandler()
Definition midi.h:155
bool RxActive()
Definition midi.h:199
void Parse(uint8_t byte)
Definition midi.h:220
bool HasEvents() const
Definition midi.h:197
void Init(Config config)
Definition midi.h:166
~MidiHandler()
Definition midi.h:156
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:25
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:89
void Tx(uint8_t *buff, size_t size)
sends the buffer of bytes out of the UART peripheral
Definition midi.h:106
~MidiUartTransport()
Definition midi.h:32
void FlushRx()
This is a no-op for UART transport - Rx is via DMA callback with circular buffer.
Definition midi.h:103
void(* MidiRxParseCallback)(uint8_t *data, size_t size, void *context)
Definition midi.h:27
MidiUartTransport()
Definition midi.h:31
bool RxActive()
returns whether the UART peripheral is actively listening in the background or not
Definition midi.h:100
void Init(Config config)
Initialization of UART using config struct.
Definition midi.h:62
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
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
Definition midi.h:159
Transport::Config transport_config
Definition midi.h:160
Configuration structure for UART MIDI.
Definition midi.h:36
Pin tx
Definition midi.h:39
Pin rx
Definition midi.h:38
UartHandler::Config::Peripheral periph
Definition midi.h:37
size_t rx_buffer_size
Definition midi.h:56
uint8_t * rx_buffer
Definition midi.h:48
representation of hardware port/pin combination
Definition daisy_core.h:193
Definition uart.h:30
Peripheral
Definition uart.h:32