71class InstrumentClipView final :
public ClipView,
public InstrumentClipMinder {
74 bool opened()
override;
75 void focusRegained()
override;
76 void displayOrLanguageChanged()
override;
80 ActionResult buttonAction(deluge::hid::Button b,
bool on,
bool inCardRoutine)
override;
82 ActionResult timerCallback()
override;
83 ActionResult handleScaleButtonAction(
bool on,
bool inCardRoutine);
84 bool handleInstrumentChange(OutputType outputType);
88 ActionResult padAction(int32_t x, int32_t y, int32_t velocity)
override;
89 ActionResult potentiallyRandomizeDrumSamples();
90 ActionResult potentiallyRandomizeDrumSample(
Kit* kit,
Drum* drum,
char* chosenFilename);
91 ActionResult commandEnterNoteVelocityEditor(int32_t x, int32_t y);
92 ActionResult commandLearnMutePad(int32_t y, int32_t velocity);
93 ActionResult commandLearnAuditionPad(
InstrumentClip* clip,
Output* output, OutputType outputType, int32_t yDisplay,
95 ActionResult commandSaveKitRow(
InstrumentClip* clip,
Output* output, OutputType outputType, int32_t yDisplay);
96 ActionResult commandActivateSongMacro(int32_t y, int32_t velocity);
118 ActionResult commandTransposeKey(int32_t offset,
bool inCardRoutine);
119 void commandTransposeScreen(int32_t offset,
bool inOctave);
120 void commandShiftColour(int32_t offset);
121 ActionResult scrollVertical(int32_t scrollAmount,
bool inCardRoutine,
bool draggingNoteRow =
false,
123 ActionResult scrollVertical_limit(int32_t scrollAmount,
bool inCardRoutine,
bool draggingNoteRow,
125 bool preventOverScrolling, int32_t& noteRowToShiftI, int32_t& noteRowToSwapWithI);
126 void scrollVertical_potentiallySwitchOffAuditionedNotes(
bool draggingNoteRow,
130 void scrollVertical_dragSelectedNoteRow(
InstrumentClip* clip,
Output* output,
bool isKit, int32_t noteRowToShiftI,
131 int32_t noteRowToSwapWithI);
132 void scrollVertical_potentiallySwitchOnAuditionedNotes(
bool draggingNoteRow,
135 bool isKit,
bool inSoundEditor,
bool currentClipIsActive,
136 bool renderDisplay,
bool updateDrumSelection);
141 void editPadAction(
bool state, uint8_t yDisplay, uint8_t xDisplay, uint32_t xZoom);
142 void mutePadPress(uint8_t yDisplay);
143 bool ensureNoteRowExistsForYDisplay(uint8_t yDisplay);
144 void recalculateColours();
145 void recalculateColour(uint8_t yDisplay);
146 void reassessAllAuditionStatus();
147 void reassessAuditionStatus(uint8_t yDisplay);
148 uint8_t getVelocityForAudition(uint8_t yDisplay, uint32_t* sampleSyncLength);
149 uint8_t getNumNoteRowsAuditioning();
150 uint8_t oneNoteAuditioning();
151 void offsetNoteCodeAction(int32_t newOffset);
152 int32_t getYVisualFromYDisplay(int32_t yDisplay);
153 int32_t getYVisualWithinOctaveFromYDisplay(int32_t yDisplay);
154 ActionResult auditionPadAction(int32_t velocity, int32_t yDisplay,
bool shiftButtonDown);
155 void potentiallyUpdateMultiRangeMenu(int32_t velocity, int32_t yDisplay,
Instrument* instrument);
156 void potentiallyRecordAuditionPadAction(
bool clipIsActiveOnInstrument, int32_t velocity, int32_t yDisplay,
160 void recordNoteOnEarly(int32_t velocity, int32_t yDisplay,
Instrument* instrument,
bool isKit,
162 void recordNoteOn(int32_t velocity, int32_t yDisplay,
Instrument* instrument,
165 NoteRow* getNoteRowOnActiveClip(int32_t yDisplay,
Instrument* instrument,
bool clipIsActiveOnInstrument,
167 void potentiallyRefreshNoteRowMenu();
168 bool startAuditioningRow(int32_t velocity, int32_t yDisplay,
bool shiftButtonDown,
bool isKit,
169 NoteRow* noteRowOnActiveClip,
Drum* drum,
bool displayNoteCode =
true);
171 void enterScaleMode(uint8_t yDisplay = 255);
172 void exitScaleMode();
173 void drawMuteSquare(
NoteRow* thisNoteRow,
RGB thisImage[], uint8_t thisOccupancyMask[]);
174 void cutAuditionedNotesToOne();
175 ActionResult horizontalEncoderAction(int32_t offset)
override;
176 void fillOffScreenImageStores();
177 void graphicsRoutine()
override;
179 void drawAuditionSquare(uint8_t yDisplay,
RGB thisImage[]);
180 void flashDefaultRootNote();
181 void selectEncoderAction(int8_t offset)
override;
182 void doubleClipLengthAction();
183 void setSelectedDrum(
Drum* drum,
bool shouldRedrawStuff =
true,
Kit* selectedKit =
nullptr,
184 bool shouldSendMidiFeedback =
true);
185 bool isDrumAuditioned(
Drum* drum);
186 int32_t setupForEnteringScaleMode(int32_t newRootNote = 2147483647, int32_t yDisplay = (kDisplayHeight / 2));
187 int32_t setupForExitingScaleMode();
188 void setupChangingOfRootNote(int32_t newRootNote, int32_t yDisplay = (kDisplayHeight / 2));
190 void cancelAllAuditioning();
191 void modEncoderButtonAction(uint8_t whichModEncoder,
bool on)
override;
193 void drawDrumName(
Drum* drum,
bool justPopUp =
false);
194 void notifyPlaybackBegun()
override;
195 void openedInBackground();
196 bool renderMainPads(uint32_t whichRows,
RGB image[][kDisplayWidth + kSideBarWidth],
197 uint8_t occupancyMask[][kDisplayWidth + kSideBarWidth],
bool drawUndefinedArea =
true)
override;
198 void performActualRender(uint32_t whichRows,
RGB* image, uint8_t occupancyMask[][kDisplayWidth + kSideBarWidth],
199 int32_t xScroll, uint32_t xZoom, int32_t renderWidth, int32_t imageWidth,
200 bool drawUndefinedArea =
true);
201 bool renderSidebar(uint32_t whichRows,
RGB image[][kDisplayWidth + kSideBarWidth],
202 uint8_t occupancyMask[][kDisplayWidth + kSideBarWidth])
override;
204 void playbackEnded()
override;
205 void scrollFinished()
override;
206 void clipNeedsReRendering(
Clip* clip)
override;
207 void modEncoderAction(int32_t whichModEncoder, int32_t offset)
override;
209 void reportMPEInitialValuesForNoteEditing(
ModelStackWithNoteRow* modelStack, int16_t
const* mpeValues);
210 void reportMPEValueForNoteEditing(int32_t expressionDimension, int32_t value);
212 void dontDeleteNotesOnDepress();
215 void tempoEncoderAction(int8_t offset,
bool encoderButtonPressed,
bool shiftButtonPressed);
216 ActionResult commandStopQuantize(int32_t y);
218 void sendAuditionNote(
bool on, uint8_t yDisplay, uint8_t velocity, uint32_t sampleSyncLength);
222 uint32_t getSquareWidth(int32_t square, int32_t effectiveLength);
223 void drawNoteCode(uint8_t yDisplay);
224 bool createNewInstrument(OutputType instrumentType,
bool is_fm =
false);
225 bool changeOutputType(OutputType newOutputType);
227 void someAuditioningHasEnded(
bool recalculateLastAuditionedNoteOnScreen);
228 bool getAffectEntire()
override;
229 void checkIfAllEditPadPressesEnded(
bool mayRenderSidebar =
true);
230 void endEditPadPress(uint8_t i);
231 void endAllEditPadPresses();
232 void copyAutomation(int32_t whichModEncoder, int32_t navSysId = NAVIGATION_CLIP);
233 void pasteAutomation(int32_t whichModEncoder, int32_t navSysId = NAVIGATION_CLIP);
237 InstrumentClipMinder::renderOLED(canvas);
240 CopiedParamAutomation copiedParamAutomation{};
242 bool auditioningSilently{};
244 bool fileBrowserShouldNotPreview{};
246 int16_t mpeValuesAtHighestPressure[MPE_RECORD_LENGTH_FOR_NOTE_EDITING][kNumExpressionDimensions]{};
247 int16_t mpeMostRecentPressure{};
248 uint32_t mpeRecordLastUpdateTime{};
251 EditPadPress editPadPresses[kEditPadPressBufferSize];
252 uint8_t lastAuditionedVelocityOnScreen[kDisplayHeight]{};
253 uint8_t auditionPadIsPressed[kDisplayHeight]{};
254 uint8_t numEditPadPressesPerNoteRowOnScreen[kDisplayHeight]{};
255 uint8_t lastAuditionedYDisplay{};
256 uint8_t numEditPadPresses;
257 uint32_t timeLastEditPadPress;
258 uint32_t timeFirstEditPadPress{};
261 uint32_t timeHorizontalKnobLastReleased{};
262 bool shouldIgnoreVerticalScrollKnobActionIfNotAlsoPressedForThisNotePress{};
263 bool shouldIgnoreHorizontalScrollKnobActionIfNotAlsoPressedForThisNotePress{};
266 bool editedAnyPerNoteRowStuffSinceAuditioningBegan{};
270 UIType
getUIType()
override {
return UIType::INSTRUMENT_CLIP; }
274 bool enterNoteEditor();
275 void exitNoteEditor();
276 void handleNoteEditorEditPadAction(int32_t x, int32_t y, int32_t on);
277 void deselectNoteAndGoUpOneLevel();
278 ActionResult handleNoteEditorVerticalEncoderAction(int32_t offset,
bool inCardRoutine);
279 ActionResult handleNoteEditorHorizontalEncoderAction(int32_t offset);
280 ActionResult handleNoteEditorButtonAction(deluge::hid::Button b,
bool on,
bool inCardRoutine);
282 SquareInfo gridSquareInfo[kDisplayHeight][kDisplayWidth]{};
283 int32_t lastSelectedNoteXDisplay;
284 int32_t lastSelectedNoteYDisplay;
287 void adjustVelocity(int32_t velocityChange);
288 void updateVelocityValue(int32_t& velocityValue, int32_t newVelocity);
289 void displayVelocity(int32_t velocityValue, int32_t velocityChange);
290 void popupVelocity(
char const* displayString);
292 void handleProbabilityOrIteranceEditing(int8_t offset,
bool editNoteRow);
293 void adjustNoteProbabilityWithOffset(int32_t offset);
294 void adjustNoteIteranceWithOffset(int32_t offset,
bool allowTogglingBetweenPresetsAndCustom =
true);
295 void adjustNoteIteranceWithFinalValue(Iterance finalValue);
296 void adjustNoteFillWithOffset(int32_t offset);
297 Note* getLeftMostNotePressed();
298 void adjustNoteParameterValue(int32_t withOffset, int32_t withFinalValue, int32_t changeType,
299 int32_t parameterMinValue, int32_t parameterMaxValue,
300 bool allowTogglingBetweenPresetsAndCustom =
true);
303 void editNoteRepeat(int32_t offset);
306 void blinkSelectedNote(int32_t whichMainRows = 0);
307 void resetSelectedNoteBlinking();
310 bool enterNoteRowEditor();
311 void exitNoteRowEditor();
312 bool handleNoteRowEditorPadAction(int32_t x, int32_t y, int32_t on);
313 bool handleNoteRowEditorMainPadAction(int32_t x, int32_t y, int32_t on);
314 void handleNoteRowEditorAuditionPadAction(int32_t y);
315 void copyNotesToFile(Serializer& writer,
bool selectedDrumOnly =
false);
316 Error pasteNotesFromFile(Deserializer& reader,
bool overwriteExisting,
bool noScaling,
bool previewOnly,
317 bool selectedDrumOnly);
318 void patternPreview();
320 ActionResult handleNoteRowEditorVerticalEncoderAction(int32_t offset,
bool inCardRoutine);
321 ActionResult handleNoteRowEditorHorizontalEncoderAction(int32_t offset);
322 ActionResult handleNoteRowEditorButtonAction(deluge::hid::Button b,
bool on,
bool inCardRoutine);
325 int32_t setNoteRowProbabilityWithOffset(int32_t offset);
326 int32_t setNoteRowIteranceWithOffset(int32_t offset,
bool allowTogglingBetweenPresetsAndCustom =
true);
327 int32_t setNoteRowIteranceWithFinalValue(Iterance finalValue);
328 int32_t setNoteRowFillWithOffset(int32_t offset);
329 int32_t setNoteRowParameterValue(int32_t withOffset, int32_t withFinalValue, int32_t changeType,
330 int32_t parameterMinValue, int32_t parameterMaxValue,
331 bool allowTogglingBetweenPresetsAndCustom =
true);
333 ModelStackWithNoteRow* createNoteRowForYDisplay(ModelStackWithTimelineCounter* modelStack, int32_t yDisplay);
334 ModelStackWithNoteRow* getOrCreateNoteRowForYDisplay(ModelStackWithTimelineCounter* modelStack, int32_t yDisplay);
335 void commandEuclidean(int32_t offset);
336 void editNumEuclideanEvents(ModelStackWithNoteRow* modelStack, int32_t offset, int32_t yDisplay);
337 void editNoteRowLength(int32_t offset);
338 void rotateNoteRowHorizontally(int32_t offset);
339 void editNoteRowLength(ModelStackWithNoteRow* modelStack, int32_t offset, int32_t yDisplay);
340 void noteRowChanged(InstrumentClip* clip, NoteRow* noteRow)
override;
343 void blinkSelectedNoteRow(int32_t whichMainRows = 0);
344 void resetSelectedNoteRowBlinking();
346 bool noteRowBlinking;
348 const char* getFillString(uint8_t fill);
351 void enterDrumCreator(ModelStackWithNoteRow* modelStack,
bool doRecording =
false);
354 bool doneAnyNudgingSinceFirstEditPadPress{};
355 bool offsettingNudgeNumberDisplay{};
357 uint8_t flashScaleModeLedErrorCount{};
359 Drum* selectedDrum{};
361 Drum* drumForNewNoteRow{};
362 uint8_t yDisplayOfNewNoteRow{};
364 int32_t quantizeAmount{};
365 uint32_t timeSongButtonPressed{};
368 bool sessionMacroSidebarActive{};
370 std::array<RGB, kDisplayHeight> rowColour;
371 std::array<RGB, kDisplayHeight> rowTailColour;
372 std::array<RGB, kDisplayHeight> rowBlurColour;
375 void nudgeNotes(int32_t offset);
376 void displayProbability(uint8_t probability,
bool prevBase);
377 void displayIterance(Iterance iterance);
378 void displayFill(uint8_t mode);
381 void copyNotes(Serializer* writer,
bool selectedDrumOnly =
false);
382 void pasteNotes(
bool overwriteExisting =
true,
bool pasteFromFile =
false,
bool noScaling =
false,
383 bool previewOnly =
false,
bool selectedDrumOnly =
false);
384 void deleteCopiedNoteRows();
385 CopiedNoteRow* firstCopiedNoteRow;
386 int32_t copiedScreenWidth{};
387 ScaleType copiedScaleType{};
388 int16_t copiedYNoteOfBottomRow{};
390 void rotateNoteRowHorizontally(ModelStackWithNoteRow* modelStack, int32_t offset, int32_t yDisplay,
391 bool shouldDisplayDirectionEvenIfNoNoteRow =
false);
393 Drum* getNextDrum(Drum* oldDrum,
bool mayBeNone =
false);
394 Drum* flipThroughAvailableDrums(int32_t newOffset, Drum* drum,
bool mayBeNone =
false);
395 NoteRow* getOrCreateEmptyNoteRowForKit(ModelStackWithTimelineCounter* modelStack, int32_t yDisplay,
396 int32_t* getIndex =
nullptr);
397 void createDrumForAuditionedNoteRow(DrumType drumType);
398 bool isRowAuditionedByInstrument(int32_t yDisplay);
401 void commandQuantizeNotes(int8_t offset, NudgeMode nudgeMode);
402 void commandStartQuantize(int8_t offset, NudgeMode nudgeMode);
403 void silenceAllAuditions();
406 Drum* getAuditionedDrum(int32_t velocity, int32_t yDisplay,
bool shiftButtonDown, Instrument* instrument,
407 ModelStackWithTimelineCounter* modelStackWithTimelineCounter,
408 ModelStackWithNoteRow* modelStackWithNoteRowOnCurrentClip);
409 void recordNoteOff(int32_t yDisplay, ModelStackWithNoteRow* modelStackWithNoteRowOnCurrentClip);
410 int32_t getVelocityToSound(int32_t velocity);