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