Vital
Loading...
Searching...
No Matches
synth_voice_handler.cpp
Go to the documentation of this file.
2
3#include "envelope.h"
4#include "envelope_module.h"
5#include "filters_module.h"
6#include "line_map.h"
7#include "operators.h"
8#include "portamento_slope.h"
9#include "random_lfo_module.h"
10#include "synth_constants.h"
11#include "lfo_module.h"
12#include "trigger_random.h"
13#include "value_switch.h"
15
16namespace vital {
17
25 VoiceHandler(0, kMaxPolyphony), producers_(nullptr), beats_per_second_(beats_per_second),
26 note_from_reference_(nullptr), midi_offset_output_(nullptr),
27 bent_midi_(nullptr), current_midi_note_(nullptr), amplitude_envelope_(nullptr), amplitude_(nullptr),
28 pitch_wheel_(nullptr), filters_module_(nullptr), lfos_(), envelopes_(), lfo_sources_(), random_(nullptr),
29 random_lfos_(), note_mapping_(nullptr), velocity_mapping_(nullptr), aftertouch_mapping_(nullptr),
30 slide_mapping_(nullptr), lift_mapping_(nullptr), mod_wheel_mapping_(nullptr),
31 pitch_wheel_mapping_(nullptr), stereo_(nullptr), note_percentage_(nullptr), last_active_voice_mask_(0) {
32 output_ = new Multiply();
33 registerOutput(output_->output());
34
35 direct_output_ = new Multiply();
36 registerOutput(direct_output_->output());
37
38 note_from_reference_ = new cr::Add();
39 midi_offset_output_ = registerControlRateOutput(note_from_reference_->output(), true);
40
41 enabled_modulation_processors_.ensureCapacity(kMaxModulationConnections);
42 }
43
51 createNoteArticulation();
52 createProducers();
53 createModulators();
54 createFilters(note_from_reference_->output());
55 createVoiceOutput();
56
57 Add* voice_sum = new Add();
58 voice_sum->plug(filters_module_, 0);
59 voice_sum->plug(producers_->output(ProducersModule::kRawOut), 1);
60 output_->plug(voice_sum, 0);
61 output_->plug(amplitude_, 1);
62 direct_output_->plug(producers_->output(ProducersModule::kDirectOut), 0);
63 direct_output_->plug(amplitude_, 1);
64
65 addProcessor(voice_sum);
66 addProcessor(output_);
67 addProcessor(direct_output_);
68
69 Output* macros[kNumMacros];
70 for (int i = 0; i < kNumMacros; ++i)
71 macros[i] = createMonoModControl("macro_control_" + std::to_string(i + 1));
72
73 setVoiceKiller(amplitude_->output());
74
75 for (int i = 0; i < vital::kMaxModulationConnections; ++i) {
76 ModulationConnectionProcessor* processor = modulation_bank_.atIndex(i)->modulation_processor.get();
77
79
80 std::string number = std::to_string(i + 1);
81 std::string amount_name = "modulation_" + number + "_amount";
82 Output* modulation_amount = createPolyModControl(amount_name);
83 processor->plug(modulation_amount, ModulationConnectionProcessor::kModulationAmount);
84 processor->initializeBaseValue(data_->controls[amount_name]);
85
86 Output* modulation_power = createPolyModControl("modulation_" + number + "_power");
87 processor->plug(modulation_power, ModulationConnectionProcessor::kModulationPower);
88
89 addProcessor(processor);
90 addSubmodule(processor);
91 processor->enable(false);
92 }
93
95 producers_->setFilter1On(filters_module_->getFilter1OnValue());
96 producers_->setFilter2On(filters_module_->getFilter2OnValue());
97 setupPolyModulationReadouts();
98
99 for (int i = 0; i < kNumMacros; ++i) {
100 std::string name = "macro_control_" + std::to_string(i + 1);
101 data_->mod_sources[name] = macros[i];
102 createStatusOutput(name, macros[i]);
103 }
104
105 for (int i = 0; i < kNumRandomLfos; ++i) {
106 std::string name = "random_" + std::to_string(i + 1);
107 data_->mod_sources[name] = random_lfos_[i]->output();
108 createStatusOutput(name, random_lfos_[i]->output());
109 }
110
111 data_->mod_sources["random"] = random_->output();
112 data_->mod_sources["stereo"] = stereo_->output();
113
114 createStatusOutput("random", random_->output());
115 createStatusOutput("stereo", stereo_->output());
116 createStatusOutput("sample_phase", producers_->samplePhaseOutput());
117 createStatusOutput("num_voices", &num_voices_);
118
119 std::string modulation_source_prefix = "modulation_source_";
120 std::string modulation_amount_prefix = "modulation_amount_";
121 for (int i = 0; i < vital::kMaxModulationConnections; ++i) {
122 ModulationConnectionProcessor* processor = modulation_bank_.atIndex(i)->modulation_processor.get();
123 std::string number = std::to_string(i + 1);
126 createStatusOutput(modulation_source_prefix + number, source_output);
127 createStatusOutput(modulation_amount_prefix + number, pre_scale_output);
128 }
129 }
130
135 for (int i = 0; i < vital::kMaxModulationConnections; ++i) {
136 ModulationConnectionProcessor* processor = modulation_bank_.atIndex(i)->modulation_processor.get();
137 removeProcessor(processor);
138 }
139 }
140
141 void SynthVoiceHandler::createProducers() {
142 producers_ = new ProducersModule();
143 producers_->plug(reset(), ProducersModule::kReset);
145 producers_->plug(bent_midi_, ProducersModule::kMidi);
148 addSubmodule(producers_);
149 addProcessor(producers_);
150 }
151
152 void SynthVoiceHandler::createModulators() {
153 for (int i = 0; i < kNumLfos; ++i) {
154 lfo_sources_[i].setLoop(false);
155 lfo_sources_[i].initTriangle();
156 std::string prefix = std::string("lfo_") + std::to_string(i + 1);
157 LfoModule* lfo = new LfoModule(prefix, &lfo_sources_[i], beats_per_second_);
158 addSubmodule(lfo);
159 addProcessor(lfo);
160 lfos_[i] = lfo;
162 lfo->plug(note_count(), LfoModule::kNoteCount);
163 lfo->plug(bent_midi_, LfoModule::kMidi);
164
165 data_->mod_sources[prefix] = lfo->output(LfoModule::kValue);
166 createStatusOutput(prefix, lfo->output(LfoModule::kValue));
167 createStatusOutput(prefix + "_phase", lfo->output(LfoModule::kOscPhase));
168 createStatusOutput(prefix + "_frequency", lfo->output(LfoModule::kOscFrequency));
169 }
170
171 for (int i = 0; i < kNumEnvelopes; ++i) {
172 std::string prefix = std::string("env_") + std::to_string(i + 1);
173 EnvelopeModule* envelope = new EnvelopeModule(prefix, i == 0);
174 envelope->plug(retrigger(), EnvelopeModule::kTrigger);
175 addSubmodule(envelope);
176 addProcessor(envelope);
177 envelopes_[i] = envelope;
178
179 data_->mod_sources[prefix] = envelope->output();
180 createStatusOutput(prefix, envelope->output(EnvelopeModule::kValue));
181 createStatusOutput(prefix + "_phase", envelope->output(EnvelopeModule::kPhase));
182 }
183
184 random_ = new TriggerRandom();
185 random_->plug(retrigger());
186 addProcessor(random_);
187
188 for (int i = 0; i < kNumRandomLfos; ++i) {
189 std::string name = "random_" + std::to_string(i + 1);
190 random_lfos_[i] = new RandomLfoModule(name, beats_per_second_);
191 random_lfos_[i]->plug(retrigger(), RandomLfoModule::kNoteTrigger);
192 random_lfos_[i]->plug(bent_midi_, RandomLfoModule::kMidi);
193 addSubmodule(random_lfos_[i]);
194 addProcessor(random_lfos_[i]);
195 }
196
197 stereo_ = new cr::Value(constants::kLeftOne);
198 addIdleMonoProcessor(stereo_);
199
200 data_->mod_sources["note"] = note_percentage_->output();
201 data_->mod_sources["note_in_octave"] = note_in_octave();
202 data_->mod_sources["aftertouch"] = aftertouch();
203 data_->mod_sources["velocity"] = velocity();
204 data_->mod_sources["slide"] = slide();
205 data_->mod_sources["lift"] = lift();
206 data_->mod_sources["mod_wheel"] = mod_wheel();
207 data_->mod_sources["pitch_wheel"] = pitch_wheel_percent();
208
209 createStatusOutput("note", note_percentage_->output());
210 createStatusOutput("note_in_octave", note_in_octave());
211 createStatusOutput("aftertouch" ,aftertouch());
212 createStatusOutput("velocity", velocity());
213 createStatusOutput("slide", slide());
214 createStatusOutput("lift", lift());
215 createStatusOutput("mod_wheel", mod_wheel());
216 createStatusOutput("pitch_wheel", pitch_wheel_percent());
217 }
218
219 void SynthVoiceHandler::createFilters(Output* keytrack) {
220 filters_module_ = new FiltersModule();
221 addSubmodule(filters_module_);
222 addProcessor(filters_module_);
223
226 filters_module_->plug(reset(), FiltersModule::kReset);
227 filters_module_->plug(keytrack, FiltersModule::kKeytrack);
228 filters_module_->plug(bent_midi_, FiltersModule::kMidi);
229 }
230
231 void SynthVoiceHandler::createNoteArticulation() {
232 Output* portamento = createPolyModControl("portamento_time");
233 Output* portamento_slope = createPolyModControl("portamento_slope");
234 Value* portamento_force = createBaseControl("portamento_force");
235 Value* portamento_scale = createBaseControl("portamento_scale");
236
237 current_midi_note_ = new PortamentoSlope();
238 current_midi_note_->plug(last_note(), PortamentoSlope::kSource);
239 current_midi_note_->plug(note(), PortamentoSlope::kTarget);
240 current_midi_note_->plug(portamento_force, PortamentoSlope::kPortamentoForce);
241 current_midi_note_->plug(portamento_scale, PortamentoSlope::kPortamentoScale);
242 current_midi_note_->plug(portamento, PortamentoSlope::kRunSeconds);
243 current_midi_note_->plug(portamento_slope, PortamentoSlope::kSlopePower);
244 current_midi_note_->plug(voice_event(), PortamentoSlope::kReset);
246 setVoiceMidi(current_midi_note_->output());
247 addProcessor(current_midi_note_);
248
249 Output* pitch_bend_range = createPolyModControl("pitch_bend_range");
250 Output* voice_tune = createPolyModControl("voice_tune");
251 Output* voice_transpose = createPolyModControl("voice_transpose");
252 cr::Multiply* pitch_bend = new cr::Multiply();
253 pitch_bend->plug(pitch_wheel(), 0);
254 pitch_bend->plug(pitch_bend_range, 1);
255 bent_midi_ = new cr::VariableAdd();
256 bent_midi_->plugNext(current_midi_note_);
257 bent_midi_->plugNext(pitch_bend);
258 bent_midi_->plugNext(local_pitch_bend());
259 bent_midi_->plugNext(voice_tune);
260 bent_midi_->plugNext(voice_transpose);
261
262 static const cr::Value max_midi_invert(1.0f / (kMidiSize - 1));
263 note_percentage_ = new cr::Multiply();
264 note_percentage_->plug(&max_midi_invert, 0);
265 note_percentage_->plug(bent_midi_, 1);
266 addProcessor(note_percentage_);
267
268 static const cr::Value reference_adjust(-kMidiTrackCenter);
269 note_from_reference_->plug(&reference_adjust, 0);
270 note_from_reference_->plug(bent_midi_, 1);
271 addProcessor(note_from_reference_);
272
273 addProcessor(pitch_bend);
274 addProcessor(bent_midi_);
275 }
276
277 void SynthVoiceHandler::createVoiceOutput() {
278 Output* velocity_track_amount = createPolyModControl("velocity_track");
279 cr::Interpolate* velocity_track_mult = new cr::Interpolate();
280 velocity_track_mult->plug(&constants::kValueOne, Interpolate::kFrom);
281 velocity_track_mult->plug(velocity(), Interpolate::kTo);
282 velocity_track_mult->plug(velocity_track_amount, Interpolate::kFractional);
283 addProcessor(velocity_track_mult);
284
285 Output* voice_amplitude = createPolyModControl("voice_amplitude");
286 cr::Multiply* amplitude = new cr::Multiply();
287 amplitude->plug(velocity_track_mult, 0);
288 amplitude->plug(voice_amplitude, 1);
289 addProcessor(amplitude);
290
291 amplitude_envelope_ = envelopes_[0];
292 amplitude_envelope_->setControlRate(false);
293
294 Processor* control_amplitude = new SmoothMultiply();
295 control_amplitude->plug(amplitude_envelope_->output(Envelope::kValue), SmoothMultiply::kAudioRate);
296 control_amplitude->plug(amplitude, SmoothMultiply::kControlRate);
297 control_amplitude->plug(reset(), SmoothMultiply::kReset);
298
299 amplitude_ = new Square();
300 amplitude_->plug(control_amplitude);
301
302 addProcessor(control_amplitude);
303 addProcessor(amplitude_);
304 }
305
312 void SynthVoiceHandler::process(int num_samples) {
313 poly_mask reset_mask = reset()->trigger_mask;
314 if (reset_mask.anyMask())
315 resetFeedbacks(reset_mask);
316
317 VoiceHandler::process(num_samples);
318 int num_voices = getNumActiveVoices();
319 num_voices_.buffer[0] = num_voices;
320 note_retriggered_.clearTrigger();
321
322 if (num_voices == 0) {
323 for (auto& status_source : data_->status_outputs)
324 status_source.second->clear();
325 }
326 else {
327 last_active_voice_mask_ = getCurrentVoiceMask();
328 for (auto& status_source : data_->status_outputs)
329 status_source.second->update(last_active_voice_mask_);
330
331 for (ModulationConnectionProcessor* processor : enabled_modulation_processors_) {
332 poly_float* buffer = processor->output()->buffer;
333 if (processor->isControlRate() || processor->isPolyphonicModulation()) {
334 poly_float masked_value = buffer[0] & last_active_voice_mask_;
335 buffer[0] = masked_value + utils::swapVoices(masked_value);
336 }
337 else {
338 for (int i = 0; i < num_samples; ++i) {
339 poly_float masked_value = buffer[i] & last_active_voice_mask_;
340 buffer[i] = masked_value + utils::swapVoices(masked_value);
341 }
342 }
343 }
344 }
345 }
346
350 void SynthVoiceHandler::noteOn(int note, mono_float velocity, int sample, int channel) {
351 if (getNumPressedNotes() < polyphony() || !legato())
352 note_retriggered_.trigger(constants::kFullMask, note, sample);
354 }
355
359 void SynthVoiceHandler::noteOff(int note, mono_float lift, int sample, int channel) {
361 note_retriggered_.trigger(constants::kFullMask, note, sample);
362
364 }
365
371 if (output->owner == amplitude_envelope_)
372 return false;
373
375 }
376
380 void SynthVoiceHandler::correctToTime(double seconds) {
381 for (int i = 0; i < kNumLfos; ++i)
382 lfos_[i]->correctToTime(seconds);
383
384 for (int i = 0; i < kNumRandomLfos; ++i)
385 random_lfos_[i]->correctToTime(seconds);
386 }
387
392 for (int i = 0; i < kNumLfos; ++i)
393 lfos_[i]->enable(false);
394
395 for (int i = 1; i < kNumEnvelopes; ++i)
396 envelopes_[i]->enable(false);
397
398 for (int i = 0; i < kNumRandomLfos; ++i)
399 random_lfos_[i]->enable(false);
400
401 random_->enable(false);
402 }
403
407 void SynthVoiceHandler::disableModSource(const std::string& source) {
408 if (source != "env_1")
409 getModulationSource(source)->owner->enable(false);
410 }
411
416 enabled_modulation_processors_.push_back(processor);
417 }
418
423 enabled_modulation_processors_.remove(processor);
424 }
425
426 void SynthVoiceHandler::setupPolyModulationReadouts() {
428
429 for (auto& mod : poly_mods)
430 poly_readouts_[mod.first] = registerControlRateOutput(mod.second, mod.second->owner->enabled());
431 }
432
437 return poly_readouts_;
438 }
439} // namespace vital
void setLoop(bool loop)
Sets whether the line should loop at the end.
Definition line_generator.h:72
void initTriangle()
Initializes the line as a triangle shape.
Definition line_generator.cpp:23
Adds two input buffers sample-by-sample.
Definition operators.h:205
@ kValue
Definition envelope.h:53
@ kTrigger
Definition envelope_module.h:25
@ kValue
Definition envelope_module.h:36
@ kPhase
Definition envelope_module.h:37
void setControlRate(bool control_rate) override
Sets the processing mode of the envelope (control-rate or audio-rate) if not forced.
Definition envelope_module.h:70
const Value * getFilter2OnValue() const
Retrieves the on/off value control for filter 2, if it exists.
Definition filters_module.h:95
@ kReset
Definition filters_module.h:32
@ kMidi
Definition filters_module.h:31
@ kFilter1Input
Definition filters_module.h:28
@ kKeytrack
Definition filters_module.h:30
@ kFilter2Input
Definition filters_module.h:29
const Value * getFilter1OnValue() const
Retrieves the on/off value control for filter 1, if it exists.
Definition filters_module.h:89
@ kTo
Definition operators.h:423
@ kFrom
Definition operators.h:422
@ kFractional
Definition operators.h:424
@ kMidi
Definition lfo_module.h:30
@ kNoteCount
Definition lfo_module.h:29
@ kNoteTrigger
Definition lfo_module.h:28
@ kOscPhase
Definition lfo_module.h:43
@ kValue
Definition lfo_module.h:42
@ kOscFrequency
Definition lfo_module.h:44
ModulationConnection * atIndex(int index)
Retrieves a ModulationConnection by index.
Definition synth_types.h:114
A processor that applies a modulation signal to a parameter, performing mapping, scaling,...
Definition modulation_connection_processor.h:18
@ kModulationPreScale
Definition modulation_connection_processor.h:45
@ kModulationSource
Definition modulation_connection_processor.h:46
void initializeBaseValue(Value *base_value)
Initializes a base value for this modulation connection, used as a starting point.
Definition modulation_connection_processor.h:121
@ kReset
Definition modulation_connection_processor.h:32
@ kModulationAmount
Definition modulation_connection_processor.h:30
@ kModulationPower
Definition modulation_connection_processor.h:31
Multiplies two input buffers sample-by-sample.
Definition operators.h:318
@ kRunSeconds
Duration of portamento in seconds input index.
Definition portamento_slope.h:47
@ kPortamentoScale
Scale portamento by interval input index.
Definition portamento_slope.h:46
@ kNumNotesPressed
Number of notes currently pressed input index.
Definition portamento_slope.h:50
@ kSlopePower
Power/curve of the slope input index.
Definition portamento_slope.h:48
@ kSource
Source value input index.
Definition portamento_slope.h:44
@ kReset
Reset trigger input index.
Definition portamento_slope.h:49
@ kTarget
Target value input index.
Definition portamento_slope.h:43
@ kPortamentoForce
Force portamento on/off input index.
Definition portamento_slope.h:45
Processor(int num_inputs, int num_outputs, bool control_rate=false, int max_oversample=1)
Constructs a Processor with a given number of inputs/outputs and oversampling.
Definition processor.cpp:25
void plugNext(const Output *source)
Connects an external Output to the first available (unplugged) input.
Definition processor.cpp:104
void plug(const Output *source)
Connects an external Output to this Processor's first input.
Definition processor.cpp:79
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
virtual void enable(bool enable)
Enables or disables this Processor.
Definition processor.h:318
A module that manages multiple audio producers (oscillators and sampler) and routes their outputs.
Definition producers_module.h:17
void setFilter2On(const Value *on)
Sets a Value that determines if Filter 2 is on.
Definition producers_module.h:137
@ kActiveVoices
Definition producers_module.h:27
@ kReset
Definition producers_module.h:24
@ kMidi
Definition producers_module.h:26
@ kNoteCount
Definition producers_module.h:28
@ kRetrigger
Definition producers_module.h:25
void setFilter1On(const Value *on)
Sets a Value that determines if Filter 1 is on.
Definition producers_module.h:130
@ kRawOut
Definition producers_module.h:39
@ kToFilter1
Definition producers_module.h:37
@ kDirectOut
Definition producers_module.h:40
@ kToFilter2
Definition producers_module.h:38
Output * samplePhaseOutput()
Gets the output phase of the sampler.
Definition producers_module.h:123
@ kNoteTrigger
Definition random_lfo_module.h:23
@ kMidi
Definition random_lfo_module.h:24
@ kControlRate
Definition operators.h:346
@ kReset
Definition operators.h:347
@ kAudioRate
Definition operators.h:345
Output * createPolyModControl(std::string name, bool audio_rate=false, bool smooth_value=false, Output *internal_modulation=nullptr, Input *reset=nullptr)
Creates a polyphonic mod control, including applying parameter scaling.
Definition synth_module.cpp:173
Value * createBaseControl(std::string name, bool audio_rate=false, bool smooth_value=false)
Creates a simple control processor for a given parameter name.
Definition synth_module.cpp:22
void addIdleMonoProcessor(Processor *processor)
Adds a mono processor that is considered idle (not part of main processing chain).
Definition synth_module.cpp:540
std::shared_ptr< ModuleData > data_
Shared data storage for this SynthModule.
Definition synth_module.h:354
virtual output_map & getPolyModulations()
Returns a reference to the map of poly modulation readouts.
Definition synth_module.cpp:490
Output * getModulationSource(std::string name)
Retrieves a modulation source output by name.
Definition synth_module.cpp:350
void addSubmodule(SynthModule *module)
Adds a submodule to this SynthModule.
Definition synth_module.h:289
void createStatusOutput(std::string name, Output *source)
Creates a status output associated with a given Output.
Definition synth_module.cpp:337
virtual void enable(bool enable) override
Enables or disables this SynthModule and its owned processors.
Definition synth_module.cpp:516
Output * createMonoModControl(std::string name, bool audio_rate=false, bool smooth_value=false, Output *internal_modulation=nullptr)
Creates a monophonic mod control, including applying parameter scaling.
Definition synth_module.cpp:104
void prepareDestroy()
Prepares the voice handler for destruction, removing processors as needed.
Definition synth_voice_handler.cpp:134
output_map & getPolyModulations() override
Retrieves a map of all polyphonic modulations.
Definition synth_voice_handler.cpp:436
void init() override
Initializes the voice handler, creating and configuring all internal modules.
Definition synth_voice_handler.cpp:50
void noteOff(int note, mono_float lift, int sample, int channel) override
Handles a note-off event, releasing voices or retriggering them in legato contexts.
Definition synth_voice_handler.cpp:359
bool shouldAccumulate(Output *output) override
Determines if the given output should be accumulated across voices.
Definition synth_voice_handler.cpp:370
void process(int num_samples) override
Processes all active voices for a given number of samples.
Definition synth_voice_handler.cpp:312
void disableUnnecessaryModSources()
Disables all unnecessary modulation sources for efficiency.
Definition synth_voice_handler.cpp:391
void disableModSource(const std::string &source)
Disables a specific modulation source by name.
Definition synth_voice_handler.cpp:407
void enableModulationConnection(ModulationConnectionProcessor *processor)
Enables a modulation connection processor, making its modulation active.
Definition synth_voice_handler.cpp:415
void noteOn(int note, mono_float velocity, int sample, int channel) override
Handles a note-on event, starting or retriggering voices as appropriate.
Definition synth_voice_handler.cpp:350
void correctToTime(double seconds) override
Corrects time-dependent parameters to a given playback time.
Definition synth_voice_handler.cpp:380
void disableModulationConnection(ModulationConnectionProcessor *processor)
Disables a modulation connection processor, removing it from active modulation.
Definition synth_voice_handler.cpp:422
SynthVoiceHandler(Output *beats_per_second)
Constructs a SynthVoiceHandler with a given beats-per-second reference.
Definition synth_voice_handler.cpp:24
A SynthModule and NoteHandler that manages a pool of polyphonic voices, handles note-on/off logic,...
Definition voice_handler.h:380
force_inline Output * velocity()
Returns a pointer to velocity, the note-on velocity.
Definition voice_handler.h:634
force_inline Output * retrigger()
Returns a pointer to the retrigger Output, used for controlling certain envelope triggers.
Definition voice_handler.h:610
force_inline Output * note()
Returns a pointer to the note Output, giving the current tuned note frequency or pitch.
Definition voice_handler.h:616
force_inline Output * pitch_wheel()
Returns a pointer to pitch_wheel, storing the pitch-bend range for each channel.
Definition voice_handler.h:649
force_inline int getNumPressedNotes()
Returns how many notes are pressed (including partial states).
Definition voice_handler.h:476
force_inline Output * local_pitch_bend()
Returns a pointer to local_pitch_bend, the per-voice pitch bend output.
Definition voice_handler.h:655
virtual void noteOn(int note, mono_float velocity, int sample, int channel) override
Handles a MIDI note-on event, starting a note with a specified velocity and timing.
Definition voice_handler.cpp:721
void resetFeedbacks(poly_mask reset_mask) override
Resets any feedback paths in the poly router, applying the given mask.
Definition voice_handler.cpp:892
force_inline Output * note_pressed()
Returns a pointer to the note_pressed Output, a count of how many times a note was pressed.
Definition voice_handler.h:622
force_inline Output * channel()
Returns a pointer to channel, indicating the MIDI channel of the voice.
Definition voice_handler.h:631
virtual void init() override
Initializes the voice and global routers, then calls SynthModule::init().
Definition voice_handler.cpp:409
force_inline Output * slide()
Returns a pointer to slide, the MPE "slide" expression value.
Definition voice_handler.h:643
int getNumActiveVoices()
Returns the number of currently active voices (not dead).
Definition voice_handler.cpp:425
force_inline int polyphony()
Returns the current maximum polyphony (number of active voices allowed).
Definition voice_handler.h:670
bool isNotePlaying(int note)
Checks if a given MIDI note is playing.
Definition voice_handler.cpp:429
force_inline Output * voice_event()
Returns a pointer to the voice_event Output, used to track voice On/Off/Kill events.
Definition voice_handler.h:607
void removeProcessor(Processor *processor) override
Removes a Processor from this router.
Definition voice_handler.cpp:880
virtual void process(int num_samples) override
Processes audio for a block of samples. For each active voice, triggers events, updates parameters,...
Definition voice_handler.cpp:321
force_inline Output * mod_wheel()
Returns a pointer to mod_wheel, storing the mod wheel value for each channel.
Definition voice_handler.h:658
virtual void noteOff(int note, mono_float velocity, int sample, int channel) override
Handles a MIDI note-off event, releasing a currently active note.
Definition voice_handler.cpp:752
force_inline Output * note_count()
Returns a pointer to note_count, a global note counter.
Definition voice_handler.h:625
force_inline Output * aftertouch()
Returns a pointer to aftertouch, storing per-voice or channel-based aftertouch.
Definition voice_handler.h:640
force_inline bool legato()
Returns true if legato mode is enabled.
Definition voice_handler.h:764
force_inline Output * pitch_wheel_percent()
Returns a pointer to pitch_wheel_percent, a normalized [0..1] version of pitch_wheel.
Definition voice_handler.h:652
force_inline Output * reset()
Returns a pointer to the reset Output, indicating a full voice reset (On from Dead).
Definition voice_handler.h:613
void addProcessor(Processor *processor) override
Adds a Processor to be managed by this router.
Definition voice_handler.cpp:870
force_inline void setVoiceKiller(const Output *killer)
Specifies an Output from a Processor used to detect silence or inactivity for voice killing.
Definition voice_handler.h:738
Output * registerOutput(Output *output) override
Registers an Output with this VoiceHandler, returning a pointer to a new accumulated or single-lane O...
Definition voice_handler.cpp:896
force_inline Output * lift()
Returns a pointer to lift, the note-off velocity or release velocity.
Definition voice_handler.h:637
force_inline Output * last_note()
Returns a pointer to the last_note Output, giving the previous note (for legato transitions).
Definition voice_handler.h:619
force_inline Output * active_mask()
Returns a pointer to active_mask, a mask that indicates which voices are active.
Definition voice_handler.h:646
Output * registerControlRateOutput(Output *output, bool active)
Registers a control-rate Output with the VoiceHandler.
Definition voice_handler.cpp:914
virtual bool shouldAccumulate(Output *output)
Determines whether an Output should be summed across voices (accumulated) or handled individually.
Definition voice_handler.cpp:316
force_inline void setVoiceMidi(const Output *midi)
Sets the Output that provides the current MIDI note for the voice.
Definition voice_handler.h:751
force_inline Output * note_in_octave()
Returns a pointer to note_in_octave, a fractional note position in [0..1).
Definition voice_handler.h:628
poly_mask getCurrentVoiceMask()
Returns a mask for the last active voice, used for writing to output buffers.
Definition voice_handler.cpp:556
Control-rate addition of two values.
Definition operators.h:700
const poly_mask kFullMask
A mask covering all lanes of a poly_float vector.
Definition synth_constants.h:257
const poly_float kLeftOne(1.0f, 0.0f)
A poly_float representing a vector [1.0f, 0.0f] used for channel manipulations.
const cr::Value kValueOne(1.0f)
force_inline poly_float swapVoices(poly_float value)
Swaps the first half of the lanes with the second half.
Definition poly_utils.h:437
Contains classes and functions used within the Vital synthesizer framework.
std::map< std::string, Output * > output_map
Maps parameter names to Output pointers, representing output signals from various modules.
Definition synth_types.h:229
constexpr int kNumRandomLfos
Number of random LFO sources (random modulation generators).
Definition synth_constants.h:25
constexpr int kMidiSize
MIDI note count (0-127).
Definition common.h:44
constexpr int kMidiTrackCenter
MIDI note considered as center (Middle C).
Definition common.h:45
constexpr int kMaxPolyphony
The maximum number of voices allocated for polyphony (includes an extra for handling transitions).
Definition synth_constants.h:40
constexpr int kNumEnvelopes
Number of envelope generators in Vital.
Definition synth_constants.h:22
constexpr int kNumLfos
Number of LFO sources available in the Vital synthesizer.
Definition synth_constants.h:13
constexpr int kMaxModulationConnections
Maximum number of modulation connections allowed.
Definition synth_constants.h:49
constexpr int kNumMacros
Number of macro controls available.
Definition synth_constants.h:28
float mono_float
Definition common.h:33
Declares the PortamentoSlope class, which applies a portamento transition between a source and target...
std::unique_ptr< ModulationConnectionProcessor > modulation_processor
Processor applying scaling/mapping.
Definition synth_types.h:75
Holds and manages a buffer of samples (poly_float) for a Processor's output.
Definition processor.h:35
force_inline void trigger(poly_mask mask, poly_float value, poly_int offset)
Sets trigger values (mask, trigger value, and offset).
Definition processor.h:63
poly_float * buffer
Pointer to the output buffer.
Definition processor.h:110
Processor * owner
Owning processor.
Definition processor.h:112
force_inline void clearTrigger()
Clears the trigger mask, value, and offset.
Definition processor.h:72
poly_mask trigger_mask
Mask for triggered voices.
Definition processor.h:115
Represents a vector of floating-point values using SIMD instructions.
Definition poly_values.h:600
Represents a vector of integer values using SIMD instructions.
Definition poly_values.h:56
static force_inline uint32_t vector_call anyMask(simd_type value)
Returns a bitmask that indicates which bytes/elements in the register are non-zero.
Definition poly_values.h:352
Declares the ValueSwitch class, which allows switching the output buffer based on a control value.