Deluge Firmware 1.3.0
Build date: 2025.06.05
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 lastLockedStepProbabilityParameterValue{0};
103 uint32_t lastLockedReverseProbabilityParameterValue{0};
104 uint32_t lastLockedChordProbabilityParameterValue{0};
105 uint32_t lastLockedRatchetProbabilityParameterValue{0};
106 uint32_t lastLockedSpreadVelocityParameterValue{0};
107 uint32_t lastLockedSpreadGateParameterValue{0};
108 uint32_t lastLockedSpreadOctaveParameterValue{0};
109
110 // Pre-calculated randomized values for each parameter
111 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedNoteProbabilityValues;
112 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedBassProbabilityValues;
113 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedStepProbabilityValues;
114 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedReverseProbabilityValues;
115 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedChordProbabilityValues;
116 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedRatchetProbabilityValues;
117 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadVelocityValues;
118 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadGateValues;
119 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadOctaveValues;
120
121 // Order for the pattern note mode
122 std::array<int8_t, PATTERN_MAX_BUFFER_SIZE> notePattern;
123
124 // Temporary flags
125 bool flagForceArpRestart{false};
126
127 // Automatable params
128 int32_t rate{0}; // Default to 25 if not set in XML
129 int32_t gate{0}; // Default to 25 if not set in XML
130 uint32_t rhythm{0};
131 uint32_t sequenceLength{0};
132 uint32_t chordPolyphony{0};
133 uint32_t ratchetAmount{0};
134 uint32_t noteProbability{4294967295u}; // Default to 25 if not set in XML
135 uint32_t bassProbability{0};
136 uint32_t stepProbability{0};
137 uint32_t reverseProbability{0};
138 uint32_t chordProbability{0};
139 uint32_t ratchetProbability{0};
140 uint32_t spreadVelocity{0};
141 uint32_t spreadGate{0};
142 uint32_t spreadOctave{0};
143};
144
145struct ArpNote {
146 ArpNote() {
147 outputMemberChannel.fill(MIDI_CHANNEL_NONE);
148 noteCodeOnPostArp.fill(ARP_NOTE_NONE);
149 }
150 int16_t inputCharacteristics[2]; // Before arpeggiation. And applying to MIDI input if that's happening. Or, channel
151 // might be MIDI_CHANNEL_NONE.
152 int16_t mpeValues[kNumExpressionDimensions];
153 uint8_t velocity;
154 uint8_t baseVelocity;
155
156 // For note-ons
157 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMemberChannel;
158 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeOnPostArp;
159};
160
162 int16_t noteCode; // Before arpeggiation
163};
164
165class ArpReturnInstruction {
166public:
167 ArpReturnInstruction() {
168 sampleSyncLengthOn = 0;
169 invertReversed = false;
170 arpNoteOn = nullptr;
171 outputMIDIChannelOff.fill(MIDI_CHANNEL_NONE);
172 noteCodeOffPostArp.fill(ARP_NOTE_NONE);
173 }
174
175 // These are only valid if doing a note-on, or when releasing the most recently played with the arp off when other
176 // notes are still playing (e.g. for mono note priority)
177 uint32_t sampleSyncLengthOn; // This defaults to zero, or may be overwritten by the caller to the Arp - and then
178 // the Arp itself may override that.
179
180 // If set to true by the arpeggiator, the reverse SAMPLE flag will be inverted for the next voices to be played
181 // and restored back to normal afterwards
182 bool invertReversed;
183
184 ArpNote* arpNoteOn;
185
186 // And these are only valid if doing a note-off
187 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMIDIChannelOff; // For MPE
188 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeOffPostArp;
189};
190
191class ArpeggiatorBase {
192public:
193 ArpeggiatorBase() {
194 noteCodeCurrentlyOnPostArp.fill(ARP_NOTE_NONE);
195 outputMIDIChannelForNoteCurrentlyOnPostArp.fill(0);
196 }
197 virtual void noteOn(ArpeggiatorSettings* settings, int32_t noteCode, int32_t velocity,
198 ArpReturnInstruction* instruction, int32_t fromMIDIChannel, int16_t const* mpeValues) = 0;
199 virtual void noteOff(ArpeggiatorSettings* settings, int32_t noteCodePreArp, ArpReturnInstruction* instruction) = 0;
200 void render(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, int32_t numSamples,
201 uint32_t gateThreshold, uint32_t phaseIncrement);
202 int32_t doTickForward(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, uint32_t ClipCurrentPos,
203 bool currentlyPlayingReversed);
204 void calculateRandomizerAmounts(ArpeggiatorSettings* settings);
205 virtual bool hasAnyInputNotesActive() = 0;
206 virtual void reset() = 0;
207 virtual ArpType getArpType() = 0;
208
209 bool gateCurrentlyActive = false;
210 uint32_t gatePos = 0;
211
212 bool playedFirstArpeggiatedNoteYet = false;
213 uint8_t lastVelocity = 0;
214 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeCurrentlyOnPostArp;
215 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMIDIChannelForNoteCurrentlyOnPostArp;
216
217 // Playing state
218 uint32_t notesPlayedFromSequence = 0;
219 uint32_t randomNotesPlayedFromOctave = 0;
220
221 // Sequence state
222 int16_t whichNoteCurrentlyOnPostArp; // As in, the index within our list
223 int8_t currentOctave = 0;
224 int8_t currentDirection = 1;
225 int8_t currentOctaveDirection = 1;
226
227 // Rhythm state
228 uint32_t notesPlayedFromRhythm = 0;
229 uint32_t lastNormalNotePlayedFromRhythm = 0;
230
231 // Locked randomizer state
232 uint32_t notesPlayedFromLockedRandomizer = 0;
233
234 // Note probability state
235 bool lastNormalNotePlayedFromNoteProbability = true;
236
237 // Bass probability state
238 bool lastNormalNotePlayedFromBassProbability = false;
239
240 // Step probability state
241 bool lastNormalNotePlayedFromStepProbability = false;
242
243 // Reverse probability state
244 bool lastNormalNotePlayedFromReverseProbability = false;
245
246 // Chord probability state
247 bool lastNormalNotePlayedFromChordProbability = false;
248
249 // Step repeat state
250 int32_t stepRepeatIndex = 0;
251
252 // Ratcheting state
253 uint32_t ratchetNotesIndex = 0;
254 uint32_t ratchetNotesMultiplier = 0;
255 uint32_t ratchetNotesCount = 0;
256 bool isRatcheting = false;
257
258 // Chord state
259 uint32_t chordNotesCount = 0;
260
261 // Calculated spread amounts
262 bool isPlayNoteForCurrentStep = true;
263 bool isPlayBassForCurrentStep = false;
264 bool isPlayRandomStepForCurrentStep = false;
265 bool isPlayReverseForCurrentStep = false;
266 bool isPlayChordForCurrentStep = false;
267 bool isPlayRatchetForCurrentStep = false;
268 int32_t spreadVelocityForCurrentStep = 0;
269 int32_t spreadGateForCurrentStep = 0;
270 int32_t spreadOctaveForCurrentStep = 0;
271 bool resetLockedRandomizerValuesNextTime = false;
272
273protected:
274 void calculateNextNoteAndOrOctave(ArpeggiatorSettings* settings, uint8_t numActiveNotes);
275 void setInitialNoteAndOctave(ArpeggiatorSettings* settings, uint8_t numActiveNotes);
276 void resetBase();
277 void resetRatchet();
278 void executeArpStep(ArpeggiatorSettings* settings, uint8_t numActiveNotes, bool isRatchet,
279 uint32_t maxSequenceLength, uint32_t rhythm, bool* shouldCarryOnRhythmNote,
280 bool* shouldPlayNote, bool* shouldPlayBassNote, bool* shouldPlayRandomStep,
281 bool* shouldPlayReverseNote, bool* shouldPlayChordNote);
282 void increasePatternIndexes(uint8_t numStepRepeats);
283 void increaseSequenceIndexes(uint32_t maxSequenceLength, uint32_t rhythm);
284 void maybeSetupNewRatchet(ArpeggiatorSettings* settings);
285 bool evaluateRhythm(uint32_t rhythm, bool isRatchet);
286 bool evaluateNoteProbability(bool isRatchet);
287 bool evaluateBassProbability(bool isRatchet);
288 bool evaluateStepProbability(bool isRatchet);
289 bool evaluateReverseProbability(bool isRatchet);
290 bool evaluateChordProbability(bool isRatchet);
291 uint32_t calculateSpreadVelocity(uint8_t velocity, int32_t spreadVelocityForCurrentStep);
292 int32_t getOctaveDirection(ArpeggiatorSettings* settings);
293 virtual void switchNoteOn(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, bool isRatchet) = 0;
294 void switchAnyNoteOff(ArpReturnInstruction* instruction);
295 bool getRandomProbabilityResult(uint32_t value);
296 int8_t getRandomBipolarProbabilityAmount(uint32_t value);
297 int8_t getRandomWeighted2BitsAmount(uint32_t value);
298};
299
300class ArpeggiatorForDrum : public ArpeggiatorBase {
301public:
302 ArpeggiatorForDrum();
303 void noteOn(ArpeggiatorSettings* settings, int32_t noteCode, int32_t velocity, ArpReturnInstruction* instruction,
304 int32_t fromMIDIChannel, int16_t const* mpeValues) override;
305 void noteOff(ArpeggiatorSettings* settings, int32_t noteCodePreArp, ArpReturnInstruction* instruction) override;
306 void reset() override;
307 ArpType getArpType() override { return ArpType::DRUM; }
308 ArpNote arpNote; // For the one note. noteCode will always be 60. velocity will be 0 if off.
309 int16_t noteForDrum;
310
311 bool invertReversedFromKitArp;
312
313protected:
314 void switchNoteOn(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, bool isRatchet) override;
315 bool hasAnyInputNotesActive() override;
316};
317
318class Arpeggiator : public ArpeggiatorBase {
319public:
320 Arpeggiator();
321
322 void reset() override;
323 ArpType getArpType() override { return ArpType::SYNTH; }
324
325 void noteOn(ArpeggiatorSettings* settings, int32_t noteCode, int32_t velocity, ArpReturnInstruction* instruction,
326 int32_t fromMIDIChannel, int16_t const* mpeValues) override;
327 void noteOff(ArpeggiatorSettings* settings, int32_t noteCodePreArp, ArpReturnInstruction* instruction) override;
328 bool hasAnyInputNotesActive() override;
329
330 // This array tracks the notes ordered by noteCode
332 // This array tracks the notes as they were played by the user
333 ResizeableArray notesAsPlayed;
334 // This array tracks the notes as ordered by the Pattern note mode
335 ResizeableArray notesByPattern;
336
337protected:
338 void rearrangePatterntArpNotes(ArpeggiatorSettings* settings);
339 void switchNoteOn(ArpeggiatorSettings* settings, ArpReturnInstruction* instruction, bool isRatchet) override;
340};
341
342class ArpeggiatorForKit : public Arpeggiator {
343public:
344 ArpeggiatorForKit();
345 ArpType getArpType() override { return ArpType::KIT; }
346 void removeDrumIndex(ArpeggiatorSettings* arpSettings, int32_t drumIndex);
347};
Definition arpeggiator.h:165
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:161
Definition arpeggiator.h:145