|
| std::size_t | add_voice (Voice *voice, int note, int choke_group=0) |
| | Registers a voice under note, which is whatever key a caller wants to address it by – a MIDI note number is the usual choice.
|
| std::size_t | voice_count () const |
| int | latency_samples () const noexcept |
| | One latency for the whole summed kit.
|
| OutputOversampling | output_oversampling () const noexcept |
| void | set_output_oversampling (OutputOversampling factor) |
| void | prepare (double sample_rate) |
| void | set_choke_fade_ms (float ms) |
| | How long a choked voice takes to fade out, in milliseconds.
|
| void | reset () |
| | Silences every voice immediately, without fades. For transport stops.
|
| void | trigger (int note, float velocity) |
| | Triggers the voice registered under note, choking any other voice in the same group first.
|
| void | trigger_slot (std::size_t index, float velocity) |
| | Triggers by slot index, which a caller that kept the index from add_voice uses to avoid searching on the audio thread.
|
| void | choke_group (int group) |
| | Fades out every voice in group.
|
| bool | is_active () const |
| | Whether any voice is still rendering.
|
| void | process (float *out, int num_samples) |
| | Adds every active voice's output into out.
|
A set of percussion voices summed into one output, with choke groups.
The kit does two things a caller would otherwise repeat for every project.
It sums. Voices render additively, so mixing is a loop rather than a pass with scratch buffers, and a voice that has finished is skipped entirely rather than contributing silence. On a sparse pattern most voices are idle most of the time, so that skip is most of the CPU saving a kit gets.
It chokes. A closed hi-hat and an open hi-hat are one pair of cymbals: physically they cannot both ring, because closing the pedal stops the ringing one. Every drum machine reproduces this, and it is the only place in a kit where triggering one voice must silence another. Voices sharing a non-zero choke group cut each other; group 0 means "chokes nothing", which is the default so that a kit assembled without thinking about it behaves like independent drums.
The choke is a short fade rather than a cut – see Voice::choke – so the cymbal stops without a click where the closing hit lands.
The kit does not own its voices. A caller keeps its voices as concrete types so it can reach their specific controls, and registers pointers here; the kit only needs the lifecycle every voice shares. Registered voices must outlive the kit.
RT contract: add_voice() and prepare() may allocate and are setup-time calls. trigger(), choke_group(), process(), and reset() allocate nothing and take no locks.