Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
song.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/menu_item/reverb/model.h"
22#include "io/midi/learned_midi.h"
23#include "model/clip/clip.h"
24#include "model/clip/clip_array.h"
25#include "model/global_effectable/global_effectable_for_song.h"
26#include "model/instrument/instrument.h"
27#include "model/output.h"
28#include "model/scale/musical_key.h"
29#include "model/scale/note_set.h"
30#include "model/scale/preset_scales.h"
31#include "model/scale/scale_change.h"
32#include "model/scale/scale_mapper.h"
33#include "model/sync.h"
34#include "model/timeline_counter.h"
35#include "modulation/params/param.h"
36#include "modulation/params/param_manager.h"
37#include "storage/flash_storage.h"
38#include "util/container/array/ordered_resizeable_array_with_multi_word_key.h"
39#include "util/d_string.h"
40#include <limits>
41
42class MidiCommand;
43class Clip;
44class AudioClip;
45class Instrument;
46class InstrumentClip;
47class Synth;
49class Instrument;
51class Drum;
52class SoundInstrument;
53class SoundDrum;
54class Action;
55class ArrangementRow;
58class Kit;
59class MIDIInstrument;
60class NoteRow;
61class Output;
62class AudioOutput;
63class ModelStack;
65Clip* getCurrentClip();
66InstrumentClip* getCurrentInstrumentClip();
67AudioClip* getCurrentAudioClip();
68Output* getCurrentOutput();
69Kit* getCurrentKit();
70Instrument* getCurrentInstrument();
71OutputType getCurrentOutputType();
72
73class Section {
74public:
75 LearnedMIDI launchMIDICommand;
76 int16_t numRepetitions;
77
78 Section() { numRepetitions = 0; }
79};
80
82 ModControllableAudio* modControllable;
83 Clip* clip;
84 ParamManager paramManager;
85};
86
87#define MAX_NOTES_CHORD_MEM 10
88
89enum SessionMacroKind : int8_t {
90 NO_MACRO = 0,
91 CLIP_LAUNCH,
92 OUTPUT_CYCLE,
93 SECTION,
94 NUM_KINDS,
95};
96
98 SessionMacroKind kind{NO_MACRO};
99 Clip* clip{nullptr};
100 Output* output{nullptr};
101 uint8_t section{0};
102};
103
104class Song final : public TimelineCounter {
105public:
106 Song();
107 ~Song() override;
108 bool mayDoubleTempo();
109 bool ensureAtLeastOneSessionClip();
110 void transposeAllScaleModeClips(int32_t interval);
111 void transposeAllScaleModeClips(int32_t offset, bool chromatic);
112 bool anyScaleModeClips();
113 void changeMusicalMode(uint8_t yVisualWithinOctave, int8_t change);
114 void rotateMusicalMode(int8_t change);
115 void replaceMusicalMode(const ScaleChange& changes, bool affectMIDITranspose);
116 int32_t getYVisualFromYNote(int32_t yNote, bool inKeyMode);
117 int32_t getYVisualFromYNote(int32_t yNote, bool inKeyMode, const MusicalKey& key);
118 int32_t getYNoteFromYVisual(int32_t yVisual, bool inKeyMode);
119 int32_t getYNoteFromYVisual(int32_t yVisual, bool inKeyMode, const MusicalKey& key);
120 bool mayMoveModeNote(int16_t yVisualWithinOctave, int8_t newOffset);
121 ParamManagerForTimeline* findParamManagerForDrum(Kit* kit, Drum* drum, Clip* stopTraversalAtClip = nullptr);
122 void setupPatchingForAllParamManagersForDrum(SoundDrum* drum);
123 void setupPatchingForAllParamManagersForInstrument(SoundInstrument* sound);
124 void grabVelocityToLevelFromMIDICableAndSetupPatchingForAllParamManagersForInstrument(MIDICable& cable,
125 SoundInstrument* instrument);
126 void grabVelocityToLevelFromMIDICableAndSetupPatchingForAllParamManagersForDrum(MIDICable& cable, SoundDrum* drum,
127 Kit* kit);
128 void grabVelocityToLevelFromMIDICableAndSetupPatchingForEverything(MIDICable& cable);
129 void getCurrentRootNoteAndScaleName(StringBuf& buffer);
130 void displayCurrentRootNoteAndScaleName();
131
132 // Scale-related methods
133
135 Scale cycleThroughScales();
137 Scale getCurrentScale();
140 Scale setScale(Scale newScale);
143 bool setScaleNotes(NoteSet newScale);
147 bool hasUserScale();
150 void setRootNote(int32_t newRootNote, InstrumentClip* clipToAvoidAdjustingScrollFor = nullptr);
153
154 void setTempoFromNumSamples(double newTempoSamples, bool shouldLogAction);
155 void setupDefault();
156 void setBPM(float tempoBPM, bool shouldLogAction);
157 void setTempoFromParams(int32_t magnitude, int8_t whichValue, bool shouldLogAction);
158 void deleteSoundsWhichWontSound();
159 void writeTemplateSong(const char* templateSong);
160 void
161 deleteClipObject(Clip* clip, bool songBeingDestroyedToo = false,
162 InstrumentRemoval instrumentRemovalInstruction = InstrumentRemoval::DELETE_OR_HIBERNATE_IF_UNUSED);
163 int32_t getMaxMIDIChannelSuffix(int32_t channel);
164 void addOutput(Output* output, bool atStart = true);
165 void deleteOutputThatIsInMainList(Output* output, bool stopAnyAuditioningFirst = true);
166 void markAllInstrumentsAsEdited();
167 Instrument* getInstrumentFromPresetSlot(OutputType outputType, int32_t presetNumber, int32_t presetSubSlotNumber,
168 char const* name, char const* dirPath, bool searchHibernatingToo = true,
169 bool searchNonHibernating = true);
170 AudioOutput* getAudioOutputFromName(String* name);
171 void setupPatchingForAllParamManagers();
172 void replaceInstrument(Instrument* oldInstrument, Instrument* newInstrument, bool keepNoteRowsWithMIDIInput = true);
173 void stopAllMIDIAndGateNotesPlaying();
174 void stopAllAuditioning();
175 void deleteOrHibernateOutput(Output* output);
176 Instrument* getNonAudioInstrumentToSwitchTo(OutputType newOutputType, Availability availabilityRequirement,
177 int16_t newSlot, int8_t newSubSlot, bool* instrumentWasAlreadyInSong);
178 void removeSessionClipLowLevel(Clip* clip, int32_t clipIndex);
179 void changeSwingInterval(int32_t newValue);
180 int32_t convertSyncLevelFromFileValueToInternalValue(int32_t fileValue);
181 int32_t convertSyncLevelFromInternalValueToFileValue(int32_t internalValue);
182 String getSongFullPath();
183 void setSongFullPath(const char* fullPath);
184 int32_t getInputTickMagnitude() const { return insideWorldTickMagnitude + insideWorldTickMagnitudeOffsetFromBPM; }
185
186 GlobalEffectableForSong globalEffectable;
187
188 ClipArray sessionClips;
189 ClipArray arrangementOnlyClips;
190
191 Output* firstOutput = nullptr;
192 Instrument* firstHibernatingInstrument =
193 nullptr; // All Instruments have inValidState set to false when they're added to this list
194
195 OrderedResizeableArrayWithMultiWordKey backedUpParamManagers;
196
197 uint32_t xZoom[2]; // Set default zoom at max zoom-out;
198 int32_t xScroll[2] = {0}; // Leave this as signed
199 int32_t xScrollForReturnToSongView = 0;
200 int32_t xZoomForReturnToSongView;
201
202 bool tripletsOn = false;
203 uint32_t tripletsLevel; // The number of ticks in one of the three triplets
204
205 uint64_t timePerTimerTickBig;
206 int32_t divideByTimePerTimerTick;
207
208 // How many orders of magnitude faster internal ticks are going than input ticks. Used in combination with
209 // inputTickScale, which is usually 1, but is different if there's an inputTickScaleClip. So, e.g. if
210 // insideWorldTickMagnitude is 1, this means the inside world is spinning twice as fast as the external world, so
211 // MIDI sync coming in representing an 8th-note would be interpreted internally as a quarter-note (because two
212 // internal 8th-notes would have happened, twice as fast, making a quarter-note)
213 int32_t insideWorldTickMagnitude = FlashStorage::defaultMagnitude;
214
215 // Sometimes, we'll do weird stuff to insideWorldTickMagnitude for sync-scaling, which would make BPM values look
216 // weird. So, we keep insideWorldTickMagnitudeOffsetFromBPM
217 int32_t insideWorldTickMagnitudeOffsetFromBPM = 0;
218
219 int8_t swingAmount = 0;
220 uint8_t swingInterval = FlashStorage::defaultSwingInterval;
221
222 Section sections[kMaxNumSections];
223
224 MusicalKey key;
225 std::bitset<NUM_PRESET_SCALES> disabledPresetScales = FlashStorage::defaultDisabledPresetScales;
226
227 uint16_t slot = std::numeric_limits<int16_t>::max();
228 int8_t subSlot = -1;
229 String name;
230
231 bool affectEntire = false;
232
233 SessionLayoutType sessionLayout = FlashStorage::defaultSessionLayout;
234 int32_t songGridScrollX = 0;
235 int32_t songGridScrollY = 0;
236 int32_t songViewYScroll = 1 - kDisplayHeight;
237 int32_t arrangementYScroll = -kDisplayHeight;
238
239 uint8_t sectionToReturnToAfterSongEnd;
240
241 bool wasLastInArrangementEditor;
242 int32_t lastClipInstanceEnteredStartPos = -1; // -1 means we are not "inside" an arrangement. While we're in the
243 // ArrangementEditor, it's 0
244
245 bool arrangerAutoScrollModeActive = false;
246
247 MIDIInstrument* hibernatingMIDIInstrument = nullptr;
248
249 bool outputClipInstanceListIsCurrentlyInvalid = false; // Set to true during scenarios like replaceInstrument(), to
250 // warn other functions not to look at Output::clipInstances
251
252 bool paramsInAutomationMode = false;
253
254 bool inClipMinderViewOnLoad; // Temp variable only valid while loading Song
255
256 int32_t unautomatedParamValues[deluge::modulation::params::kMaxNumUnpatchedParams];
257
258 String dirPath;
259
260 std::array<SessionMacro, 8> sessionMacros{};
261
262 bool getAnyClipsSoloing() const;
263 Clip* getCurrentClip();
264 void setCurrentClip(Clip* clip) {
265 if (currentClip != nullptr) {
266 previousClip = currentClip;
267 }
268 currentClip = clip;
269 }
270 uint32_t getInputTickScale();
271 Clip* getSyncScalingClip();
272 void setInputTickScaleClip(Clip* clip);
273 inline bool isFillModeActive() { return fillModeActive; }
274 void changeFillMode(bool on);
275 void loadNextSong();
276 void setClipLength(Clip* clip, uint32_t newLength, Action* action, bool mayReSyncClip = true);
277 void doubleClipLength(InstrumentClip* clip, Action* action = nullptr);
278 Clip* getClipWithOutput(Output* output, bool mustBeActive = false, Clip* excludeClip = nullptr);
279 Error readFromFile(Deserializer& reader);
280 void writeToFile();
281 void loadAllSamples(bool mayActuallyReadFiles = true);
282 void renderAudio(std::span<StereoSample> outputBuffer, int32_t* reverbBuffer, int32_t sideChainHitPending);
283 bool isYNoteAllowed(int32_t yNote, bool inKeyMode);
284 Clip* syncScalingClip = nullptr;
285 void setTimePerTimerTick(uint64_t newTimeBig, bool shouldLogAction = false);
286 bool hasAnySwing();
287 void resyncLFOs();
288 void ensureInaccessibleParamPresetValuesWithoutKnobsAreZero(Sound* sound);
289 bool areAllClipsInSectionPlaying(int32_t section);
290 void removeYNoteFromMode(int32_t yNoteWithinOctave);
291 void turnSoloingIntoJustPlaying(bool getRidOfArmingToo = true);
292 void reassessWhetherAnyClipsSoloing();
293 float getTimePerTimerTickFloat();
294 uint32_t getTimePerTimerTickRounded();
295 int32_t getNumOutputs();
296 Clip* getNextSessionClipWithOutput(int32_t offset, Output* output, Clip* prevClip);
297 bool anyClipsSoloing = false;
298
299 ParamManager* getBackedUpParamManagerForExactClip(ModControllableAudio* modControllable, Clip* clip,
300 ParamManager* stealInto = nullptr);
301 ParamManager* getBackedUpParamManagerPreferablyWithClip(ModControllableAudio* modControllable, Clip* clip,
302 ParamManager* stealInto = nullptr);
303 void backUpParamManager(ModControllableAudio* modControllable, Clip* clip, ParamManagerForTimeline* paramManager,
304 bool shouldStealExpressionParamsToo = false);
305 void moveInstrumentToHibernationList(Instrument* instrument);
306 void deleteOrHibernateOutputIfNoClips(Output* output);
307 void removeInstrumentFromHibernationList(Instrument* instrument);
308 bool doesOutputHaveActiveClipInSession(Output* output);
309 bool doesNonAudioSlotHaveActiveClipInSession(OutputType outputType, int32_t slot, int32_t subSlot = -1);
310 bool doesOutputHaveAnyClips(Output* output);
311 void deleteBackedUpParamManagersForClip(Clip* clip);
312 void deleteBackedUpParamManagersForModControllable(ModControllableAudio* modControllable);
313 void deleteHibernatingInstrumentWithSlot(OutputType outputType, char const* name);
314 void loadCrucialSamplesOnly();
315 Clip* getSessionClipWithOutput(Output* output, int32_t requireSection = -1, Clip* excludeClip = nullptr,
316 int32_t* clipIndex = nullptr, bool excludePendingOverdubs = false);
317 void restoreClipStatesBeforeArrangementPlay();
318 void deleteOrAddToHibernationListOutput(Output* output);
319 int32_t getLowestSectionWithNoSessionClipForOutput(Output* output);
320 void assertActiveness(ModelStackWithTimelineCounter* modelStack, int32_t endInstanceAtTime = -1);
321 [[nodiscard]] bool isClipActive(Clip const* clip) const;
322 void sendAllMIDIPGMs();
323 void sortOutWhichClipsAreActiveWithoutSendingPGMs(ModelStack* modelStack, int32_t playbackWillStartInArrangerAtPos);
324 void deactivateAnyArrangementOnlyClips();
325 Clip* getLongestClip(bool includePlayDisabled, bool includeArrangementOnly);
326 Clip* getLongestActiveClipWithMultipleOrFactorLength(int32_t targetLength, bool revertToAnyActiveClipIfNone = true,
327 Clip* excludeClip = nullptr);
328 int32_t getOutputIndex(Output* output);
329 void setHibernatingMIDIInstrument(MIDIInstrument* newInstrument);
330 void deleteHibernatingMIDIInstrument();
331 MIDIInstrument* grabHibernatingMIDIInstrument(int32_t newSlot, int32_t newSubSlot);
332 NoteRow* findNoteRowForDrum(Kit* kit, Drum* drum, Clip* stopTraversalAtClip = nullptr);
333
334 bool anyOutputsSoloingInArrangement = false;
335 bool getAnyOutputsSoloingInArrangement();
336 void reassessWhetherAnyOutputsSoloingInArrangement();
337 bool isOutputActiveInArrangement(Output* output);
338 Output* getOutputFromIndex(int32_t index);
339 void ensureAllInstrumentsHaveAClipOrBackedUpParamManager(char const* errorMessageNormal,
340 char const* errorMessageHibernating);
341 Error placeFirstInstancesOfActiveClips(int32_t pos);
342 void endInstancesOfActiveClips(int32_t pos, bool detachClipsToo = false);
343 void clearArrangementBeyondPos(int32_t pos, Action* action);
344 void deletingClipInstanceForClip(Output* output, Clip* clip, Action* action, bool shouldPickNewActiveClip);
345 bool arrangementHasAnyClipInstances();
346 void resumeClipsClonedForArrangementRecording();
347 void setParamsInAutomationMode(bool newState);
348 bool shouldOldOutputBeReplaced(Clip* clip, Availability* availabilityRequirement = nullptr);
349 Output* navigateThroughPresetsForInstrument(Output* output, int32_t offset);
350 void instrumentSwapped(Instrument* newInstrument);
351 Instrument* changeOutputType(Instrument* oldInstrument, OutputType newOutputType);
352 AudioOutput* getFirstAudioOutput();
353 AudioOutput* createNewAudioOutput(Output* replaceOutput = nullptr);
355 void getNoteLengthName(StringBuf& buffer, uint32_t noteLength, char const* notesString = "-notes",
356 bool clarifyPerColumn = false) const;
357 void replaceOutputLowLevel(Output* newOutput, Output* oldOutput);
358 void removeSessionClip(Clip* clip, int32_t clipIndex, bool forceClipsAboveToMoveVertically = false);
359 bool deletePendingOverdubs(Output* onlyWithOutput = nullptr, int32_t* originalClipIndex = nullptr,
360 bool createConsequencesForOtherLinearlyRecordingClips = false);
361 Clip* getPendingOverdubWithOutput(Output* output);
362 Clip* getClipWithOutputAboutToBeginLinearRecording(Output* output);
363 Clip* createPendingNextOverdubBelowClip(Clip* clip, int32_t clipIndex, OverDubType newOverdubNature);
364 bool hasAnyPendingNextOverdubs();
365 Output* getNextAudioOutput(int32_t offset, Output* oldOutput, Availability availabilityRequirement);
366 void deleteOutput(Output* output);
367 void cullAudioClipVoice();
368 int32_t getYScrollSongViewWithoutPendingOverdubs();
369 int32_t removeOutputFromMainList(Output* output, bool stopAnyAuditioningFirst = true);
370 void swapClips(Clip* newClip, Clip* oldClip, int32_t clipIndex);
371 Clip* replaceInstrumentClipWithAudioClip(Clip* oldClip, int32_t clipIndex);
372 void setDefaultVelocityForAllInstruments(uint8_t newDefaultVelocity);
373 void midiCableBendRangeUpdatedViaMessage(ModelStack* modelStack, MIDICable& cable, int32_t channelOrZone,
374 int32_t whichBendRange, int32_t bendSemitones);
375 Error addInstrumentsToFileItems(OutputType outputType);
376
377 uint32_t getQuarterNoteLength();
378 uint32_t getBarLength();
379 uint32_t getSixteenthNoteLength();
380 ModelStackWithThreeMainThings* setupModelStackWithSongAsTimelineCounter(void* memory);
381 ModelStackWithTimelineCounter* setupModelStackWithCurrentClip(void* memory);
382 ModelStackWithThreeMainThings* addToModelStack(ModelStack* modelStack);
385 ModelStackWithAutoParam* getModelStackWithParam(ModelStackWithThreeMainThings* modelStack, int32_t paramID);
386
387 // TimelineCounter implementation
388 [[nodiscard]] int32_t getLastProcessedPos() const override;
389 [[nodiscard]] uint32_t getLivePos() const override;
390 [[nodiscard]] int32_t getLoopLength() const override;
391 [[nodiscard]] bool isPlayingAutomationNow() const override;
392 [[nodiscard]] bool backtrackingCouldLoopBackToEnd() const override;
393 [[nodiscard]] int32_t getPosAtWhichPlaybackWillCut(ModelStackWithTimelineCounter const* modelStack) const override;
394 void getActiveModControllable(ModelStackWithTimelineCounter* modelStack) override;
395 void expectEvent() override;
396 TimelineCounter* getTimelineCounterToRecordTo() override;
397
398 // Reverb params to be stored here between loading and song being made the active one
399 dsp::Reverb::Model model = deluge::dsp::Reverb::Model::MUTABLE;
400 float reverbRoomSize = 30 / 50.f;
401 float reverbHPF = 0;
402 float reverbLPF = 1;
403 float reverbDamp = 36 / 50.f;
404 float reverbWidth = 1;
405 int32_t reverbPan = 0;
406 int32_t reverbSidechainVolume;
407 int32_t reverbSidechainShape = -601295438;
408 int32_t reverbSidechainAttack;
409 int32_t reverbSidechainRelease;
410 SyncLevel reverbSidechainSync = SYNC_LEVEL_8TH;
411
412 // START ~ new Automation Arranger View Variables
413 int32_t lastSelectedParamID = kNoSelection; // last selected Parameter to be edited in Automation Arranger View
414 deluge::modulation::params::Kind lastSelectedParamKind =
415 deluge::modulation::params::Kind::NONE; // 0 = patched, 1 = unpatched, 2 = global effectable, 3 = none
416 int32_t lastSelectedParamShortcutX = kNoSelection;
417 int32_t lastSelectedParamShortcutY = kNoSelection;
418 int32_t lastSelectedParamArrayPosition = 0;
419 // END ~ new Automation Arranger View Variables
420
421 // Song level transpose control (encoder actions)
422 int32_t masterTransposeInterval = 0;
423 void transpose(int32_t interval);
424 void adjustMasterTransposeInterval(int32_t interval);
425 void displayMasterTransposeInterval();
426
427 // MIDI controlled song transpose
428 bool hasBeenTransposed = 0;
429 int16_t transposeOffset = 0;
430
431 int32_t countAudioClips() const;
432
433 // Chord memory
434 uint8_t chordMemNoteCount[kDisplayHeight] = {0};
435 uint8_t chordMem[kDisplayHeight][MAX_NOTES_CHORD_MEM] = {0};
436
437 // Tempo automation
438 void clearTempoAutomation();
439 void updateBPMFromAutomation();
440
441 float calculateBPM() {
442 float timePerTimerTick = getTimePerTimerTickFloat();
443 return calculateBPM(timePerTimerTick);
444 }
445 float calculateBPM(float timePerTimerTick) {
446
447 if (insideWorldTickMagnitude > 0) {
448 timePerTimerTick *= ((uint32_t)1 << (insideWorldTickMagnitude));
449 }
450 float tempoBPM = (float)110250 / timePerTimerTick;
451 if (insideWorldTickMagnitude < 0) {
452 tempoBPM *= ((uint32_t)1 << (-insideWorldTickMagnitude));
453 }
454 return tempoBPM;
455 }
456
457 int8_t defaultAudioClipOverdubOutputCloning = -1; // -1 means no default set
458
459 // Threshold
460 void changeThresholdRecordingMode(int8_t offset);
461 void displayThresholdRecordingMode();
462 ThresholdRecordingMode thresholdRecordingMode = FlashStorage::defaultThresholdRecordingMode;
463
464private:
465 ScaleMapper scaleMapper;
466 NoteSet userScaleNotes;
467 bool fillModeActive = false;
468 Clip* currentClip = nullptr;
469 Clip* previousClip = nullptr; // for future use, maybe finding an instrument clip or something
470 void inputTickScalePotentiallyJustChanged(uint32_t oldScale);
471 Error readClipsFromFile(Deserializer& reader, ClipArray* clipArray);
472 void addInstrumentToHibernationList(Instrument* instrument);
473 void deleteAllBackedUpParamManagers(bool shouldAlsoEmptyVector = true);
474 void deleteAllBackedUpParamManagersWithClips();
475 void deleteAllOutputs(Output** prevPointer);
476 void setupClipIndexesForSaving();
477 void setBPMInner(float tempoBPM, bool shouldLogAction);
478 void clearTempoAutomation(float tempoBPM);
479 int32_t intBPM{0};
480};
481
482extern Song* currentSong;
483extern Song* preLoadedSong;
Definition action.h:75
Definition arpeggiator.h:46
Definition audio_clip.h:35
Definition audio_output.h:37
Definition clip_array.h:25
Definition clip.h:46
Definition drum.h:44
Definition global_effectable_for_song.h:22
Definition instrument_clip.h:48
Definition instrument.h:45
Definition kit.h:34
Definition learned_midi.h:30
A MIDI cable connection. Stores all state specific to a given cable and its contained ports and chann...
Definition midi_device.h:94
Definition midi_instrument.h:37
Definition mod_controllable_audio.h:47
Definition model_stack.h:129
Definition model_stack.h:123
Definition musical_key.h:10
Definition note_row.h:98
Definition note_set.h:20
Definition ordered_resizeable_array_with_multi_word_key.h:25
Definition output.h:81
Definition param_manager.h:174
Definition param_manager.h:45
Definition scale_change.h:5
Definition song.h:104
Scale getCurrentScale()
Returns current scale.
Definition song.cpp:2932
Scale setScale(Scale newScale)
Returns CUSTOM_SCALE_WITH_MORE_THAN_7_NOTES we can't use the newScale.
Definition song.cpp:2884
void learnScaleFromCurrentNotes()
Learns a user scale from notes in scale mode clips.
ModelStackWithAutoParam * getModelStackWithParam(ModelStackWithThreeMainThings *modelStack, int32_t paramID)
Definition song.cpp:5826
void setRootNote(int32_t newRootNote, InstrumentClip *clipToAvoidAdjustingScrollFor=nullptr)
Definition song.cpp:521
bool hasUserScale()
Returns true if the song has a user scale.
Definition song.cpp:2928
void getNoteLengthName(StringBuf &buffer, uint32_t noteLength, char const *notesString="-notes", bool clarifyPerColumn=false) const
buffer must have at least 5 characters on 7seg, or 30 for OLED
Definition song.cpp:5088
NoteSet notesInScaleModeClips()
Returns a NoteSet with all notes currently in used in scale mdoe clips.
Definition song.cpp:511
int32_t getLastProcessedPos() const override
Get the tick at which this timeline counter last did anything.
Definition song.cpp:5598
bool setScaleNotes(NoteSet newScale)
Definition song.cpp:2897
uint32_t getLivePos() const override
Get the current tick of this timeline counter relative to the playback handler.
Definition song.cpp:5586
Scale cycleThroughScales()
Changes to next applicable scale.
Definition song.cpp:2868
Definition sound_drum.h:28
Definition sound_instrument.h:30
Definition d_string.h:106
Definition d_string.h:46
Kind
Definition param.h:42
Definition song.h:81
Definition song.h:97