Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
sound.h
1/*
2 * Copyright © 2014-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/mod_controllable/mod_controllable_audio.h"
22#include "model/sample/sample_recorder.h"
23#include "model/voiced.h"
24#include "modulation/arpeggiator.h"
25#include "modulation/knob.h"
26#include "modulation/lfo.h"
27#include "modulation/params/param.h"
28#include "modulation/params/param_manager.h"
29#include "modulation/params/param_set.h"
30#include "modulation/patch/patcher.h"
31#include "modulation/sidechain/sidechain.h"
32#include "processing/engines/audio_engine.h"
33#include "processing/source.h"
34#include "util/misc.h"
35#include <bitset>
36#include <memory>
37
38struct CableGroup;
39class StereoSample;
40class Voice;
41class Kit;
43class TimelineCounter;
44class Clip;
49
50#define PARAM_LPF_OFF (-1)
51
52struct ParamLPF {
53 int32_t p; // PARAM_LPF_OFF means none
54 int32_t currentValue;
55};
56
57#define NUM_MOD_SOURCE_SELECTION_BUTTONS 2
58
59/*
60 * Sound can be either an Instrument or a Drum, in the form of SoundInstrument or SoundDrum respectively.
61 * These classes are implemented using “multiple inheritance”, which is sacrilegious to many C++ programmers.
62 * I (Rohan) consider it to be a more or less appropriate solution in this case and a few others in the Deluge codebase
63 * where it’s used. It’s a little while though since I’ve sat and thought about what the alternatives could be and
64 * whether anything else would be appropriate.
65 *
66 * Anyway, Sound (which may be named a bit too broadly) basically means a synth or sample, or any combination of the
67 * two. And, to reiterate the above, it can exist as a “synth” as the melodic Output of one entire Clip(s), or as just a
68 * Drum - one of the many items in a Kit, normally associated with a row of notes.
69 */
70
71class Sound : public ModControllableAudio, public virtual Voiced {
72public:
73 using ActiveVoice = AudioEngine::VoicePool::pointer_type;
74
75 Sound();
76 ~Sound() override { std::erase(AudioEngine::sounds, this); }
77
78 Patcher patcher;
79
80 ParamLPF paramLPF{};
81
82 Source sources[kNumSources];
83
84 // This is for the *global* params only, and begins with FIRST_GLOBAL_PARAM, so subtract that from your p value
85 // before accessing this array!
86 std::array<int32_t, deluge::modulation::params::kNumParams - deluge::modulation::params::FIRST_GLOBAL>
87 paramFinalValues{};
88 std::array<int32_t, util::to_underlying(kFirstLocalSource)> globalSourceValues{};
89
90 uint32_t sourcesChanged{}; // Applies from first source up to FIRST_UNCHANGEABLE_SOURCE
91
92 LFO globalLFO1;
93 LFO globalLFO3;
94 LFOConfig lfoConfig[LFO_COUNT];
95
96 bool invertReversed{}; // Used by the arpeggiator to invert the reverse flag just for the current voice
97
98 // December 3, 2024
99 // @todo
100 // Commit 6534979986d465a0acf01018e066e1d7ca1d170e
101 // From PR #2004 (LFO: cleanups in preparation for LFO2 sync support)
102 // (https://github.com/SynthstromAudible/DelugeFirmware/pull/2004)
103 // Removed four uint8_t lfo variables from this section and replaced them with the LFOConfig
104 // definition above. This unknowingly introduced a "release" bug which changed the sound of the
105 // Deluge synth engine compared to 1.1 as reported in issue #2660:
106 // (https://github.com/SynthstromAudible/DelugeFirmware/issues/2660)
107 // As a solution modKnobs is aligned to 8 bytes. I don't know why this fixes the problem but it seems to work even
108 // with other changes to the class. We think the issue relates to the use of "offsetof" in the
109 // param and patcher system (related to the paramFinalValues / globalSourceValues definitions above)
110
111 alignas(8) ModKnob modKnobs[kNumModButtons][kNumPhysicalModKnobs];
112
113 int32_t sideChainSendLevel = 0;
114
115 PolyphonyMode polyphonic = PolyphonyMode::POLY;
116 uint8_t maxVoiceCount = 8;
117
118 int16_t transpose = 0;
119
120 uint8_t numUnison = 1;
121 int8_t unisonDetune = 8;
122 uint8_t unisonStereoSpread = 0;
123
124 // For sending MIDI notes for SoundDrums
125 uint8_t outputMidiChannel = MIDI_CHANNEL_NONE;
126 uint8_t outputMidiNoteForDrum = MIDI_NOTE_NONE;
127
128 int16_t modulatorTranspose[kNumModulators] = {0, -12};
129 int8_t modulatorCents[kNumModulators] = {0, 0};
130
131 PhaseIncrementFineTuner modulatorTransposers[kNumModulators];
132
133 PhaseIncrementFineTuner unisonDetuners[kMaxNumVoicesUnison];
134 int32_t unisonPan[kMaxNumVoicesUnison]{};
135
136 SynthMode synthMode = SynthMode::SUBTRACTIVE;
137 bool modulator1ToModulator0 = false;
138
139 int32_t volumeNeutralValueForUnison{0};
140
141 int32_t lastNoteCode = std::numeric_limits<int32_t>::min();
142
143 bool oscillatorSync = false;
144
145 VoicePriority voicePriority = VoicePriority::MEDIUM;
146
147 bool skippingRendering = true;
148
149 std::bitset<kNumExpressionDimensions> expressionSourcesChangedAtSynthLevel{0};
150
151 // I really didn't want to store these here, since they're stored in the ParamManager, but.... complications! Always
152 // 0 for Drums - that was part of the problem - a Drum's main ParamManager's expression data has been sent to the
153 // "polyphonic" bit, and we don't want it to get referred to twice. These get manually refreshed in setActiveClip().
154 std::array<int32_t, kNumExpressionDimensions> monophonicExpressionValues{};
155
156 std::array<uint32_t, kNumSources> oscRetriggerPhase{}; // 4294967295 means "off"
157 std::array<uint32_t, kNumModulators> modulatorRetriggerPhase{};
158
159 uint32_t timeStartedSkippingRenderingModFX{0};
160 uint32_t timeStartedSkippingRenderingLFO{0};
161 uint32_t timeStartedSkippingRenderingArp{0};
162 uint32_t startSkippingRenderingAtTime = 0; // Valid when not 0. Allows a wait-time before render skipping starts,
163 // for if mod fx are on
164
165 virtual ArpeggiatorSettings* getArpSettings(InstrumentClip* clip = nullptr) = 0;
166 virtual void setSkippingRendering(bool newSkipping);
167
168 ModFXType getModFXType() override;
169 bool setModFXType(ModFXType newType) final;
170
171 void patchedParamPresetValueChanged(uint8_t p, ModelStackWithSoundFlags* modelStack, int32_t oldValue,
172 int32_t newValue);
173 void render(ModelStackWithThreeMainThings* modelStack, std::span<StereoSample> output, int32_t* reverbBuffer,
174 int32_t sideChainHitPending, int32_t reverbAmountAdjust = 134217728,
175 bool shouldLimitDelayFeedback = false, int32_t pitchAdjust = kMaxSampleValue,
176 SampleRecorder* recorder = nullptr);
177
178 void ensureInaccessibleParamPresetValuesWithoutKnobsAreZero(Song* song) final; // Song may be NULL
179 void ensureInaccessibleParamPresetValuesWithoutKnobsAreZero(ModelStackWithThreeMainThings* modelStack);
180 void ensureInaccessibleParamPresetValuesWithoutKnobsAreZeroWithMinimalDetails(ParamManager* paramManager);
181 void ensureParamPresetValueWithoutKnobIsZero(ModelStackWithAutoParam* modelStack);
182 void ensureParamPresetValueWithoutKnobIsZeroWithMinimalDetails(ParamManager* paramManager, int32_t p);
183
184 PatchCableAcceptance maySourcePatchToParam(PatchSource s, uint8_t p, ParamManager* paramManager);
185
186 void resyncGlobalLFOs();
187
188 int8_t getKnobPos(uint8_t p, ParamManagerForTimeline* paramManager, uint32_t timePos, TimelineCounter* counter);
189 int32_t getKnobPosBig(int32_t p, ParamManagerForTimeline* paramManager, uint32_t timePos, TimelineCounter* counter);
190 bool learnKnob(MIDICable* cable, ParamDescriptor paramDescriptor, uint8_t whichKnob, uint8_t modKnobMode,
191 uint8_t midiChannel, Song* song) final;
192
193 bool hasFilters();
194
195 void sampleZoneChanged(MarkerType markerType, int32_t s, ModelStackWithSoundFlags* modelStack);
196 void setNumUnison(int32_t newNum, ModelStackWithSoundFlags* modelStack);
197 void setUnisonDetune(int32_t newAmount, ModelStackWithSoundFlags* modelStack);
198 void setUnisonStereoSpread(int32_t newAmount);
199 void setModulatorTranspose(int32_t m, int32_t value, ModelStackWithSoundFlags* modelStack);
200 void setModulatorCents(int32_t m, int32_t value, ModelStackWithSoundFlags* modelStack);
201 Error readFromFile(Deserializer& reader, ModelStackWithModControllable* modelStack, int32_t readAutomationUpToPos,
202 ArpeggiatorSettings* arpSettings);
203 void writeToFile(Serializer& writer, bool savingSong, ParamManager* paramManager, ArpeggiatorSettings* arpSettings,
204 const char* pathAttribute = NULL);
205
206 void voiceUnassigned(ModelStackWithSoundFlags* modelStack);
207 bool isSourceActiveCurrently(int32_t s, ParamManagerForTimeline* paramManager);
208 bool isSourceActiveEverDisregardingMissingSample(int32_t s, ParamManager* paramManager);
209 bool isSourceActiveEver(int32_t s, ParamManager* paramManager);
210 bool isNoiseActiveEver(ParamManagerForTimeline* paramManager);
211 void noteOn(ModelStackWithThreeMainThings* modelStack, ArpeggiatorBase* arpeggiator, int32_t noteCode,
212 int16_t const* mpeValues, uint32_t sampleSyncLength = 0, int32_t ticksLate = 0,
213 uint32_t samplesLate = 0, int32_t velocity = 64, int32_t fromMIDIChannel = 16);
214 void noteOff(ModelStackWithThreeMainThings* modelStack, ArpeggiatorBase* arpeggiator, int32_t noteCode);
215 void allNotesOff(ModelStackWithThreeMainThings* modelStack, ArpeggiatorBase* arpeggiator);
216
217 void noteOffPostArpeggiator(ModelStackWithSoundFlags* modelStack, int32_t noteCode = -32768);
218 void noteOnPostArpeggiator(ModelStackWithSoundFlags* modelStack, int32_t newNoteCodeBeforeArpeggiation,
219 int32_t newNoteCodeAfterArpeggiation, int32_t velocity, int16_t const* mpeValues,
220 uint32_t sampleSyncLength, int32_t ticksLate, uint32_t samplesLate,
221 int32_t fromMIDIChannel = 16);
222 void polyphonicExpressionEventOnChannelOrNote(int32_t newValue, int32_t expressionDimension,
223 int32_t channelOrNoteNumber,
224 MIDICharacteristic whichCharacteristic) override;
225
226 int16_t getMaxOscTranspose(InstrumentClip* clip);
227 int16_t getMinOscTranspose();
228 void setSynthMode(SynthMode value, Song* song);
229 [[nodiscard]] SynthMode getSynthMode() const { return synthMode; }
230
231 virtual bool isDrum() { return false; }
232 void setupAsSample(ParamManagerForTimeline* paramManager);
233 void recalculateAllVoicePhaseIncrements(ModelStackWithSoundFlags* modelStack);
234 Error loadAllAudioFiles(bool mayActuallyReadFiles);
235 bool envelopeHasSustainCurrently(int32_t e, ParamManagerForTimeline* paramManager);
236 bool envelopeHasSustainEver(int32_t e, ParamManagerForTimeline* paramManager);
237 bool renderingOscillatorSyncCurrently(ParamManagerForTimeline* paramManager);
238 bool renderingOscillatorSyncEver(ParamManager* paramManager);
239 void setupAsBlankSynth(ParamManager* paramManager, bool is_dx = false);
240 void setupAsDefaultSynth(ParamManager* paramManager);
241 void modButtonAction(uint8_t whichModButton, bool on, ParamManagerForTimeline* paramManager) final;
242 bool modEncoderButtonAction(uint8_t whichModEncoder, bool on, ModelStackWithThreeMainThings* modelStack) final;
243 static void writeParamsToFile(Serializer& writer, ParamManager* paramManager, bool writeAutomation);
244 static void readParamsFromFile(Deserializer& reader, ParamManagerForTimeline* paramManager,
245 int32_t readAutomationUpToPos);
246 static bool readParamTagFromFile(Deserializer& reader, char const* tagName, ParamManagerForTimeline* paramManager,
247 int32_t readAutomationUpToPos);
248 static void initParams(ParamManager* paramManager);
249 static Error createParamManagerForLoading(ParamManagerForTimeline* paramManager);
250 int32_t hasAnyTimeStretchSyncing(ParamManagerForTimeline* paramManager, bool getSampleLength = false,
251 int32_t note = 0);
252 int32_t hasCutOrLoopModeSamples(ParamManagerForTimeline* paramManager, int32_t note, bool* anyLooping = nullptr);
253 bool hasCutModeSamples(ParamManagerForTimeline* paramManager);
254 bool allowsVeryLateNoteStart(InstrumentClip* clip, ParamManagerForTimeline* paramManager);
255 void fastReleaseAllVoices(ModelStackWithSoundFlags* modelStack);
256 void recalculatePatchingToParam(uint8_t p, ParamManagerForTimeline* paramManager);
257 void doneReadingFromFile();
258 virtual void setupPatchingForAllParamManagers(Song* song) {}
259 void compensateVolumeForResonance(ModelStackWithThreeMainThings* modelStack);
260 // void channelAftertouchReceivedFromInputMIDIChannel(int32_t newValue);
261 ModelStackWithAutoParam* getParamFromModEncoder(int32_t whichModEncoder, ModelStackWithThreeMainThings* modelStack,
262 bool allowCreation = true) final;
263 void reassessRenderSkippingStatus(ModelStackWithSoundFlags* modelStack, bool shouldJustCutModFX = false);
264 void getThingWithMostReverb(Sound** soundWithMostReverb, ParamManager** paramManagerWithMostReverb,
265 GlobalEffectableForClip** globalEffectableWithMostReverb,
266 int32_t* highestReverbAmountFound, ParamManagerForTimeline* paramManager);
267 virtual bool readTagFromFile(Deserializer& reader, char const* tagName) = 0;
268 void detachSourcesFromAudioFiles();
269
270 // Yup, inlining this helped a tiny bit.
271 [[gnu::always_inline]] int32_t getSmoothedPatchedParamValue(int32_t p, ParamManager& paramManager) const {
272 if (paramLPF.p == p) {
273 return paramLPF.currentValue;
274 }
275 return paramManager.getPatchedParamSet()->getValue(p);
276 }
277
278 void notifyValueChangeViaLPF(int32_t p, bool shouldDoParamLPF, ModelStackWithThreeMainThings const* modelStack,
279 int32_t oldValue, int32_t newValue, bool fromAutomation);
280 void deleteMultiRange(int32_t s, int32_t r);
281 void wontBeRenderedForAWhile() override;
283 virtual ArpeggiatorBase* getArp() = 0;
284 void possiblySetupDefaultExpressionPatching(ParamManager* paramManager);
285
286 [[gnu::always_inline]] void saturate(int32_t* data, uint32_t* workingValue) {
287 // Clipping
288 if (clippingAmount != 0u) {
289 int32_t shiftAmount = (clippingAmount >= 2) ? (clippingAmount - 2) : 0;
290 //*data = getTanHUnknown(*data, 5 + clippingAmount) << (shiftAmount);
291 *data = getTanHAntialiased(*data, workingValue, 5 + clippingAmount) << (shiftAmount);
292 }
293 }
294 uint32_t getSyncedLFOPhaseIncrement(const LFOConfig& config);
295
297 [[nodiscard]] bool hasActiveVoices() const override { return !voices_.empty(); }
298
300 [[nodiscard]] size_t numActiveVoices() const { return voices_.size(); }
301
303 void killAllVoices() override;
304
307 [[nodiscard]] const ActiveVoice& getLowestPriorityVoice() const;
308
310 [[nodiscard]] const deluge::fast_vector<ActiveVoice>& voices() const { return voices_; }
311
316 void freeActiveVoice(const ActiveVoice& voice, ModelStackWithSoundFlags* modelStack = nullptr, bool erase = true);
317
318 // Voiced overrides
319 bool anyNoteIsOn() override;
320 bool allowNoteTails(ModelStackWithSoundFlags* modelStack, bool disregardSampleLoop = false) override;
321 void prepareForHibernation() override;
322
323private:
324 uint32_t getGlobalLFOPhaseIncrement(LFO_ID lfoId, deluge::modulation::params::Global param);
325 void recalculateModulatorTransposer(uint8_t m, ModelStackWithSoundFlags* modelStack);
326 void setupUnisonDetuners(ModelStackWithSoundFlags* modelStack);
327 void setupUnisonStereoSpread();
328 void calculateEffectiveVolume();
329 void ensureKnobReferencesCorrectVolume(Knob& knob);
330 Error readTagFromFileOrError(Deserializer& reader, char const* tagName, ParamManagerForTimeline* paramManager,
331 int32_t readAutomationUpToPos, ArpeggiatorSettings* arpSettings, Song* song);
332
333 void writeSourceToFile(Serializer& writer, int32_t s, char const* tagName);
334 Error readSourceFromFile(Deserializer& reader, int32_t s, ParamManagerForTimeline* paramManager,
335 int32_t readAutomationUpToPos);
336 void stopSkippingRendering(ArpeggiatorSettings* arpSettings);
337 void startSkippingRendering(ModelStackWithSoundFlags* modelStack);
338 void getArpBackInTimeAfterSkippingRendering(ArpeggiatorSettings* arpSettings);
339 void doParamLPF(int32_t numSamples, ModelStackWithSoundFlags* modelStack);
340 void stopParamLPF(ModelStackWithSoundFlags* modelStack);
341 bool renderingVoicesInStereo(ModelStackWithSoundFlags* modelStack);
342 void setupDefaultExpressionPatching(ParamManager* paramManager);
343 void pushSwitchActionOnEncoderForParam(int32_t p, bool on, ModelStackWithThreeMainThings* modelStack);
344 ModelStackWithAutoParam* getParamFromModEncoderDeeper(int32_t whichModEncoder,
346 bool allowCreation = true);
347
349 // O(n) lookup is fine when most of the time we're iterating over all voices anyways.
350 // Went with a vector instead of a list so that we don't need to always allocate if
351 // we're constantly cycling between a minimum and maximum number of voices.
352 deluge::fast_vector<ActiveVoice> voices_;
353
357 const ActiveVoice& acquireVoice() noexcept(false); // throws an exception if no memory is available
358
360 void checkVoiceExists(const ActiveVoice& voice, const char* error) const;
361
364 const ActiveVoice& stealOneActiveVoice();
365
368
371};
Definition arpeggiator.h:188
Definition arpeggiator.h:46
Definition clip.h:46
Definition storage_manager.h:185
Definition global_effectable_for_clip.h:33
Definition instrument_clip.h:48
Definition kit.h:34
Definition knob.h:24
Definition lfo.h:26
Definition lfo.h:35
A MIDI cable connection. Stores all state specific to a given cable and its contained ports and chann...
Definition midi_device.h:94
Definition knob.h:34
Definition knob.h:46
Definition model_stack.h:269
Definition model_stack.h:225
Definition model_stack.h:287
Definition model_stack.h:231
Definition param_descriptor.h:27
Definition param_manager.h:174
Definition param_manager.h:45
Definition patcher.h:38
Definition phase_increment_fine_tuner.h:21
Definition sample_recorder.h:49
Definition storage_manager.h:119
Definition song.h:104
bool hasActiveVoices() const override
Does this sound have any active voices?
Definition sound.h:297
const ActiveVoice & acquireVoice() noexcept(false)
Acquire a voice for use by a note Internally this will either acquire a new voice or steal an existin...
Definition sound.cpp:4796
void terminateOneActiveVoice()
Force a voice to release very quickly - will be almost instant but click-free.
Definition sound.cpp:4855
ModelStackWithAutoParam * getParamFromMIDIKnob(MIDIKnob &knob, ModelStackWithThreeMainThings *modelStack) final
Check that autoParam isn't NULL, after calling this.
Definition sound.cpp:4760
void freeActiveVoice(const ActiveVoice &voice, ModelStackWithSoundFlags *modelStack=nullptr, bool erase=true)
Releases a given voice from the Sound.
Definition sound.cpp:4819
Error readSourceFromFile(Deserializer &reader, int32_t s, ParamManagerForTimeline *paramManager, int32_t readAutomationUpToPos)
Definition sound.cpp:3250
bool learnKnob(MIDICable *cable, ParamDescriptor paramDescriptor, uint8_t whichKnob, uint8_t modKnobMode, uint8_t midiChannel, Song *song) final
Definition sound.cpp:2751
const deluge::fast_vector< ActiveVoice > & voices() const
Get the voices for this sound.
Definition sound.h:310
void killAllVoices() override
Immediately ends all active voices.
Definition sound.cpp:4826
void forceReleaseOneActiveVoice()
Force a voice to release, or speed up its release if it's already releasing.
Definition sound.cpp:4882
const ActiveVoice & getLowestPriorityVoice() const
Get the voice with the lowest priority.
Definition sound.cpp:4836
const ActiveVoice & stealOneActiveVoice()
Steals a currently-in-use voice for use by another note.
Definition sound.cpp:4840
void checkVoiceExists(const ActiveVoice &voice, const char *error) const
Check if a voice exists in the list of active voices.
Definition sound.cpp:4908
deluge::fast_vector< ActiveVoice > voices_
the list of active voices for this sound
Definition sound.h:352
size_t numActiveVoices() const
Get the number of active voices.
Definition sound.h:300
Definition source.h:31
Definition timeline_counter.h:28
Definition voice.h:35
std::unique_ptr< Voice, decltype(&recycle)> pointer_type
Definition object_pool.h:89
Global
Definition param.h:131
constexpr ParamType kNumParams
None is the last global param, 0 indexed so it's also the number of patched params.
Definition param.h:251
Definition patch_cable_set.h:29
Definition sound.h:52
Definition stereo_sample.h:25
Definition voiced.h:21