Runtime values and conversions
Sample rate, sample period, explicit casts, vector constructors and the properties of an external buffer.
Anyone looking up units, types or the values supplied by a host.
A DSP expression often needs information about the world around it: the sample rate, the size of a loaded sample, or the difference between a floating-point position and an integer index. This page puts those small interfaces in one place. Maths functions have their own reference.
processor.frequency#
processor.frequency → float, in HzThe processor's sample rate: how many frames it computes per second. It is
supplied by the host and is available in main() and init. It takes no
arguments and is a property, so do not append parentheses.
let frequencyHz = 440.0f;
let cyclesPerFrame = frequencyHz / processor.frequency;
out <- cyclesPerFrame;At 48 kHz, a 440 Hz oscillator advances by about 0.00917 cycles per frame. Using the supplied rate keeps its pitch correct when the host uses 44.1 or 96 kHz instead. A divided graph node receives its own effective rate.
processor.period#
processor.period → float, in secondsThe reciprocal of the sample rate: 1.0f / processor.frequency. Multiplying
hertz by the period gives cycles per frame; dividing seconds by the period
gives a duration in frames.
let cyclesPerFrame = 440.0f * processor.period;
let samplesInTenMs = int(0.010f / processor.period);
out <- cyclesPerFrame;int(value)#
int(float value) → intParameter: value, a finite float within the signed 32-bit integer range.
Returns: the value with its fractional part discarded toward zero.
int(2.9f) is 2 and int(-2.9f) is -2. This is different from rounding down
with floor, especially for negative positions.
let delaySeconds = 0.25f;
let delaySamples = int(delaySeconds * processor.frequency);
out <- float(delaySamples);A cast changes the type, not the unit. The multiplication changes seconds to samples; the cast then makes that sample count usable as an index.
float(value)#
float(int value) → floatParameter: value, an integer to use in floating-point arithmetic.
Returns: its 32-bit floating-point representation. Large integers may lose
precision: a float cannot represent every integer beyond 16,777,216 exactly.
let index = 7;
let tablePosition = float(index) / 1024.0f;
out <- tablePosition;Pole does not insert numeric conversions for you. Keep both operands the same numeric kind, and write the conversion where the meaning changes from an index to a continuous value.
float<2>(left, right)#
float<2>(float left, float right) → float<2>Parameters: left and right, one float for each lane.
Returns: a stereo pair in that order. This constructs a value; it does not
create a state array.
output stream float<2> out;
let mono = in * 0.5f;
out <- float<2>(mono, mono);Use pair[0] and pair[1] to read individual lanes. The
types chapter covers wider vectors and the
rules for broadcasting.
External-buffer properties#
Declare an external to read data supplied by the host:
external float sample[];
let sampleCount = sample.length;
let sourceRate = sample.rate;
let channelCount = sample.channels;
out <- 0.0f;| Property | Type | Meaning |
|---|---|---|
sample.length | int | Number of elements in the bound buffer. For interleaved scalar audio, this counts all channels' samples. |
sample.rate | float | Source sample rate in Hz. Zero means the host supplied no rate, as can happen for a wavetable. |
sample.channels | int | Source channel count; at least 1. For interleaved stereo data this is 2. |
For scalar interleaved audio, sample.length / sample.channels gives the
number of audio frames. A 100-frame stereo file has 200 scalar elements, not
200 stereo frames. These properties belong to externals; an ordinary state
array has a size declared in the source.
A fixed-size external uses wrapped indexing; a sizeless external uses its runtime length and clamps reads to the available range. See arrays and external state before building a sample player.
advance()#
advance() → frame boundaryTakes no arguments and produces no value to assign. Place it at the end of
the frame loop, after writing outputs and updating state. It is a language
operation, not a maths helper; helpers, event handlers and init cannot use it.
See program structure for a complete processor and the rules for unwritten outputs.