87 const auto validation = validate_(buffer, frame_count, input, routing);
94 const std::array<std::pair<VoiceModulationTarget, float>,
lane_count> lanes{{
95 {routing.pitch,
static_cast<float>(pitch)},
96 {routing.velocity,
static_cast<float>(input.
velocity) / 127.0f},
97 {routing.gate, input.
gate ? 1.0f : 0.0f},
99 {routing.timbre, input.
timbre},
103 auto buffer_result =
buffer.begin_block(frame_count);
104 if (!buffer_result.ok)
105 return buffer_failure_(buffer_result.status);
106 for (
const auto& [target, value] : lanes) {
107 buffer_result =
buffer.add_constant(target, value);
108 if (!buffer_result.ok) {
110 return buffer_failure_(buffer_result.status);
117 static bool normalized_(
float value)
noexcept {
118 return std::isfinite(value) &&
value >= 0.0f &&
value <= 1.0f;
122 return static_cast<std::uint8_t
>(target) <=
134 static VoiceNoteModulationResult validate_(
const VoiceModulationBuffer& buffer,
135 std::uint32_t frame_count,
136 const VoiceNoteModulationInput& input,
137 const VoiceNoteModulationRouting& routing)
noexcept {
140 if (frame_count == 0 || frame_count >
buffer.max_frames())
158 if (!std::isfinite(pitch) ||
159 pitch <
static_cast<double>(std::numeric_limits<float>::lowest()) ||
160 pitch >
static_cast<double>(std::numeric_limits<float>::max()))
163 const std::array<VoiceModulationTarget, lane_count> targets{{
171 for (std::size_t i = 0;
i < targets.size(); ++
i) {
172 if (!target_valid_(targets[i]))
174 for (std::size_t j = 0;
j <
i; ++
j) {
175 if (targets[i] == targets[j])
195 [[nodiscard]]
bool ok() const noexcept {
208 "VoiceRuntimeFacade owner must be midi::Synthesiser<Voice> "
209 "or audio::InstrumentVoiceAllocator");
230 return owner_->polyphony();
233 return owner_->active_count();
236 return owner_->releasing_count();
239 return owner_->telemetry();
249 owner_->set_steal_strategy(strategy);
253 return owner_->steal_strategy();
256 if (!std::isfinite(semitones) || semitones <= 0.0f)
258 owner_->set_pitch_bend_range_semitones(semitones);
262 return owner_->pitch_bend_range_semitones();
265 void note_on(std::uint8_t channel, std::uint8_t note, std::uint8_t velocity,
266 int8_t priority = 0, std::uint8_t voice_group = 0,
bool choke_group =
false,
267 float choke_fade_ms = 0.0f) {
268 owner_->note_on(channel, note, velocity, priority, voice_group, choke_group, choke_fade_ms);
270 void note_off(std::uint8_t channel, std::uint8_t note) {
271 owner_->note_off(channel, note);
273 void control_change(std::uint8_t channel, std::uint8_t controller, std::uint8_t value) {
274 owner_->cc(channel, controller, value);
277 owner_->pitch_bend(channel, semitones);
280 owner_->aftertouch(channel, pressure);
284 owner_->process(
events, output, frame_count);
289 owner_->process(
events, output, frame_count, note_on_policy);
292 template <
typename PolicyFn>
294 std::uint8_t, std::uint8_t>
296 PolicyFn&& policy_for_note) {
297 owner_->process(
events, output, frame_count, std::forward<PolicyFn>(policy_for_note));
301 return owner_->voice(index);
304 return owner_->voice(index);
333 return owner_->max_voices();
336 return owner_->active_voice_count();
339 return owner_->allocated_voice_count();
346 owner_->set_steal_policy(policy);
350 return owner_->steal_policy();
353 owner_->set_termination_fade_frames(frames);
358 std::span<VoiceModulationBuffer> modulation)
noexcept {
359 const auto voices = owner_->max_voices();
362 if (terminations.size() !=
voices)
364 if (modulation.size() !=
voices)
366 for (
const auto& buffer : modulation) {
367 if (!buffer.prepared())
371 const auto allocation = owner_->trigger(
trigger, terminations);
372 if (!allocation.allocated)
374 for (std::uint32_t i = 0; i < allocation.termination_count; ++i)
375 modulation[terminations[i].voice_index].
reset();
376 modulation[allocation.voice_index].reset();
381 return owner_->release_voice(voice_index);
385 return owner_->release_note(note, sample_id);
388 std::span<VoiceModulationBuffer> modulation)
noexcept {
389 if (!modulation_valid_(modulation) || voice_index >= modulation.size())
391 if (!owner_->finish_voice(voice_index))
393 modulation[voice_index].reset();
397 std::span<const InstrumentVoice>
voices() const noexcept {
398 return owner_->voices();
402 std::uint64_t frames,
const VoiceSumOptions& options = {})
const noexcept {
407 reset(std::span<VoiceModulationBuffer> modulation)
noexcept {
408 if (owner_->max_voices() == 0)
410 if (!modulation_valid_(modulation))
413 for (
auto& buffer : modulation)
419 bool modulation_valid_(std::span<const VoiceModulationBuffer> modulation)
const noexcept {
420 if (modulation.size() != owner_->max_voices())
422 for (
const auto& buffer : modulation) {
423 if (!buffer.prepared())
Non-owning view over multi-channel audio sample data.
Definition buffer.hpp:30
Definition instrument_voice_allocator.hpp:68
Definition voice_modulation_buffer.hpp:78
Definition voice_runtime_facade.hpp:75
static constexpr std::uint32_t lane_count
Definition voice_runtime_facade.hpp:77
static VoiceNoteModulationResult write(VoiceModulationBuffer &buffer, std::uint32_t frame_count, const VoiceNoteModulationInput &input, const VoiceNoteModulationRouting &routing={}) noexcept
Replaces the current block with six constant lanes.
Definition voice_runtime_facade.hpp:84
Owner & owner() noexcept
Definition voice_runtime_facade.hpp:325
std::uint32_t voice_count() const noexcept
Definition voice_runtime_facade.hpp:332
std::uint32_t allocated_voice_count() const noexcept
Definition voice_runtime_facade.hpp:338
const Owner & owner() const noexcept
Definition voice_runtime_facade.hpp:328
std::span< const InstrumentVoice > voices() const noexcept
Definition voice_runtime_facade.hpp:397
InstrumentVoiceAllocator Owner
Definition voice_runtime_facade.hpp:321
bool release_voice(std::uint32_t voice_index) noexcept
Definition voice_runtime_facade.hpp:380
std::uint32_t active_voice_count() const noexcept
Definition voice_runtime_facade.hpp:335
AllocatedVoiceRuntimeTriggerResult trigger(const InstrumentVoiceTrigger &trigger, std::span< VoiceTermination > terminations, std::span< VoiceModulationBuffer > modulation) noexcept
Definition voice_runtime_facade.hpp:357
void set_termination_fade_frames(std::uint32_t frames) noexcept
Definition voice_runtime_facade.hpp:352
bool finish_voice(std::uint32_t voice_index, std::span< VoiceModulationBuffer > modulation) noexcept
Definition voice_runtime_facade.hpp:387
VoiceSumResult mix(std::span< const VoiceSumInput > inputs, BufferView< float > destination, std::uint64_t frames, const VoiceSumOptions &options={}) const noexcept
Definition voice_runtime_facade.hpp:401
VoiceStealPolicy steal_policy() const noexcept
Definition voice_runtime_facade.hpp:349
bool set_steal_policy(VoiceStealPolicy policy) noexcept
Definition voice_runtime_facade.hpp:342
VoiceRuntimeFacadeStatus reset(std::span< VoiceModulationBuffer > modulation) noexcept
Definition voice_runtime_facade.hpp:407
std::uint32_t release_note(int note, std::uint32_t sample_id=kInvalidSampleId) noexcept
Definition voice_runtime_facade.hpp:383
VoiceRuntimeFacade(Owner &owner) noexcept
Definition voice_runtime_facade.hpp:323
void pitch_bend(std::uint8_t channel, float semitones)
Definition voice_runtime_facade.hpp:276
float pitch_bend_range_semitones() const noexcept
Definition voice_runtime_facade.hpp:261
midi::Synthesiser< Voice > Owner
Definition voice_runtime_facade.hpp:218
void control_change(std::uint8_t channel, std::uint8_t controller, std::uint8_t value)
Definition voice_runtime_facade.hpp:273
std::size_t voice_count() const noexcept
Definition voice_runtime_facade.hpp:229
Owner & owner() noexcept
Definition voice_runtime_facade.hpp:222
std::size_t releasing_voice_count() const noexcept
Definition voice_runtime_facade.hpp:235
bool set_pitch_bend_range_semitones(float semitones) noexcept
Definition voice_runtime_facade.hpp:255
void process(const midi::MidiBuffer &events, float *output, int frame_count, PolicyFn &&policy_for_note)
Definition voice_runtime_facade.hpp:295
VoiceRuntimeFacade(Owner &owner) noexcept
Definition voice_runtime_facade.hpp:220
void aftertouch(std::uint8_t channel, float pressure)
Definition voice_runtime_facade.hpp:279
const Voice & voice(std::size_t index) const noexcept
Definition voice_runtime_facade.hpp:303
std::size_t active_voice_count() const noexcept
Definition voice_runtime_facade.hpp:232
void process(const midi::MidiBuffer &events, float *output, int frame_count, const midi::SynthesiserNoteOnPolicy ¬e_on_policy)
Definition voice_runtime_facade.hpp:287
void note_on(std::uint8_t channel, std::uint8_t note, std::uint8_t velocity, int8_t priority=0, std::uint8_t voice_group=0, bool choke_group=false, float choke_fade_ms=0.0f)
Definition voice_runtime_facade.hpp:265
void process(const midi::MidiBuffer &events, float *output, int frame_count)
Definition voice_runtime_facade.hpp:283
midi::VoiceStealStrategy steal_strategy() const noexcept
Definition voice_runtime_facade.hpp:252
void note_off(std::uint8_t channel, std::uint8_t note)
Definition voice_runtime_facade.hpp:270
void reset()
Definition voice_runtime_facade.hpp:306
const Owner & owner() const noexcept
Definition voice_runtime_facade.hpp:225
midi::SynthesiserTelemetry telemetry() const
Definition voice_runtime_facade.hpp:238
Voice & voice(std::size_t index) noexcept
Definition voice_runtime_facade.hpp:300
bool set_steal_strategy(midi::VoiceStealStrategy strategy) noexcept
Definition voice_runtime_facade.hpp:242
Primary template intentionally rejects unsupported owners.
Definition voice_runtime_facade.hpp:206
static VoiceSumResult mix(std::span< const VoiceSumInput > inputs, BufferView< float > destination, std::uint64_t frames, const VoiceSumOptions &options={}) noexcept
Collection of timestamped MIDI events within a single audio buffer period.
Definition buffer.hpp:31
Polyphonic synth that routes plain-MIDI events into a pool of Voice instances.
Definition synthesiser.hpp:229
constexpr bool unsupported_voice_runtime_owner
Definition voice_runtime_facade.hpp:201
Definition analyzer_provider.hpp:12
VoiceStealPolicy
Definition instrument_voice_allocator.hpp:12
@ Oldest
Definition instrument_voice_allocator.hpp:13
@ PreferSameVoiceGroupOldest
Definition instrument_voice_allocator.hpp:14
VoiceRuntimeFacade(Owner &) -> VoiceRuntimeFacade< Owner >
@ NotPrepared
Definition sample_heritage_bus_dsp.hpp:21
@ Ok
Definition loop_types.hpp:34
VoiceNoteModulationStatus
Definition voice_runtime_facade.hpp:28
@ InvalidNote
Definition voice_runtime_facade.hpp:32
@ NotPrepared
Definition voice_runtime_facade.hpp:30
@ BufferRejected
Definition voice_runtime_facade.hpp:37
@ InvalidRouting
Definition voice_runtime_facade.hpp:35
@ InvalidFrameCount
Definition voice_runtime_facade.hpp:31
@ Ok
Definition voice_runtime_facade.hpp:29
@ InvalidBendRange
Definition voice_runtime_facade.hpp:34
@ InvalidController
Definition voice_runtime_facade.hpp:33
@ InsufficientLanes
Definition voice_runtime_facade.hpp:36
constexpr std::uint32_t kInvalidSampleId
Definition sample_identity.hpp:8
@ Voice
Definition sample_heritage_schema.hpp:35
VoiceModulationTarget
Definition voice_modulation_buffer.hpp:9
@ PitchCents
Definition voice_modulation_buffer.hpp:11
@ Gain
Definition voice_modulation_buffer.hpp:10
@ Aux7
Definition voice_modulation_buffer.hpp:22
@ Aux1
Definition voice_modulation_buffer.hpp:16
@ Pressure
Definition voice_modulation_buffer.hpp:13
@ Aux0
Definition voice_modulation_buffer.hpp:15
@ Timbre
Definition voice_modulation_buffer.hpp:14
VoiceRuntimeFacadeStatus
Definition voice_runtime_facade.hpp:183
@ OwnerRejected
Definition voice_runtime_facade.hpp:188
@ InvalidModulationCapacity
Definition voice_runtime_facade.hpp:186
@ OwnerNotPrepared
Definition voice_runtime_facade.hpp:185
@ Ok
Definition voice_runtime_facade.hpp:184
@ InvalidTerminationCapacity
Definition voice_runtime_facade.hpp:187
VoiceModulationStatus
Definition voice_modulation_buffer.hpp:30
@ NotPrepared
Definition voice_modulation_buffer.hpp:32
@ InvalidFrameCount
Definition voice_modulation_buffer.hpp:33
@ Ok
Definition voice_modulation_buffer.hpp:31
Definition child_process_manager.hpp:18
Definition custom_node_events.hpp:26
VoiceStealStrategy
Voice-stealing strategy applied when note_on fires and no free voice is available.
Definition synthesiser.hpp:54
@ Oldest
Steal the oldest active voice (smallest note_id).
Definition synthesiser.hpp:56
@ Priority
Steal the voice with the lowest priority.
Definition synthesiser.hpp:68
@ Highest
Steal the voice with the highest MIDI note number.
Definition synthesiser.hpp:65
@ Quietest
Steal the voice currently reporting the lowest peak_level().
Definition synthesiser.hpp:61
@ Lowest
Steal the voice with the lowest MIDI note number.
Definition synthesiser.hpp:63
@ buffer
A borrowed static buffer with a traversable playhead.
Definition granular.hpp:110
@ i
Definition formant_filter_bank.hpp:20
@ value
the widget's primary value (Knob, Fader, RangeSlider, Toggle, ProgressBar)
Definition binding_diagnostics.hpp:19
@ j
Definition input_events.hpp:40
Definition voice_runtime_facade.hpp:191
VoiceAllocationResult allocation
Definition voice_runtime_facade.hpp:193
VoiceRuntimeFacadeStatus status
Definition voice_runtime_facade.hpp:192
bool ok() const noexcept
Definition voice_runtime_facade.hpp:195
Definition instrument_voice_allocator.hpp:47
Definition instrument_voice_allocator.hpp:56
Definition voice_runtime_facade.hpp:40
VoiceNoteModulationStatus status
Definition voice_runtime_facade.hpp:42
bool ok
Definition voice_runtime_facade.hpp:41
VoiceModulationStatus buffer_status
Definition voice_runtime_facade.hpp:43
Explicit mapping from note semantics to VoiceModulationBuffer targets.
Definition voice_runtime_facade.hpp:66
VoiceModulationTarget timbre
Definition voice_runtime_facade.hpp:71
VoiceModulationTarget pitch
Definition voice_runtime_facade.hpp:67
VoiceModulationTarget pressure
Definition voice_runtime_facade.hpp:70
VoiceModulationTarget expression
Definition voice_runtime_facade.hpp:72
VoiceModulationTarget gate
Definition voice_runtime_facade.hpp:69
VoiceModulationTarget velocity
Definition voice_runtime_facade.hpp:68
Definition voice_sum_mixer.hpp:16
Definition voice_sum_mixer.hpp:20
Constant note-on metadata for MIDI-buffer dispatch.
Definition synthesiser.hpp:219
Definition synthesiser.hpp:71
Generic MIDI-1 polyphonic synth framework.