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