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

A zap: a phase-distortion percussion voice. More...

#include <zap.hpp>

Public Member Functions

 ZapVoice ()
void set_tune_hz (double hz)
void set_pitch_sweep_octaves (double octaves)
 Depth and time constant of the pitch drop, in octaves.
void set_pitch_sweep_ms (double ms)
void set_decay_ms (double ms)
 How long the note lasts, as a T60.
void set_shape (PhaseDistortionShape shape)
void set_distortion (double amount)
 Distortion depth at the start of the hit, and how quickly it collapses.
void set_distortion_ms (double ms)
void set_resonant_depth (double multiples)
 Highest carrier multiple the resonant shapes reach.
void set_detune_cents (double cents)
 Detune of the second oscillator, in cents.
void set_ring (double amount)
 Depth of a ring modulation applied to the pair, and its ratio to the tuning.
void set_ring_ratio (double ratio)
LowpassGate & gate ()
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
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 zap: a phase-distortion percussion voice.

The sound this voice is named for is the one phase distortion is uniquely good at. Two envelopes run at once and they are doing different things: the pitch drops, as in any electronic drum, and the distortion amount drops independently, which sweeps the apparent resonant peak down through the spectrum. Because the peak is produced by reading a cosine at a swept multiple of the phase rather than by a filter, it can be swept faster and further than any filter would stay stable through — which is exactly why the resulting sound has no equivalent in a subtractive voice.

Decoupling the two is the point. Tying the distortion sweep to the pitch sweep gives an ordinary filtered drop; letting the distortion collapse while the pitch is still falling is what produces the zap.

Two oscillators, the second detuned, because a single phase-distortion oscillator is a very pure sound and the beating between two is most of what gives the voice weight.

Lineage: Casio's phase-distortion patent, US 4,658,691 (expired), implemented from the published description. See pulp::signal::PhaseDistortionOscT.

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

Constructor & Destructor Documentation

◆ ZapVoice()

pulp::signal::drum::ZapVoice::ZapVoice ( )
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.

◆ gate()

LowpassGate & pulp::signal::drum::ZapVoice::gate ( )
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::ZapVoice::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::ZapVoice::on_is_active ( ) const
inlineoverrideprotectedvirtual

◆ on_note_on()

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

◆ output() [2/2]

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

◆ output_oversampling()

OutputOversampling pulp::signal::drum::ZapVoice::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]

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

◆ output_stage() [2/2]

OutputStage * pulp::signal::drum::ZapVoice::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.

◆ 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::ZapVoice::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_decay_ms()

void pulp::signal::drum::ZapVoice::set_decay_ms ( double ms)
inline

How long the note lasts, as a T60.

◆ set_detune_cents()

void pulp::signal::drum::ZapVoice::set_detune_cents ( double cents)
inline

Detune of the second oscillator, in cents.

◆ set_distortion()

void pulp::signal::drum::ZapVoice::set_distortion ( double amount)
inline

Distortion depth at the start of the hit, and how quickly it collapses.

This envelope is deliberately independent of the pitch sweep.

◆ set_distortion_ms()

void pulp::signal::drum::ZapVoice::set_distortion_ms ( double ms)
inline

◆ set_output_oversampling()

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

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

◆ set_pitch_sweep_ms()

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

◆ set_pitch_sweep_octaves()

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

Depth and time constant of the pitch drop, in octaves.

◆ set_resonant_depth()

void pulp::signal::drum::ZapVoice::set_resonant_depth ( double multiples)
inline

Highest carrier multiple the resonant shapes reach.

◆ set_ring()

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

Depth of a ring modulation applied to the pair, and its ratio to the tuning.

Ring modulation of an already-swept pair is what takes the voice from a zap toward a clang.

◆ set_ring_ratio()

void pulp::signal::drum::ZapVoice::set_ring_ratio ( double ratio)
inline

◆ set_shape()

void pulp::signal::drum::ZapVoice::set_shape ( PhaseDistortionShape shape)
inline

◆ set_tune_hz()

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

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