Deluge Firmware 1.3.0
Build date: 2025.06.05
Loading...
Searching...
No Matches
midi_device_manager.h
1/*
2 * Copyright © 2015-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#ifdef __cplusplus
20#include "definitions_cxx.hpp"
21#include "io/midi/cable_types/usb_common.h"
22#include "io/midi/cable_types/usb_device_cable.h"
23#include "io/midi/root_complex/din.h"
24#include "io/midi/root_complex/usb_hosted.h"
25#include "util/container/vector/named_thing_vector.h"
26#include <gsl/gsl>
27
28class Serializer;
29class Deserializer;
30
31#else
32#include "definitions.h"
33struct MIDICableUSB;
34#endif
35
36// size in 32-bit messages
37// NOTE: increasing this even more doesn't work.
38// Looks like a hardware limitation (maybe we more in FS mode)?
39#define MIDI_SEND_BUFFER_LEN_INNER 32
40// Seems to be the max for a hydrasynth on a usb hub? We should figure out how to find this from the device config but I
41// haven't seen anything below this yet. Widi bud's can do 3, both do fine at 16 without a hub involved
42#define MIDI_SEND_BUFFER_LEN_INNER_HOST 2
43
44// MUST be an exact power of two
45#define MIDI_SEND_BUFFER_LEN_RING 1024
46#define MIDI_SEND_RING_MASK (MIDI_SEND_BUFFER_LEN_RING - 1)
47
48#ifdef __cplusplus
49/*A ConnectedUSBMIDIDevice is used directly to interface with the USB driver
50 * When a ConnectedUSBMIDIDevice has a numMessagesQueued>=MIDI_SEND_BUFFER_LEN and tries to add another,
51 * all outputs are sent. The send routine calls the USB output function, points the
52 * USB pipes FIFO buffer directly at the dataSendingNow array, and then sends.
53 * Sends can also be triggered by the midiAndGateOutput interrupt
54 *
55 * Reads are more complicated.
56 * Actual reads are done by usb_cstd_usb_task, which has a commented out interrupt associated
57 * The function is instead called in the midiengine::checkincomingUSBmidi function, which is called
58 * in the audio engine loop
59 *
60 * The USB read function is configured by setupUSBHostReceiveTransfer, which is called to
61 * setup the next device after each successful read. Data is written directly into the receiveData
62 * array from the USB device, it's set as the USB pipe address during midi engine setup
63 */
65public:
66 MIDICableUSB* cable[4]; // If NULL, then no cable is connected here
67 ConnectedUSBMIDIDevice();
68 void bufferMessage(uint32_t fullMessage);
69 void setup();
70
71 // move data from ring buffer to dataSendingNow, assuming it is free
72 bool consumeSendData();
73 bool hasBufferedSendData();
74 int sendBufferSpace();
75#else
76// warning - accessed as a C struct from usb driver
78 struct MIDICableUSB* device[4];
79#endif
80 uint8_t currentlyWaitingToReceive;
81 uint8_t sq; // Only for connections as HOST
82 uint8_t canHaveMIDISent;
83 uint16_t numBytesReceived;
84 uint8_t receiveData[64];
85
86 // This buffer is passed directly to the USB driver, and is limited to what the hardware allows
87 uint8_t dataSendingNow[MIDI_SEND_BUFFER_LEN_INNER * 4];
88 // This will show a value after the general flush function is called, throughout other Devices being sent to before
89 // this one, and until we've completed our send
90 uint8_t numBytesSendingNow;
91
92 // This is a ring buffer for data waiting to be sent which doesn't fit the smaller buffer above.
93 // Any code which wants to send midi data would use the writing side and append more messages.
94 // When we are ready to send data on this device, we consume data on the reading side and move it into the
95 // smaller dataSendingNow buffer above.
96 uint32_t sendDataRingBuf[MIDI_SEND_BUFFER_LEN_RING];
97 uint32_t ringBufWriteIdx;
98 uint32_t ringBufReadIdx;
99
100 uint8_t maxPortConnected;
101};
102
103#ifdef __cplusplus
104namespace MIDIDeviceManager {
105
106void slowRoutine();
107MIDICable* readDeviceReferenceFromFile(Deserializer& reader);
108void readDeviceReferenceFromFlash(GlobalMIDICommand whichCommand, uint8_t const* memory);
109void writeDeviceReferenceToFlash(GlobalMIDICommand whichCommand, uint8_t* memory);
110void readMidiFollowDeviceReferenceFromFlash(MIDIFollowChannelType whichType, uint8_t const* memory);
111void writeMidiFollowDeviceReferenceToFlash(MIDIFollowChannelType whichType, uint8_t* memory);
112void recountSmallestMPEZones();
113void writeDevicesToFile();
114void readAHostedDeviceFromFile(Deserializer& reader);
115void readDevicesFromFile();
116
119void setUSBRoot(MIDIRootComplex* root);
120
121extern DINRootComplex root_din;
122extern gsl::owner<MIDIRootComplex*> root_usb;
123
124MIDIRootComplexUSBHosted* getHosted();
125
126extern bool differentiatingInputsByDevice;
127
128extern uint8_t lowestLastMemberChannelOfLowerZoneOnConnectedOutput;
129extern uint8_t highestLastMemberChannelOfUpperZoneOnConnectedOutput;
130extern bool anyChangesToSave;
131} // namespace MIDIDeviceManager
132
133#endif
134
135extern struct ConnectedUSBMIDIDevice connectedUSBMIDIDevices[][MAX_NUM_USB_MIDI_DEVICES];
Definition din.h:24
Definition storage_manager.h:185
Definition usb_common.h:22
A MIDI cable connection. Stores all state specific to a given cable and its contained ports and chann...
Definition midi_device.h:94
Definition usb_hosted.h:25
Definition midi_root_complex.h:36
Definition storage_manager.h:119
Definition midi_device_manager.h:77