38class MIDIInstrument final :
public NonAudioInstrument {
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,
55 void readDeviceDefinitionFileNameFromPresetOrSong(
Deserializer& reader);
60 void writeDeviceDefinitionFileNameToPresetOrSong(
Serializer& writer);
64 void setNameForCC(int32_t cc, std::string_view name);
67 bool loadDeviceDefinitionFile =
false;
68 bool hideUnlabeledCC =
false;
70 void sendMIDIPGM()
override;
72 void sendNoteToInternal(
bool on, int32_t note, uint8_t velocity, uint8_t channel);
75 int32_t changeControlNumberForModKnob(int32_t offset, int32_t whichModEncoder, int32_t modKnobMode);
79 int32_t moveAutomationToDifferentCC(int32_t offset, int32_t whichModEncoder, int32_t modKnobMode,
82 int32_t channel, int32_t note, int32_t velocity,
bool shouldRecordNotes,
83 bool* doingMidiThru)
override;
89 bool allowCreation =
true)
override;
90 uint8_t* getModKnobMode()
override {
return &modKnobMode; }
96 int32_t getOutputMasterChannel();
98 inline bool sendsToMPE() {
99 return (getChannel() == MIDI_CHANNEL_MPE_LOWER_ZONE || getChannel() == MIDI_CHANNEL_MPE_UPPER_ZONE);
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 {
105 if (type == otherType) {
106 match = (getChannel() == otherChannel && (channelSuffix == otherSuffix));
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};
117 std::array<int8_t, kNumModButtons * kNumPhysicalModKnobs> modKnobCCAssignments;
120 MPEOutputMemberChannel mpeOutputMemberChannels[16];
122 char const* getXMLTag()
override {
return "midi"; }
123 char const* getSlotXMLTag()
override {
124 return sendsToMPE() ?
"zone" : sendsToInternal() ?
"internalDest" :
"channel";
126 char const* getSubSlotXMLTag()
override {
return "suffix"; }
132 ModelStackWithAutoParam* getModelStackWithParam(ModelStackWithTimelineCounter* modelStack, Clip* clip,
134 bool affectEntire,
bool useMenuStack)
override;
137 uint32_t paramID)
override {
139 if (paramID == X_PITCH_BEND) {
141 return old_value >> 18 != new_value >> 18;
144 return old_value >> 24 != new_value >> 24;
146 return old_value >> 25 != new_value >> 25;
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;
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);
164 deluge::fast_map<uint8_t, std::string> labels;