Deluge Firmware 1.3.0
Build date: 2025.04.16
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
39class MIDICable;
40class Serializer;
41class Deserializer;
42
43class MIDIPort {
44public:
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
65class MIDIInputChannel {
66public:
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
94class MIDICable {
95public:
96 MIDICable();
97 virtual void writeToFlash(uint8_t* memory) = 0;
98 virtual char const* getDisplayName() = 0;
99
100 void dataEntryMessageReceived(ModelStack* modelStack, int32_t channel, int32_t msb);
101
103 [[nodiscard]] virtual bool wantsToOutputMIDIOnChannel(MIDIMessage message, int32_t filter) const;
104
107 void writeReferenceToFile(Serializer& writer, char const* tagName = "device");
108 void writeToFile(Serializer& writer, char const* tagName);
109 void readFromFile(Deserializer& reader);
110 bool worthWritingToFile();
111 void writePorts(Serializer& writer);
113
116
118 virtual void sendMessage(MIDIMessage message) = 0;
119
124 virtual void sendSysex(const uint8_t* data, int32_t len) = 0;
125
127 [[nodiscard]] virtual size_t sendBufferSpace() const = 0;
128
132
134 void sendAllMCMs();
135
136 inline void sendCC(int32_t channel, int32_t cc, int32_t value) { sendMessage(MIDIMessage::cc(channel, cc, value)); }
137 void sendRPN(int32_t channel, int32_t rpnMSB, int32_t rpnLSB, int32_t valueMSB);
138 // @}
139
140 inline bool hasDefaultVelocityToLevelSet() { return defaultVelocityToLevel; }
141
142 // Only 2 ports per device, but this is functionally set in stone due to existing code
143 // Originally done to ease integration to the midi device setting menu
144 MIDIPort ports[2];
145
146 uint8_t mpeZoneBendRanges[2][2]; // 0 means none set. It's [zone][whichBendRange].
147
148 MIDIInputChannel inputChannels[16];
149
150 int32_t defaultVelocityToLevel;
151
152 // 0 if not connected. For USB devices, the bits signal a connection of the corresponding connectedUSBMIDIDevices[].
153 // Of course there'll usually just be one bit set, unless two of the same device are connected.
154 uint8_t connectionFlags;
155 bool sendClock; // whether to send clocks to this device
156 uint8_t incomingSysexBuffer[1024];
157 int32_t incomingSysexPos = 0;
158
159protected:
160 // These go both into SETTINGS/MIDIDevices.XML and also any song/preset
161 // files where there's a reference to this Device.
162 virtual void writeReferenceAttributesToFile(Serializer& writer) = 0;
163
164 // These only go into SETTINGS/MIDIDevices.XML
165 void writeDefinitionAttributesToFile(Serializer& writer);
166};
Definition storage_manager.h:185
A MIDI cable connection. Stores all state specific to a given cable and its contained ports and chann...
Definition midi_device.h:94
void sendAllMCMs()
Send MPE control messages.
Definition midi_device.cpp:165
virtual size_t sendBufferSpace() const =0
Get the number of bytes available in the send buffer.
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:134
virtual void sendSysex(const uint8_t *data, int32_t len)=0
virtual void sendMessage(MIDIMessage message)=0
Send a MIDI message.
Definition model_stack.h:123
Definition storage_manager.h:119
Definition message.h:30