Deluge Firmware
1.3.0
Build date: 2026.08.23
Toggle main menu visibility
Loading...
Searching...
No Matches
midi_device.h
1
/*
2
* Copyright © 2021-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
#include "definitions_cxx.hpp"
21
#include "model/midi/message.h"
22
#include "model/model_stack.h"
23
#include "util/d_string.h"
24
#include <array>
25
26
// These numbers are what get stored just in the internal Deluge flash memory to represent things.
27
#define VENDOR_ID_NONE 0
28
#define VENDOR_ID_UPSTREAM_USB 1
29
#define VENDOR_ID_DIN 2
30
#define VENDOR_ID_UPSTREAM_USB2 3
31
#define VENDOR_ID_UPSTREAM_USB3 4
32
33
#define MIDI_DIRECTION_INPUT_TO_DELUGE 0
34
#define MIDI_DIRECTION_OUTPUT_FROM_DELUGE 1
35
36
#define MPE_ZONE_LOWER_NUMBERED_FROM_0 0
37
#define MPE_ZONE_UPPER_NUMBERED_FROM_0 1
38
39
class
MIDICable
;
40
class
Serializer
;
41
class
Deserializer
;
42
43
class
MIDIPort {
44
public
:
45
MIDIPort() {
46
mpeLowerZoneLastMemberChannel = 0;
47
mpeUpperZoneLastMemberChannel = 15;
48
}
49
int32_t channelToZone(int32_t inputChannel);
50
void
writeToFile(
Serializer
& writer,
char
const
* tagName);
51
bool
worthWritingToFile();
52
void
readFromFile(
Deserializer
& reader,
MIDICable
* deviceToSendMCMsOn);
53
void
moveUpperZoneOutOfWayOfLowerZone();
54
void
moveLowerZoneOutOfWayOfUpperZone();
55
bool
isMasterChannel(int32_t inputChannel);
56
inline
bool
isChannelPartOfAnMPEZone(int32_t channel) {
57
return
(channel >= 1 && channel <= 14
58
&& (mpeLowerZoneLastMemberChannel >= channel || mpeUpperZoneLastMemberChannel <= channel));
59
}
60
61
uint8_t mpeLowerZoneLastMemberChannel;
// 0 means off
62
uint8_t mpeUpperZoneLastMemberChannel;
// 15 means off
63
};
64
65
class
MIDIInputChannel {
66
public
:
67
MIDIInputChannel() {
68
bendRange = 0;
// Means not set; don't copy value. Also, note this is the "main" bend range; there isn't one for
69
// finger-level because this is a non-MPE single MIDI channel.
70
rpnLSB = 127;
// Means no param specified
71
rpnMSB = 127;
72
}
73
74
/* These are stored as full-range 16-bit values (scaled up from 7 or 14-bit MIDI depending on which), and you'll
75
* want to scale this up again to 32-bit to use them. X and Y may be both positive and negative, and Z may only be
76
* positive (so has been scaled up less from incoming bits). These default to 0. These are just for
77
* MelodicInstruments. For Drums, the values get stored in the Drum itself.
78
*/
79
std::array<int16_t, kNumExpressionDimensions> defaultInputMPEValues{0};
80
81
uint8_t rpnLSB;
82
uint8_t rpnMSB;
83
uint8_t bendRange;
84
};
85
86
/*
87
* MidiDevice primarily holds configuration settings and associated data - the sendMessage function
88
* is used only during setup, and data is r/w directly from the super device (connectedUSBMIDIDevice)
89
* or the serial ports as applicable
90
* See MIDIDeviceManager or midiengine.cpp for details
91
*/
92
93
enum class
clock_setting { NONE, RECEIVE, SEND, BOTH };
94
96
class
MIDICable {
97
public
:
98
MIDICable();
99
virtual
void
writeToFlash(uint8_t* memory) = 0;
100
virtual
char
const
* getDisplayName() = 0;
101
102
void
dataEntryMessageReceived(
ModelStack
* modelStack, int32_t channel, int32_t msb);
103
105
[[nodiscard]]
virtual
bool
wantsToOutputMIDIOnChannel
(
MIDIMessage
message, int32_t filter)
const
;
106
109
void
writeReferenceToFile(
Serializer
& writer,
char
const
* tagName =
"device"
);
110
void
writeToFile(
Serializer
& writer,
char
const
* tagName);
111
void
readFromFile(
Deserializer
& reader);
112
bool
worthWritingToFile();
113
void
writePorts(
Serializer
& writer);
115
118
120
virtual
void
sendMessage
(
MIDIMessage
message) = 0;
121
126
virtual
void
sendSysex
(
const
uint8_t* data, int32_t len) = 0;
127
129
[[nodiscard]]
virtual
size_t
sendBufferSpace
()
const
= 0;
130
134
136
void
sendAllMCMs
();
137
138
inline
void
sendCC(int32_t channel, int32_t cc, int32_t value) {
sendMessage
(MIDIMessage::cc(channel, cc, value)); }
139
void
sendRPN(int32_t channel, int32_t rpnMSB, int32_t rpnLSB, int32_t valueMSB);
140
// @}
141
142
inline
bool
hasDefaultVelocityToLevelSet() {
return
defaultVelocityToLevel; }
143
144
// Only 2 ports per device, but this is functionally set in stone due to existing code
145
// Originally done to ease integration to the midi device setting menu
146
MIDIPort ports[2];
147
148
uint8_t mpeZoneBendRanges[2][2];
// 0 means none set. It's [zone][whichBendRange].
149
150
MIDIInputChannel inputChannels[16];
151
152
int32_t defaultVelocityToLevel;
153
154
// 0 if not connected. For USB devices, the bits signal a connection of the corresponding connectedUSBMIDIDevices[].
155
// Of course there'll usually just be one bit set, unless two of the same device are connected.
156
uint8_t connectionFlags;
157
bool
sendClock;
// whether to send clocks to this device
158
bool
receiveClock;
// whether to receive clocks from this device
159
bool
is_relative;
// whether this device receive's relative cc's (used with midi takeover)
160
uint8_t incomingSysexBuffer[1024];
161
int32_t incomingSysexPos = 0;
162
163
protected
:
164
// These go both into SETTINGS/MIDIDevices.XML and also any song/preset
165
// files where there's a reference to this Device.
166
virtual
void
writeReferenceAttributesToFile(Serializer& writer) = 0;
167
168
// These only go into SETTINGS/MIDIDevices.XML
169
void
writeDefinitionAttributesToFile(Serializer& writer);
170
};
Deserializer
Definition
storage_manager.h:185
MIDICable
A MIDI cable connection. Stores all state specific to a given cable and its contained ports and chann...
Definition
midi_device.h:96
MIDICable::sendAllMCMs
void sendAllMCMs()
Send MPE control messages.
Definition
midi_device.cpp:167
MIDICable::sendBufferSpace
virtual size_t sendBufferSpace() const =0
Get the number of bytes available in the send buffer.
MIDICable::wantsToOutputMIDIOnChannel
virtual bool wantsToOutputMIDIOnChannel(MIDIMessage message, int32_t filter) const
Used to decide if the given message should be output on a channel.
Definition
midi_device.cpp:136
MIDICable::sendSysex
virtual void sendSysex(const uint8_t *data, int32_t len)=0
MIDICable::sendMessage
virtual void sendMessage(MIDIMessage message)=0
Send a MIDI message.
ModelStack
Definition
model_stack.h:123
Serializer
Definition
storage_manager.h:119
MIDIMessage
Definition
message.h:30