audio(...) -- Play a Single File
Triggers playback of a named audio file when the playhead crosses the cue element. The basic building block of Oscilla's audio system.
Syntax
audio(src:kick.wav, amp:0.9, loop:1, fade:0.3, pan:-0.5, speed:1.2)
Parameters
| Key | Default | Description |
|---|---|---|
src (required) |
-- | Filename or stem (.wav auto-appended) |
amp |
1 | Gain, 0--1 |
pan |
0 | Stereo position, -1 (left) to 1 (right) |
speed |
1 | Playback rate multiplier. Negative values play in reverse |
loop |
1 | 1=once, N>1 repeats, 0=infinite |
fade |
0 | Shorthand for both fadeIn and fadeOut |
fadeIn |
0 | Fade-in duration (seconds or percentage) |
fadeOut |
0 | Fade-out duration (seconds or percentage) |
in |
0 | Start offset in seconds — or a list / pattern of several start points (see below) |
out |
0 | End point in seconds (0 = full file) |
seg |
– | Length of each play from its start point (s, or list/pattern per play); overrides out — see Multiple start points |
toggle |
false | Second trigger stops instead of restarting |
poly |
1 | Polyphony: 1=mono (retrigger updates), 0=unlimited, N=capped |
uid |
src | Playback identity for stop/toggle tracking |
filter |
-- | Filter object {type, freq, q} |
delay |
-- | Delay object {time, fb, mix} |
reverb |
-- | Reverb object {mix, time, damp} |
waveform |
self |
Waveform display target: self, none, or element id |
overlay |
2 | Overlay detail level: 0/off, 1/brief, 2/expanded |
pin |
-- | Pin element to playhead for N seconds (see pin) |
extent |
element width | Active-region width in score units from the element's left edge, with a draggable score-visible line (see extent) |
See audio_shared for details on fades, random expressions, effects, waveform display, and OSC output.
File Resolution
Files load from the project /audio folder first. If not found there, the external search path is tried (when set via audiopath() in the live console). Finally, the shared /audio directory is checked. Extensions .wav, .ogg, .mp3, .m4a are recognised. Bare stems without an extension default to .wav.
Paths containing / must be quoted: src:"fx/rain.wav".
Polyphony
The poly parameter controls how retriggers with the same uid behave:
| Value | Behaviour |
|---|---|
poly:1 (default) |
Mono mode. Retrigger updates the running voice in place (hot-update) |
poly:0 |
Unlimited overlapping voices. Each trigger creates a new independent voice |
poly:N |
Up to N overlapping voices. When at capacity, the oldest voice is stopped |
In mono mode (poly:1), retriggering with the same uid calls update() on the running voice -- parameters change smoothly without restarting playback. This is ideal for live console tweaking.
In poly mode (poly:0 or poly:N), each trigger creates a fresh voice with a unique internal key. Voices play independently and clean up on completion. This is ideal for layering the same file at different speeds, pitches, or pan positions.
Multi-Cursor Waveform (Poly Mode)
When poly is active, each voice adds its own coloured waveform layer and cursor on top of the base waveform. Colours are assigned from a 12-colour palette. Layers and cursors auto-remove when their voice completes.
// Layer three copies at different speeds on one waveform
audio(src:drone.wav, loop:0, speed:1, uid:pad, poly:0)
audio(src:drone.wav, loop:0, speed:0.5, uid:pad, poly:0)
audio(src:drone.wav, loop:0, speed:0.25, uid:pad, poly:0)
All three voices share the same waveform rect, each with its own cursor sweeping at its own speed.
Speed and Reverse Playback
The speed parameter controls both playback rate and direction:
| Value | Effect |
|---|---|
speed:1 |
Normal playback |
speed:0.5 |
Half speed (lower pitch) |
speed:2 |
Double speed (higher pitch) |
speed:-1 |
Reverse at normal speed |
speed:-0.5 |
Reverse at half speed |
Reverse playback uses a sample-reversed buffer copy (cached after first use). The waveform display mirrors horizontally and the cursor moves right-to-left.
In/Out Points
Loop a subsection of a file by specifying start and end positions in seconds:
audio(src:longfile.wav, in:2, out:8, loop:0)
Multiple start points
in: also takes a list or a pattern. Each loop iteration — and each
retrigger of the cue — draws the next start point, so one file becomes a
set of places to jump between:
audio(src:field.wav, in:Prand(2.5, 14, 31.2, inf), loop:0) // random jump every loop
audio(src:field.wav, in:[2.5, 14, 31.2], loop:0) // cycle through them in order
audio(src:field.wav, in:Pseq(2.5, 14, 31.2, 2), out:40) // the sequence twice, then stop
Every play runs from the drawn start point to out: (or the end of the
file), so segment lengths vary with the start point — unless you give
each play a length of its own:
seg: — length of each play, from its start point
seg: (seconds) ends every play that long after its start point,
overriding out:. A number, or a list/pattern drawn per play. Together
with a start-point pattern and loop: this is a grain / glitch-rhythm
generator:
audio(src:bowl.wav, in:Prand(0.2, 1, 2.5, 4, 7, inf), seg:0.2, loop:40, fadeIn:0.005, fadeOut:0.02)
// 40 grains of 200 ms jumping between five points — a 5 Hz rhythm
audio(src:bowl.wav, in:Prand(0.2, 1, 2.5, 4, inf), seg:Pseq(0.2, 0.2, 0.4, inf), loop:0)
// same, with a long-short-short pulse from the seg pattern
With seg: set, fadeIn/fadeOut apply to every play (not just the
first and last) so grains don't click — a few milliseconds is enough.
A speed: pattern is drawn per play too, and negative values play that
grain backwards — so one pattern randomises pitch and direction:
audio(src:bowl.wav, in:Prand(0.2, 1, 2.5, 4, 7, inf), seg:0.2,
speed:Prand(0.5, 0.75, 1, 1.5, 2, -1, -0.75, -1.5, inf), loop:40, fadeIn:0.005, fadeOut:0.02)
``` The DSL
editor's start and seg fields carry chips for these forms. That is
deliberately the whole feature — per-marker end points, weights and
crossfades belong in an external audio tool driven by Oscilla over OSC.
This loops seconds 2--8 of the file. In/out points work with both forward and reverse playback. When `speed` is negative, the segment plays backwards.
In/out points are deferred during live update -- they take effect on the next loop iteration.
---
## Toggle Mode
With `toggle:true`, the first trigger starts playback and the second trigger stops it. The playback state is tracked by `uid`, so multiple elements sharing the same `uid` act as a single toggle group.
---
## Waveform Display
When `waveform` is not `none`, a waveform visualisation is rendered inside the cue element at score load time. A cursor line tracks playback progress. The waveform shape is drawn from the decoded audio buffer.
Waveforms are preloaded during `assignCues` so they appear immediately when the score loads, not only when the cue fires.
An info text line above the waveform peaks shows current parameter values (filename, amp, speed, pan, loop, fades, in/out). This text updates in real time during live console changes.
When reverse playback is active, the waveform contours mirror horizontally via SVG transform and the cursor sweeps right-to-left.
---
## Live Console
### Live Audio Rects
When audio cues are triggered from the live console (which has no SVG cue element to anchor to), the system automatically creates an ephemeral SVG rect centered in the visible viewport. This rect serves as the waveform anchor -- peaks render inside it and cursors track playback as normal.
Each unique `uid` gets its own rect. Multiple live layers stack vertically:
// Three independent layers, each with its own rect and waveform audio(src:"noise/rain.wav", amp:0.6, loop:0, uid:layer1) audio(src:"pads/drone.wav", amp:0.3, speed:0.5, uid:layer2) audio(src:"perc/click.wav", amp:0.8, loop:0, uid:layer3)
To layer multiple voices on a single rect, use the same uid with `poly:0`:
// Three voices on one rect with colored peak layers and independent cursors audio(src:"pads/drone.wav", loop:0, speed:1, uid:mix, poly:0) audio(src:"pads/drone.wav", loop:0, speed:0.5, uid:mix, poly:0) audio(src:"pads/drone.wav", loop:0, speed:0.25, uid:mix, poly:0)
Live audio rects are cleaned up by the global stop button, or individually:
```javascript
removeLiveAudioRect("layer1") // remove one
clearLiveAudioRects() // remove all
Hot-Update
Running audio cues can be modified in real time from the live console. Retrigger with the same uid to update parameters without restarting playback. If a voice with that uid is already playing, the update() method is called instead of stop-and-restart.
Immediate Parameters
These take effect within 50ms via smooth Web Audio ramps on the running nodes:
| Parameter | Behaviour |
|---|---|
amp |
Gain ramp on the GainNode |
pan |
Stereo position ramp on the StereoPannerNode (created on the fly if needed) |
speed |
Playback rate ramp (same direction only) |
Deferred Parameters
These take effect on the next loop iteration when playOne creates a fresh BufferSource:
| Parameter | Behaviour |
|---|---|
fadeIn, fadeOut |
New envelope values |
in, out |
New segment boundaries |
src |
Async fetch + decode of the new file; waveform peaks redraw when ready |
speed (direction change) |
Swaps between forward/reversed buffer on next loop |
Loop Control
The loop parameter can be changed while playing:
| Value | Effect |
|---|---|
loop:1 |
Finish after the current iteration |
loop:3 |
Play 3 more iterations then stop |
loop:0 |
Switch to infinite looping |
Waveform Reconnection
When a voice finishes and is later restarted from the live console (which has no cue element), the new voice reconnects to the existing waveform SVG via getWaveform(uid). The cursor and info text resume as normal. When src changes during hot-update, the waveform peaks redraw to show the new file.
Example Workflow
// Start an infinite drone
audio(src:drone.wav, loop:0, uid:myDrone)
// Drop the speed live
audio(src:drone.wav, speed:0.5, uid:myDrone)
// Loop just seconds 2--8
audio(src:drone.wav, in:2, out:8, uid:myDrone)
// Swap to a different file on next loop (peaks redraw)
audio(src:other.wav, uid:myDrone)
// Reverse playback on next loop
audio(src:drone.wav, speed:-1, uid:myDrone)
// Finish after current iteration
audio(src:drone.wav, loop:1, uid:myDrone)
Examples
// Simple drone with slow fade
audio(src:drone.wav, loop:0, fade:2)
// Slowed-down atmosphere
audio(src:atmosphere.wav, speed:0.5, loop:0, fadeIn:3, fadeOut:5)
// Reverse playback with fade
audio(src:texture.wav, speed:-1, loop:0, fadeIn:2)
// Loop a section of a file
audio(src:longfile.wav, in:4.5, out:12, loop:0, speed:0.8)
// Togglable click track
audio(src:click.wav, amp:0.6, toggle:true, uid:metroClick)
// Short percussive hit, no waveform
audio(src:rimshot.wav, amp:0.8, waveform:none)
// Looping pad with percentage fade
audio(src:pad.wav, loop:0, fadeIn:"10%", fadeOut:"30%")
// Pinned for 15 seconds at the playhead
audio(src:long-texture.wav, loop:0, fade:5, pin:15)
// Layered voices with poly -- three speeds on one waveform
audio(src:drone.wav, loop:0, speed:1, uid:pad, poly:0)
audio(src:drone.wav, loop:0, speed:0.5, uid:pad, poly:0)
audio(src:drone.wav, loop:0, speed:0.25, uid:pad, poly:0)
// Polyphony capped at 4 voices
audio(src:grain.wav, loop:0, speed:rand(0.3,2), uid:grains, poly:4)
// Path with subdirectory (must be quoted)
audio(src:"fx/rain.wav", loop:0, fade:3)
See Also
- audioPool -- one-shot selection from a folder
- audioImpulse -- stochastic repeating process
- audio_shared -- fades, random expressions, waveform, OSC
- pin -- pin element to playhead
Demo
See demo-audio — single-file playback, trimming, fades, extents and waveform display.
http://localhost:8001/?project=demo-audio
Tip: use ← → or ↑ ↓ to navigate the docs