Deluge Firmware 1.3.0
Build date: 2026.08.29
Loading...
Searching...
No Matches
midi_follow.h
1/*
2 * Copyright (c) 2024 Sean Ditny
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/global_effectable/global_effectable.h"
22#include "modulation/params/param.h"
23#include "storage/storage_manager.h"
24#include "util/containers.h"
25#include <array>
26#include <cstdint>
27
28class AudioClip;
29class InstrumentClip;
30class Clip;
31class Kit;
32class Drum;
33class ModelStack;
36enum class MIDIMatchType;
37
39
40class MidiFollow final {
41public:
42 MidiFollow();
43 void factoryReset(bool showPopup = true);
46
48 Clip* clip, int32_t soundParamId, int32_t globalParamId,
49 bool displayError = true);
50 void noteMessageReceived(MIDICable& cable, bool on, int32_t channel, int32_t note, int32_t velocity,
51 bool* doingMidiThru, bool shouldRecordNotesNowNow, ModelStack* modelStack);
52 Output* sendNoteToClip(MIDICable& cable, Clip* clip, MIDIMatchType match, bool on, int32_t channel, int32_t note,
53 int32_t velocity, bool* doingMidiThru, bool shouldRecordNotesNowNow, ModelStack* modelStack,
54 bool updateClipForLastNoteReceived = true);
55 void midiCCReceived(MIDICable& cable, uint8_t channel, uint8_t ccNumber, uint8_t ccValue, bool* doingMidiThru,
56 ModelStack* modelStack);
57 void pitchBendReceived(MIDICable& cable, uint8_t channel, uint8_t data1, uint8_t data2, bool* doingMidiThru,
58 ModelStack* modelStack);
59 void aftertouchReceived(MIDICable& cable, int32_t channel, int32_t value, int32_t noteCode, bool* doingMidiThru,
60 ModelStack* modelStack);
61
62 void clearStoredClips();
63 void removeClip(Clip* clip);
64
65 // midi CC mappings
66 int32_t getCCFromParam(deluge::modulation::params::Kind paramKind, int32_t paramID);
68
69 std::array<uint8_t, kMaxMIDIValue + 1> ccToSoundParam;
70 std::array<uint8_t, kMaxMIDIValue + 1> ccToGlobalParam;
71 std::array<uint8_t, params::UNPATCHED_START + params::UNPATCHED_SOUND_MAX_NUM> soundParamToCC;
72 std::array<uint8_t, params::UNPATCHED_GLOBAL_MAX_NUM> globalParamToCC;
73
74 int32_t previousKnobPos[kMaxMIDIValue + 1];
75 uint32_t timeLastCCSent[kMaxMIDIValue + 1];
76 uint32_t timeAutomationFeedbackLastSent;
77
78 // public so it can be called from View::sendMidiFollowFeedback
79 bool isFeedbackEnabled();
80 void sendCCWithoutModelStackForMidiFollowFeedback(bool isAutomation = false);
82 void sendCCForMidiFollowFeedback(int32_t ccNumber, int32_t knobPos);
83
84 void handleReceivedCC(MIDICable& cable, ModelStackWithTimelineCounter& modelStack, Clip* clip, int32_t ccNumber,
85 int32_t ccValue);
86
87private:
88 // initialize
89 void init();
90 void initState();
91 void clearMappings();
92 void initDefaultMappings();
93
94 // note recieved
95 Output* noteMessageReceivedForSelectedOrActiveClip(MIDICable& cable, bool on, int32_t channel, int32_t note,
96 int32_t velocity, bool* doingMidiThru,
97 bool shouldRecordNotesNowNow, ModelStack* modelStack);
98 void noteMessageReceivedForSpecificTrack(MIDICable& cable, bool on, int32_t channel, int32_t note, int32_t velocity,
99 bool* doingMidiThru, bool shouldRecordNotesNowNow, ModelStack* modelStack,
100 Output* specific_track, int32_t specific_track_index);
101 // cc received
102 Output* midiCCReceivedForSelectedOrActiveClip(MIDICable& cable, uint8_t channel, uint8_t ccNumber, uint8_t ccValue,
103 bool* doingMidiThru, ModelStack* modelStack);
104 void midiCCReceivedForSpecificTrack(MIDICable& cable, uint8_t channel, uint8_t ccNumber, uint8_t ccValue,
105 bool* doingMidiThru, ModelStack* modelStack, Output* specific_track,
106 int32_t specific_track_index);
107
108 // pitch bend received
109 Output* pitchBendReceivedForSelectedOrActiveClip(MIDICable& cable, uint8_t channel, uint8_t data1, uint8_t data2,
110 bool* doingMidiThru, ModelStack* modelStack);
111 void pitchBendReceivedForSpecificTrack(MIDICable& cable, uint8_t channel, uint8_t data1, uint8_t data2,
112 bool* doingMidiThru, ModelStack* modelStack, Output* specific_track,
113 int32_t specific_track_index);
114
115 // after touch received
116 Output* aftertouchReceivedForSelectedOrActiveClip(MIDICable& cable, int32_t channel, int32_t value,
117 int32_t noteCode, bool* doingMidiThru, ModelStack* modelStack);
118 void aftertouchReceivedForSpecificTrack(MIDICable& cable, int32_t channel, int32_t value, int32_t noteCode,
119 bool* doingMidiThru, ModelStack* modelStack, Output* specific_track,
120 int32_t specific_track_index);
121
124 Clip* getActiveClip(ModelStack* modelStack);
125 [[nodiscard]] const size_t getTrackCount() const;
126 Output* getTrackFromIndex(uint32_t trackIndex, uint32_t maxTrack);
127
128 // get model stack with auto param for midi follow cc-param control
129 ModelStackWithAutoParam* getModelStackWithParamForSong(ModelStackWithThreeMainThings* modelStackWithThreeMainThings,
130 int32_t soundParamId, int32_t globalParamId);
131 ModelStackWithAutoParam* getModelStackWithParamForClip(ModelStackWithTimelineCounter* modelStackWithTimelineCounter,
132 Clip* clip, int32_t soundParamId, int32_t globalParamId);
134 getModelStackWithParamForSynthClip(ModelStackWithTimelineCounter* modelStackWithTimelineCounter, Clip* clip,
135 int32_t soundParamId, int32_t globalParamId);
137 getModelStackWithParamForKitClip(ModelStackWithTimelineCounter* modelStackWithTimelineCounter, Clip* clip,
138 int32_t soundParamId, int32_t globalParamId);
140 getModelStackWithParamForAudioClip(ModelStackWithTimelineCounter* modelStackWithTimelineCounter, Clip* clip,
141 int32_t soundParamId, int32_t globalParamId);
142 void displayParamControlError(int32_t soundParamId, int32_t globalParamId);
143
144 MIDIMatchType checkMidiFollowMatch(MIDICable& cable, uint8_t channel);
145 MIDIMatchType checkMidiFollowMatchForSpecificTrack(MIDICable& cable, uint8_t channel, int32_t specific_track_index);
146
147 static constexpr size_t kMaxMIDIFollowFeedbackTargets = 2;
148 using FeedbackChannelTypes = std::array<MIDIFollowChannelType, kMaxMIDIFollowFeedbackTargets>;
149 size_t getChannelTypesForFeedback(FeedbackChannelTypes& feedbackChannelTypes);
150 MIDIFollowChannelType getChannelTypeForTrackFeedback();
151 bool addChannelTypeForFeedback(FeedbackChannelTypes& feedbackChannelTypes, size_t& numChannelTypes,
152 MIDIFollowChannelType feedbackChannelType);
154 void sendCCForMidiFollowFeedback(FeedbackChannelTypes const& feedbackChannelTypes, size_t numChannelTypes,
155 int32_t ccNumber, int32_t knobPos);
157 void sendCCForMidiFollowFeedback(MIDIFollowChannelType feedbackChannelType, int32_t ccNumber, int32_t knobPos);
158
159 // Saving
160
161 // CC Mappings
163
164 // Settings
167 void writeSpecificChannelSettingsToFile(Serializer& writer, MIDIFollowChannelType type);
171
172 // Loading
173 bool successfullyReadDefaultsFromFile;
174
175 // CC Mappings
177
178 // Settings
181 void readSpecificChannelSettingsFromFile(Deserializer& reader, MIDIFollowChannelType type);
185
186 // string tags / values
187 char const* getNameFromChannelType(MIDIFollowChannelType type);
188 MIDIFollowChannelType getChannelTypeFromName(char const* name);
189
190 char const* getNameFromFeedbackChannelType(MIDIFollowFeedbackChannelType type);
191 MIDIFollowFeedbackChannelType getFeedbackChannelTypeFromName(char const* name);
192
193 char const* getNameFromFeedbackAutomationMode(MIDIFollowFeedbackAutomationMode mode);
194 MIDIFollowFeedbackAutomationMode getFeedbackAutomationModeFromName(char const* name);
195
196 char const* getNameFromBool(bool value);
197 bool getBoolFromName(char const* name);
198};
199
200extern MidiFollow midiFollow;
Definition audio_clip.h:35
Definition clip.h:46
Definition storage_manager.h:185
Definition drum.h:44
Definition instrument_clip.h:48
Definition kit.h:34
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_follow.h:40
void writeFeedbackSettingsToFile(Serializer &writer)
Write Feedback settings to XML.
Definition midi_follow.cpp:1786
Clip * getSelectedClip()
Definition midi_follow.cpp:419
size_t getChannelTypesForFeedback(FeedbackChannelTypes &feedbackChannelTypes)
Definition midi_follow.cpp:1220
bool addChannelTypeForFeedback(FeedbackChannelTypes &feedbackChannelTypes, size_t &numChannelTypes, MIDIFollowChannelType feedbackChannelType)
Definition midi_follow.cpp:1181
void writeDefaultsToFile()
Definition midi_follow.cpp:1631
int32_t getCCFromParam(deluge::modulation::params::Kind paramKind, int32_t paramID)
Definition midi_follow.cpp:670
void writeKitRootNoteSettingToFile(Serializer &writer)
Write Kit Root Note setting to XML.
Definition midi_follow.cpp:1779
const size_t getTrackCount() const
used to forward midi messages to specific tracks
Definition midi_follow.cpp:474
void noteMessageReceivedForSpecificTrack(MIDICable &cable, bool on, int32_t channel, int32_t note, int32_t velocity, bool *doingMidiThru, bool shouldRecordNotesNowNow, ModelStack *modelStack, Output *specific_track, int32_t specific_track_index)
Definition midi_follow.cpp:803
void writeSpecificChannelSettingsToFile(Serializer &writer, MIDIFollowChannelType type)
Write Specific Channel settings to XML.
Definition midi_follow.cpp:1759
MIDIMatchType checkMidiFollowMatch(MIDICable &cable, uint8_t channel)
Definition midi_follow.cpp:1597
Clip * getSelectedOrActiveClip()
Definition midi_follow.cpp:395
Clip * getActiveClip(ModelStack *modelStack)
Definition midi_follow.cpp:459
void writeChannelSettingsToFile(Serializer &writer)
Write Channel settings to XML.
Definition midi_follow.cpp:1736
void aftertouchReceivedForSpecificTrack(MIDICable &cable, int32_t channel, int32_t value, int32_t noteCode, bool *doingMidiThru, ModelStack *modelStack, Output *specific_track, int32_t specific_track_index)
Definition midi_follow.cpp:1568
void writeDefaultMappingsToFile(Serializer &writer)
convert paramID to a paramName to write to XML
Definition midi_follow.cpp:1661
void readDefaultSettingsFromFile(Deserializer &reader)
read default settings (channels, kit root note, feedback, display param) from XML
Definition midi_follow.cpp:1894
void removeClip(Clip *clip)
Definition midi_follow.cpp:725
void readDefaultsFromFile()
read defaults from XML
Definition midi_follow.cpp:1800
Output * pitchBendReceivedForSelectedOrActiveClip(MIDICable &cable, uint8_t channel, uint8_t data1, uint8_t data2, bool *doingMidiThru, ModelStack *modelStack)
Definition midi_follow.cpp:1430
ModelStackWithAutoParam * getModelStackWithParam(ModelStackWithTimelineCounter *modelStackWithTimelineCounter, Clip *clip, int32_t soundParamId, int32_t globalParamId, bool displayError=true)
Definition midi_follow.cpp:508
void midiCCReceivedForSpecificTrack(MIDICable &cable, uint8_t channel, uint8_t ccNumber, uint8_t ccValue, bool *doingMidiThru, ModelStack *modelStack, Output *specific_track, int32_t specific_track_index)
Definition midi_follow.cpp:976
void pitchBendReceived(MIDICable &cable, uint8_t channel, uint8_t data1, uint8_t data2, bool *doingMidiThru, ModelStack *modelStack)
Definition midi_follow.cpp:1399
void pitchBendReceivedForSpecificTrack(MIDICable &cable, uint8_t channel, uint8_t data1, uint8_t data2, bool *doingMidiThru, ModelStack *modelStack, Output *specific_track, int32_t specific_track_index)
Definition midi_follow.cpp:1469
Output * midiCCReceivedForSelectedOrActiveClip(MIDICable &cable, uint8_t channel, uint8_t ccNumber, uint8_t ccValue, bool *doingMidiThru, ModelStack *modelStack)
Definition midi_follow.cpp:905
Output * noteMessageReceivedForSelectedOrActiveClip(MIDICable &cable, bool on, int32_t channel, int32_t note, int32_t velocity, bool *doingMidiThru, bool shouldRecordNotesNowNow, ModelStack *modelStack)
Definition midi_follow.cpp:767
void handleReceivedCC(MIDICable &cable, ModelStackWithTimelineCounter &modelStack, Clip *clip, int32_t ccNumber, int32_t ccValue)
Definition midi_follow.cpp:1054
void midiCCReceived(MIDICable &cable, uint8_t channel, uint8_t ccNumber, uint8_t ccValue, bool *doingMidiThru, ModelStack *modelStack)
Definition midi_follow.cpp:875
char const * getNameFromChannelType(MIDIFollowChannelType type)
enum / string lookup functions
Definition midi_follow.cpp:2014
void noteMessageReceived(MIDICable &cable, bool on, int32_t channel, int32_t note, int32_t velocity, bool *doingMidiThru, bool shouldRecordNotesNowNow, ModelStack *modelStack)
Definition midi_follow.cpp:736
void readDefaultMappingsFromFile(Deserializer &reader)
Definition midi_follow.cpp:1852
void readChannelSettingsFromFile(Deserializer &reader)
Read Channel settings from XML.
Definition midi_follow.cpp:1918
void clearStoredClips()
Definition midi_follow.cpp:716
void readKitRootNoteSettingFromFile(Deserializer &reader)
Read Kit Root Note setting from XML.
Definition midi_follow.cpp:1953
void aftertouchReceived(MIDICable &cable, int32_t channel, int32_t value, int32_t noteCode, bool *doingMidiThru, ModelStack *modelStack)
Definition midi_follow.cpp:1498
bool isGlobalEffectableContext()
Definition midi_follow.cpp:691
MIDIMatchType checkMidiFollowMatchForSpecificTrack(MIDICable &cable, uint8_t channel, int32_t specific_track_index)
Definition midi_follow.cpp:1611
Output * getTrackFromIndex(uint32_t trackIndex, uint32_t maxTrack)
used to forward midi messages to specific tracks
Definition midi_follow.cpp:488
void readDisplayParamSettingFromFile(Deserializer &reader)
Read Display Param setting from XML.
Definition midi_follow.cpp:1999
void readSpecificChannelSettingsFromFile(Deserializer &reader, MIDIFollowChannelType type)
Read Specific Channel settings from XML.
Definition midi_follow.cpp:1932
void readFeedbackSettingsFromFile(Deserializer &reader)
Read Feedback settings from XML.
Definition midi_follow.cpp:1969
void writeDisplayParamSettingToFile(Serializer &writer)
Write Display Param setting to XML.
Definition midi_follow.cpp:1795
void sendCCWithoutModelStackForMidiFollowFeedback(bool isAutomation=false)
Definition midi_follow.cpp:1281
void writeDefaultSettingsToFile(Serializer &writer)
write default settings (channels, kit root note, feedback, display param) to XML
Definition midi_follow.cpp:1701
void sendCCForMidiFollowFeedback(int32_t ccNumber, int32_t knobPos)
Resolve the configured MIDI Follow feedback targets and send a learned CC value to each one.
Definition midi_follow.cpp:1363
Output * aftertouchReceivedForSelectedOrActiveClip(MIDICable &cable, int32_t channel, int32_t value, int32_t noteCode, bool *doingMidiThru, ModelStack *modelStack)
Definition midi_follow.cpp:1529
Definition model_stack.h:269
Definition model_stack.h:231
Definition model_stack.h:129
Definition model_stack.h:123
Definition output.h:81
Definition storage_manager.h:119
Definition param.cpp:28
Kind
Definition param.h:42