104class Song final :
public TimelineCounter {
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);
122 void setupPatchingForAllParamManagersForDrum(
SoundDrum* drum);
123 void setupPatchingForAllParamManagersForInstrument(
SoundInstrument* sound);
124 void grabVelocityToLevelFromMIDICableAndSetupPatchingForAllParamManagersForInstrument(
MIDICable& cable,
126 void grabVelocityToLevelFromMIDICableAndSetupPatchingForAllParamManagersForDrum(
MIDICable& cable,
SoundDrum* drum,
128 void grabVelocityToLevelFromMIDICableAndSetupPatchingForEverything(
MIDICable& cable);
129 void getCurrentRootNoteAndScaleName(
StringBuf& buffer);
130 void displayCurrentRootNoteAndScaleName();
154 void setTempoFromNumSamples(
double newTempoSamples,
bool shouldLogAction);
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);
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);
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);
183 void setSongFullPath(
const char* fullPath);
184 int32_t getInputTickMagnitude()
const {
return insideWorldTickMagnitude + insideWorldTickMagnitudeOffsetFromBPM; }
191 Output* firstOutput =
nullptr;
198 int32_t xScroll[2] = {0};
199 int32_t xScrollForReturnToSongView = 0;
200 int32_t xZoomForReturnToSongView;
202 bool tripletsOn =
false;
203 uint32_t tripletsLevel;
205 uint64_t timePerTimerTickBig;
206 int32_t divideByTimePerTimerTick;
213 int32_t insideWorldTickMagnitude = FlashStorage::defaultMagnitude;
217 int32_t insideWorldTickMagnitudeOffsetFromBPM = 0;
219 int8_t swingAmount = 0;
220 uint8_t swingInterval = FlashStorage::defaultSwingInterval;
222 Section sections[kMaxNumSections];
225 std::bitset<NUM_PRESET_SCALES> disabledPresetScales = FlashStorage::defaultDisabledPresetScales;
227 uint16_t slot = std::numeric_limits<int16_t>::max();
231 bool affectEntire =
false;
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;
239 uint8_t sectionToReturnToAfterSongEnd;
241 bool wasLastInArrangementEditor;
242 int32_t lastClipInstanceEnteredStartPos = -1;
245 bool arrangerAutoScrollModeActive =
false;
247 MIDIInstrument* hibernatingMIDIInstrument =
nullptr;
249 bool outputClipInstanceListIsCurrentlyInvalid =
false;
252 bool paramsInAutomationMode =
false;
254 bool inClipMinderViewOnLoad;
256 int32_t unautomatedParamValues[deluge::modulation::params::kMaxNumUnpatchedParams];
260 std::array<SessionMacro, 8> sessionMacros{};
262 bool getAnyClipsSoloing()
const;
263 Clip* getCurrentClip();
264 void setCurrentClip(Clip* clip) {
265 if (currentClip !=
nullptr) {
266 previousClip = currentClip;
270 uint32_t getInputTickScale();
271 Clip* getSyncScalingClip();
272 void setInputTickScaleClip(Clip* clip);
273 inline bool isFillModeActive() {
return fillModeActive; }
274 void changeFillMode(
bool on);
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);
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);
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;
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);
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);
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);
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;
399 dsp::Reverb::Model model = deluge::dsp::Reverb::Model::MUTABLE;
400 float reverbRoomSize = 30 / 50.f;
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;
413 int32_t lastSelectedParamID = kNoSelection;
415 deluge::modulation::params::Kind::NONE;
416 int32_t lastSelectedParamShortcutX = kNoSelection;
417 int32_t lastSelectedParamShortcutY = kNoSelection;
418 int32_t lastSelectedParamArrayPosition = 0;
422 int32_t masterTransposeInterval = 0;
423 void transpose(int32_t interval);
424 void adjustMasterTransposeInterval(int32_t interval);
425 void displayMasterTransposeInterval();
428 bool hasBeenTransposed = 0;
429 int16_t transposeOffset = 0;
431 int32_t countAudioClips()
const;
434 uint8_t chordMemNoteCount[kDisplayHeight] = {0};
435 uint8_t chordMem[kDisplayHeight][MAX_NOTES_CHORD_MEM] = {0};
438 void clearTempoAutomation();
439 void updateBPMFromAutomation();
441 float calculateBPM() {
442 float timePerTimerTick = getTimePerTimerTickFloat();
443 return calculateBPM(timePerTimerTick);
445 float calculateBPM(
float timePerTimerTick) {
447 if (insideWorldTickMagnitude > 0) {
448 timePerTimerTick *= ((uint32_t)1 << (insideWorldTickMagnitude));
450 float tempoBPM = (float)110250 / timePerTimerTick;
451 if (insideWorldTickMagnitude < 0) {
452 tempoBPM *= ((uint32_t)1 << (-insideWorldTickMagnitude));
457 int8_t defaultAudioClipOverdubOutputCloning = -1;
460 void changeThresholdRecordingMode(int8_t offset);
461 void displayThresholdRecordingMode();
462 ThresholdRecordingMode thresholdRecordingMode = FlashStorage::defaultThresholdRecordingMode;
465 ScaleMapper scaleMapper;
466 NoteSet userScaleNotes;
467 bool fillModeActive =
false;
468 Clip* currentClip =
nullptr;
469 Clip* previousClip =
nullptr;
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);