Deluge Firmware 1.3.0
Build date: 2025.07.11
Loading...
Searching...
No Matches
arpeggiator.h
1/*
2 * Copyright © 2017-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 "model/sync.h"
22#include "storage/storage_manager.h"
23#include "util/container/array/ordered_resizeable_array.h"
24#include "util/container/array/resizeable_array.h"
25
26#include <array>
27#include <cstddef>
28#include <cstdint>
29
30class PostArpTriggerable;
33
34constexpr uint32_t RANDOMIZER_LOCK_MAX_SAVED_VALUES = 16;
35constexpr uint32_t ARP_MAX_INSTRUCTION_NOTES = 4;
36constexpr uint32_t PATTERN_MAX_BUFFER_SIZE = 16;
37
38constexpr uint32_t ARP_NOTE_NONE = 32767;
39
40enum class ArpType : uint8_t {
41 SYNTH,
42 DRUM,
43 KIT,
44};
45
46class ArpeggiatorSettings {
47public:
48 ArpeggiatorSettings();
49
50 void updateParamsFromUnpatchedParamSet(UnpatchedParamSet* unpatchedParams);
51
52 void cloneFrom(ArpeggiatorSettings const* other);
53
54 bool readCommonTagsFromFile(Deserializer& reader, char const* tagName, Song* songToConvertSyncLevel);
55
56 bool readNonAudioTagsFromFile(Deserializer& reader, char const* tagName);
57
58 void writeCommonParamsToFile(Serializer& writer, Song* songToConvertSyncLevel);
59
60 void writeNonAudioParamsToFile(Serializer& writer);
61
62 void generateNewNotePattern();
63
64 void updatePresetFromCurrentSettings();
65
66 void updateSettingsFromCurrentPreset();
67
68 uint32_t getPhaseIncrement(int32_t arpRate);
69
70 // Main settings
71 ArpPreset preset{ArpPreset::OFF};
72 ArpMode mode{ArpMode::OFF};
73
74 bool includeInKitArp{true};
75
76 // Sequence settings
77 ArpOctaveMode octaveMode{ArpOctaveMode::UP};
78 ArpNoteMode noteMode{ArpNoteMode::UP};
79
80 // Octave settings
81 uint8_t numOctaves{2};
82
83 // Number of repetitions of each step
84 uint8_t numStepRepeats{1};
85
86 // Chord type (only for kit arpeggiators)
87 uint8_t chordTypeIndex{0};
88
89 // Sync settings
90 SyncLevel syncLevel;
91 SyncType syncType;
92
93 // Arp randomizer lock
94 bool randomizerLock{false};
95
96 // MPE settings
97 ArpMpeModSource mpeVelocity{ArpMpeModSource::OFF};
98
99 // Spread last lock
100 uint32_t lastLockedNoteProbabilityParameterValue{0};
101 uint32_t lastLockedBassProbabilityParameterValue{0};
102 uint32_t lastLockedSwapProbabilityParameterValue{0};
103 uint32_t lastLockedGlideProbabilityParameterValue{0};
104 uint32_t lastLockedReverseProbabilityParameterValue{0};
105 uint32_t lastLockedChordProbabilityParameterValue{0};
106 uint32_t lastLockedRatchetProbabilityParameterValue{0};
107 uint32_t lastLockedSpreadVelocityParameterValue{0};
108 uint32_t lastLockedSpreadGateParameterValue{0};
109 uint32_t lastLockedSpreadOctaveParameterValue{0};
110
111 // Pre-calculated randomized values for each parameter
112 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedNoteProbabilityValues;
113 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedBassProbabilityValues;
114 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSwapProbabilityValues;
115 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedGlideProbabilityValues;
116 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedReverseProbabilityValues;
117 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedChordProbabilityValues;
118 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedRatchetProbabilityValues;
119 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadVelocityValues;
120 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadGateValues;
121 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadOctaveValues;
122
123 // Order for the pattern note mode
124 std::array<int8_t, PATTERN_MAX_BUFFER_SIZE> notePattern;
125
126 // Temporary flags
127 bool flagForceArpRestart{false};
128
129 // Automatable params
130 int32_t rate{0}; // Default to 25 if not set in XML
131 int32_t gate{0}; // Default to 25 if not set in XML
132 uint32_t rhythm{0};
133 uint32_t sequenceLength{0};
134 uint32_t chordPolyphony{0};
135 uint32_t ratchetAmount{0};
136 uint32_t noteProbability{4294967295u}; // Default to 25 if not set in XML
137 uint32_t bassProbability{0};
138 uint32_t swapProbability{0};
139 uint32_t glideProbability{0};
140 uint32_t reverseProbability{0};
141 uint32_t chordProbability{0};
142 uint32_t ratchetProbability{0};
143 uint32_t spreadVelocity{0};
144 uint32_t spreadGate{0};
145 uint32_t spreadOctave{0};
146};
147
148struct ArpNote {
149 ArpNote() {
150 outputMemberChannel.fill(MIDI_CHANNEL_NONE);
151 noteCodeOnPostArp.fill(ARP_NOTE_NONE);
152 }
153 int16_t inputCharacteristics[2]; // Before arpeggiation. And applying to MIDI input if that's happening. Or, channel
154 // might be MIDI_CHANNEL_NONE.
155 int16_t mpeValues[kNumExpressionDimensions];
156 uint8_t velocity;
157 uint8_t baseVelocity;
158
159 // For note-ons
160 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMemberChannel;
161 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeOnPostArp;
162};
163
165 int16_t noteCode; // Before arpeggiation
166};
167
168class ArpReturnInstruction {
169public:
170 ArpReturnInstruction() {
171 sampleSyncLengthOn = 0;
172 invertReversed = false;
173 arpNoteOn = nullptr;
174 outputMIDIChannelOff.fill(MIDI_CHANNEL_NONE);
175 noteCodeOffPostArp.fill(ARP_NOTE_NONE);
176 glideOutputMIDIChannelOff.fill(MIDI_CHANNEL_NONE);
177 glideNoteCodeOffPostArp.fill(ARP_NOTE_NONE);
178 }
179
180 // These are only valid if doing a note-on, or when releasing the most recently played with the arp off when other
181 // notes are still playing (e.g. for mono note priority)
182 uint32_t sampleSyncLengthOn; // This defaults to zero, or may be overwritten by the caller to the Arp - and then
183 // the Arp itself may override that.
184
185 // If set to true by the arpeggiator, the reverse SAMPLE flag will be inverted for the next voices to be played
186 // and restored back to normal afterwards
187 bool invertReversed;
188
189 ArpNote* arpNoteOn;
190
191 // And these are only valid if doing a note-off
192 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMIDIChannelOff; // For MPE
193 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeOffPostArp;
194 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> glideOutputMIDIChannelOff; // For MPE
195 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> glideNoteCodeOffPostArp;
196};
197
198class ArpeggiatorBase {
199public:
200 ArpeggiatorBase() {
201 noteCodeCurrentlyOnPostArp.fill(ARP_NOTE_NONE);
202 glideNoteCodeCurrentlyOnPostArp.fill(ARP_NOTE_NONE);
203 outputMIDIChannelForNoteCurrentlyOnPostArp.fill(0);
204 outputMIDIChannelForGlideNoteCurrentlyOnPostArp.fill(0);
205 }
206 virtual void noteOn(ArpeggiatorSettings* settings, int32_t noteCode, int32_t velocity,
207 ArpReturnInstruction* instruction, int32_t fromMIDIChannel, int16_t const* mpeValues) = 0;
208 virtual void noteOff(ArpeggiatorSettings* settings, int32_t noteCodePreArp, ArpReturnInstruction* instruction) = 0;
209 void render(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, int32_t numSamples,
210 uint32_t gateThreshold, uint32_t phaseIncrement);
211 int32_t doTickForward(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, uint32_t ClipCurrentPos,
212 bool currentlyPlayingReversed);
213 void calculateRandomizerAmounts(ArpeggiatorSettings* settings);
214 virtual bool hasAnyInputNotesActive() = 0;
215 virtual void reset() = 0;
216 virtual ArpType getArpType() = 0;
217
218 bool gateCurrentlyActive = false;
219 uint32_t gatePos = 0;
220
221 bool playedFirstArpeggiatedNoteYet = false;
222 uint8_t lastVelocity = 0;
223 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeCurrentlyOnPostArp;
224 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> glideNoteCodeCurrentlyOnPostArp;
225 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMIDIChannelForNoteCurrentlyOnPostArp;
226 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMIDIChannelForGlideNoteCurrentlyOnPostArp;
227
228 // Playing state
229 uint32_t notesPlayedFromSequence = 0;
230 uint32_t randomNotesPlayedFromOctave = 0;
231
232 // Sequence state
233 int16_t whichNoteCurrentlyOnPostArp; // As in, the index within our list
234 int8_t currentOctave = 0;
235 int8_t currentDirection = 1;
236 int8_t currentOctaveDirection = 1;
237
238 // Rhythm state
239 uint32_t notesPlayedFromRhythm = 0;
240 uint32_t lastNormalNotePlayedFromRhythm = 0;
241
242 // Locked randomizer state
243 uint32_t notesPlayedFromLockedRandomizer = 0;
244
245 // Note probability state
246 bool lastNormalNotePlayedFromNoteProbability = true;
247
248 // Bass probability state
249 bool lastNormalNotePlayedFromBassProbability = false;
250
251 // Swap probability state
252 bool lastNormalNotePlayedFromSwapProbability = false;
253
254 // Reverse probability state
255 bool lastNormalNotePlayedFromReverseProbability = false;
256
257 // Chord probability state
258 bool lastNormalNotePlayedFromChordProbability = false;
259
260 // Step repeat state
261 int32_t stepRepeatIndex = 0;
262
263 // Ratcheting state
264 uint32_t ratchetNotesIndex = 0;
265 uint32_t ratchetNotesMultiplier = 0;
266 uint32_t ratchetNotesCount = 0;
267 bool isRatcheting = false;
268
269 // Glide state
270 bool glideOnNextNoteOff = false;
271
272 // Calculated randomizer values
273 bool isPlayNoteForCurrentStep = true;
274 bool isPlayBassForCurrentStep = false;
275 bool isPlayRandomStepForCurrentStep = false;
276 bool isPlayReverseForCurrentStep = false;
277 bool isPlayChordForCurrentStep = false;
278 bool isPlayRatchetForCurrentStep = false;
279 bool isPlayGlideForCurrentStep = false;
280 int32_t spreadVelocityForCurrentStep = 0;
281 int32_t spreadGateForCurrentStep = 0;
282 int32_t spreadOctaveForCurrentStep = 0;
283 bool resetLockedRandomizerValuesNextTime = false;
284
285protected:
286 void calculateNextNoteAndOrOctave(ArpeggiatorSettings* settings, uint8_t numActiveNotes);
287 void setInitialNoteAndOctave(ArpeggiatorSettings* settings, uint8_t numActiveNotes);
288 void resetBase();
289 void resetRatchet();
290 void executeArpStep(ArpeggiatorSettings* settings, uint8_t numActiveNotes, bool isRatchet,
291 uint32_t maxSequenceLength, uint32_t rhythm, bool* shouldCarryOnRhythmNote,
292 bool* shouldPlayNote, bool* shouldPlayBassNote, bool* shouldPlayRandomStep,
293 bool* shouldPlayReverseNote, bool* shouldPlayChordNote);
294 void increasePatternIndexes(uint8_t numStepRepeats);
295 void increaseSequenceIndexes(uint32_t maxSequenceLength, uint32_t rhythm);
296 void maybeSetupNewRatchet(ArpeggiatorSettings* settings);
297 bool evaluateRhythm(uint32_t rhythm, bool isRatchet);
298 bool evaluateNoteProbability(bool isRatchet);
299 bool evaluateBassProbability(bool isRatchet);
300 bool evaluateSwapProbability(bool isRatchet);
301 bool evaluateReverseProbability(bool isRatchet);
302 bool evaluateChordProbability(bool isRatchet);
303 uint32_t calculateSpreadVelocity(uint8_t velocity, int32_t spreadVelocityForCurrentStep);
304 int32_t getOctaveDirection(ArpeggiatorSettings* settings);
305 virtual void switchNoteOn(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, bool isRatchet) = 0;
306 void switchAnyNoteOff(ArpReturnInstruction* instruction);
307 bool getRandomProbabilityResult(uint32_t value);
308 int8_t getRandomBipolarProbabilityAmount(uint32_t value);
309 int8_t getRandomWeighted2BitsAmount(uint32_t value);
310};
311
312class ArpeggiatorForDrum : public ArpeggiatorBase {
313public:
314 ArpeggiatorForDrum();
315 void noteOn(ArpeggiatorSettings* settings, int32_t noteCode, int32_t velocity, ArpReturnInstruction* instruction,
316 int32_t fromMIDIChannel, int16_t const* mpeValues) override;
317 void noteOff(ArpeggiatorSettings* settings, int32_t noteCodePreArp, ArpReturnInstruction* instruction) override;
318 void reset() override;
319 ArpType getArpType() override { return ArpType::DRUM; }
320 ArpNote arpNote; // For the one note. noteCode will always be 60. velocity will be 0 if off.
321 int16_t noteForDrum;
322
323 bool invertReversedFromKitArp;
324
325protected:
326 void switchNoteOn(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, bool isRatchet) override;
327 bool hasAnyInputNotesActive() override;
328};
329
330class Arpeggiator : public ArpeggiatorBase {
331public:
332 Arpeggiator();
333
334 void reset() override;
335 ArpType getArpType() override { return ArpType::SYNTH; }
336
337 void noteOn(ArpeggiatorSettings* settings, int32_t noteCode, int32_t velocity, ArpReturnInstruction* instruction,
338 int32_t fromMIDIChannel, int16_t const* mpeValues) override;
339 void noteOff(ArpeggiatorSettings* settings, int32_t noteCodePreArp, ArpReturnInstruction* instruction) override;
340 bool hasAnyInputNotesActive() override;
341
342 // This array tracks the notes ordered by noteCode
344 // This array tracks the notes as they were played by the user
345 ResizeableArray notesAsPlayed;
346 // This array tracks the notes as ordered by the Pattern note mode
347 ResizeableArray notesByPattern;
348
349protected:
350 void rearrangePatterntArpNotes(ArpeggiatorSettings* settings);
351 void switchNoteOn(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, bool isRatchet) override;
352};
353
354class ArpeggiatorForKit : public Arpeggiator {
355public:
356 ArpeggiatorForKit();
357 ArpType getArpType() override { return ArpType::KIT; }
358 void removeDrumIndex(ArpeggiatorSettings* arpSettings, int32_t drumIndex);
359};
Definition arpeggiator.h:168
Definition arpeggiator.h:46
Definition storage_manager.h:185
Definition ordered_resizeable_array.h:22
Definition param_manager.h:174
Definition resizeable_array.h:28
Definition storage_manager.h:119
Definition song.h:104
Definition param_set.h:98
Definition arpeggiator.h:164
Definition arpeggiator.h:148