134 poly_float last_note,
int note_pressed,
int note_count,
135 int sample,
int channel) {
136 event_sample_ = sample;
149 aftertouch_sample_ = 0;
160 last_key_state_ = key_state_;
168 last_key_state_ = key_state_;
179 return key_state_ ==
kHeld;
212 event_sample_ = sample;
222 event_sample_ = sample;
233 return event_sample_ >= 0;
243 aftertouch_sample_ = sample;
253 slide_sample_ = sample;
258 return aftertouch_sample_ >= 0;
263 return slide_sample_ >= 0;
281 event_sample_ -= num_samples;
289 aftertouch_sample_ -= num_samples;
297 slide_sample_ -= num_samples;
303 aftertouch_sample_ = -1;
308 aftertouch_sample_ = -1;
316 aftertouch_sample_ = -1;
324 for (
Voice* voice : shared_voices) {
326 shared_voices_.push_back(voice);
343 std::vector<Voice*> shared_voices_;
350 int aftertouch_sample_;
449 virtual void process(
int num_samples)
override;
454 virtual void init()
override;
566 mod_wheel_values_[
channel] = value;
575 mod_wheel_values_[i] = value;
585 pitch_wheel_values_[
channel] = value;
586 for (
Voice* voice : active_voices_) {
587 if (voice->state().channel ==
channel && voice->held())
588 voice->setLocalPitchBend(value);
599 VITAL_ASSERT(from_channel < kNumMidiChannels && from_channel >= 0);
600 VITAL_ASSERT(to_channel < kNumMidiChannels && to_channel >= 0);
602 for (
int i = from_channel; i <= to_channel; ++i)
603 zoned_pitch_wheel_values_[i] = value;
739 voice_killer_ = killer;
808 Voice* grabFreeVoice();
809 Voice* grabFreeParallelVoice();
811 Voice* getVoiceToKill(
int max_voices);
812 int grabNextUnplayedPressedNote();
813 void sortVoicePriority();
814 void addParallelVoices();
815 void prepareVoiceTriggers(
AggregateVoice* aggregate_voice,
int num_samples);
817 void processVoice(
AggregateVoice* aggregate_voice,
int num_samples);
818 void clearAccumulatedOutputs();
819 void clearNonaccumulatedOutputs();
820 void accumulateOutputs(
int num_samples);
821 void combineAccumulatedOutputs(
int num_samples);
822 void writeNonaccumulatedOutputs(
poly_mask voice_mask,
int num_samples);
827 std::map<Output*, std::unique_ptr<Output>> last_voice_outputs_;
829 std::map<Output*, std::unique_ptr<Output>> accumulated_outputs_;
831 const Output* voice_killer_;
832 const Output* voice_midi_;
834 int last_num_voices_;
885 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(
VoiceHandler)
A class for managing microtonal tunings and custom pitch mappings in Vital.
Definition tuning.h:23
A generic circular buffer (FIFO) data structure that allows adding and removing elements efficiently.
Definition circular_queue.h:32
force_inline int size() const
Returns the current number of elements in the queue.
Definition circular_queue.h:410
An interface for handling MIDI note events within a synthesizer or audio system.
Definition note_handler.h:16
Base class for all signal-processing units in Vital.
Definition processor.h:212
virtual void setOversampleAmount(int oversample)
Sets the oversampling amount and updates the effective sample rate.
Definition processor.h:293
virtual bool isPolyphonic() const
Checks if this Processor is polyphonic by querying its ProcessorRouter.
Definition processor.cpp:73
force_inline Output * output(unsigned int index=0) const
Retrieves the Output pointer at a given index.
Definition processor.h:616
A specialized Processor that manages a directed graph of Processors and ensures correct processing or...
Definition processor_router.h:34
virtual void setOversampleAmount(int oversample) override
Sets the oversampling amount for all Processors in this router.
Definition processor_router.cpp:104
A ProcessorRouter that encapsulates a cohesive unit of functionality in the synthesizer.
Definition synth_module.h:129
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
void removeGlobalProcessor(Processor *processor)
Removes a Processor from the global router.
Definition voice_handler.cpp:888
void allNotesOffRange(int sample, int from_channel, int to_channel)
Definition voice_handler.cpp:546
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 void setModWheel(mono_float value, int channel=0)
Sets the mod wheel value for a single channel.
Definition voice_handler.h:564
virtual Processor * clone() const override
Clones this VoiceHandler. Not supported for this class.
Definition voice_handler.h:439
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
void setPolyphony(int polyphony)
Sets the polyphony to a new value, allocating or freeing voices as needed.
Definition voice_handler.cpp:847
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
void setChannelAftertouch(int channel, mono_float aftertouch, int sample)
Sets channel-wide aftertouch (applies to all voices on that channel).
Definition voice_handler.cpp:812
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
@ kVoicePriority
Priority scheme for stealing or reassigning voices.
Definition voice_handler.h:391
@ kVoiceOverride
Behavior when exceeding polyphony: kill or steal.
Definition voice_handler.h:392
@ kNumInputs
Definition voice_handler.h:393
@ kPolyphony
Desired polyphony setting (1..kMaxActivePolyphony).
Definition voice_handler.h:390
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
void setAftertouch(int note, mono_float aftertouch, int sample, int channel)
Handles per-note aftertouch for a specific note and channel.
Definition voice_handler.cpp:804
force_inline Output * slide()
Returns a pointer to slide, the MPE "slide" expression value.
Definition voice_handler.h:643
void sostenutoOn(int channel)
Turns on sostenuto for a single channel.
Definition voice_handler.cpp:457
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
virtual ~VoiceHandler()
Virtual destructor.
Definition voice_handler.cpp:141
bool isNotePlaying(int note)
Checks if a given MIDI note is playing.
Definition voice_handler.cpp:429
void setActiveNonaccumulatedOutput(Output *output)
Marks an Output as "active" for non-accumulated usage (e.g., for the last active voice only).
Definition voice_handler.cpp:941
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
virtual ProcessorRouter * getMonoRouter() override
Returns the monophonic (global) ProcessorRouter for this VoiceHandler.
Definition voice_handler.h:680
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
VoiceOverride
Behavior for assigning a new note when at max polyphony.
Definition voice_handler.h:400
@ kNumVoiceOverrides
Definition voice_handler.h:403
@ kKill
Immediately kill an existing voice to free one.
Definition voice_handler.h:401
@ kSteal
Steal an existing voice that is in a certain state (released/sustained).
Definition voice_handler.h:402
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
void sostenutoOffRange(int sample, int from_channel, int to_channel)
Turns off sostenuto for a range of channels, prompting release if not sustained.
Definition voice_handler.cpp:503
force_inline void setPitchWheel(mono_float value, int channel=0)
Sets the pitch wheel value for a single channel, applying to all held voices on that channel.
Definition voice_handler.h:583
void addGlobalProcessor(Processor *processor)
Adds a Processor to the "global" (monophonic) router, e.g. for final mixing or master effects.
Definition voice_handler.cpp:884
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
virtual void setOversampleAmount(int oversample) override
Sets the oversampling factor for both SynthModule and the internal poly/mono routers.
Definition voice_handler.h:779
force_inline bool legato()
Returns true if legato mode is enabled.
Definition voice_handler.h:764
force_inline Output * getAccumulatedOutput(Output *output)
Retrieves the accumulated Output associated with a given output pointer.
Definition voice_handler.h:665
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 allNotesOff(int sample) override
Turns off all currently active notes, optionally specifying a sample index for timing.
Definition voice_handler.cpp:530
VoicePriority
Determines the voice stealing strategy (oldest, newest, highest, etc.).
Definition voice_handler.h:410
@ kRoundRobin
Definition voice_handler.h:415
@ kHighest
Definition voice_handler.h:413
@ kOldest
Definition voice_handler.h:412
@ kNumVoicePriorities
Definition voice_handler.h:416
@ kNewest
Definition voice_handler.h:411
@ kLowest
Definition voice_handler.h:414
force_inline void setModWheelAllChannels(mono_float value)
Sets the mod wheel value for all channels at once.
Definition voice_handler.h:573
void sustainOff(int sample, int channel)
Turns off sustain for a single channel, prompting voices to release.
Definition voice_handler.cpp:449
void addProcessor(Processor *processor) override
Adds a Processor to be managed by this router.
Definition voice_handler.cpp:870
static constexpr mono_float kLocalPitchBendRange
Range of local pitch bend in semitones for each voice.
Definition voice_handler.h:383
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
virtual ProcessorRouter * getPolyRouter() override
Returns the polyphonic (voice) ProcessorRouter for this VoiceHandler.
Definition voice_handler.h:685
void addIdleProcessor(Processor *processor) override
Adds a Processor that should remain idle (not processed) in the router.
Definition voice_handler.cpp:875
force_inline void setZonedPitchWheel(mono_float value, int from_channel, int to_channel)
Sets pitch wheel in a zoned manner for a range of MIDI channels.
Definition voice_handler.h:598
void setTuning(const Tuning *tuning)
Sets the custom Tuning object (if any) for note->frequency conversion.
Definition voice_handler.h:466
VoiceHandler()=delete
Disabled default constructor; must specify polyphony and output count.
void allSoundsOff() override
Immediately turns off all sounding notes and stops all sound production.
Definition voice_handler.cpp:517
void setInactiveNonaccumulatedOutput(Output *output)
Marks an Output as "inactive" for non-accumulated usage, effectively disabling it.
Definition voice_handler.cpp:949
mono_float getLastActiveNote() const
Gets the last active note's tuned frequency (or 0 if none).
Definition voice_handler.cpp:863
void sostenutoOff(int sample, int channel)
Turns off sostenuto for a single channel, prompting release if not sustained.
Definition voice_handler.cpp:465
void sustainOffRange(int sample, int from_channel, int to_channel)
Turns off sustain for a range of channels, prompting voices to release.
Definition voice_handler.cpp:482
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
virtual void setSampleRate(int sample_rate) override
Sets the sample rate for both mono/global and voice (poly) routers.
Definition voice_handler.cpp:416
force_inline Output * lift()
Returns a pointer to lift, the note-off velocity or release velocity.
Definition voice_handler.h:637
force_inline void setVoiceKiller(const Processor *killer)
Overload for setting the voice killer from a Processor directly.
Definition voice_handler.h:743
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
void sustainOnRange(int from_channel, int to_channel)
Turns on sustain for a range of channels.
Definition voice_handler.cpp:477
void sustainOn(int channel)
Turns on sustain for a single channel.
Definition voice_handler.cpp:445
force_inline void setLegato(bool legato)
Enables or disables legato mode (disables retriggers if still in Held state).
Definition voice_handler.h:759
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
void setChannelRangeAftertouch(int from_channel, int to_channel, mono_float aftertouch, int sample)
Sets channel-wide aftertouch for a range of channels.
Definition voice_handler.cpp:821
poly_mask getCurrentVoiceMask()
Returns a mask for the last active voice, used for writing to output buffers.
Definition voice_handler.cpp:556
void setChannelSlide(int channel, mono_float aftertouch, int sample)
Sets channel-wide MPE "slide" for a single channel.
Definition voice_handler.cpp:830
void setChannelRangeSlide(int from_channel, int to_channel, mono_float aftertouch, int sample)
Sets channel-wide MPE "slide" for a range of channels.
Definition voice_handler.cpp:838
void sostenutoOnRange(int from_channel, int to_channel)
Turns on sostenuto for a range of channels.
Definition voice_handler.cpp:493
Represents a single playing note/voice, including voice-state and event handling.
Definition voice_handler.h:54
force_inline bool sustained()
Returns true if the voice is in the kSustained state.
Definition voice_handler.h:173
force_inline bool released()
Returns true if the voice is in the kReleased state.
Definition voice_handler.h:183
force_inline void shiftAftertouchEvent(int num_samples)
Shifts the aftertouch event sample index by num_samples.
Definition voice_handler.h:288
force_inline bool held()
Returns true if the voice is in the kHeld state.
Definition voice_handler.h:178
force_inline void setSostenuto(bool sostenuto)
Sets the sostenuto flag on or off.
Definition voice_handler.h:193
static constexpr mono_float kDefaultLiftVelocity
Default lift velocity to use if none is provided.
Definition voice_handler.h:57
force_inline void clearSlideEvent()
Clears the unprocessed slide event, if any.
Definition voice_handler.h:307
force_inline void setVoiceInfo(int voice_index, poly_mask voice_mask)
Sets the voice index within its parallel group and the corresponding SIMD mask.
Definition voice_handler.h:335
force_inline bool sostenuto()
Returns true if the voice has sostenuto pressed.
Definition voice_handler.h:188
virtual ~Voice()
Virtual destructor.
Definition voice_handler.h:87
force_inline mono_float slide()
Returns the current slide (MPE expression) value for this voice.
Definition voice_handler.h:117
force_inline void kill(int sample=0)
Immediately kills this voice (disregarding release).
Definition voice_handler.h:221
KeyState
Describes the lifecycle stage of a voice: kTriggering -> kHeld -> kReleased -> kDead,...
Definition voice_handler.h:64
@ kDead
The voice is no longer active.
Definition voice_handler.h:69
@ kReleased
The note has ended (off event) and is releasing.
Definition voice_handler.h:68
@ kSustained
The note has ended, but sustain pedal is holding it on.
Definition voice_handler.h:67
@ kNumStates
Definition voice_handler.h:70
@ kTriggering
Note-on occurred, but hasn't processed yet.
Definition voice_handler.h:65
@ kHeld
The note is actively held down.
Definition voice_handler.h:66
force_inline void sustain()
Switches this voice to the kSustained state, typically when a sustain pedal is active.
Definition voice_handler.h:167
force_inline mono_float aftertouch()
Returns the current aftertouch value for this voice.
Definition voice_handler.h:111
force_inline void setLocalPitchBend(mono_float bend)
Sets the local pitch bend (used for legato transitions or channel pitch bend).
Definition voice_handler.h:198
force_inline void clearEvents()
Clears both note-on/off events and aftertouch events, marking them processed.
Definition voice_handler.h:314
force_inline int event_sample()
Returns the sample index at which the latest event (on/off) was triggered.
Definition voice_handler.h:102
force_inline poly_mask voice_mask()
Returns the SIMD mask representing this voice's active lanes.
Definition voice_handler.h:108
force_inline mono_float aftertouch_sample()
Returns the sample index at which the latest aftertouch event occurred.
Definition voice_handler.h:114
force_inline void setSharedVoices(std::vector< Voice * > shared_voices)
Stores references to other Voices in the same parallel group for advanced sharing logic.
Definition voice_handler.h:323
force_inline void setAftertouch(mono_float aftertouch, int sample=0)
Sets the aftertouch (pressure) value for the voice.
Definition voice_handler.h:241
force_inline const KeyState last_key_state()
Returns the previous key state (before the most recent update).
Definition voice_handler.h:96
force_inline void markDead()
Marks this voice as kDead, meaning it's completely inactive.
Definition voice_handler.h:227
force_inline int voice_index()
Returns the index of this voice within an AggregateVoice (also the SIMD lane grouping).
Definition voice_handler.h:105
force_inline void deactivate(int sample=0)
Deactivates (turns off) this voice with a note-off event, transitioning to kReleased.
Definition voice_handler.h:211
Voice()=delete
Disabled default constructor: Voice must belong to an AggregateVoice.
force_inline void shiftVoiceEvent(int num_samples)
Shifts the event sample index by num_samples (e.g., for partial block processing).
Definition voice_handler.h:280
force_inline void setKeyState(KeyState key_state)
Sets the key state of this voice (e.g., from Triggering to Held).
Definition voice_handler.h:159
force_inline const VoiceState & state()
Returns a const reference to the VoiceState struct that holds all relevant data.
Definition voice_handler.h:93
force_inline bool hasNewEvent()
Checks if there is a new (non-processed) on/off event for this voice.
Definition voice_handler.h:232
force_inline AggregateVoice * parent()
Returns the pointer to the parent AggregateVoice.
Definition voice_handler.h:90
force_inline const KeyState key_state()
Returns the current key state.
Definition voice_handler.h:99
force_inline void shiftSlideEvent(int num_samples)
Shifts the slide event sample index by num_samples.
Definition voice_handler.h:296
force_inline bool hasNewSlide()
Returns true if there's a new slide event not yet processed.
Definition voice_handler.h:262
force_inline void setSlide(mono_float slide, int sample=0)
Sets the MPE "slide" value for the voice (often CC#74).
Definition voice_handler.h:251
force_inline void completeVoiceEvent()
Completes (consumes) the voice event, marking it as processed. If the voice was kTriggering,...
Definition voice_handler.h:270
force_inline void clearAftertouchEvent()
Clears the unprocessed aftertouch event, if any.
Definition voice_handler.h:302
force_inline bool hasNewAftertouch()
Returns true if there's a new aftertouch event not yet processed.
Definition voice_handler.h:257
force_inline void setLiftVelocity(mono_float lift)
Adjusts the lift velocity (release velocity) of the note-off.
Definition voice_handler.h:203
force_inline void activate(int midi_note, mono_float tuned_note, mono_float velocity, poly_float last_note, int note_pressed, int note_count, int sample, int channel)
Activates (starts) the voice with the given note parameters.
Definition voice_handler.h:133
force_inline mono_float slide_sample()
Returns the sample index at which the latest slide event occurred.
Definition voice_handler.h:120
#define VITAL_ASSERT(x)
Definition common.h:11
#define force_inline
Definition common.h:23
Contains classes and functions used within the Vital synthesizer framework.
VoiceEvent
Enumerates different states or events of a synth voice's lifecycle.
Definition common.h:74
@ kInvalid
Definition common.h:75
@ kVoiceOn
Definition common.h:77
@ kVoiceKill
Definition common.h:81
@ kVoiceOff
Definition common.h:80
constexpr int kNumMidiChannels
MIDI channels available per device.
Definition common.h:57
float mono_float
Definition common.h:33
Declares the ProcessorRouter class, which manages a graph of Processors and their dependencies.
An aggregate grouping that pairs multiple (parallel) voices with a shared Processor instance.
Definition voice_handler.h:365
CircularQueue< Voice * > voices
Collection of active Voice pointers.
Definition voice_handler.h:366
std::unique_ptr< Processor > processor
A single processor instance shared by these voices.
Definition voice_handler.h:367
Holds and manages a buffer of samples (poly_float) for a Processor's output.
Definition processor.h:35
Holds state data for a single voice, such as MIDI note, velocity, pitch bend, etc.
Definition voice_handler.h:24
int channel
Which MIDI channel this voice is associated with.
Definition voice_handler.h:41
int note_count
A global note counter (incremented with each note-on).
Definition voice_handler.h:40
VoiceState()
Default constructor initializes state to neutral or inactive values.
Definition voice_handler.h:28
int midi_note
MIDI note (0-127 usually).
Definition voice_handler.h:33
VoiceEvent event
The most recent voice event (on/off/kill).
Definition voice_handler.h:32
int note_pressed
Pressed note count (e.g., for note priority logic).
Definition voice_handler.h:39
mono_float local_pitch_bend
Per-voice pitch bend amount for legato-like transitions.
Definition voice_handler.h:38
mono_float velocity
Velocity of the note-on event.
Definition voice_handler.h:36
mono_float lift
Velocity of the note-off (a.k.a. release velocity).
Definition voice_handler.h:37
mono_float tuned_note
Possibly adjusted by a Tuning object.
Definition voice_handler.h:34
bool sostenuto_pressed
True if this voice is currently held by sostenuto pedal.
Definition voice_handler.h:42
poly_float last_note
Holds the last note played for this voice.
Definition voice_handler.h:35
A specialized Output that always runs at control rate (buffer_size = 1).
Definition processor.h:189
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
Defines the SynthModule class which extends ProcessorRouter to form a building block of the Vital syn...