48class ArpeggiatorSettings {
50 ArpeggiatorSettings();
54 void cloneFrom(ArpeggiatorSettings
const* other);
56 bool readCommonTagsFromFile(
Deserializer& reader,
char const* tagName,
Song* songToConvertSyncLevel);
58 bool readNonAudioTagsFromFile(
Deserializer& reader,
char const* tagName);
60 void writeCommonParamsToFile(
Serializer& writer,
Song* songToConvertSyncLevel);
62 void writeNonAudioParamsToFile(
Serializer& writer);
64 void generateNewNotePattern();
66 void updatePresetFromCurrentSettings();
68 void updateSettingsFromCurrentPreset();
70 uint32_t getPhaseIncrement(int32_t arpRate);
73 ArpPreset preset{ArpPreset::OFF};
74 ArpMode mode{ArpMode::OFF};
76 bool includeInKitArp{
true};
79 ArpOctaveMode octaveMode{ArpOctaveMode::UP};
80 ArpNoteMode noteMode{ArpNoteMode::UP};
83 uint8_t numOctaves{2};
86 uint8_t numStepRepeats{1};
89 uint8_t chordTypeIndex{0};
96 bool randomizerLock{
false};
99 ArpMpeModSource mpeVelocity{ArpMpeModSource::OFF};
102 uint32_t lastLockedNoteProbabilityParameterValue{0};
103 uint32_t lastLockedBassProbabilityParameterValue{0};
104 uint32_t lastLockedSwapProbabilityParameterValue{0};
105 uint32_t lastLockedGlideProbabilityParameterValue{0};
106 uint32_t lastLockedReverseProbabilityParameterValue{0};
107 uint32_t lastLockedChordProbabilityParameterValue{0};
108 uint32_t lastLockedRatchetProbabilityParameterValue{0};
109 uint32_t lastLockedSpreadVelocityParameterValue{0};
110 uint32_t lastLockedSpreadGateParameterValue{0};
111 uint32_t lastLockedSpreadOctaveParameterValue{0};
114 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedNoteProbabilityValues;
115 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedBassProbabilityValues;
116 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSwapProbabilityValues;
117 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedGlideProbabilityValues;
118 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedReverseProbabilityValues;
119 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedChordProbabilityValues;
120 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedRatchetProbabilityValues;
121 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadVelocityValues;
122 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadGateValues;
123 std::array<int8_t, RANDOMIZER_LOCK_MAX_SAVED_VALUES> lockedSpreadOctaveValues;
126 std::array<int8_t, PATTERN_MAX_BUFFER_SIZE> notePattern;
129 bool flagForceArpRestart{
false};
135 uint32_t sequenceLength{0};
136 uint32_t chordPolyphony{0};
137 uint32_t ratchetAmount{0};
138 uint32_t noteProbability{4294967295u};
139 uint32_t bassProbability{0};
140 uint32_t swapProbability{0};
141 uint32_t glideProbability{0};
142 uint32_t reverseProbability{0};
143 uint32_t chordProbability{0};
144 uint32_t ratchetProbability{0};
145 uint32_t spreadVelocity{0};
146 uint32_t spreadGate{0};
147 uint32_t spreadOctave{0};
157 outputMemberChannel.fill(MIDI_CHANNEL_NONE);
158 noteCodeOnPostArp.fill(ARP_NOTE_NONE);
159 noteStatus.fill(ArpNoteStatus::OFF);
162 return std::ranges::any_of(noteStatus, [](ArpNoteStatus status) {
return status == ArpNoteStatus::PENDING; });
167 return noteStatus[0] == ArpNoteStatus::PENDING && noteCodeOnPostArp[0] != ARP_NOTE_NONE;
169 void resetPostArpArrays() {
170 outputMemberChannel.fill(MIDI_CHANNEL_NONE);
171 noteCodeOnPostArp.fill(ARP_NOTE_NONE);
172 noteStatus.fill(ArpNoteStatus::OFF);
174 int16_t inputCharacteristics[2]{};
176 int16_t mpeValues[kNumExpressionDimensions]{};
178 uint8_t baseVelocity{0};
180 uint32_t sampleSyncLength{0};
183 std::array<ArpNoteStatus, ARP_MAX_INSTRUCTION_NOTES> noteStatus{};
184 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMemberChannel{};
185 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeOnPostArp{};
192class ArpReturnInstruction {
194 ArpReturnInstruction() {
195 sampleSyncLengthOn = 0;
196 invertReversed =
false;
198 outputMIDIChannelOff.fill(MIDI_CHANNEL_NONE);
199 noteCodeOffPostArp.fill(ARP_NOTE_NONE);
200 glideOutputMIDIChannelOff.fill(MIDI_CHANNEL_NONE);
201 glideNoteCodeOffPostArp.fill(ARP_NOTE_NONE);
206 uint32_t sampleSyncLengthOn;
216 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMIDIChannelOff;
217 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> noteCodeOffPostArp;
218 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> glideOutputMIDIChannelOff;
219 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> glideNoteCodeOffPostArp;
222class ArpeggiatorBase {
224 virtual ~ArpeggiatorBase() =
default;
226 glideNoteCodeCurrentlyOnPostArp.fill(ARP_NOTE_NONE);
227 outputMIDIChannelForGlideNoteCurrentlyOnPostArp.fill(0);
240 uint32_t gateThreshold, uint32_t phaseIncrement);
242 bool currentlyPlayingReversed);
244 virtual bool hasAnyInputNotesActive() = 0;
245 virtual void reset() = 0;
246 virtual ArpType getArpType() = 0;
250 return (settings ==
nullptr) || settings->mode == ArpMode::OFF;
254 std::array<int16_t, ARP_MAX_INSTRUCTION_NOTES> glideNoteCodeCurrentlyOnPostArp;
255 std::array<uint8_t, ARP_MAX_INSTRUCTION_NOTES> outputMIDIChannelForGlideNoteCurrentlyOnPostArp;
256 uint32_t gatePos = 0;
257 uint8_t lastVelocity = 0;
265 uint32_t maxSequenceLength, uint32_t rhythm,
bool* shouldCarryOnRhythmNote,
266 bool* shouldPlayNote,
bool* shouldPlayBassNote,
bool* shouldPlayRandomStep,
267 bool* shouldPlayReverseNote,
bool* shouldPlayChordNote);
268 void increasePatternIndexes(uint8_t numStepRepeats);
269 void increaseSequenceIndexes(uint32_t maxSequenceLength, uint32_t rhythm);
271 bool evaluateRhythm(uint32_t rhythm,
bool isRatchet);
272 bool evaluateNoteProbability(
bool isRatchet);
273 bool evaluateBassProbability(
bool isRatchet);
274 bool evaluateSwapProbability(
bool isRatchet);
275 bool evaluateReverseProbability(
bool isRatchet);
276 bool evaluateChordProbability(
bool isRatchet);
277 uint32_t calculateSpreadVelocity(uint8_t velocity, int32_t spreadVelocityForCurrentStep);
281 bool getRandomProbabilityResult(uint32_t value);
282 int8_t getRandomBipolarProbabilityAmount(uint32_t value);
283 int8_t getRandomWeighted2BitsAmount(uint32_t value);
285 bool gateCurrentlyActive =
false;
287 bool playedFirstArpeggiatedNoteYet =
false;
290 uint32_t notesPlayedFromSequence = 0;
291 uint32_t randomNotesPlayedFromOctave = 0;
294 int16_t whichNoteCurrentlyOnPostArp;
295 int8_t currentOctave = 0;
296 int8_t currentDirection = 1;
297 int8_t currentOctaveDirection = 1;
300 uint32_t notesPlayedFromRhythm = 0;
301 uint32_t lastNormalNotePlayedFromRhythm = 0;
304 uint32_t notesPlayedFromLockedRandomizer = 0;
307 bool lastNormalNotePlayedFromNoteProbability =
true;
310 bool lastNormalNotePlayedFromBassProbability =
false;
313 bool lastNormalNotePlayedFromSwapProbability =
false;
316 bool lastNormalNotePlayedFromReverseProbability =
false;
319 bool lastNormalNotePlayedFromChordProbability =
false;
322 int32_t stepRepeatIndex = 0;
325 uint32_t ratchetNotesIndex = 0;
326 uint32_t ratchetNotesMultiplier = 0;
327 uint32_t ratchetNotesCount = 0;
328 bool isRatcheting =
false;
331 bool glideOnNextNoteOff =
false;
334 bool isPlayNoteForCurrentStep =
true;
335 bool isPlayBassForCurrentStep =
false;
336 bool isPlayRandomStepForCurrentStep =
false;
337 bool isPlayReverseForCurrentStep =
false;
338 bool isPlayChordForCurrentStep =
false;
339 bool isPlayRatchetForCurrentStep =
false;
340 bool isPlayGlideForCurrentStep =
false;
341 int32_t spreadVelocityForCurrentStep = 0;
342 int32_t spreadGateForCurrentStep = 0;
343 int32_t spreadOctaveForCurrentStep = 0;
344 bool resetLockedRandomizerValuesNextTime =
false;