37class MIDIInstrument final :
public NonAudioInstrument {
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,
54 void readDeviceDefinitionFileNameFromPresetOrSong(
Deserializer& reader);
58 void writeDeviceDefinitionFileNameToPresetOrSong(
Serializer& writer);
62 void setNameForCC(int32_t cc, std::string_view name);
65 bool loadDeviceDefinitionFile =
false;
67 void sendMIDIPGM()
override;
69 void sendNoteToInternal(
bool on, int32_t note, uint8_t velocity, uint8_t channel);
71 int32_t changeControlNumberForModKnob(int32_t offset, int32_t whichModEncoder, int32_t modKnobMode);
75 int32_t moveAutomationToDifferentCC(int32_t offset, int32_t whichModEncoder, int32_t modKnobMode,
78 int32_t channel, int32_t note, int32_t velocity,
bool shouldRecordNotes,
79 bool* doingMidiThru)
override;
85 bool allowCreation =
true)
override;
86 uint8_t* getModKnobMode()
override {
return &modKnobMode; }
92 int32_t getOutputMasterChannel();
94 inline bool sendsToMPE() {
95 return (getChannel() == MIDI_CHANNEL_MPE_LOWER_ZONE || getChannel() == MIDI_CHANNEL_MPE_UPPER_ZONE);
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 {
101 if (type == otherType) {
102 match = (getChannel() == otherChannel && (channelSuffix == otherSuffix));
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};
113 std::array<int8_t, kNumModButtons * kNumPhysicalModKnobs> modKnobCCAssignments;
116 MPEOutputMemberChannel mpeOutputMemberChannels[16];
118 char const* getXMLTag()
override {
return "midi"; }
119 char const* getSlotXMLTag()
override {
120 return sendsToMPE() ?
"zone" : sendsToInternal() ?
"internalDest" :
"channel";
122 char const* getSubSlotXMLTag()
override {
return "suffix"; }
124 ModelStackWithAutoParam* getModelStackWithParam(ModelStackWithTimelineCounter* modelStack, Clip* clip,
126 bool affectEntire,
bool useMenuStack)
override;
129 uint32_t paramID)
override {
131 if (paramID == X_PITCH_BEND) {
133 return old_value >> 18 != new_value >> 18;
136 return old_value >> 24 != new_value >> 24;
138 return old_value >> 25 != new_value >> 25;
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;
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);
156 deluge::fast_map<uint8_t, std::string> labels;