55 if (voice !=
nullptr) {
59 return slots_.size() - 1;
76 oversampling_ = factor;
77 for (
auto& slot : slots_) {
78 if (slot.voice !=
nullptr)
79 slot.voice->set_output_oversampling(oversampling_);
81 for (
const auto& slot : slots_) {
82 if (slot.voice !=
nullptr &&
83 slot.voice->output_oversampling() != oversampling_) {
88 for (
auto& fallback_slot : slots_) {
89 if (fallback_slot.voice !=
nullptr)
90 fallback_slot.voice->set_output_oversampling(
99 sample_rate_ = sample_rate > 0.0 ? sample_rate : sample_rate_;
100 for (
auto& slot : slots_) {
101 if (slot.voice !=
nullptr) {
102 slot.voice->set_output_oversampling(oversampling_);
103 slot.voice->prepare(sample_rate_);
113 for (
auto& slot : slots_) {
114 if (slot.voice !=
nullptr) slot.voice->reset();
122 for (std::size_t
i = 0;
i < slots_.size(); ++
i) {
123 if (slots_[
i].note == note) {
133 if (index >= slots_.size() || slots_[index].voice ==
nullptr)
return;
135 slots_[index].voice->set_output_oversampling(oversampling_);
136 const int group = slots_[index].choke_group;
138 for (std::size_t other = 0; other < slots_.size(); ++other) {
139 if (other == index || slots_[other].
choke_group != group)
continue;
140 if (slots_[other].voice !=
nullptr) {
141 slots_[other].voice->choke(choke_fade_ms_);
145 slots_[index].voice->note_on(velocity);
151 if (group == 0)
return;
152 for (
auto& slot : slots_) {
153 if (slot.choke_group == group && slot.voice !=
nullptr) {
154 slot.voice->choke(choke_fade_ms_);
161 for (
const auto& slot : slots_) {
162 if (slot.voice !=
nullptr && slot.voice->is_active())
return true;
170 if (out ==
nullptr || num_samples <= 0)
return;
171 for (
auto& slot : slots_) {
172 if (slot.voice !=
nullptr && slot.voice->is_active()) {
173 slot.voice->set_output_oversampling(oversampling_);
174 slot.voice->process(out, num_samples);
181 Voice* voice =
nullptr;
186 std::vector<Slot> slots_;
187 double sample_rate_ = 44100.0;
188 float choke_fade_ms_ = 4.0f;
A set of percussion voices summed into one output, with choke groups.
Definition kit.hpp:40
void choke_group(int group)
Fades out every voice in group.
Definition kit.hpp:150
void process(float *out, int num_samples)
Adds every active voice's output into out.
Definition kit.hpp:169
void reset()
Silences every voice immediately, without fades. For transport stops.
Definition kit.hpp:112
OutputOversampling output_oversampling() const noexcept
Definition kit.hpp:71
void set_output_oversampling(OutputOversampling factor)
Definition kit.hpp:75
void set_choke_fade_ms(float ms)
How long a choked voice takes to fade out, in milliseconds.
Definition kit.hpp:109
void trigger(int note, float velocity)
Triggers the voice registered under note, choking any other voice in the same group first.
Definition kit.hpp:121
bool is_active() const
Whether any voice is still rendering.
Definition kit.hpp:160
int latency_samples() const noexcept
One latency for the whole summed kit.
Definition kit.hpp:67
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 ...
Definition kit.hpp:132
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 num...
Definition kit.hpp:48
void prepare(double sample_rate)
Definition kit.hpp:98
std::size_t voice_count() const
Definition kit.hpp:62
static constexpr int latency_samples_for(OutputOversampling factor) noexcept
Definition output_stage.hpp:97
The lifecycle every percussion voice shares.
Definition voice.hpp:52
void prepare(double sample_rate)
Fixes the sample rate and clears all state.
Definition voice.hpp:62
OutputOversampling
Realtime quality choices for the shared drum output nonlinearity.
Definition output_stage.hpp:20
@ x2
Definition output_stage.hpp:22
@ bypass
Definition output_stage.hpp:21
@ i
Definition formant_filter_bank.hpp:20