Deluge Firmware 1.3.0
Build date: 2026.10.14
Loading...
Searching...
No Matches
midi_engine.h
1/*
2 * Copyright © 2014-2023 Synthstrom Audible Limited
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#ifdef __cplusplus
21
22#include "OSLikeStuff/scheduler_api.h"
23#include "definitions_cxx.hpp"
24#include "io/midi/learned_midi.h"
25#include "playback/playback_handler.h"
26
27struct InterruptsDisabled;
28struct QueuedMIDI;
29class MIDICable;
30class MIDIDrum;
31class MIDIInstrument;
32class MidiFollow;
33class PlaybackHandler;
34
37struct MIDISource {
38 void const* source_{nullptr};
39
40 MIDISource() = default;
41 ~MIDISource() = default;
42
43 MIDISource(MIDICable const* cable) : source_(cable) {};
44 MIDISource(MIDIInstrument const* instrument) : source_(instrument) {};
45 MIDISource(PlaybackHandler const* handler) : source_(handler) {};
46 MIDISource(MidiFollow const* follow) : source_(follow) {};
47 MIDISource(MIDIDrum const* drum) : source_(drum) {};
48 MIDISource(Sound const* sound) : source_(sound) {};
49
50 MIDISource(MIDICable const& cable) : source_(&cable) {};
51 MIDISource(MIDIInstrument const& instrument) : source_(&instrument) {};
52 MIDISource(MIDIDrum const& drum) : source_(&drum) {};
53 MIDISource(Sound const& sound) : source_(&sound) {};
54 MIDISource(MidiFollow const& follow) : source_(&follow) {};
55 MIDISource(PlaybackHandler const& handler) : source_(&handler) {};
56
57 MIDISource(MIDISource const& other) = default;
58 MIDISource(MIDISource&& other) = default;
59
60 MIDISource& operator=(MIDISource const& other) = default;
61 MIDISource& operator=(MIDISource&& other) = default;
62
63 bool operator==(MIDISource const& other) const { return source_ == other.source_; }
64};
65
66class MidiEngine {
67public:
68 MidiEngine();
69
70 void sendNote(MIDISource source, bool on, int32_t note, uint8_t velocity, uint8_t channel, int32_t filter);
71 void sendCC(MIDISource source, int32_t channel, int32_t cc, int32_t value, int32_t filter);
72 bool checkIncomingSerialMidi();
73 static void check_incoming_usb();
74 void checkIncomingUsbMidi();
75
76 void checkIncomingUsbSysex(uint8_t const* message, int32_t ip, int32_t d, int32_t cable);
77
78 void sendMidi(MIDISource source, MIDIMessage message, int32_t filter = kMIDIOutputFilterNoMPE, bool sendUSB = true);
79 void sendClock(MIDISource source, bool sendUSB = true, int32_t howMany = 1);
80 void sendStart(MIDISource source);
81 void sendStop(MIDISource source);
82 void sendPositionPointer(MIDISource source, uint16_t positionPointer);
83 void sendContinue(MIDISource source);
84
85 void flushMIDI();
86 void sendUsbMidi(MIDIMessage message, int32_t filter);
87 void sendSerialMidi(MIDIMessage message);
88
89 void sendPGMChange(MIDISource source, int32_t channel, int32_t pgm, int32_t filter);
90 void sendAllNotesOff(MIDISource source, int32_t channel, int32_t filter);
91 void sendBank(MIDISource source, int32_t channel, int32_t num, int32_t filter);
92 void sendSubBank(MIDISource source, int32_t channel, int32_t num, int32_t filter);
96 void sendPitchBend(MIDISource source, int32_t channel, uint16_t bend, int32_t filter);
98 void sendChannelAftertouch(MIDISource source, int32_t channel, int32_t value, int32_t filter);
100 void sendPolyphonicAftertouch(MIDISource source, int32_t channel, int32_t value, uint8_t noteCode, int32_t filter);
101 bool anythingInOutputBuffer();
102
106 void setMIDIDue(uint32_t due) { midiDue_ = due; }
110 bool flushDueMIDI(uint32_t now, const InterruptsDisabled&);
113 void flushAllQueuedMIDI(const InterruptsDisabled&);
115 bool nextMIDIDue(uint32_t& due);
116
117 void setupUSBHostReceiveTransfer(int32_t ip, int32_t midiDeviceNum);
118 void flushUSBMIDIOutput();
119
120 // If bit "16" (actually bit 4) is 1, this is a program change. (Wait, still?)
121 LearnedMIDI globalMIDICommands[kNumGlobalMIDICommands];
122
123 bool midiThru;
124 LearnedMIDI midiFollowChannelType[kNumMIDIFollowChannelTypesIncludingTracks]; // A, B, C, Track 1-16
125 MIDIFollowFeedbackChannelType midiFollowFeedbackChannelType; // NONE, A, B, C, Track, Track + A/B/C
126 uint8_t midiFollowKitRootNote;
127 bool midiFollowDisplayParam;
128 MIDIFollowFeedbackAutomationMode midiFollowFeedbackAutomation;
129 bool midiFollowFeedbackFilter;
130 MIDITakeoverMode midiTakeover;
131 bool midiSelectKitRow;
132 TaskID routine_task_id;
133
134 // shared buffer for formatting sysex messages.
135 // Not safe for use in interrupts.
136 uint8_t sysex_fmt_buffer[1024];
137
147 void midiMessageReceived(MIDICable& cable, uint8_t statusType, uint8_t channel, uint8_t data1, uint8_t data2,
148 uint32_t* timer = nullptr);
149
155 void midiSysexReceived(MIDICable& cable, uint8_t* data, int32_t len);
156
157private:
158 uint8_t serialMidiInput[3];
159 uint8_t numSerialMidiInput;
160
161 bool currentlyReceivingSysExSerial;
162
163 using EventStackStorage = std::array<MIDISource, 16>;
166 EventStackStorage eventStack_;
168 EventStackStorage::iterator eventStackTop_;
169
170 int32_t getPotentialNumConnectedUSBMIDIDevices(int32_t ip);
171
172 void queueMIDI(MIDIMessage message, int32_t filter, bool sendUSB, bool sendDIN, uint32_t due);
174 bool flushQueuedMIDI(bool all, uint32_t now);
177 bool sendOldestQueuedMIDI(const InterruptsDisabled&);
178 void sendQueuedMIDI(const QueuedMIDI& queued);
179
180 uint32_t midiDue_{0};
181};
182
183extern MidiEngine midiEngine;
184extern bool anythingInUSBOutputBuffer;
185
186extern "C" {
187#endif
188extern uint16_t g_usb_usbmode;
189
190void usbSendCompleteAsHost(int32_t ip); // used when deluge is in host mode
191void usbSendCompleteAsPeripheral(int32_t ip); // used in peripheral mode
192#ifdef __cplusplus
193}
194#endif
A MIDI cable connection. Stores all state specific to a given cable and its contained ports and chann...
Definition midi_device.h:96
Definition midi_drum.h:22
Definition midi_instrument.h:38
Definition midi_follow.h:40
Definition playback_handler.h:54
Definition midi_queue.h:38