How to read this book
A path from your first sample to a playable instrument, with a few useful words and listening habits along the way.
Newcomers to audio programming and experienced developers learning Pole.
An audio program can be surprisingly small. Multiply a sample and you have a volume control. Remember the previous output and you can begin to build a filter. Remember many samples and you have an echo. The interesting part is learning how those small ideas fit together.
This wiki has two reading speeds. Follow the chapters to build that picture, or jump to a reference entry when you already know what you want to write. You do not need to understand compiler internals to begin.
A route through the chapters#
| Stage | Read | What you will be able to do |
|---|---|---|
| 1. Hear a sample become sound | Your first patch | Read a processor and change its volume or pitch. |
| 2. Give the sound memory | State and init, then Arrays | Keep oscillator phase, filter history and delayed samples. |
| 3. Give the listener control | Parameters, then Functions | Expose controls and turn repeated expressions into named operations. |
| 4. Build an effect | A filter, then A delay | Follow a signal through several calculations and hear what each control changes. |
| 5. Make an instrument | An envelope, then Notes and events | Turn note presses and releases into changing sound. |
| 6. Connect larger ideas | Graphs, then Node arrays | Reuse processors and give every voice its own memory. |
| 7. Take it elsewhere | Emit targets | Choose between a WAV, a native export and a browser build. |
If you already write DSP, begin with types, frame boundaries and the function reference. Those pages cover the conventions most likely to differ from a language you know.
Five words that make the examples easier#
Sample. One number representing a signal at one instant. A mono signal has
one number per instant; stereo has two, usually written float<2> in Pole.
Audio commonly uses -1 to 1 as its nominal full-scale range. Arithmetic can
exceed that range, so output level is something your patch should manage.
Frame. One instant across all the signal's channels. At 48,000 frames per
second, a frame lasts about 20.8 microseconds. The frame loop computes an
output, updates its memory, then calls advance().
Frequency. How often something repeats each second, measured in hertz (Hz). An oscillator at 220 Hz completes 220 cycles per second. An LFO at 0.5 Hz completes one cycle every two seconds; it is often used to move a control.
Phase. Where you are within a cycle. These pages use either cycles (0 to
- or radians (0 to 2π), and say which.
sinandcostake radians. A phase increment offrequency / processor.frequencyis measured in cycles per frame.
State. Memory that survives the next frame. A local intermediate value helps describe this sample's calculation; a state variable remembers something for the next one. This is the difference between turning down today's sample and knowing what yesterday's sample was.
Read a worked example in three passes#
First, look at the endpoints and controls. Does this processor generate sound, or does it need an input? Which parameters can you move, and what units do they use?
Second, find the state. A phase tracks a cycle; a line holds delayed
audio; an env remembers an envelope level. Knowing what the processor
remembers often tells you more than reading every arithmetic expression.
Third, follow one trip through the loop. Find the input, the transformed value and the output. Then ask what gets saved for the next trip. A cookbook walkthrough follows that order so you can keep the whole signal path in mind.
Learn with your ears as well as the code#
Start with the default settings. Change one control, predict what should happen, then listen. A larger delay time should spread echoes apart. More feedback should lengthen the tail. A slower attack should soften the start of a note. If the result surprises you, follow that control from its declaration to the expression that uses it.
A sine makes distortion easy to hear because new harmonics stand out. A saw or noise makes a filter's changing brightness easier to hear. An impulse or a short note reveals the shape of a delay or reverb tail.
A runnable block has a Run button and its own controls. Other blocks are small excerpts or local-only examples. Do not paste a reference signature as a complete program: a signature describes a call, while a complete example includes the processor and its frame loop.
Keep the reference nearby#
- Built-in maths: signatures, argument order, units, returned values and short calls.
- Runtime values and conversions: sample rate, sample period, casts and external-buffer properties.
- Keywords: the language's vocabulary.
- Diagnostics: find a
compiler message by its
POLEcode.
Next: What Pole is, or go directly to your first patch and make a sound.