Skip to content

Levels & Files

The methods named here are in the audio reference.

FactValue
UnitdB. 0 is unity gain.
Range−70 to +6. −70 and below is silence; above +6 is held at +6.
set_norm(0…1)0 is −70 dB, 1 is +6 dB, linear in dB between
A new valueGlides there over 10 ms
From a signalThe signal’s value in dB
FactValue
Range−1 (left) to 1 (right); 0 is centre
LawConstant power: θ = (pan + 1)·π/4, left gain √2·cos θ, right gain √2·sin θ
CentreBoth channels at unity, exactly
Hard left or rightThat side +3 dB, the other side silent
A stereo trackEach channel is scaled by its gain: the pan acts as a balance
A mono samplePlayed on both channels, then panned
FactValue
Sample rateThe device’s own, unless sample_rate is set in preferences; 48000 if the device does not say
Buffer sizeThe device’s own, unless buffer_size is set; at most 4096 frames
FileFormat
A sample, a kit soundWAV, integer or float, any bit depth, sample rate or channel count. No other format is read.
render outputWAV, stereo, 48000 Hz, 24-bit integer, whatever the device’s rate. Samples beyond ±1 are clipped; no dither.
track.save, clip.saveWAV, 32-bit float, at the clip’s own sample rate and channel count

A render is cycles cycles long, exactly: floor(48000 / cps) × cycles frames. It goes to a new folder. A render never writes into an earlier one’s folder: one that starts in the same second as the last gets _2 after its time, then _3, and so on.

renders/<name>_<YYYY-MM-DD>_<HH-MM-SS>/
├── master.wav render(n), render(master, n)
├── <track>.wav render(track, n), one per track rendered
├── <wav>.wav.json beside each WAV: the tempo it was bounced at
├── screen.mp4 render(screen, n) on macOS: H.264 + master AAC, 60 fps
└── frames/ render(screen, n) elsewhere: frame_00000.png onwards, 60 fps

<name> is the project’s set_project_title, else its package name, else untitled — lower-cased, with every character other than a letter, digit or - made _, runs of _ made one, _ trimmed from both ends, and cut to 50 characters. How to render is in Render a Project.

Each WAV has its bounce’s tempo beside it, as master.wav.json beside master.wav: {"cps", "beats_per_cycle", "cycles"}. A bounce plays at one tempo from start to end. resonon analyze --spectrogram reads it to number the cycles.

A render runs the session’s audio graph offline, from cycle 0, whatever the play head is doing. It works in a file run and in a live session, where live output pauses while it runs.

FileWhat is in it
master.wavEvery audio track that reaches the master: instruments, effects, faders, sends, buses, the master’s effects, modulation and automation, with plugin latency compensated
screen.mp4 (macOS)The routed visual at the composition size and 60 fps, with the bounced master mix as AAC audio. Both composition dimensions must be even.
<track>.wavThe track’s output as the mix hears it: its instrument, effects and fader, with its sidechains keyed and its latency compensated as in master.wav. Its buses, its sends and the master’s effects are not in it.

Not in a render:

MIDI tracksA WAV holds audio. midi_export() writes their notes.
A track sent to hardware outputsNot in master.wav, as it is not in the master live. Its own <track>.wav has it.
A track’s .set_delay()The round trip to outboard gear is not there to compensate, and the delay is not applied.
Live inputsA track’s set_input() is silent.
The tailThe render stops at its last cycle; a reverb or delay still sounding is cut. To keep it, render more cycles: a song plays nothing past its end, so they hold only the tail.

Each <track>.wav is a pass of the whole session: every other track and bus keeps playing, so a sidechain key — a track, a bus, a return, or a key that is ducked itself — reaches the track’s effects as in the mix. A key is read after its track’s fader, before mute and solo, so a muted track still keys. Only the track itself reaches the file. A render of n tracks and master takes about n + 1 times as long as master alone.

Effects are not cleared first: in a live session, a delay or reverb still sounding carries it into the render’s first cycle. rand_true() and choose_true() give a new value every call, in a render too, so a render that uses them differs every time; seeded rand() and choose() do not.

save_project() writes the state of every CLAP and VST3 plugin in the session to the project’s plugin-state/ folder, and load_project() reads it back.

plugin-state/
├── track__<track>__instrument.preset
├── track__<track>__effect__<slot>.preset
├── master__effect__<slot>.preset
└── .history/
└── <YYYY-MM-DD_HH-MM-SS-mmm>/ a copy of each save, the last 100

Names are made safe for a file name. When two plugins’ names would give one file name, a 6-digit hexadecimal hash is added (__h1a2b3c). A .preset file of a plugin no longer in the session is removed at the next save.

A .preset file is JSON:

KeyValue
resonon_preset1, the format version
plugin_nameThe plugin’s name
state.paramsEach parameter’s value, by its path
state.binary_stateThe plugin’s own saved state, base64, when it has one