Audio Tools Reference
All 93 tools the AI agent can call to edit your audio session.
Tools are deterministic functions the agent calls to manipulate your audio session. You do not invoke tools directly — instead, describe what you want in natural language and the agent selects the right tool chain. Every tool call creates a new session node (non-destructive).
Prompt tips
- Name the track when you have multiple:
normalize track 1not justnormalize. - Use minutes:seconds for time:
cut from 1:30 to 2:00. - Chain operations in one message — the agent plans the full sequence before executing.
- Correct inline — if the agent misunderstood, say what was wrong:
not that track — the second one.
File and Track Management
loadDecode an audio file (MP3, WAV, FLAC) and create a new track in the session.
Example prompt: load /path/to/file.wav
Returns: track_id, duration_sec
add_trackAdd a new empty track to the session.
Example prompt: add an empty track called "drums"
Returns: track_id
remove_trackRemove a track. Does not delete the source file on disk.
Example prompt: remove track 2
Returns: node_id
duplicate_trackCreate an exact copy of a track (same clips, gain, pan, effects). The duplicate is appended after all existing tracks.
Example prompt: duplicate track 1
Returns: node_id
rename_trackRename a track.
Example prompt: rename track 2 to "guitar"
Returns: node_id
mute_trackMute or unmute a track. Muted tracks produce silence in the mix.
Example prompt: mute track 3
Returns: node_id
solo_trackSolo or un-solo a track. When any track is soloed, only soloed tracks play in the mix.
Example prompt: solo the vocals
Returns: node_id
set_panSet the stereo pan of a track. -1.0 = full left, 0.0 = centre, 1.0 = full right.
Example prompt: pan track 2 hard left
Returns: node_id
time_shiftMove a track's clips forward or backward in time. Positive offset_sec moves later, negative moves earlier (clamped to 0).
Example prompt: move track 2 two seconds later
Returns: node_id
mix_to_new_trackOffline-render the selected tracks together and add the result as a new mixed track. track_indices selects which tracks to include.
Example prompt: mix tracks 1 and 2 into a new track
Returns: node_id
Region Editing
cut_rangeRemove a time range. Audio after the cut point shifts left.
Example prompt: cut from 1:30 to 2:00 on track 1
Returns: node_id, synced_tracks
With sync-lock on, the same span comes out of every track so a multitrack recording stays aligned.
set_sync_lockTurn sync-lock on or off. With it on, an edit that shifts time on one track shifts every track. An interview is one track per speaker, and cutting a sentence from one of them leaves every later word on that track early while the other speaker stays put — the conversation comes apart, and nothing about the edit says it will. Affects cut_range and insert_silence.
Example prompt: keep the tracks in sync when you cut
Returns: node_id, sync_lock, changed
Each affected edit is still one undoable node covering every track it moved, so undo restores the whole edit rather than half of it. The mode is part of the session, so it survives Save As and the agent can read it before deciding whether a cut is safe.
punch_inReplace a region of a track with audio from a file, in place. The region's length does not change, so everything after the punch stays exactly where it was — this is how a misread line gets fixed without re-recording the whole take or shifting the rest of the session out of sync.
Example prompt: replace 1:20 to 1:35 with the retake I just recorded
Returns: node_id, region_sec, take_sec, trimmed_sec, padded_sec
A take longer than the region is trimmed and a shorter one is padded with silence, and the tool says which happened. It never stretches the performance and never ripples the timeline — rippling is exactly what punching in exists to avoid.
copy_regionCopy a time region to the clipboard, and persist it as a content-addressed blob so a later paste can be replayed rather than merely kept.
Example prompt: copy the section from 0:30 to 1:00
Returns: clipboard_blob hash
paste_regionInsert clipboard contents into a track. Audio shifts right at the insert point.
Example prompt: paste at 2:00 on track 1
Returns: node_id
trimRemove silence from the start and/or end of a track.
Example prompt: remove the silence at the start of track 1
Returns: node_id, trimmed_start_sec, trimmed_end_sec
insert_silenceInsert a gap of silence at a position. Audio shifts right.
Example prompt: add 2 seconds of silence at 0:30
Returns: node_id
reverseReverse a region (or the full track).
Example prompt: reverse track 1
Returns: node_id
silence_regionZero out audio samples between start_sec and end_sec on a track.
Example prompt: silence 0:10 to 0:12
Returns: node_id
repeat_selectionDuplicate the audio region [start_sec, end_sec) on a track N additional times, \ appending copies after the original buffer.
Example prompt: repeat 0:00-0:04 three more times
Returns: node_id
split_clipSplit a clip into two at the specified time position. Both resulting clips reference the same source file with adjusted offsets.
Example prompt: split track 1 at 1:30
Returns: node_id
move_clipMove one clip to a new start position, leaving the other clips where they are. Use time_shift to move a whole track together. Clips are re-sorted by start, so a clip dragged past its neighbour keeps the arrangement and the waveform in step.
Example prompt: move the second clip on track 1 to 8 seconds
Returns: node_id
remove_clipRemove one clip from a track. The gap it leaves is silence — this does not close up the timeline. Use remove_track to drop a whole track.
Example prompt: delete the second clip on track 1
Returns: node_id
invertInvert (negate) audio polarity on a track, optionally within a time range.
Example prompt: invert the polarity of track 2
Returns: node_id
Volume and Dynamics
gainApply a static dB gain to a region of a track. Range: −60 to +12 dB.
Example prompt: boost the vocals by 3 dB
Returns: node_id
set_track_gainSet the overall gain level for an entire track.
Example prompt: set track 2 gain to -3 dB
Returns: node_id
create_busCreate a mix bus with its own effect chain. Tracks feed it through sends, so one reverb can serve several tracks instead of being applied to each.
Example prompt: make a reverb bus
Returns: node_id, bus_id
set_sendRoute a track to a bus at a given level in dB. The send is tapped after the track's own gain and pan.
Example prompt: send 30% of the vocal to the reverb bus
Returns: node_id
remove_sendRemove a track's send to a bus, leaving both the track and the bus in place.
Example prompt: stop sending the vocal to the reverb bus
Returns: node_id
normalizeScan a track for its peak amplitude and set its gain so the peak lands on target_dbfs. Peak-based — two files normalised to the same peak can still differ by 10 LUFS in perceived loudness, so use normalize_loudness when the goal is 'as loud as everything else'.
Example prompt: normalize the peak to -1 dBFS
Returns: node_id, applied_gain_db
normalize_loudnessSet gain so the track hits an integrated LUFS target, measured with EBU R128. Takes either a number or a platform by name — spotify, youtube, apple_podcasts, broadcast — so the target does not have to be remembered. Gain is capped at a true-peak ceiling (−1 dBFS by default) so it never clips getting there; when the cap bites, the result reports the shortfall rather than claiming success.
Example prompt: normalize for Spotify
Returns: node_id, measured_lufs, preset, applied_gain_db, achieved_lufs, shortfall_db, capped_by_ceiling
Presets: spotify / youtube −14 LUFS, apple_podcasts −16, broadcast −23. A custom target_lufs still works.
fadeApply a fade-in or fade-out envelope. Curve options: linear, exponential, logarithmic.
Example prompt: add a 3-second fade-out
Returns: node_id
set_clip_envelopeSet a per-clip volume automation curve. Provide (time_sec, gain_db) pairs and the engine linearly interpolates between them.
Example prompt: set a volume fade: track 0 clip 0, from 0s at -20dB to 2s at 0dB
Returns: node_id
duck_under_speechDrop a music track under the speech and bring it back in the gaps, keyed on the transcript rather than on level. A sidechain compressor keys on level, so a breath triggers it and a quiet line escapes it; the transcript says where the words actually are. It also ducks slightly before each line starts, which a level trigger cannot do — it only knows a line began after it has.
Example prompt: duck the music under the voiceover
Returns: node_id, passages, ducks
The result is an ordinary volume-automation curve on the music clip, so it is visible in the automation lane and draggable if a duck lands wrong. Short pauses inside a sentence do not un-duck: bringing the music up for a comma is a pump, not an edit.
limiterBrick-wall limiter: hard-clip any samples exceeding ceiling_db. Prevents digital clipping.
Example prompt: limit track 1 to -1 dBFS
Returns: node_id
noise_gateApply a noise gate: audio below threshold_db is silenced. attack_ms and release_ms control how fast the gate opens/closes.
Example prompt: gate anything below -45 dB
Returns: node_id
levelerApply dynamic leveling: normalise each short window to a target RMS level. Reduces variation between loud and quiet passages.
Example prompt: even out the levels on track 1
Returns: node_id
de_esserReduce harsh sibilant 's' and 'sh' sounds. frequency_hz sets where sibilance detection begins (default 7000Hz); threshold_db is the compression trigger level.
Example prompt: take the harshness off the s sounds
Returns: node_id
truncate_silenceFind and remove silent regions in a track. threshold_db is the silence floor; min_silence_ms is the minimum gap duration to remove.
Example prompt: remove the long pauses
Returns: node_id
Effects
eqApply a parametric EQ to a track using a chain of biquad peak filters. Specify frequency, gain (dB), and Q for each band.
Example prompt: boost the highs on track 1 by 3 dB at 8 kHz
Returns: node_id
compressorApply a dynamic compressor with configurable threshold, ratio, attack, and release. Uses an envelope follower for smooth gain reduction.
Example prompt: compress track 1: threshold -18 dB, ratio 4:1
Returns: node_id
noise_reductionRemove broadband noise via spectral subtraction (realFFT + overlap-add). Estimates the noise floor from a silent region and subtracts it from the signal.
Example prompt: reduce background noise on track 1
Returns: node_id
reverbApply Freeverb algorithmic reverb. room_size (0-1) controls reverb length, damping (0-1) controls high-freq decay, wet (0-1) is the wet/dry blend.
Example prompt: add a small room reverb
Returns: node_id
echoAdd a single echo (delay + decay). delay_ms is the echo offset in milliseconds; decay (0..1) is the echo amplitude.
Example prompt: add a 300 ms echo
Returns: node_id
phaserApply a phaser effect using an all-pass filter chain with LFO sweep. rate_hz controls LFO speed; depth is the wet blend; stages sets the filter chain length (2-12).
Example prompt: add a slow phaser
Returns: node_id
tremoloApply tremolo (LFO amplitude modulation). rate_hz controls oscillation speed; depth (0..1) controls modulation depth.
Example prompt: add tremolo at 5 Hz
Returns: node_id
distortionApply soft-clip distortion (tanh waveshaper) followed by a tone filter. drive > 1 increases gain before clipping; tone (0=dark, 1=bright) controls the output filter.
Example prompt: drive track 2 a little
Returns: node_id
stereo_widenerWiden or narrow the stereo field using M/S processing. width=0 collapses to mono, width=1 is original, width=2 doubles the stereo width. Requires stereo track.
Example prompt: widen the stereo image
Returns: node_id
vocal_reductionReduce center-panned vocals using L-R channel subtraction (Karaoke effect). Works on stereo tracks; results depend on how centrally the vocals are mixed.
Example prompt: take the vocals out
Returns: node_id
click_removalRemove clicks and pops by detecting sample spikes (via median filter) and replacing them with interpolated values. threshold is the amplitude deviation that triggers detection.
Example prompt: remove the clicks
Returns: node_id
low_pass_filterApply a Butterworth low-pass filter to a track, removing frequencies above cutoff_hz.
Example prompt: roll off everything above 8 kHz
Returns: node_id
high_pass_filterApply a Butterworth high-pass filter to a track, removing frequencies below cutoff_hz.
Example prompt: high-pass at 80 Hz
Returns: node_id
notch_filterApply a notch (band-reject) filter to a track, attenuating frequencies near center_hz. q controls the width: higher Q = narrower notch.
Example prompt: notch out the 50 Hz hum
Returns: node_id
Effect Chains
add_effectAppend an effect to a track's chain. The chain is applied at render time and the source audio is never rewritten, so the parameters stay editable — unlike the destructive effect tools above, which bake their result into a new node.
Example prompt: put a low-pass at 4 kHz on the guitar track
Returns: node_id, effect_index
Effects run in the order they appear in the chain. Not every effect can stream yet; ones that cannot are rejected at render time with a message naming them.
set_effect_paramsEdit an effect already in a chain. Given parameters are merged into the existing ones by default; pass replace to swap the whole set instead.
Example prompt: change that low-pass to 2 kHz
Returns: node_id
set_effect_bypassedTurn an effect off without removing it. A bypassed effect renders byte-identically to one that is not there, so it is an A/B switch rather than an approximation.
Example prompt: bypass the compressor on track 1
Returns: node_id
reorder_effectsReorder a track's chain. Takes a full permutation of the existing indices — a partial list is rejected rather than silently dropping effects.
Example prompt: put the EQ before the compressor
Returns: node_id
remove_effectRemove an effect from a track's chain by index.
Example prompt: take the reverb off the drums
Returns: node_id
Time and Pitch
time_stretchChange the duration without changing the pitch.
Example prompt: stretch track 1 to 4 minutes
Returns: node_id, new_duration_sec
pitch_shiftChange the pitch without changing the duration. Set preserve_formants on voices so a shift sounds like the same person singing higher, not a chipmunk. Range: −12 to +12 semitones.
Example prompt: shift the vocals up 2 semitones
Returns: node_id
change_speedResample a track to change playback speed without pitch preservation. factor > 1 speeds up (shorter duration), factor < 1 slows down (longer).
Example prompt: speed track 1 up by 10%
Returns: node_id
resample_trackResample a track to a different sample rate using linear interpolation. Common rates: 22050, 44100, 48000, 96000.
Example prompt: resample track 1 to 44.1 kHz
Returns: node_id
Analysis
analyze_trackDetect BPM, musical key, integrated loudness (LUFS), true peak, and transient count.
Example prompt: analyze track 1
Returns: bpm, key, loudness_lufs, peak_dbfs, transient_count
align_to_beatWarp a track in time so its beats land on a target grid, without changing the pitch. Each segment between beats is stretched by its own ratio in one pass, so there is no seam at the beats. Get source_beats from analyze_track.
Example prompt: find the beats, then warp this onto a steady grid
Returns: node_id
plot_spectrumCompute the FFT magnitude spectrum of a track region.
Example prompt: show me the spectrum of track 1
Returns: frequency/magnitude data
select_regionResolve a description of a region into a concrete time range, using the session's transcript and tempo map. Give a phrase to find, a passage of speech (1 is the first, -1 the last), or a beat range. Returns start_sec and end_sec for any tool that takes a range.
Example prompt: select the bit where he talks about latency
Returns: start_sec, end_sec, duration_sec, matched
It refuses rather than approximating: a phrase that is not in the transcript selects nothing, because the next call is usually a destructive edit and a range that is nearly right is worse than none. Every range-taking tool became describable without any of them changing.
silence_finderAnalyse a track and return the time ranges of silent regions.
Example prompt: where are the silent bits?
Returns: list of {start_sec, end_sec}
export_recipeWrite the session's edit chain — every tool and its parameters, in order — to a JSON file with no audio in it. Reviewable by eye before anyone runs it, and replayable against the same source or a different one.
Example prompt: export this edit chain so I can reuse it
Returns: path, steps, blockers
Steps that cannot be replayed (ML models) are marked in the file rather than silently dropped.
apply_recipeReplay an exported edit chain. Every step is checked before any of them runs, so a recipe that cannot keep its promise is refused whole — naming the step — rather than half-applied. Takes an optional different source, and a dry run that reports the plan without touching the session.
Example prompt: run my podcast chain on this recording
Returns: steps_applied, head, notes
Replaying against the same audio reproduces the same bytes; the derived files are named by their own samples, so a drifted rebuild is detected rather than substituted.
audition_effectHear an effect on a track without applying it. Renders a few seconds of the session with the effect added to that track's chain and hands back a WAV to play — no session node, so there is nothing to undo. Call add_effect with the same arguments to keep it.
Example prompt: what would a 1 kHz low-pass sound like on the vocal?
Returns: path, cached, start_sec, end_sec
The audition includes gain, pan, mute, solo, sends and the master chain, so it sounds like the result will. Repeating settings you have already heard is instant.
batch_applyRun an exported edit chain across every audio file in a folder. Each file becomes its own project with its own history — a batch is not one giant session. Every file is attempted even if an earlier one fails, and the report says what succeeded, what refused, and why.
Example prompt: run my podcast chain over every file in this folder
Returns: files, succeeded, refused, per-file results
A chain that cannot be replayed is refused once, up front — that is a property of the chain, not of the twelve files.
cut_wordsDelete a span of transcribed words and the audio underneath, closing the gap. Indices are into the session transcript from `transcribe`. The remaining word timings shift so they still line up with the audio, and the whole thing is one undoable node.
Example prompt: delete the bit where he repeats himself
Returns: node_id, removed_words, removed_text, removed_sec
The span runs from the first word's start to the last word's end — cutting from the first word's end would leave a clipped syllable behind.
remove_fillersFind filler words in the transcript and, when asked, remove them and their audio in one undoable edit. Reports by default without changing anything — this is a destructive edit across a whole track. Hesitations (um, uh, er) go wherever they appear; discourse markers (like, actually) only where they stand alone between pauses, because speech with every hesitation stripped sounds rushed.
Example prompt: how many ums are in this?
Returns: found, would_save_sec, per-word list; node_id when applied
Leaves a short pause where each filler was, so the result does not sound spliced. The word list can be replaced — fillers are language- and speaker-specific.
compact_sessionPrune old history and delete the audio only it referenced. Reports what it would remove and changes nothing unless asked twice, because this removes undo steps permanently — the nodes are gone, not archived. The most recent nodes on the current chain are never pruned, so ordinary undo keeps working; what goes is the tail beyond them and any branches forked away from and never returned to.
Example prompt: this project is huge — reclaim some disk
Returns: prunable_nodes, reclaimable_bytes; removed_nodes and freed_bytes when applied
For space without losing history, the derived-audio cache sweeps itself: a file whose whole chain records a reproducible op regenerates byte-identically, so removing it costs a re-render on undo and nothing else.
storage_reportReport what the session costs on disk, split by category: audio the current version needs, audio only the undo history needs (and how much of that is rebuildable from recorded operations), audio nothing references at all, the bounded preview cache, and clipboard blobs. Every destructive edit writes a new file and none are deleted, so a long session grows without bound. Reads only — it deletes nothing.
Example prompt: how much disk is this session using?
Returns: total_bytes, live, history, unreferenced, preview_cache, clipboard_blobs
Pair it with compact_session, which does the reclaiming — this is the before-and-after measurement.
ML Tools
separate_stemsNot implemented in this build. Would run Demucs stem separation on-device, producing 4 tracks: vocals, drums, bass, other.
Example prompt: separate the stems on track 1
Returns: node_id, stem track IDs
Inference ships as a stub, so this currently returns an error whatever you configure — there is no model download or environment variable that changes that. Only htdemucs and htdemucs_ft are recognised model ids.
split_by_speakerTurn one track and a set of speaker segments into a track per speaker, so each voice gets its own gain, EQ and noise treatment. Writes no new audio — every speaker track points at the same source file, which is why combined playback is unchanged. Audio no segment covers goes to an 'unassigned' track rather than being dropped, and overlapping turns are awarded to whoever was listed first and reported back.
Example prompt: split track 1 by speaker: Priya 0-12s, Sam 12-30s
Returns: node_id, tracks, speakers, unassigned_samples, overlapping_segments
Segments can come from anywhere — a diariser, a transcript that names speakers, or a cue sheet you type. Speaker turns land as ordinary clips, so you correct a boundary by dragging it.
transcribeNot implemented in this build. Would transcribe spoken audio on-device with an ONNX Whisper-base export, storing word-level timestamps in the session.
Example prompt: transcribe track 1
Returns: node_id, word_count, language
The decoder ships as a stub, so this currently returns an error whatever you configure. Text-based editing (cut_words) depends on a transcript and is unavailable for the same reason.
Generators
generate_toneSynthesize a tone (sine, square, sawtooth, or triangle wave) and add it as a new track.
Example prompt: generate a 440 Hz sine for 5 seconds
Returns: track index
generate_noiseGenerate a noise track (white, pink, or brown/Brownian noise) and add it as a new track.
Example prompt: generate 3 seconds of pink noise
Returns: track index
Channel Layout
stereo_to_monoConvert a stereo (or multi-channel) track to mono by averaging all channels.
Example prompt: make track 1 mono
Returns: node_id
mono_to_stereoConvert a mono track to stereo by duplicating the channel to both L and R.
Example prompt: make track 1 stereo
Returns: node_id
DAG Operations
fork_nodeFork the current node to create an independent branch. The fork becomes the new head.
Example prompt: fork the session and call it "take-2"
Returns: node_id
revert_toMove the session head to an earlier node. Does not delete any nodes.
Example prompt: revert to before the reverb
Returns: node_id
compare_nodesGenerate a diff between two nodes: tracks added/removed, gain changes.
Example prompt: compare the current version with the one before normalization
Returns: tracks_added, tracks_removed, tracks_changed
apply_diffApply a computed diff from compare_nodes to the current session.
Example prompt: (used internally by the agent)
Returns: node_id
name_nodeSet a human-readable label on the current head node.
Example prompt: name this state "final mix"
Returns: node_id
Annotations
labelAdd a named point marker or region annotation to the timeline.
Example prompt: mark the chorus at 1:05
Returns: annotation_id
import_labelsImport Audacity-format label text into the session as annotations. Format: each line is 'start_sec TAB end_sec TAB name'.
Example prompt: import these Audacity labels
Returns: node_id
export_labelsExport session annotations as Audacity-format label text (start_sec TAB end_sec TAB name, one per line).
Example prompt: export the markers as labels
Returns: label text
Rendering
render_finalRender the full session to WAV, FLAC or MP3. FLAC is lossless — identical audio, roughly half the size. MP3 is lossy but plays anywhere; bitrate defaults to 192 kbps. Takes title, artist, album, year and comment, written as Vorbis comments on FLAC and ID3v2 on MP3, and can carry the session's markers through as chapters.
Example prompt: export to /Users/me/Desktop/final.wav
Returns: path, duration_sec, peak_dbfs, sample_rate, tagged, chapters
Tags are applied after encoding — FLAC blocks are rewritten in place and an ID3 tag is a prefix — so tagging never touches a sample. WAV has no standard tag container worth using and refuses metadata rather than dropping it silently.
render_previewRender a preview WAV, cached by node id — re-previewing the same session state reuses the render instead of redoing it.
Example prompt: (used internally for playback)
Returns: path
export_multipleExport selected tracks as individual WAV files to a directory.
Example prompt: export tracks 1 and 2 as separate files
Returns: list of exported paths