Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::signal::drum::KickVoice Class Reference

A kick drum. More...

#include <kick.hpp>

Public Member Functions

 KickVoice ()
void set_body (KickBody body)
KickBody body () const
void set_tune_hz (double hz)
 Fundamental of the body, in Hz.
void set_body_decay_ms (double ms)
 How long the body rings, as a T60 in milliseconds.
void set_pitch_sweep_octaves (double octaves)
 Depth of the downward pitch sweep, in octaves, and how quickly it settles.
void set_pitch_sweep_ms (double ms)
void set_click_level (double level)
 Level of the attack click, and the corner of the one-pole that tones it.
void set_click_tone_hz (double hz)
void set_click_decay_ms (double ms)
void set_noise_level (double level)
 Level and decay of the noise layer.
void set_noise_decay_ms (double ms)
void set_noise_color (NoiseColor color)
void set_sub_level (double level)
 Level of the sub layer, a sine an octave below the body gated by the body's own envelope.
OutputStage & output ()
 The saturation and degradation stage the voice ends with.
const OutputStage & output () const
OutputStage * output_stage () noexcept override
 The terminal saturation and degradation stage, at the generic voice boundary.
int latency_samples () const noexcept override
 Fixed host-rate delay introduced by this voice's selected output quality.
OutputOversampling output_oversampling () const noexcept override
 Output quality at the generic voice boundary.
void set_output_oversampling (OutputOversampling factor) override
void set_oscillator_triangle (bool triangle)
 Triangle instead of sine.
void set_fm_amount (double amount)
 Phase-modulation depth and the modulator's frequency ratio.
void set_fm_ratio (double ratio)
void set_circuit_components (const BridgedTComponents &c)
 Component values of the bridged-T network.
void set_circuit_feedback (double gain)
 Regeneration around the network, 0 to 1.
void set_circuit_attack_ms (double ms)
 How long the attack shunt grounds the transistor's collector after a trigger.
void set_circuit_pulse_ms (double ms)
 Width of the trigger pulse into the pulse shaper, in milliseconds.
void set_circuit_drive (double amount)
 How hard the trigger drives the network, 0 to 1.
void set_circuit_sigh (bool enabled)
 Disconnect the leakage path that produces the pitch sigh.
void set_circuit_hit_life (HitLifeMode mode)
 Select whether circuit retriggers restart, vary their excitation, or preserve the network memory.
HitLifeMode circuit_hit_life () const
void prepare (double sample_rate)
 Fixes the sample rate and clears all state.
void reset ()
 Silences the voice immediately, without a fade.
void note_on (float velocity)
 Starts a hit. velocity is in [0, 1]; values outside are clamped.
void choke (float fade_ms=4.0f)
 Fades the voice out over fade_ms and then silences it.
bool is_active () const
 Whether the voice still has something to render.
VoiceState state () const
float velocity () const
double sample_rate () const
const OutputStage * output_stage () const noexcept
void set_velocity_response (const VelocityResponse &r)
const VelocityResponse & velocity_response () const
void process (float *out, int num_samples)
 Adds num_samples of this voice's output into out.
void process_stereo (float *left, float *right, int num_samples)
 Adds a stereo rendering to left and right.

Protected Member Functions

void on_prepare (double sample_rate) override
 Sizes buffers and fixes coefficients.
void on_reset () override
 Clears every piece of state the voice carries, so is_active() becomes false and the next render starts from silence.
void on_note_on (float velocity) override
 Starts a hit at the given velocity, already clamped to [0, 1].
bool on_is_active () const override
void render_add (float *out, int num_samples) override
 Adds the voice's output into out. Must add, never assign.
virtual void render_add_stereo (float *left, float *right, int num_samples)
 Optional stereo realization.

Detailed Description

A kick drum.

The layers are the ones every electronic kick has had since the 1970s: a body that carries the pitch, a click that carries the attack, a noise layer that carries the air the beater moves, and an optional sub an octave down for systems that reproduce it. What distinguishes one machine's kick from another's is almost entirely how the body is made, which is what KickBody selects.

Velocity reaches timbre through VelocityResponse: harder hits bend the pitch further and brighten the click, which is what a beater striking a head harder actually does. The default response has both enabled, so a caller gets a velocity-sensitive kick without configuring one.

RT contract: prepare() allocates nothing; every other method, including note_on and process, allocates nothing and takes no locks.

Constructor & Destructor Documentation

◆ KickVoice()

pulp::signal::drum::KickVoice::KickVoice ( )
inline

Member Function Documentation

◆ body()

KickBody pulp::signal::drum::KickVoice::body ( ) const
inline

◆ choke()

void pulp::signal::drum::Voice::choke ( float fade_ms = 4.0f)
inlineinherited

Fades the voice out over fade_ms and then silences it.

Used by choke groups; a shorter fade is more abrupt but never clicks the way an instant cut does.

◆ circuit_hit_life()

HitLifeMode pulp::signal::drum::KickVoice::circuit_hit_life ( ) const
inline

◆ is_active()

bool pulp::signal::drum::Voice::is_active ( ) const
inlineinherited

Whether the voice still has something to render.

A kit uses this to skip voices entirely rather than summing silence.

◆ latency_samples()

int pulp::signal::drum::KickVoice::latency_samples ( ) const
inlineoverridevirtualnoexcept

Fixed host-rate delay introduced by this voice's selected output quality.

Generic registry consumers can report it without recovering the concrete voice type.

Reimplemented from pulp::signal::drum::Voice.

◆ note_on()

void pulp::signal::drum::Voice::note_on ( float velocity)
inlineinherited

Starts a hit. velocity is in [0, 1]; values outside are clamped.

◆ on_is_active()

bool pulp::signal::drum::KickVoice::on_is_active ( ) const
inlineoverrideprotectedvirtual

◆ on_note_on()

void pulp::signal::drum::KickVoice::on_note_on ( float velocity)
inlineoverrideprotectedvirtual

Starts a hit at the given velocity, already clamped to [0, 1].

Implements pulp::signal::drum::Voice.

◆ on_prepare()

void pulp::signal::drum::KickVoice::on_prepare ( double sample_rate)
inlineoverrideprotectedvirtual

Sizes buffers and fixes coefficients.

The only hook allowed to allocate.

Implements pulp::signal::drum::Voice.

◆ on_reset()

void pulp::signal::drum::KickVoice::on_reset ( )
inlineoverrideprotectedvirtual

Clears every piece of state the voice carries, so is_active() becomes false and the next render starts from silence.

Implements pulp::signal::drum::Voice.

◆ output() [1/2]

OutputStage & pulp::signal::drum::KickVoice::output ( )
inline

The saturation and degradation stage the voice ends with.

◆ output() [2/2]

const OutputStage & pulp::signal::drum::KickVoice::output ( ) const
inline

◆ output_oversampling()

OutputOversampling pulp::signal::drum::KickVoice::output_oversampling ( ) const
inlineoverridevirtualnoexcept

Output quality at the generic voice boundary.

Kits use this surface to keep every registered path on one latency contract.

Reimplemented from pulp::signal::drum::Voice.

◆ output_stage() [1/2]

OutputStage * pulp::signal::drum::KickVoice::output_stage ( )
inlineoverridevirtualnoexcept

The terminal saturation and degradation stage, at the generic voice boundary.

A registry consumer reaches it without recovering the concrete voice type, so adding an engine cannot desynchronise a downcast from the engine it was selected for. A voice that ends without one returns nullptr.

Reimplemented from pulp::signal::drum::Voice.

◆ output_stage() [2/2]

const OutputStage * pulp::signal::drum::Voice::output_stage ( ) const
inlinenoexceptinherited

◆ prepare()

void pulp::signal::drum::Voice::prepare ( double sample_rate)
inlineinherited

Fixes the sample rate and clears all state.

The only method a derived voice may allocate in.

◆ process()

void pulp::signal::drum::Voice::process ( float * out,
int num_samples )
inlineinherited

Adds num_samples of this voice's output into out.

◆ process_stereo()

void pulp::signal::drum::Voice::process_stereo ( float * left,
float * right,
int num_samples )
inlineinherited

Adds a stereo rendering to left and right.

Voices that do not provide a stereo realization are placed in the centre with half their mono signal in each channel, so summing the two channels reproduces process() exactly. A stereo-capable voice may override render_add_stereo, but the shared choke fade remains here.

◆ render_add()

void pulp::signal::drum::KickVoice::render_add ( float * out,
int num_samples )
inlineoverrideprotectedvirtual

Adds the voice's output into out. Must add, never assign.

Implements pulp::signal::drum::Voice.

◆ render_add_stereo()

virtual void pulp::signal::drum::Voice::render_add_stereo ( float * left,
float * right,
int num_samples )
inlineprotectedvirtualinherited

Optional stereo realization.

The default is centre-panned and preserves exact mono-sum equivalence.

Reimplemented in pulp::signal::drum::ClapVoice.

◆ reset()

void pulp::signal::drum::Voice::reset ( )
inlineinherited

Silences the voice immediately, without a fade.

For transport stops and buffer-size changes, where a click cannot be heard because nothing is playing either side of it.

◆ sample_rate()

double pulp::signal::drum::Voice::sample_rate ( ) const
inlineinherited

◆ set_body()

void pulp::signal::drum::KickVoice::set_body ( KickBody body)
inline

◆ set_body_decay_ms()

void pulp::signal::drum::KickVoice::set_body_decay_ms ( double ms)
inline

How long the body rings, as a T60 in milliseconds.

◆ set_circuit_attack_ms()

void pulp::signal::drum::KickVoice::set_circuit_attack_ms ( double ms)
inline

How long the attack shunt grounds the transistor's collector after a trigger.

The shunt lifts the centre frequency by over an octave, so this is the length of the thump before the note settles.

◆ set_circuit_components()

void pulp::signal::drum::KickVoice::set_circuit_components ( const BridgedTComponents & c)
inline

Component values of the bridged-T network.

Substituting a capacitor retunes the drum the way it does on the bench.

◆ set_circuit_drive()

void pulp::signal::drum::KickVoice::set_circuit_drive ( double amount)
inline

How hard the trigger drives the network, 0 to 1.

Unlike most drive controls this one is not a taste control layered on top of a working circuit – it moves the network through the only range in which it behaves at all, so the control is mapped across that window rather than across an arbitrary one.

At 0 the ring only just pushes the transistor past its conduction knee, so the pitch drop is at its weakest. Below that window the drop stops happening entirely, which is why 0 is the floor. At 1 the op-amp is approaching its supply rail, so the ring begins to flatten into a square. Both ends are audible character rather than faults, and they are reachable on purpose: clamping the range to the middle would remove the two sounds the circuit is most recognisable for.

◆ set_circuit_feedback()

void pulp::signal::drum::KickVoice::set_circuit_feedback ( double gain)
inline

Regeneration around the network, 0 to 1.

This is the 808's decay control: the loop replaces some of what the network dissipates each cycle, so more feedback is a longer ring rather than a louder one.

The control is normalised rather than being the raw loop gain, because the raw gain has a hard ceiling: past about 0.87 the loop replaces more than the network loses and the drum becomes an oscillator that never stops. 1 here maps to just under that, which is a very long ring and still a drum. The real instrument's decay pot has an end stop for the same reason.

◆ set_circuit_hit_life()

void pulp::signal::drum::KickVoice::set_circuit_hit_life ( HitLifeMode mode)
inline

Select whether circuit retriggers restart, vary their excitation, or preserve the network memory.

The authentic default is preserved_state.

◆ set_circuit_pulse_ms()

void pulp::signal::drum::KickVoice::set_circuit_pulse_ms ( double ms)
inline

Width of the trigger pulse into the pulse shaper, in milliseconds.

◆ set_circuit_sigh()

void pulp::signal::drum::KickVoice::set_circuit_sigh ( bool enabled)
inline

Disconnect the leakage path that produces the pitch sigh.

Proves the sigh is emergent rather than scripted, and is a usable sound in itself.

◆ set_click_decay_ms()

void pulp::signal::drum::KickVoice::set_click_decay_ms ( double ms)
inline

◆ set_click_level()

void pulp::signal::drum::KickVoice::set_click_level ( double level)
inline

Level of the attack click, and the corner of the one-pole that tones it.

A click is a noise burst through a lowpass: lowering the corner turns a beater tick into a thump.

◆ set_click_tone_hz()

void pulp::signal::drum::KickVoice::set_click_tone_hz ( double hz)
inline

◆ set_fm_amount()

void pulp::signal::drum::KickVoice::set_fm_amount ( double amount)
inline

Phase-modulation depth and the modulator's frequency ratio.

Modulation adds inharmonic partials to the attack without lengthening it.

◆ set_fm_ratio()

void pulp::signal::drum::KickVoice::set_fm_ratio ( double ratio)
inline

◆ set_noise_color()

void pulp::signal::drum::KickVoice::set_noise_color ( NoiseColor color)
inline

◆ set_noise_decay_ms()

void pulp::signal::drum::KickVoice::set_noise_decay_ms ( double ms)
inline

◆ set_noise_level()

void pulp::signal::drum::KickVoice::set_noise_level ( double level)
inline

Level and decay of the noise layer.

◆ set_oscillator_triangle()

void pulp::signal::drum::KickVoice::set_oscillator_triangle ( bool triangle)
inline

Triangle instead of sine.

A triangle body carries odd harmonics, which survive small speakers where a sine disappears.

◆ set_output_oversampling()

void pulp::signal::drum::KickVoice::set_output_oversampling ( OutputOversampling factor)
inlineoverridevirtual

Reimplemented from pulp::signal::drum::Voice.

◆ set_pitch_sweep_ms()

void pulp::signal::drum::KickVoice::set_pitch_sweep_ms ( double ms)
inline

◆ set_pitch_sweep_octaves()

void pulp::signal::drum::KickVoice::set_pitch_sweep_octaves ( double octaves)
inline

Depth of the downward pitch sweep, in octaves, and how quickly it settles.

These apply to the oscillator body only. The resonant body is struck at a fixed frequency, and the circuit body produces its sweep from the network; both ignore these. The velocity bend is carried on the same term, so it too reaches the oscillator body alone – which is why the Forge catalog declares neither control on the other bodies.

Octaves rather than a linear multiplier, so the sweep composes additively with the velocity bend, which is also in octaves. A depth quoted in the multiplier form converts as octaves = log2(1 + amount).

◆ set_sub_level()

void pulp::signal::drum::KickVoice::set_sub_level ( double level)
inline

Level of the sub layer, a sine an octave below the body gated by the body's own envelope.

◆ set_tune_hz()

void pulp::signal::drum::KickVoice::set_tune_hz ( double hz)
inline

Fundamental of the body, in Hz.

◆ set_velocity_response()

void pulp::signal::drum::Voice::set_velocity_response ( const VelocityResponse & r)
inlineinherited

◆ state()

VoiceState pulp::signal::drum::Voice::state ( ) const
inlineinherited

◆ velocity()

float pulp::signal::drum::Voice::velocity ( ) const
inlineinherited

◆ velocity_response()

const VelocityResponse & pulp::signal::drum::Voice::velocity_response ( ) const
inlineinherited

The documentation for this class was generated from the following file:
  • /home/runner/work/pulp/pulp/core/signal/include/pulp/signal/drum/kick.hpp