Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
note_row.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 "gui/colour/colour.h"
22#include "io/midi/learned_midi.h"
23#include "model/iterance/iterance.h"
24#include "model/note/note_vector.h"
25#include "modulation/params/param_manager.h"
26
27#define SQUARE_NEW_NOTE 1
28#define SQUARE_NOTE_HEAD 2
29#define SQUARE_NOTE_TAIL_UNMODIFIED 3
30#define SQUARE_NOTE_TAIL_MODIFIED 4
31#define SQUARE_BLURRED 5
32#define SQUARE_NO_NOTE 6
33#define SQUARE_NOTE_TAIL 7
34
35#define CORRESPONDING_NOTES_ADJUST_VELOCITY 0
36#define CORRESPONDING_NOTES_SET_PROBABILITY 1
37#define CORRESPONDING_NOTES_SET_VELOCITY 2
38#define CORRESPONDING_NOTES_SET_ITERANCE 3
39#define CORRESPONDING_NOTES_SET_FILL 4
40
41class InstrumentClip;
42class Song;
43class PlaybackHandler;
44class Note;
45class Drum;
47class Kit;
48class DrumName;
49class Action;
50class NoteRow;
51class CopiedNoteRow;
52class Sound;
53class TimelineView;
57
58struct SquareInfo {
59 Note* firstNote;
60 int32_t squareStartPos;
61 int32_t squareEndPos;
62 int32_t numNotes;
63 uint8_t squareType;
64 int32_t averageVelocity;
65 int32_t probability;
66 Iterance iterance;
67 int32_t fill;
68 bool isValid{false};
69};
70
72 NoteRow* noteRow;
73 int32_t noteRowId;
74 uint32_t sampleSyncLength;
75 int32_t ticksLate;
76 uint8_t probability;
77 uint8_t velocity;
78 Iterance iterance;
79 uint8_t fill;
80};
81
83 PendingNoteOn pendingNoteOns[kMaxNumNoteOnsPending];
84 uint8_t count;
85};
86
87constexpr int32_t kQuantizationPrecision = 10;
88
98class NoteRow {
99public:
100 NoteRow(int16_t newY = -32768);
101 ~NoteRow();
102 void renderRow(TimelineView* editorScreen, RGB, RGB, RGB, RGB* image, uint8_t[], bool, uint32_t,
103 bool allowNoteTails, int32_t imageWidth, int32_t xScroll, uint32_t xZoom, int32_t xStart = 0,
104 int32_t xEnd = kDisplayWidth, bool drawRepeats = false);
105 void deleteNoteByPos(ModelStackWithNoteRow* modelStack, int32_t pos, Action* action);
106 void stopCurrentlyPlayingNote(ModelStackWithNoteRow* modelStack, bool actuallySoundChange = true,
107 Note* note = nullptr);
108 bool generateRepeats(ModelStackWithNoteRow* modelStack, uint32_t oldLength, uint32_t newLength,
109 int32_t numRepeatsRounded, Action* action);
110 void toggleMute(ModelStackWithNoteRow* modelStack, bool clipIsActiveAndPlaybackIsOn);
111 void maybeStartLateNote(ModelStackWithNoteRow* modelStack, int32_t effectiveActualCurrentPos);
112 bool hasNoNotes();
113 void resumePlayback(ModelStackWithNoteRow* modelStack, bool clipMayMakeSound);
114 void writeToFile(Serializer& writer, int32_t drumIndex, InstrumentClip* clip);
115 Error readFromFile(Deserializer& reader, int32_t*, InstrumentClip*, Song* song, int32_t readAutomationUpToPos);
116 inline int32_t getNoteCode() { return y; }
117 void writeToFlash();
118 void readFromFlash(InstrumentClip* parentClip);
119 uint32_t getNumNotes();
120 void setDrum(Drum* newDrum, Kit* kit, ModelStackWithNoteRow* modelStack,
121 InstrumentClip* favourClipForCloningParamManager = nullptr, ParamManager* paramManager = nullptr,
122 bool backupOldParamManager = true);
123
124 int32_t getDistanceToNextNote(int32_t pos, ModelStackWithNoteRow const* modelStack, bool reversed = false);
125
126 int16_t y; // This has to be at the top
127 bool muted;
128
129 int32_t loopLengthIfIndependent; // 0 means obeying parent
130 int32_t lastProcessedPosIfIndependent;
131 int32_t repeatCountIfIndependent;
132
133 // Valid only if not obeying parent, or if obeyed parent is pingponging and we have independent length
134 bool currentlyPlayingReversedIfIndependent;
135
136 SequenceDirection sequenceDirectionMode;
137 uint32_t getLivePos(ModelStackWithNoteRow const* modelStack);
138 bool hasIndependentPlayPos();
139
140 ParamManagerForTimeline paramManager;
141 Drum* drum;
142 DrumName* firstOldDrumName;
143 NoteVector notes;
144 // values for whole row
145 uint8_t probabilityValue;
146 Iterance iteranceValue;
147 uint8_t fillValue;
148 // These are deprecated, and only used during loading for compatibility with old song files
149 LearnedMIDI muteMIDICommand;
150 LearnedMIDI midiInput;
151
152 int8_t colourOffset;
153
154 // External classes aren't really supposed to set this to OFF. Call something like cancelAutitioning() instead -
155 // which calls Clip::expectEvent(), which is needed
156 bool sequenced;
157
165
166 int32_t getDefaultProbability();
167 Iterance getDefaultIterance();
168 int32_t getDefaultFill(ModelStackWithNoteRow* modelStack);
169 int32_t attemptNoteAdd(int32_t pos, int32_t length, int32_t velocity, int32_t probability, Iterance iterance,
170 int32_t fill, ModelStackWithNoteRow* modelStack, Action* action);
171 int32_t attemptNoteAddReversed(ModelStackWithNoteRow* modelStack, int32_t pos, int32_t velocity,
172 bool allowingNoteTails);
173 Error addCorrespondingNotes(int32_t pos, int32_t length, uint8_t velocity, ModelStackWithNoteRow* modelStack,
174 bool allowNoteTails, Action* action);
175 int32_t processCurrentPos(ModelStackWithNoteRow* modelStack, int32_t ticksSinceLast,
176 PendingNoteOnList* pendingNoteOnList);
177 void initRowSquareInfo(SquareInfo rowSquareInfo[kDisplayWidth], bool anyNotes);
178 void initSquareInfo(SquareInfo& squareInfo, bool anyNotes, int32_t x);
179 void getRowSquareInfo(int32_t effectiveLength, SquareInfo rowSquareInfo[kDisplayWidth]);
180 void getSquareInfo(int32_t x, int32_t effectiveLength, SquareInfo& squareInfo);
181 void addNotesToSquareInfo(int32_t effectiveLength, SquareInfo& squareInfo, int32_t& noteIndex, Note** note);
182 void calculateSquareAverages(SquareInfo& squareInfo);
183 uint8_t getSquareType(int32_t squareStart, int32_t squareWidth, Note** firstNote, Note** lastNote,
184 ModelStackWithNoteRow* modelStack, bool allowNoteTails, int32_t desiredNoteLength,
185 Action* action, bool clipCurrentlyPlaying, bool extendPreviousNoteIfPossible);
186 Error clearArea(int32_t areaStart, int32_t areaWidth, ModelStackWithNoteRow* modelStack, Action* action,
187 uint32_t wrapEditLevel, bool actuallyExtendNoteAtStartOfArea = false);
188 void trimToLength(uint32_t newLength, ModelStackWithNoteRow* modelStack, Action* action);
189 void trimNoteDataToNewClipLength(uint32_t newLength, InstrumentClip* clip, Action* action, int32_t noteRowId);
190 void recordNoteOff(uint32_t pos, ModelStackWithNoteRow* modelStack, Action* action, int32_t velocity);
191 int8_t getColourOffset(InstrumentClip* clip);
192 void rememberDrumName();
193 void shiftHorizontally(int32_t amount, ModelStackWithNoteRow* modelStack, bool shiftAutomation,
194 bool shiftSequenceAndMPE);
195 void clear(Action* action, ModelStackWithNoteRow* modelStack, bool clearAutomation, bool clearSequenceAndMPE);
196 bool doesProbabilityExist(int32_t apartFromPos, int32_t probability, int32_t secondProbability = -1);
197 bool paste(ModelStackWithNoteRow* modelStack, CopiedNoteRow* copiedNoteRow, float scaleFactor, int32_t screenEndPos,
198 Action* action);
199 void giveMidiCommandsToDrum();
200 void grabMidiCommandsFromDrum();
201 void deleteParamManager(bool shouldUpdatePointer = true);
202 void deleteOldDrumNames(bool shouldUpdatePointer = true);
203 Error appendNoteRow(ModelStackWithNoteRow* thisModelStack, ModelStackWithNoteRow* otherModelStack, int32_t offset,
204 int32_t whichRepeatThisIs, int32_t otherClipLength);
205 Error beenCloned(ModelStackWithNoteRow* modelStack, bool shouldFlattenReversing);
206 void resumeOriginalNoteRowFromThisClone(ModelStackWithNoteRow* modelStackOriginal,
207 ModelStackWithNoteRow* modelStackClone);
208 void silentlyResumePlayback(ModelStackWithNoteRow* modelStack);
209 void trimParamManager(ModelStackWithNoteRow* modelStack);
210 void deleteNoteByIndex(int32_t index, Action* action, int32_t noteRowId, InstrumentClip* clip);
211 void complexSetNoteLength(Note* thisNote, uint32_t newLength, ModelStackWithNoteRow* modelStack, Action* action);
212 Error changeNotesAcrossAllScreens(int32_t editPos, ModelStackWithNoteRow* modelStack, Action* action,
213 int32_t changeType, int32_t changeValue);
217 Error nudgeNotesAcrossAllScreens(int32_t editPos, ModelStackWithNoteRow* modelStack, Action* action,
218 uint32_t wrapEditLevel, int32_t nudgeOffset);
225 Error quantize(ModelStackWithNoteRow* modelStack, int32_t increment, int32_t amount);
226 Error editNoteRepeatAcrossAllScreens(int32_t editPos, int32_t squareWidth, ModelStackWithNoteRow* modelStack,
227 Action* action, uint32_t wrapEditLevel, int32_t newNumNotes);
228 void setLength(ModelStackWithNoteRow* modelStack, int32_t newLength, Action* actionToRecordTo, int32_t oldPos,
229 bool hadIndependentPlayPosBefore);
230 void getMPEValues(ModelStackWithNoteRow* modelStack, int16_t* mpeValues);
231 void clearMPEUpUntilNextNote(ModelStackWithNoteRow* modelStack, int32_t pos, int32_t wrapEditLevel,
232 bool shouldJustDeleteNodes = false);
233 SequenceDirection getEffectiveSequenceDirectionMode(ModelStackWithNoteRow const* modelStack);
234 bool recordPolyphonicExpressionEvent(ModelStackWithNoteRow* modelStackWithNoteRow, int32_t newValueBig,
235 int32_t expressionDimension, bool forDrum);
236 void setSequenceDirectionMode(ModelStackWithNoteRow* modelStack, SequenceDirection newMode);
237 bool isAuditioning(ModelStackWithNoteRow* modelStack);
238
239 bool isDroning(int32_t effectiveLength);
240
241private:
242 void playNote(bool, ModelStackWithNoteRow* modelStack, Note*, int32_t ticksLate = 0, uint32_t samplesLate = 0,
243 bool noteMightBeConstant = false, PendingNoteOnList* pendingNoteOnList = nullptr);
244 void playNextNote(InstrumentClip*, bool, bool noteMightBeConstant = false,
245 PendingNoteOnList* pendingNoteOnList = nullptr);
246 void findNextNoteToPlay(uint32_t);
247 void attemptLateStartOfNextNoteToPlay(ModelStackWithNoteRow* modelStack, Note* note);
248 bool noteRowMayMakeSound(bool);
249 void drawTail(int32_t startTail, int32_t endTail, uint8_t squareColour[], bool overwriteExisting,
250 uint8_t image[][3], uint8_t occupancyMask[]);
251 bool ignoredNoteOn{false};
252 int32_t ignoreUntil{0};
253 int32_t ignoredTicks{0};
254};
Definition action.h:75
Definition copied_note_row.h:23
Definition storage_manager.h:185
Definition drum_name.h:22
Definition drum.h:44
Definition instrument_clip.h:48
Definition kit.h:34
Definition learned_midi.h:30
Definition model_stack.h:189
Definition model_stack.h:129
Definition note_row.h:98
Error nudgeNotesAcrossAllScreens(int32_t editPos, ModelStackWithNoteRow *modelStack, Action *action, uint32_t wrapEditLevel, int32_t nudgeOffset)
Definition note_row.cpp:1337
void getRowSquareInfo(int32_t effectiveLength, SquareInfo rowSquareInfo[kDisplayWidth])
get info about squares for display at current zoom level
Definition note_row.cpp:240
Error quantize(ModelStackWithNoteRow *modelStack, int32_t increment, int32_t amount)
Definition note_row.cpp:1636
bool isDroning(int32_t effectiveLength)
Definition note_row.cpp:4530
void addNotesToSquareInfo(int32_t effectiveLength, SquareInfo &squareInfo, int32_t &noteIndex, Note **note)
Definition note_row.cpp:316
void getSquareInfo(int32_t x, int32_t effectiveLength, SquareInfo &squareInfo)
get info about the notes in this square at current zoom level
Definition note_row.cpp:281
uint32_t ignoreNoteOnsBefore_
Definition note_row.h:164
void calculateSquareAverages(SquareInfo &squareInfo)
Definition note_row.cpp:375
Definition note_vector.h:26
Definition note.h:24
Definition param_manager.h:174
Definition param_manager.h:45
Definition playback_handler.h:54
This class represents the colour format most used by the Deluge globally.
Definition rgb.h:14
Definition storage_manager.h:119
Definition song.h:104
Definition sound.h:71
Definition timeline_view.h:27
Definition iterance.h:23
Definition note_row.h:82
Definition note_row.h:71
Definition note_row.h:58