Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::host::synthesis::vocoder Namespace Reference

Classes

struct  Instance

Typedefs

using Voc = signal::Vocoder

Functions

float vocoder_worst_case_gain (double sample_rate=48000.0)
 Worst-case linear gain for the Forge registry (series law 8).
float vocoder_all_sample_rates_worst_case_gain ()
 Sample-rate-independent ceiling for registries whose metadata cannot vary with the host rate.
CustomNodeType make_vocoder_node ()
 Two inputs, one output.
ForgeNodeDescriptor descriptor ()

Variables

constexpr const char * kTypeId = "synthesis.vocoder"
constexpr PortIndex kModulatorPort = 0
 Input port roles.
constexpr PortIndex kCarrierPort = 1
constexpr state::ParamID kBandCount = 1
constexpr state::ParamID kFreqLoHz = 2
constexpr state::ParamID kFreqHiHz = 3
constexpr state::ParamID kCarrierSource = 4
constexpr state::ParamID kInternalWave = 5
constexpr state::ParamID kInternalPw = 6
constexpr state::ParamID kCarrierPitchHz = 7
constexpr state::ParamID kNoiseMix = 8
constexpr state::ParamID kAttackMs = 9
constexpr state::ParamID kReleaseMs = 10
constexpr state::ParamID kUnvoicedSens = 11
constexpr state::ParamID kSibilanceMix = 12
constexpr state::ParamID kFormantShiftSt = 13
constexpr state::ParamID kFormantFreeze = 14
constexpr state::ParamID kOutputTrimDb = 15
constexpr state::ParamID kDryWet = 16

Typedef Documentation

◆ Voc

Function Documentation

◆ descriptor()

ForgeNodeDescriptor pulp::host::synthesis::vocoder::descriptor ( )

◆ make_vocoder_node()

CustomNodeType pulp::host::synthesis::vocoder::make_vocoder_node ( )

Two inputs, one output.

See this file's header for why the ports are plain audio ports rather than a sidechain, and why the modulator is port 0.

◆ vocoder_all_sample_rates_worst_case_gain()

float pulp::host::synthesis::vocoder::vocoder_all_sample_rates_worst_case_gain ( )

Sample-rate-independent ceiling for registries whose metadata cannot vary with the host rate.

The high-pass L1 term approaches (but never exceeds) 2 as the sample rate rises, so this is the supremum of vocoder_worst_case_gain(sample_rate) over every positive sample rate.

◆ vocoder_worst_case_gain()

float pulp::host::synthesis::vocoder::vocoder_worst_case_gain ( double sample_rate = 48000.0)

Worst-case linear gain for the Forge registry (series law 8).

The DSP's own asserted invariant is the RECONSTRUCTION bound: its suite measures the summed synthesis bank against kWorstCaseGain at every band count from 10 to 20, with the per-band VcaT clamp making that a bound rather than an estimate. But the node exposes two things the DSP's own T-GAIN case deliberately parks: the sibilance path (which that test sets to zero so the bank's bound is measured alone) and the output trim. A baked param can be automated anywhere in its declared range, so the node's number has to include both — the FET compressor reports at its parameter ceilings for the same reason.

Assembled from shipped constants:

  • the trimmed bank, kOutputHeadroomTrim · kWorstCaseGain — 1.0, which is the ≤ 1 the DSP suite asserts post-trim;
  • plus the sibilance path at its ceiling, sibilance_mix · u · |hp| with both controls at 1 and hp a first-order high-pass whose L1 norm is 2/(1 + tan(π f_c/f_s)) — just under 2, not the unity its PASSBAND gain suggests, which is the same distinction the chorus family's cross-feed term turns on;
  • all of it times the output trim's ceiling.

The dry/wet blend cannot raise it: it is a convex combination of that wet sum and a dry signal bounded by 1.

This is a GAIN, i.e. a bound for |input| ≤ 1, and the premise matters more here than it does for most nodes. The two paths respond to input level completely differently: the bank's is amplitude-INSENSITIVE, because the per-band VcaT clamps its control and a louder modulator only saturates it sooner — while the sibilance path is amplitude-PROPORTIONAL, passing the modulator's own high end straight to the output. A modulator driven 20 dB hot therefore does not make the vocoding 20 dB louder; it makes the SIBILANCE 20 dB louder, and the balance the sibilance_mix control sets moves under the level. Worth knowing at the mixer as well as at the bound.

Sample-rate dependent through the high-pass term, which is why this takes a rate rather than pretending to be a constant.

Variable Documentation

◆ kAttackMs

state::ParamID pulp::host::synthesis::vocoder::kAttackMs = 9
inlineconstexpr

◆ kBandCount

state::ParamID pulp::host::synthesis::vocoder::kBandCount = 1
inlineconstexpr

◆ kCarrierPitchHz

state::ParamID pulp::host::synthesis::vocoder::kCarrierPitchHz = 7
inlineconstexpr

◆ kCarrierPort

PortIndex pulp::host::synthesis::vocoder::kCarrierPort = 1
inlineconstexpr

◆ kCarrierSource

state::ParamID pulp::host::synthesis::vocoder::kCarrierSource = 4
inlineconstexpr

◆ kDryWet

state::ParamID pulp::host::synthesis::vocoder::kDryWet = 16
inlineconstexpr

◆ kFormantFreeze

state::ParamID pulp::host::synthesis::vocoder::kFormantFreeze = 14
inlineconstexpr

◆ kFormantShiftSt

state::ParamID pulp::host::synthesis::vocoder::kFormantShiftSt = 13
inlineconstexpr

◆ kFreqHiHz

state::ParamID pulp::host::synthesis::vocoder::kFreqHiHz = 3
inlineconstexpr

◆ kFreqLoHz

state::ParamID pulp::host::synthesis::vocoder::kFreqLoHz = 2
inlineconstexpr

◆ kInternalPw

state::ParamID pulp::host::synthesis::vocoder::kInternalPw = 6
inlineconstexpr

◆ kInternalWave

state::ParamID pulp::host::synthesis::vocoder::kInternalWave = 5
inlineconstexpr

◆ kModulatorPort

PortIndex pulp::host::synthesis::vocoder::kModulatorPort = 0
inlineconstexpr

Input port roles.

Named constants rather than bare 0 and 1, because the one mistake this node cannot survive is a transposition and a named port is harder to swap by accident than an integer literal.

◆ kNoiseMix

state::ParamID pulp::host::synthesis::vocoder::kNoiseMix = 8
inlineconstexpr

◆ kOutputTrimDb

state::ParamID pulp::host::synthesis::vocoder::kOutputTrimDb = 15
inlineconstexpr

◆ kReleaseMs

state::ParamID pulp::host::synthesis::vocoder::kReleaseMs = 10
inlineconstexpr

◆ kSibilanceMix

state::ParamID pulp::host::synthesis::vocoder::kSibilanceMix = 12
inlineconstexpr

◆ kTypeId

const char* pulp::host::synthesis::vocoder::kTypeId = "synthesis.vocoder"
inlineconstexpr

◆ kUnvoicedSens

state::ParamID pulp::host::synthesis::vocoder::kUnvoicedSens = 11
inlineconstexpr