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