71class Sound :
public ModControllableAudio,
public virtual Voiced {
76 ~Sound()
override { std::erase(AudioEngine::sounds,
this); }
82 Source sources[kNumSources];
88 std::array<int32_t, util::to_underlying(kFirstLocalSource)> globalSourceValues{};
90 uint32_t sourcesChanged{};
96 bool invertReversed{};
111 alignas(8)
ModKnob modKnobs[kNumModButtons][kNumPhysicalModKnobs];
113 int32_t sideChainSendLevel = 0;
115 PolyphonyMode polyphonic = PolyphonyMode::POLY;
116 uint8_t maxVoiceCount = 8;
118 int16_t transpose = 0;
120 uint8_t numUnison = 1;
121 int8_t unisonDetune = 8;
122 uint8_t unisonStereoSpread = 0;
125 uint8_t outputMidiChannel = MIDI_CHANNEL_NONE;
126 uint8_t outputMidiNoteForDrum = MIDI_NOTE_NONE;
128 int16_t modulatorTranspose[kNumModulators] = {0, -12};
129 int8_t modulatorCents[kNumModulators] = {0, 0};
134 int32_t unisonPan[kMaxNumVoicesUnison]{};
136 SynthMode synthMode = SynthMode::SUBTRACTIVE;
137 bool modulator1ToModulator0 =
false;
139 int32_t volumeNeutralValueForUnison{0};
141 int32_t lastNoteCode = std::numeric_limits<int32_t>::min();
143 bool oscillatorSync =
false;
145 VoicePriority voicePriority = VoicePriority::MEDIUM;
147 bool skippingRendering =
true;
149 std::bitset<kNumExpressionDimensions> expressionSourcesChangedAtSynthLevel{0};
154 std::array<int32_t, kNumExpressionDimensions> monophonicExpressionValues{};
156 std::array<uint32_t, kNumSources> oscRetriggerPhase{};
157 std::array<uint32_t, kNumModulators> modulatorRetriggerPhase{};
159 uint32_t timeStartedSkippingRenderingModFX{0};
160 uint32_t timeStartedSkippingRenderingLFO{0};
161 uint32_t timeStartedSkippingRenderingArp{0};
162 uint32_t startSkippingRenderingAtTime = 0;
166 virtual void setSkippingRendering(
bool newSkipping);
168 ModFXType getModFXType()
override;
169 bool setModFXType(ModFXType newType)
final;
174 int32_t sideChainHitPending, int32_t reverbAmountAdjust = 134217728,
175 bool shouldLimitDelayFeedback =
false, int32_t pitchAdjust = kMaxSampleValue,
178 void ensureInaccessibleParamPresetValuesWithoutKnobsAreZero(
Song* song)
final;
180 void ensureInaccessibleParamPresetValuesWithoutKnobsAreZeroWithMinimalDetails(
ParamManager* paramManager);
182 void ensureParamPresetValueWithoutKnobIsZeroWithMinimalDetails(
ParamManager* paramManager, int32_t p);
184 PatchCableAcceptance maySourcePatchToParam(PatchSource s, uint8_t p,
ParamManager* paramManager);
186 void resyncGlobalLFOs();
191 uint8_t midiChannel,
Song* song)
final;
198 void setUnisonStereoSpread(int32_t newAmount);
204 const char* pathAttribute = NULL);
208 bool isSourceActiveEverDisregardingMissingSample(int32_t s,
ParamManager* paramManager);
209 bool isSourceActiveEver(int32_t s,
ParamManager* paramManager);
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);
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;
227 int16_t getMinOscTranspose();
228 void setSynthMode(SynthMode value,
Song* song);
229 [[nodiscard]] SynthMode getSynthMode()
const {
return synthMode; }
231 virtual bool isDrum() {
return false; }
234 Error loadAllAudioFiles(
bool mayActuallyReadFiles);
238 bool renderingOscillatorSyncEver(
ParamManager* paramManager);
239 void setupAsBlankSynth(
ParamManager* paramManager,
bool is_dx =
false);
245 int32_t readAutomationUpToPos);
247 int32_t readAutomationUpToPos);
252 int32_t hasCutOrLoopModeSamples(
ParamManagerForTimeline* paramManager, int32_t note,
bool* anyLooping =
nullptr);
257 void doneReadingFromFile();
258 virtual void setupPatchingForAllParamManagers(
Song* song) {}
262 bool allowCreation =
true)
final;
264 void getThingWithMostReverb(Sound** soundWithMostReverb,
ParamManager** paramManagerWithMostReverb,
267 virtual bool readTagFromFile(
Deserializer& reader,
char const* tagName) = 0;
268 void detachSourcesFromAudioFiles();
271 [[gnu::always_inline]] int32_t getSmoothedPatchedParamValue(int32_t p,
ParamManager& paramManager)
const {
272 if (paramLPF.p == p) {
273 return paramLPF.currentValue;
275 return paramManager.getPatchedParamSet()->getValue(p);
279 int32_t oldValue, int32_t newValue,
bool fromAutomation);
280 void deleteMultiRange(int32_t s, int32_t r);
281 void wontBeRenderedForAWhile()
override;
284 void possiblySetupDefaultExpressionPatching(
ParamManager* paramManager);
286 [[gnu::always_inline]]
void saturate(int32_t* data, uint32_t* workingValue) {
288 if (clippingAmount != 0u) {
289 int32_t shiftAmount = (clippingAmount >= 2) ? (clippingAmount - 2) : 0;
291 *data = getTanHAntialiased(*data, workingValue, 5 + clippingAmount) << (shiftAmount);
294 uint32_t getSyncedLFOPhaseIncrement(
const LFOConfig& config);
310 [[nodiscard]]
const deluge::fast_vector<ActiveVoice>&
voices()
const {
return voices_; }
319 bool anyNoteIsOn()
override;
321 void prepareForHibernation()
override;
327 void setupUnisonStereoSpread();
328 void calculateEffectiveVolume();
329 void ensureKnobReferencesCorrectVolume(
Knob& knob);
333 void writeSourceToFile(
Serializer& writer, int32_t s,
char const* tagName);
335 int32_t readAutomationUpToPos);
342 void setupDefaultExpressionPatching(
ParamManager* paramManager);
346 bool allowCreation =
true);