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