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

A snare drum. More...

#include <snare.hpp>

Public Member Functions

 SnareVoice ()
void set_tune_hz (double hz)
 Fundamental of the lower tone oscillator, in Hz.
void set_tone_ratio (double ratio)
 Frequency ratio of the upper tone oscillator to the lower.
void set_tone_level (double level)
void set_tone_decay_ms (double ms)
void set_pitch_sweep_octaves (double octaves)
 Depth and time constant of the shared downward pitch sweep, in octaves.
void set_pitch_sweep_ms (double ms)
void set_fm_amount (double amount)
 Phase-modulation depth of the upper oscillator into the lower.
void set_ring (double amount)
 Crossfade from the two oscillators summed (0) to ring-modulated (1).
void set_noise_level (double level)
void set_noise_decay_ms (double ms)
void set_noise_color (NoiseColor color)
void set_noise_cutoff_hz (double hz)
 Corner and resonance of the filter the wires are heard through.
void set_noise_resonance (double q)
void set_noise_sweep_octaves (double octaves)
 How far that corner sweeps over the note, in octaves.
void set_rattle (double amount)
 Depth and rate of the wires' buzz against the head.
void set_rattle_hz (double hz)
void set_snap_level (double level)
 The strike itself: a short highpassed crack, distinct from the wires.
void set_snap_cutoff_hz (double hz)
void set_snap_decay_ms (double ms)
void set_shell_level (double level)
 Level of the shell resonance applied to the noise path, and its Q.
void set_shell_resonance (double q)
OutputStage & output ()
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
LofiChain & tone_lofi ()
 Degradation applied to the pitched shell before it meets the wires.
LofiChain & noise_lofi ()
 A second degradation chain on the noise path alone.
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 snare drum.

A snare is two instruments in a shared shell and it has to be built that way. The drum itself is a small tuned membrane, which the tone pair below stands in for; the snares are a set of wires under the bottom head that rattle against it, which is the filtered noise. Neither alone reads as a snare – the tone on its own is a tom, and the noise on its own is a splash – and the balance between them is the single most recognisable control on the instrument.

Three details separate this from a tom with noise added:

  • Two tone oscillators, not one. A snare's shell is small enough that its two lowest modes are close together and beat audibly. One oscillator cannot produce that beating, and the ratio between the two is what makes a snare sound taut rather than hollow.
  • The wires buzz. They are not simply excited by the strike; they leave the head and return, which amplitude-modulates the noise at a rate set by how tight they are. set_rattle is that modulation, and without it the noise layer reads as a hiss laid over a drum.
  • The shell resonates the noise. The high-Q bandpass takes the strike and the wires and puts the shell's own pitch back into them, which is why a snare's noise is pitched even though noise has no pitch.

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

Constructor & Destructor Documentation

◆ SnareVoice()

pulp::signal::drum::SnareVoice::SnareVoice ( )
inline

Member Function Documentation

◆ 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.

◆ 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::SnareVoice::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.

◆ noise_lofi()

LofiChain & pulp::signal::drum::SnareVoice::noise_lofi ( )
inline

A second degradation chain on the noise path alone.

Crushing the wires harder than the shell is a distinct and much-used sound, and one shared chain cannot produce it.

◆ 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::SnareVoice::on_is_active ( ) const
inlineoverrideprotectedvirtual

◆ on_note_on()

void pulp::signal::drum::SnareVoice::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::SnareVoice::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::SnareVoice::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::SnareVoice::output ( )
inline

◆ output() [2/2]

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

◆ output_oversampling()

OutputOversampling pulp::signal::drum::SnareVoice::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::SnareVoice::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::SnareVoice::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_fm_amount()

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

Phase-modulation depth of the upper oscillator into the lower.

◆ set_noise_color()

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

◆ set_noise_cutoff_hz()

void pulp::signal::drum::SnareVoice::set_noise_cutoff_hz ( double hz)
inline

Corner and resonance of the filter the wires are heard through.

◆ set_noise_decay_ms()

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

◆ set_noise_level()

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

◆ set_noise_resonance()

void pulp::signal::drum::SnareVoice::set_noise_resonance ( double q)
inline

◆ set_noise_sweep_octaves()

void pulp::signal::drum::SnareVoice::set_noise_sweep_octaves ( double octaves)
inline

How far that corner sweeps over the note, in octaves.

Positive opens the wires up as they decay; negative closes them down.

◆ set_output_oversampling()

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

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

◆ set_pitch_sweep_ms()

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

◆ set_pitch_sweep_octaves()

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

Depth and time constant of the shared downward pitch sweep, in octaves.

◆ set_rattle()

void pulp::signal::drum::SnareVoice::set_rattle ( double amount)
inline

Depth and rate of the wires' buzz against the head.

◆ set_rattle_hz()

void pulp::signal::drum::SnareVoice::set_rattle_hz ( double hz)
inline

◆ set_ring()

void pulp::signal::drum::SnareVoice::set_ring ( double amount)
inline

Crossfade from the two oscillators summed (0) to ring-modulated (1).

Ring modulation replaces the pair with their sum and difference tones, which removes the fundamentals and leaves a hollow, metallic shell.

◆ set_shell_level()

void pulp::signal::drum::SnareVoice::set_shell_level ( double level)
inline

Level of the shell resonance applied to the noise path, and its Q.

◆ set_shell_resonance()

void pulp::signal::drum::SnareVoice::set_shell_resonance ( double q)
inline

◆ set_snap_cutoff_hz()

void pulp::signal::drum::SnareVoice::set_snap_cutoff_hz ( double hz)
inline

◆ set_snap_decay_ms()

void pulp::signal::drum::SnareVoice::set_snap_decay_ms ( double ms)
inline

◆ set_snap_level()

void pulp::signal::drum::SnareVoice::set_snap_level ( double level)
inline

The strike itself: a short highpassed crack, distinct from the wires.

◆ set_tone_decay_ms()

void pulp::signal::drum::SnareVoice::set_tone_decay_ms ( double ms)
inline

◆ set_tone_level()

void pulp::signal::drum::SnareVoice::set_tone_level ( double level)
inline

◆ set_tone_ratio()

void pulp::signal::drum::SnareVoice::set_tone_ratio ( double ratio)
inline

Frequency ratio of the upper tone oscillator to the lower.

Values between about 1.5 and 1.8 are where a shell's two lowest modes actually sit; further apart the pair stops beating and reads as two drums.

◆ set_tune_hz()

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

Fundamental of the lower tone oscillator, 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

◆ tone_lofi()

LofiChain & pulp::signal::drum::SnareVoice::tone_lofi ( )
inline

Degradation applied to the pitched shell before it meets the wires.

Keeping this separate from both the wire path and the shared output stage lets a preset age either half of the instrument independently.

◆ 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/snare.hpp