Deluge Firmware 1.3.0
Build date: 2026.08.23
Loading...
Searching...
No Matches
midi_instrument.h
1/*
2 * Copyright © 2014-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/instrument/non_audio_instrument.h"
22#include "util/containers.h"
23#include "util/d_stringbuf.h"
24#include <array>
25#include <string_view>
26
27class ModelStack;
30
32 int16_t lastNoteCode{32767};
33 uint16_t noteOffOrder{0};
34 int16_t lastXValueSent{0}; // The actual 14-bit number. But signed (goes positive and negative).
35 int8_t lastYAndZValuesSent[2]{0}; // The actual 7-bit numbers. Y goes both positive and negative.
36};
37
38class MIDIInstrument final : public NonAudioInstrument {
39public:
40 MIDIInstrument();
41
42 void ccReceivedFromInputMIDIChannel(int32_t cc, int32_t value, ModelStackWithTimelineCounter* modelStack) override;
43
44 void allNotesOff();
45
46 bool setActiveClip(ModelStackWithTimelineCounter* modelStack, PgmChangeSend maySendMIDIPGMs) override;
47 bool writeDataToFile(Serializer& writer, Clip* clipForSavingOutputOnly, Song* song) override;
48 bool readTagFromFile(Deserializer& reader, char const* tagName) override;
49 Error readModKnobAssignmentsFromFile(int32_t readAutomationUpToPos,
50 ParamManagerForTimeline* paramManager = nullptr);
51
52 // midi device definition file
54 Error readDeviceDefinitionFile(Deserializer& reader, bool readFromPresetOrSong);
55 void readDeviceDefinitionFileNameFromPresetOrSong(Deserializer& reader);
56 Error readCCLabelsFromFile(Deserializer& reader);
57 Error readHideUnlabeledCCFromFile(Deserializer& reader);
59 void writeDeviceDefinitionFile(Serializer& writer, bool writeFileNameToPresetOrSong);
60 void writeDeviceDefinitionFileNameToPresetOrSong(Serializer& writer);
61 void writeCCLabelsToFile(Serializer& writer);
63 std::string_view getNameFromCC(int32_t cc);
64 void setNameForCC(int32_t cc, std::string_view name);
67 bool loadDeviceDefinitionFile = false;
68 bool hideUnlabeledCC = false;
69
70 void sendMIDIPGM() override;
71
72 void sendNoteToInternal(bool on, int32_t note, uint8_t velocity, uint8_t channel);
73
74 int32_t getNextSelectableCC(int32_t cc, int32_t offset, bool includeNoCC = false);
75 int32_t changeControlNumberForModKnob(int32_t offset, int32_t whichModEncoder, int32_t modKnobMode);
76 int32_t getFirstUnusedCC(ModelStackWithThreeMainThings* modelStack, int32_t direction, int32_t startAt,
77 int32_t stopAt);
78 Error moveAutomationToDifferentCC(int32_t oldCC, int32_t newCC, ModelStackWithThreeMainThings* modelStack);
79 int32_t moveAutomationToDifferentCC(int32_t offset, int32_t whichModEncoder, int32_t modKnobMode,
81 void offerReceivedNote(ModelStackWithTimelineCounter* modelStackWithTimelineCounter, MIDICable& cable, bool on,
82 int32_t channel, int32_t note, int32_t velocity, bool shouldRecordNotes,
83 bool* doingMidiThru) override;
84
85 // ModControllable implementation
86 bool modEncoderButtonAction(uint8_t whichModEncoder, bool on, ModelStackWithThreeMainThings* modelStack) override;
87 void modButtonAction(uint8_t whichModButton, bool on, ParamManagerForTimeline* paramManager) override;
88 ModelStackWithAutoParam* getParamFromModEncoder(int32_t whichModEncoder, ModelStackWithThreeMainThings* modelStack,
89 bool allowCreation = true) override;
90 uint8_t* getModKnobMode() override { return &modKnobMode; }
91
92 int32_t getKnobPosForNonExistentParam(int32_t whichModEncoder, ModelStackWithAutoParam* modelStack) override;
93 ModelStackWithAutoParam* getParamToControlFromInputMIDIChannel(int32_t cc,
94 ModelStackWithThreeMainThings* modelStack) override;
95 bool doesAutomationExistOnMIDIParam(ModelStackWithThreeMainThings* modelStack, int32_t cc);
96 int32_t getOutputMasterChannel();
97
98 inline bool sendsToMPE() {
99 return (getChannel() == MIDI_CHANNEL_MPE_LOWER_ZONE || getChannel() == MIDI_CHANNEL_MPE_UPPER_ZONE);
100 }
101 inline bool sendsToInternal() { return (getChannel() >= IS_A_DEST); }
102 bool matchesPreset(OutputType otherType, int32_t otherChannel, int32_t otherSuffix, char const* otherName,
103 char const* otherPath) override {
104 bool match{false};
105 if (type == otherType) {
106 match = (getChannel() == otherChannel && (channelSuffix == otherSuffix));
107 }
108 return match;
109 }
110 int32_t channelSuffix{-1};
111 int32_t lastNoteCode{32767};
112 bool collapseAftertouch{false};
113 bool collapseMPE{true};
114 CCNumber outputMPEY{CC_EXTERNAL_MPE_Y};
115 float ratio; // for combining per finger and global bend
116
117 std::array<int8_t, kNumModButtons * kNumPhysicalModKnobs> modKnobCCAssignments;
118
119 // Numbers 0 to 15 can all be an MPE member depending on configuration
120 MPEOutputMemberChannel mpeOutputMemberChannels[16];
121
122 char const* getXMLTag() override { return "midi"; }
123 char const* getSlotXMLTag() override {
124 return sendsToMPE() ? "zone" : sendsToInternal() ? "internalDest" : "channel";
125 }
126 char const* getSubSlotXMLTag() override { return "suffix"; }
127
130 bool appendCCName(StringBuf& buf, int32_t cc);
131
132 ModelStackWithAutoParam* getModelStackWithParam(ModelStackWithTimelineCounter* modelStack, Clip* clip,
133 int32_t paramID, deluge::modulation::params::Kind paramKind,
134 bool affectEntire, bool useMenuStack) override;
135
136 bool valueChangedEnoughToMatter(int32_t old_value, int32_t new_value, deluge::modulation::params::Kind kind,
137 uint32_t paramID) override {
139 if (paramID == X_PITCH_BEND) {
140 // pitch is in 14 bit instead of 7
141 return old_value >> 18 != new_value >> 18;
142 }
143 // aftertouch and mod wheel are positive only and recorded into a smaller range than CCs
144 return old_value >> 24 != new_value >> 24;
145 }
146 return old_value >> 25 != new_value >> 25;
147 }
148
149protected:
150 void polyphonicExpressionEventPostArpeggiator(int32_t newValue, int32_t noteCodeAfterArpeggiation,
151 int32_t expressionDimension, ArpNote* arpNote,
152 int32_t noteIndex) override;
153 void noteOnPostArp(int32_t noteCodePostArp, ArpNote* arpNote, int32_t noteIndex) override;
154 void noteOffPostArp(int32_t noteCodePostArp, int32_t oldMIDIChannel, int32_t velocity, int32_t noteIndex) override;
155 void monophonicExpressionEvent(int32_t newValue, int32_t expressionDimension) override;
156
157private:
158 void sendMonophonicExpressionEvent(int32_t expressionDimension);
159 void combineMPEtoMono(int32_t value32, int32_t expressionDimension);
160 void outputAllMPEValuesOnMemberChannel(int16_t const* mpeValuesToUse, int32_t outputMemberChannel);
161 Error readMIDIParamFromFile(Deserializer& reader, int32_t readAutomationUpToPos,
162 MIDIParamCollection* midiParamCollection, int8_t* getCC = nullptr);
163
164 deluge::fast_map<uint8_t, std::string> labels;
165};
Definition clip.h:46
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:96
String deviceDefinitionFileName
definition file
Definition midi_instrument.h:66
Error readDeviceDefinitionFile(Deserializer &reader, bool readFromPresetOrSong)
reading
Definition midi_instrument.cpp:562
int32_t getNextSelectableCC(int32_t cc, int32_t offset, bool includeNoCC=false)
Definition midi_instrument.cpp:709
std::string_view getNameFromCC(int32_t cc)
getting / updating cc labels
Definition midi_instrument.cpp:1376
void writeDeviceDefinitionFile(Serializer &writer, bool writeFileNameToPresetOrSong)
writing
Definition midi_instrument.cpp:422
bool appendCCName(StringBuf &buf, int32_t cc)
Definition midi_instrument.cpp:103
Definition model_stack.h:269
Definition model_stack.h:287
Definition model_stack.h:231
Definition model_stack.h:129
Definition model_stack.h:123
Definition param_manager.h:174
Definition storage_manager.h:119
Definition song.h:103
Definition d_string.h:41
Kind
Definition param.h:42
@ EXPRESSION
Parameter connected to an MPE expression axis.
Definition param.h:58
Definition midi_instrument.h:31