Built-in maths
Function signatures, argument descriptions, return values and practical DSP examples for every supported maths builtin.
Anyone looking up a function while writing a patch.
A function call is easiest to use when you can see what goes in and what comes out. Start with the table to find a function, then open its entry for argument order, units, return values and a small example.
The available names and argument counts below are checked against the local compiler. The explanations and examples are maintained alongside that check, and every Pole example is compiled by the documentation verifier.
Quick lookup#
| Call | Use | Scalar types |
|---|---|---|
sin(x) | Trigonometry | float |
cos(x) | Trigonometry | float |
tan(x) | Trigonometry | float |
tanh(x) | Shaping and rounding | float |
exp(x) | Powers and logarithms | float |
log(x) | Powers and logarithms | float |
log10(x) | Powers and logarithms | float |
sqrt(x) | Powers and logarithms | float |
abs(x) | Shaping and rounding | float |
floor(x) | Shaping and rounding | float |
ceil(x) | Shaping and rounding | float |
pow(base, exponent) | Powers and logarithms | float |
min(a, b) | Bounds and comparisons | float or int |
max(a, b) | Bounds and comparisons | float or int |
clamp(x, low, high) | Bounds and comparisons | float or int |
Reading a signature#
float pow(float base, float exponent) means that the function takes two
float arguments in that order and returns a float. You call it as
pow(2.0f, 3.0f), without writing the types at the call site. The signatures
are reference notation; the examples below are actual Pole statements.
All arguments are required and positional. Builtins accept vectors of the
same numeric kind and operate separately on each lane. Scalar arguments
broadcast to the vector width; two vector arguments must have matching widths.
A call on a float<2> therefore returns a float<2>, not a mono value.
Only min, max and clamp accept integers. Within one call, use all int
or all float arguments: clamp(3, 0, 7) works; clamp(3, 0.0f, 7.0f) does
not. A whole-number float result from floor or ceil is still a float.
The examples that output a coefficient, frequency or decibel value demonstrate arithmetic; they are not complete audio effects. See the cookbook to use these values in a signal path, and Functions to write your own helpers.
sin#
float sin(float x)Use a phase accumulator for an oscillator. Multiply a phase measured in cycles by 2π before calling sin; passing a frequency in Hz directly does not create a tone.
Parameters
| Name | Meaning |
|---|---|
x | Angle in radians, not degrees or cycles. |
Returns
The sine of x, between -1 and 1 for finite inputs.
Example
let phaseCycles = 0.25f;
let sample = sin(6.2831853f * phaseCycles); // approximately 1.0
out <- sample;cos#
float cos(float x)cos starts at 1 when its angle is zero. It is a quarter cycle ahead of sin, useful when the left and right channels need offset modulation from one phase accumulator.
Parameters
| Name | Meaning |
|---|---|
x | Angle in radians. |
Returns
The cosine of x, between -1 and 1 for finite inputs.
Example
let sample = cos(0.0f); // 1.0
out <- sample;tan#
float tan(float x)Useful in filter coefficient calculations. Near its poles the magnitude becomes very large, so constrain a cutoff before converting it to an angle.
Parameters
| Name | Meaning |
|---|---|
x | Angle in radians; keep away from π/2 plus integer multiples of π. |
Returns
The tangent of x. Unlike sin and cos, the result is not bounded to -1…1.
Example
let cutoffHz = 1000.0f;
let coefficient = tan(3.14159265f * cutoffHz / processor.frequency);
out <- coefficient;tanh#
float tanh(float x)A convenient soft clipper: near zero it is almost linear; larger inputs are compressed smoothly. Increasing drive changes both tone and loudness, so add output trim. Nonlinear shaping can still alias.
Parameters
| Name | Meaning |
|---|---|
x | Input value after any desired drive gain. |
Returns
The hyperbolic tangent of x, approaching -1 and 1 as the input magnitude grows.
Example
let drive = 3.0f;
let trim = 0.5f;
out <- tanh(in * drive) * trim;exp#
float exp(float x)An exponential envelope multiplies its previous level by a coefficient just below 1 each sample. Large positive arguments can overflow; envelope coefficients normally use a negative exponent.
Parameters
| Name | Meaning |
|---|---|
x | Exponent of Euler's number e; dimensionless. |
Returns
e raised to x. exp(0.0f) is 1.0f; negative inputs produce values between 0 and 1.
Example
let seconds = 0.1f;
let coefficient = exp(-1.0f / (seconds * processor.frequency));
out <- coefficient;log#
float log(float x)This is the inverse of exp. Zero produces negative infinity and negative inputs are outside the real-valued domain; protect values derived from audio with a positive floor.
Parameters
| Name | Meaning |
|---|---|
x | Positive value, strictly greater than zero. |
Returns
The natural logarithm of x (base e). log(1.0f) is 0.0f.
Example
let magnitude = max(abs(in), 0.000001f);
out <- log(magnitude);log10#
float log10(float x)For an amplitude ratio, decibels are 20 * log10(ratio). For a power ratio the multiplier is 10. A meter needs a positive floor so silence has a finite display value.
Parameters
| Name | Meaning |
|---|---|
x | Positive value, strictly greater than zero. |
Returns
The base-10 logarithm of x. log10(10.0f) is 1.0f.
Example
let amplitude = max(abs(in), 0.000001f);
let decibels = 20.0f * log10(amplitude); // floor: -120 dB
out <- decibels;sqrt#
float sqrt(float x)Used in RMS metering and equal-power gains. Negative values are outside the real-valued domain. sqrt is not an integer conversion, even when the input is a whole number.
Parameters
| Name | Meaning |
|---|---|
x | Non-negative value, including zero. |
Returns
The non-negative square root of x, as a float.
Example
let mix = 0.5f;
let dryGain = sqrt(1.0f - mix);
let wetGain = sqrt(mix);
out <- in * dryGain;abs#
float abs(float x)Rectification is the first step in an envelope follower: abs turns both halves of the waveform positive. It does not smooth the result; that needs a filter and state.
Parameters
| Name | Meaning |
|---|---|
x | A float value; convert an int explicitly before calling. |
Returns
The magnitude of x, with its sign removed. abs(-0.5f) is 0.5f.
Example
let rectified = abs(in);
out <- rectified;floor#
float floor(float x)floor(-1.7f) is -2.0f. int(-1.7f) is -1, because the cast truncates toward zero. Use x - floor(x) for a fractional phase that stays in [0, 1) even when x is negative.
Parameters
| Name | Meaning |
|---|---|
x | Value to round downward. |
Returns
The greatest whole-number value less than or equal to x, still typed float.
Example
let phase = -0.25f;
let wrapped = phase - floor(phase); // 0.75
out <- wrapped;ceil#
float ceil(float x)ceil(1.2f) is 2.0f, and ceil(-1.2f) is -1.0f. If the result becomes an array index, use an explicit int conversion after rounding.
Parameters
| Name | Meaning |
|---|---|
x | Value to round upward. |
Returns
The smallest whole-number value greater than or equal to x, still typed float.
Example
let index = int(ceil(1.2f)); // int value 2
out <- float(index);pow#
float pow(float base, float exponent)Pitch intervals are ratios: an octave multiplies frequency by 2, and a semitone by 2^(1/12). Negative bases require integer-valued exponents for a real result; avoid zero with a negative exponent.
Parameters
| Name | Meaning |
|---|---|
base | Base value; use a positive base for arbitrary fractional exponents. |
exponent | Power to raise the base to. Both arguments must be float values. |
Returns
base raised to exponent. pow(2.0f, 3.0f) is 8.0f.
Example
let semitones = 12.0f;
let frequency = 440.0f * pow(2.0f, semitones / 12.0f); // 880 Hz
out <- frequency;min#
float min(float a, float b)
int min(int a, int b)Use min to impose a ceiling, for example on a feedback amount. It does not impose a lower bound; use clamp when both limits matter.
Parameters
| Name | Meaning |
|---|---|
a | First value. |
b | Second value, with the same numeric kind as a. |
Returns
The smaller of a and b, keeping the numeric kind of the arguments.
Example
let ceiling = min(1.2f, 0.9f); // 0.9
let count = min(12, 8); // int value 8
out <- ceiling;max#
float max(float a, float b)
int max(int a, int b)Use max to impose a floor. A positive floor on a duration prevents division by zero; a positive floor on a magnitude makes logarithms usable at silence.
Parameters
| Name | Meaning |
|---|---|
a | First value. |
b | Second value, with the same numeric kind as a. |
Returns
The larger of a and b, keeping the numeric kind of the arguments.
Example
let seconds = max(0.0f, 0.001f); // 1 ms minimum
let count = max(-2, 0); // int value 0
out <- seconds;clamp#
float clamp(float x, float low, float high)
int clamp(int x, int low, int high)The order is value, minimum, maximum. Bounds are not automatically sorted. On stereo input a pair of scalar bounds applies to both channels. Use this for hard clipping or for keeping a computed control in its intended range.
Parameters
| Name | Meaning |
|---|---|
x | Value to constrain. |
low | Inclusive lower bound; must be no greater than high. |
high | Inclusive upper bound. |
Returns
x when it is inside the bounds, low below them, or high above them. The result keeps the arguments' numeric kind.
Example
let sample = clamp(in, -1.0f, 1.0f);
let index = clamp(12, 0, 7); // int value 7
out <- sample;Common mistakes#
| Symptom | Check |
|---|---|
Unknown function (POLE0325) | Pole's builtins are the ones above. Write helpers such as lerp yourself. |
Wrong argument count (POLE0326) | Compare the call with its signature; clamp needs three arguments. |
Wrong argument type (POLE0327) | Use 1.0f for a float literal or convert explicitly with float(value). |
| Unexpected oscillator pitch | sin takes an angle in radians. Advance phase using frequency divided by sample rate. |
| Non-finite output | Check the input domain of log, sqrt and pow, and divisions used to form their arguments. |
For vector examples and the optional approximation mode, continue to maths in a patch.