44 r.bend_octaves = 1.0f;
47 r.brightness_octaves = 0.8f;
51 void set_tune_hz(
double hz) { tune_hz_ = std::clamp(hz, 20.0, 4000.0); }
55 pitch_sweep_oct_ = std::clamp(octaves, 0.0, 6.0);
60 void set_decay_ms(
double ms) { decay_ms_ = std::clamp(ms, 10.0, 4000.0); }
66 void set_distortion(
double amount) { distortion_ = std::clamp(amount, 0.0, 1.0); }
71 resonant_depth_ = std::clamp(multiples, 1.0, 32.0);
80 void set_ring(
double amount) { ring_ = std::clamp(amount, 0.0, 1.0); }
88 return output_.latency_samples();
91 return output_.oversampling();
94 output_.set_oversampling(factor);
122 output_.reset_nonlinear_state();
125 velocity_gain_ = response.gain(
velocity);
126 applied_bend_ = pitch_sweep_oct_ + response.bend(
velocity);
129 applied_distortion_ =
130 std::clamp(distortion_ *
static_cast<double>(response.brightness_scale(
velocity)),
135 osc_a_.set_shape(shape_);
136 osc_b_.set_shape(shape_);
137 osc_a_.set_resonant_depth(resonant_depth_);
138 osc_b_.set_resonant_depth(resonant_depth_);
142 pitch_env_.set_attack_ms(0.0);
143 pitch_env_.set_decay_time_constant_ms(pitch_sweep_ms_);
144 pitch_env_.trigger();
148 dcw_env_.set_attack_ms(0.0);
149 dcw_env_.set_decay_time_constant_ms(distortion_ms_);
152 amp_env_.set_attack_ms(0.3);
153 amp_env_.set_decay_t60_ms(decay_ms_);
158 return amp_env_.is_active() || output_.has_tail();
162 const double detune = std::pow(2.0, detune_cents_ / 1200.0);
164 for (
int i = 0;
i < num_samples; ++
i) {
165 const double pitch = pitch_env_.process();
166 const double dcw = dcw_env_.process();
167 const double amplitude = amp_env_.process();
169 const double f = tune_hz_ * std::exp2(applied_bend_ * pitch);
170 osc_a_.set_frequency(f);
171 osc_b_.set_frequency(f *
detune);
173 const double warp = applied_distortion_ * dcw;
174 osc_a_.set_amount(warp);
175 osc_b_.set_amount(warp);
177 double mixed = 0.5 * (
static_cast<double>(osc_a_.process()) +
178 static_cast<double>(osc_b_.process()));
182 if (ring_phase_ >= 1.0) ring_phase_ -= std::floor(ring_phase_);
183 mixed += ring_ * mixed *
184 std::cos(2.0 * 3.14159265358979323846 * ring_phase_);
189 const double centred = dc_.process(
static_cast<float>(mixed));
190 const double gated = gate_.process(
static_cast<float>(centred * amplitude),
192 out[
i] +=
static_cast<float>(
193 output_.process(
static_cast<float>(
gated)) * velocity_gain_);
198 double tune_hz_ = 220.0;
199 double pitch_sweep_oct_ = 2.5;
200 double pitch_sweep_ms_ = 35.0;
201 double decay_ms_ = 350.0;
203 double distortion_ = 0.8;
204 double distortion_ms_ = 60.0;
205 double resonant_depth_ = 12.0;
206 double detune_cents_ = 9.0;
208 double ring_ratio_ = 1.5;
219 double velocity_gain_ = 1.0;
220 double applied_bend_ = 2.5;
221 double applied_distortion_ = 0.8;
222 double ring_phase_ = 0.0;
One-pole DC blocker (first-order high-pass).
Definition dc_blocker.hpp:28
double sample_rate() const
Definition voice.hpp:105
void set_velocity_response(const VelocityResponse &r)
Definition voice.hpp:129
float velocity() const
Definition voice.hpp:104
const VelocityResponse & velocity_response() const
Definition voice.hpp:130
LowpassGate & gate()
Definition zap.hpp:83
void set_pitch_sweep_octaves(double octaves)
Depth and time constant of the pitch drop, in octaves.
Definition zap.hpp:54
void set_detune_cents(double cents)
Detune of the second oscillator, in cents.
Definition zap.hpp:75
bool on_is_active() const override
Definition zap.hpp:157
void set_ring_ratio(double ratio)
Definition zap.hpp:81
void on_prepare(double sample_rate) override
Sizes buffers and fixes coefficients.
Definition zap.hpp:98
void set_distortion(double amount)
Distortion depth at the start of the hit, and how quickly it collapses.
Definition zap.hpp:66
void render_add(float *out, int num_samples) override
Adds the voice's output into out. Must add, never assign.
Definition zap.hpp:161
void set_ring(double amount)
Depth of a ring modulation applied to the pair, and its ratio to the tuning.
Definition zap.hpp:80
int latency_samples() const noexcept override
Fixed host-rate delay introduced by this voice's selected output quality.
Definition zap.hpp:87
void set_pitch_sweep_ms(double ms)
Definition zap.hpp:57
void set_output_oversampling(OutputOversampling factor) override
Definition zap.hpp:93
OutputStage * output_stage() noexcept override
The terminal saturation and degradation stage, at the generic voice boundary.
Definition zap.hpp:86
OutputStage & output()
Definition zap.hpp:84
void set_tune_hz(double hz)
Definition zap.hpp:51
void set_shape(PhaseDistortionShape shape)
Definition zap.hpp:62
const OutputStage & output() const
Definition zap.hpp:85
void set_decay_ms(double ms)
How long the note lasts, as a T60.
Definition zap.hpp:60
void on_note_on(float velocity) override
Starts a hit at the given velocity, already clamped to [0, 1].
Definition zap.hpp:121
void set_resonant_depth(double multiples)
Highest carrier multiple the resonant shapes reach.
Definition zap.hpp:70
void on_reset() override
Clears every piece of state the voice carries, so is_active() becomes false and the next render start...
Definition zap.hpp:109
void set_distortion_ms(double ms)
Definition zap.hpp:67
OutputOversampling output_oversampling() const noexcept override
Output quality at the generic voice boundary.
Definition zap.hpp:90
ZapVoice()
Definition zap.hpp:41
OutputOversampling
Realtime quality choices for the shared drum output nonlinearity.
Definition output_stage.hpp:20
OutputStageT< float > OutputStage
Definition output_stage.hpp:384
PhaseDistortionOscT< float > PhaseDistortionOsc
Definition phase_distortion.hpp:116
@ ratio
base_frequency_hz * ratio.
Definition fm_operator_engine.hpp:20
@ i
Definition formant_filter_bank.hpp:20
PhaseDistortionShape
Which phase warp a PhaseDistortionOscT applies.
Definition phase_distortion.hpp:9
@ resonant_saw
a swept carrier windowed by a falling ramp
Definition phase_distortion.hpp:12
@ gated
Flat body, hard cut.
Definition nonlin_ambience_design.hpp:245
DecayEnvelopeT< double > DecayEnvelope64
Definition decay_envelope.hpp:201
@ detune
Sub-semitone offset scaled by the pedal. Dry on.
Definition pitch_shifter.hpp:171
LowpassGateT< float > LowpassGate
Definition lowpass_gate.hpp:138
How hard a hit changes the sound, beyond changing how loud it is.
Definition velocity.hpp:33