72class InstrumentClipView final :
public ClipView,
public InstrumentClipMinder {
75 bool opened()
override;
76 void focusRegained()
override;
77 void displayOrLanguageChanged()
override;
81 ActionResult buttonAction(deluge::hid::Button b,
bool on,
bool inCardRoutine)
override;
83 ActionResult timerCallback()
override;
84 ActionResult handleScaleButtonAction(
bool on,
bool inCardRoutine);
85 bool handleInstrumentChange(OutputType outputType);
89 ActionResult padAction(int32_t x, int32_t y, int32_t velocity)
override;
90 ActionResult potentiallyRandomizeDrumSamples();
91 ActionResult potentiallyRandomizeDrumSample(
Kit* kit,
Drum* drum,
char* chosenFilename);
92 ActionResult commandEnterNoteVelocityEditor(int32_t x, int32_t y);
93 ActionResult commandLearnMutePad(int32_t y, int32_t velocity);
94 ActionResult commandLearnAuditionPad(
InstrumentClip* clip,
Output* output, OutputType outputType, int32_t yDisplay,
96 ActionResult commandSaveKitRow(
InstrumentClip* clip,
Output* output, OutputType outputType, int32_t yDisplay);
97 ActionResult commandActivateSongMacro(int32_t y, int32_t velocity);
119 ActionResult commandTransposeKey(int32_t offset,
bool inCardRoutine);
120 void commandTransposeScreen(int32_t offset,
bool inOctave);
121 void commandShiftColour(int32_t offset);
122 ActionResult scrollVertical(int32_t scrollAmount,
bool inCardRoutine,
bool draggingNoteRow =
false,
124 ActionResult scrollVertical_limit(int32_t scrollAmount,
bool inCardRoutine,
bool draggingNoteRow,
126 bool preventOverScrolling, int32_t& noteRowToShiftI, int32_t& noteRowToSwapWithI);
127 void scrollVertical_potentiallySwitchOffAuditionedNotes(
bool draggingNoteRow,
131 void scrollVertical_dragSelectedNoteRow(
InstrumentClip* clip,
Output* output,
bool isKit, int32_t noteRowToShiftI,
132 int32_t noteRowToSwapWithI);
133 void scrollVertical_potentiallySwitchOnAuditionedNotes(
bool draggingNoteRow,
136 bool isKit,
bool inSoundEditor,
bool currentClipIsActive,
137 bool renderDisplay,
bool updateDrumSelection);
142 void editPadAction(
bool state, uint8_t yDisplay, uint8_t xDisplay, uint32_t xZoom);
143 void mutePadPress(uint8_t yDisplay);
144 bool ensureNoteRowExistsForYDisplay(uint8_t yDisplay);
145 void recalculateColours();
146 void recalculateColour(uint8_t yDisplay);
147 void reassessAllAuditionStatus();
148 void reassessAuditionStatus(uint8_t yDisplay);
149 uint8_t getVelocityForAudition(uint8_t yDisplay, uint32_t* sampleSyncLength);
150 uint8_t getNumNoteRowsAuditioning();
151 uint8_t oneNoteAuditioning();
152 void offsetNoteCodeAction(int32_t newOffset);
153 int32_t getYVisualFromYDisplay(int32_t yDisplay);
154 int32_t getYVisualWithinOctaveFromYDisplay(int32_t yDisplay);
155 ActionResult auditionPadAction(int32_t velocity, int32_t yDisplay,
bool shiftButtonDown);
156 void potentiallyUpdateMultiRangeMenu(int32_t velocity, int32_t yDisplay,
Instrument* instrument);
157 void potentiallyRecordAuditionPadAction(
bool clipIsActiveOnInstrument, int32_t velocity, int32_t yDisplay,
161 void recordNoteOnEarly(int32_t velocity, int32_t yDisplay,
Instrument* instrument,
bool isKit,
163 void recordNoteOn(int32_t velocity, int32_t yDisplay,
Instrument* instrument,
166 NoteRow* getNoteRowOnActiveClip(int32_t yDisplay,
Instrument* instrument,
bool clipIsActiveOnInstrument,
168 void potentiallyRefreshNoteRowMenu();
169 bool startAuditioningRow(int32_t velocity, int32_t yDisplay,
bool shiftButtonDown,
bool isKit,
170 NoteRow* noteRowOnActiveClip,
Drum* drum,
bool displayNoteCode =
true);
172 void enterScaleMode(uint8_t yDisplay = 255);
173 void exitScaleMode();
174 void drawMuteSquare(
NoteRow* thisNoteRow,
RGB thisImage[], uint8_t thisOccupancyMask[]);
175 void cutAuditionedNotesToOne();
176 ActionResult horizontalEncoderAction(int32_t offset)
override;
177 void fillOffScreenImageStores();
178 void graphicsRoutine()
override;
180 void drawAuditionSquare(uint8_t yDisplay,
RGB thisImage[]);
181 void flashDefaultRootNote();
182 void selectEncoderAction(int8_t offset)
override;
183 void doubleClipLengthAction();
184 void setSelectedDrum(
Drum* drum,
bool shouldRedrawStuff =
true,
Kit* selectedKit =
nullptr,
185 bool shouldSendMidiFeedback =
true);
186 bool isDrumAuditioned(
Drum* drum);
187 int32_t setupForEnteringScaleMode(int32_t newRootNote = 2147483647, int32_t yDisplay = (kDisplayHeight / 2));
188 int32_t setupForExitingScaleMode();
189 void setupChangingOfRootNote(int32_t newRootNote, int32_t yDisplay = (kDisplayHeight / 2));
191 void cancelAllAuditioning();
192 void modEncoderButtonAction(uint8_t whichModEncoder,
bool on)
override;
194 void drawDrumName(
Drum* drum,
bool justPopUp =
false);
195 void notifyPlaybackBegun()
override;
196 void openedInBackground();
197 bool renderMainPads(uint32_t whichRows,
RGB image[][kDisplayWidth + kSideBarWidth],
198 uint8_t occupancyMask[][kDisplayWidth + kSideBarWidth],
bool drawUndefinedArea =
true)
override;
199 void performActualRender(uint32_t whichRows,
RGB* image, uint8_t occupancyMask[][kDisplayWidth + kSideBarWidth],
200 int32_t xScroll, uint32_t xZoom, int32_t renderWidth, int32_t imageWidth,
201 bool drawUndefinedArea =
true);
202 bool renderSidebar(uint32_t whichRows,
RGB image[][kDisplayWidth + kSideBarWidth],
203 uint8_t occupancyMask[][kDisplayWidth + kSideBarWidth])
override;
205 void playbackEnded()
override;
206 void scrollFinished()
override;
207 void clipNeedsReRendering(
Clip* clip)
override;
208 void modEncoderAction(int32_t whichModEncoder, int32_t offset)
override;
210 void reportMPEInitialValuesForNoteEditing(
ModelStackWithNoteRow* modelStack, int16_t
const* mpeValues);
211 void reportMPEValueForNoteEditing(int32_t expressionDimension, int32_t value);
213 void dontDeleteNotesOnDepress();
216 void tempoEncoderAction(int8_t offset,
bool encoderButtonPressed,
bool shiftButtonPressed);
217 ActionResult commandStopQuantize(int32_t y);
219 void sendAuditionNote(
bool on, uint8_t yDisplay, uint8_t velocity, uint32_t sampleSyncLength);
223 uint32_t getSquareWidth(int32_t square, int32_t effectiveLength);
224 void drawNoteCode(uint8_t yDisplay);
225 bool createNewInstrument(OutputType instrumentType,
bool is_fm =
false);
226 bool changeOutputType(OutputType newOutputType);
228 void someAuditioningHasEnded(
bool recalculateLastAuditionedNoteOnScreen);
229 bool getAffectEntire()
override;
230 void checkIfAllEditPadPressesEnded(
bool mayRenderSidebar =
true);
231 void endEditPadPress(uint8_t i);
232 void endAllEditPadPresses();
233 void copyAutomation(int32_t whichModEncoder, int32_t navSysId = NAVIGATION_CLIP);
234 void pasteAutomation(int32_t whichModEncoder, int32_t navSysId = NAVIGATION_CLIP);
238 InstrumentClipMinder::renderOLED(canvas);
241 CopiedParamAutomation copiedParamAutomation{};
243 bool auditioningSilently{};
245 bool fileBrowserShouldNotPreview{};
247 int16_t mpeValuesAtHighestPressure[MPE_RECORD_LENGTH_FOR_NOTE_EDITING][kNumExpressionDimensions]{};
248 int16_t mpeMostRecentPressure{};
249 uint32_t mpeRecordLastUpdateTime{};
252 EditPadPress editPadPresses[kEditPadPressBufferSize];
253 uint8_t lastAuditionedVelocityOnScreen[kDisplayHeight]{};
254 uint8_t auditionPadIsPressed[kDisplayHeight]{};
255 uint8_t numEditPadPressesPerNoteRowOnScreen[kDisplayHeight]{};
256 uint8_t lastAuditionedYDisplay{};
257 uint8_t numEditPadPresses;
258 uint32_t timeLastEditPadPress;
259 uint32_t timeFirstEditPadPress{};
262 uint32_t timeHorizontalKnobLastReleased{};
263 bool shouldIgnoreVerticalScrollKnobActionIfNotAlsoPressedForThisNotePress{};
264 bool shouldIgnoreHorizontalScrollKnobActionIfNotAlsoPressedForThisNotePress{};
267 bool editedAnyPerNoteRowStuffSinceAuditioningBegan{};
271 UIType
getUIType()
override {
return UIType::INSTRUMENT_CLIP; }
275 bool enterNoteEditor();
277 void exitNoteEditor();
278 void handleNoteEditorEditPadAction(int32_t x, int32_t y, int32_t on);
279 void deselectNoteAndGoUpOneLevel();
280 ActionResult handleNoteEditorVerticalEncoderAction(int32_t offset,
bool inCardRoutine);
281 ActionResult handleNoteEditorHorizontalEncoderAction(int32_t offset);
282 ActionResult handleNoteEditorButtonAction(deluge::hid::Button b,
bool on,
bool inCardRoutine);
284 SquareInfo gridSquareInfo[kDisplayHeight][kDisplayWidth]{};
287 void adjustVelocity(int32_t velocityChange,
bool display_value =
true);
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 pulseSelectedNote();
309 bool enterNoteRowEditor();
310 void exitNoteRowEditor();
311 bool handleNoteRowEditorPadAction(int32_t x, int32_t y, int32_t on);
312 bool handleNoteRowEditorMainPadAction(int32_t x, int32_t y, int32_t on);
313 void handleNoteRowEditorAuditionPadAction(int32_t y);
314 void copyNotesToFile(Serializer& writer,
bool selectedDrumOnly =
false);
315 Error pasteNotesFromFile(Deserializer& reader,
bool overwriteExisting,
bool noScaling,
bool previewOnly,
316 bool selectedDrumOnly);
317 void patternPreview();
319 ActionResult handleNoteRowEditorVerticalEncoderAction(int32_t offset,
bool inCardRoutine);
320 ActionResult handleNoteRowEditorHorizontalEncoderAction(int32_t offset);
321 ActionResult handleNoteRowEditorButtonAction(deluge::hid::Button b,
bool on,
bool inCardRoutine);
324 int32_t setNoteRowProbabilityWithOffset(int32_t offset);
325 int32_t setNoteRowIteranceWithOffset(int32_t offset,
bool allowTogglingBetweenPresetsAndCustom =
true);
326 int32_t setNoteRowIteranceWithFinalValue(Iterance finalValue);
327 int32_t setNoteRowFillWithOffset(int32_t offset);
328 int32_t setNoteRowParameterValue(int32_t withOffset, int32_t withFinalValue, int32_t changeType,
329 int32_t parameterMinValue, int32_t parameterMaxValue,
330 bool allowTogglingBetweenPresetsAndCustom =
true);
332 ModelStackWithNoteRow* createNoteRowForYDisplay(ModelStackWithTimelineCounter* modelStack, int32_t yDisplay);
333 ModelStackWithNoteRow* getOrCreateNoteRowForYDisplay(ModelStackWithTimelineCounter* modelStack, int32_t yDisplay);
334 void commandEuclidean(int32_t offset);
335 void editNumEuclideanEvents(ModelStackWithNoteRow* modelStack, int32_t offset, int32_t yDisplay);
336 void editNoteRowLength(int32_t offset);
337 void rotateNoteRowHorizontally(int32_t offset);
338 void editNoteRowLength(ModelStackWithNoteRow* modelStack, int32_t offset, int32_t yDisplay);
339 void noteRowChanged(InstrumentClip* clip, NoteRow* noteRow)
override;
342 void blinkSelectedNoteRow(int32_t whichMainRows = 0);
343 void resetSelectedNoteRowBlinking();
345 bool noteRowBlinking;
347 const char* getFillString(uint8_t fill);
350 void enterDrumCreator(ModelStackWithNoteRow* modelStack,
bool doRecording =
false);
352 ModControllableAudio* getModControllableAudioOrNone()
override;
355 bool doneAnyNudgingSinceFirstEditPadPress{};
356 bool offsettingNudgeNumberDisplay{};
358 uint8_t flashScaleModeLedErrorCount{};
360 Drum* selectedDrum{};
362 Drum* drumForNewNoteRow{};
363 uint8_t yDisplayOfNewNoteRow{};
365 int32_t quantizeAmount{};
366 uint32_t timeSongButtonPressed{};
369 bool sessionMacroSidebarActive{};
371 std::array<RGB, kDisplayHeight> rowColour;
372 std::array<RGB, kDisplayHeight> rowTailColour;
373 std::array<RGB, kDisplayHeight> rowBlurColour;
376 void nudgeNotes(int32_t offset);
377 void displayProbability(uint8_t probability,
bool prevBase);
378 void displayIterance(Iterance iterance);
379 void displayFill(uint8_t mode);
384 ModelStackWithNoteRow* get_note_edit_row(ModelStackWithTimelineCounter* model_stack,
const EditPadPress& target);
385 EditPadPress remembered_notes[kEditPadPressBufferSize]{};
386 int32_t remembered_note_row_ids[kEditPadPressBufferSize]{};
387 int32_t remembered_note_count = 0;
390 void render_selected_note_pulse(uint32_t which_rows, RGB image[][kDisplayWidth + kSideBarWidth]);
391 void render_selected_square_pulse(int32_t selection_index, uint32_t which_rows,
392 RGB image[][kDisplayWidth + kSideBarWidth], uint32_t* pulsed_columns);
393 void stopSelectedNotePulsing();
394 int32_t note_pulse_progress = 1;
395 bool note_pulse_increasing =
true;
396 RGB note_pulse_base_colours[kDisplayHeight][kDisplayWidth]{};
397 bool updating_note_pulse_directly =
false;
400 void copyNotes(Serializer* writer,
bool selectedDrumOnly =
false);
401 void pasteNotes(
bool overwriteExisting =
true,
bool pasteFromFile =
false,
bool noScaling =
false,
402 bool previewOnly =
false,
bool selectedDrumOnly =
false);
403 void deleteCopiedNoteRows();
404 CopiedNoteRow* firstCopiedNoteRow;
405 int32_t copiedScreenWidth{};
406 ScaleType copiedScaleType{};
407 int16_t copiedYNoteOfBottomRow{};
409 void rotateNoteRowHorizontally(ModelStackWithNoteRow* modelStack, int32_t offset, int32_t yDisplay,
410 bool shouldDisplayDirectionEvenIfNoNoteRow =
false);
412 Drum* getNextDrum(Drum* oldDrum,
bool mayBeNone =
false);
413 Drum* flipThroughAvailableDrums(int32_t newOffset, Drum* drum,
bool mayBeNone =
false);
414 NoteRow* getOrCreateEmptyNoteRowForKit(ModelStackWithTimelineCounter* modelStack, int32_t yDisplay,
415 int32_t* getIndex =
nullptr);
416 void createDrumForAuditionedNoteRow(DrumType drumType);
417 bool isRowAuditionedByInstrument(int32_t yDisplay);
420 void commandQuantizeNotes(int8_t offset, NudgeMode nudgeMode);
421 void commandStartQuantize(int8_t offset, NudgeMode nudgeMode);
422 void silenceAllAuditions();
425 Drum* getAuditionedDrum(int32_t velocity, int32_t yDisplay,
bool shiftButtonDown, Instrument* instrument,
426 ModelStackWithTimelineCounter* modelStackWithTimelineCounter,
427 ModelStackWithNoteRow* modelStackWithNoteRowOnCurrentClip);
428 void recordNoteOff(int32_t yDisplay, ModelStackWithNoteRow* modelStackWithNoteRowOnCurrentClip);
429 int32_t getVelocityToSound(int32_t velocity);