Pipes & Holes
The pipe operator (|>) and hole (@) define Akkado’s signal flow model.
The pipe operator |>
The pipe operator connects audio processing nodes, creating a signal flow graph.
// Signal flows left to right
saw(220) |> lp(@, 800) |> out(@) This reads as: “Generate a sawtooth at 220 Hz, pipe it through a lowpass filter at 800 Hz, then pipe to the output.”
Why pipes?
Pipes make signal flow explicit and readable:
// Without pipes (harder to read)
out(lp(saw(220), 800), lp(saw(220), 800))
// With pipes (clearer)
saw(220) |> lp(@, 800) |> out(@) The hole @
The hole (@) is a placeholder that gets filled with the signal from the left side of the pipe.
Single hole
When you use @ once, it receives the piped signal:
sine(440) |> out(@)
// ^ ^
// | |
// Both holes filled with sine(440) Multiple holes
You can use @ multiple times in the same expression:
// Send signal to both filter and output
sine(440) |> lp(@, 1000) + @ |> out(@)
// ^
// Original unfiltered signal mixed back in Hole with math
The hole can be used in calculations:
// Reduce volume by half
sine(440) |> @ * 0.5 |> out(@) // Add DC offset
sine(440) |> @ + 0.5 |> out(@) Chaining pipes
Build signal chains by connecting multiple pipes:
// Oscillator -> Filter -> Distortion -> Output
saw(110) |> lp(@, 800) |> saturate(@, 2) |> out(@) Branching
The hole lets you create parallel paths:
// Dry/wet mix
saw(110) |> lp(@, 500) * 0.7 + @ * 0.3 |> out(@)
// filtered (wet) original (dry) Examples
Basic synth voice
// Oscillator through filter with envelope
saw(220) * adsr(trigger(2), 0.01, 0.2) |> lp(@, 1000) |> out(@) Effects chain
// Guitar-like processing
saw(110)
|> saturate(@, 3)
|> lp(@, 2000)
|> delay(@, 0.3, 0.4)
|> out(@) Stereo processing
// Stereo spread
saw(220) |> out(lp(@, 500), lp(@, 2000))