edytlab logoedytlab

Changelog

Recent landed work. The authoritative list of binaries and tags lives on GitHub Releases.

v0.2.02026-09

  • Edit audio by editing its transcript. The transcript pane shows the words with their times; cut a word from the text and the audio goes with it.
  • Split an interview into one track per speaker. Each voice gets its own gain, EQ and noise treatment, and because every speaker's clips point at the same source file, playing them together is sample-identical to the original.
  • Describe a region instead of dragging it: "select where he talks about latency", "the last thirty seconds of speech", "bars 9 to 16". The selection appears for you to check before anything acts on it, and a description that cannot be resolved says so rather than guessing.
  • Timer record starts and stops a recording unattended, and punch-in replaces a selected region with a new take while leaving the rest untouched.
  • Every row of the timeline shares one time axis. A shorter track, or a clip moved along the timeline, now sits under the ruler where it plays — each lane used to stretch its own audio across the pane. Zoomed in, the selection, the playhead and a drag follow what is on screen, and one scrollbar (or a horizontal swipe) pans every track, the clips, the automation and the labels together.
  • A label lane you type into. Chapter marks are added, renamed, moved and deleted next to the audio, survive edits that shift time, and round-trip through label export.
  • Opening a file loads it straight into the session. It used to be sent to the agent as a sentence, so with no model set up yet the waveform appeared and every edit afterwards failed.
  • A returning user opens into their project where they left it — zoom, selection and playhead — instead of the empty state, and an edit made in the last moment before quitting is no longer undone by the saved view.
  • Undo and redo work on macOS, and redo works at all. Labels, template applications and batch loads now move the session head they create, so undo undoes them rather than the edit before.
  • Destructive edits keep every clip's volume automation, labels and the transcript move with cuts, silences, speed changes and stretches, and a whole track shifts together instead of clamping clip by clip.
  • Audio fixes: the resampler's latency is compensated, the leveler applies its gain continuously rather than per block, a clip's frames are read at its own sample rate, and the effect chain is built per track so it no longer restarts at every clip.
  • A drawn track made of several clips is written by streaming its sources a chunk at a time, instead of decoding a whole recording into memory — over a gigabyte for an hour of stereo audio.
  • Derived audio that no version of the project refers to any more is removed when the project opens. Audio that undo history still needs is kept.
  • Security: the app ships a Content Security Policy, the webview can read only the project's own audio rather than any file on disk, and the capability whitelist is enforced when a tool runs, not only in the list the model sees.
  • The typefaces are bundled with the app, so it no longer contacts Google Fonts on launch.
  • Auditions play instead of printing a file path, the spectrogram toggle draws a spectrogram, an undecodable file says so, and A/B comparison keeps the playhead when you switch sides.
  • Project metadata — title, artist, album and more — carries through to the tags on exported MP3 and FLAC files.

v0.1.02026-08

  • Per-track effect chains. Track.effects round-tripped through save/load since Phase 1 and the render path refused the moment anything populated it, so a field in the model was unreachable in practice. Chains now reach the audio, with five tools to operate them — and because the processors are built once per render rather than per chunk, there is no click at the second boundary.
  • Phase locking in the vocoder. Every bin's phase advanced independently, so bins belonging to one partial stopped agreeing and the partial alternately reinforced and cancelled itself. On a steady 2 kHz tone stretched 2x that was an envelope swinging 2.09x — 6 dB of warble on a flat input. Identity phase locking brings the same measurement to 1.003x.
  • A stretched feature now lands where the ratio says. time_stretch put everything up to 41 ms off its mark, and the error was exactly zero at ratio 1, which is why every existing test missed it: the lead-in trim named the frame holding sample 0 at its left edge, where the analysis window weight is zero, rather than the frame holding it at its centre.
  • storage_report. Every destructive edit writes a content-addressed WAV and none are ever deleted, so a long session grows without bound. The report splits the cost three ways — what the current version needs, what only undo is holding, and what nothing references — because collapsing them into one number is what would make a sweep look safe when it is not.
  • Nodes record how they were made. A node carried a human label and the transform was an anonymous closure, so nothing could replay an edit. tool, parameters and engine version are now recorded — by the dispatcher, so all 81 tools are covered by one code path — which is the prerequisite for treating derived audio as a cache rather than as data.
  • A real logo. Every icon in the repo was still the stock Tauri mark while the brand colour had been violet since the site was written.
  • Point any provider anywhere. A base URL field per provider, so a local server on another port, a gateway or a proxy all work — LM Studio, llama.cpp and vLLM included. The model catalogue follows the same endpoint the agent uses, because listing one server's models while chat talks to another is worse than not listing.
  • Mixer controls. Gain, pan, mute and solo are editable per track without asking the agent — none of them had a command before, so every mixing decision went through a sentence and a model round trip. Pan in particular had a balance law in the render engine and nothing in the product able to reach it.
  • Volume automation is visible and editable. The curve, its persistence and the render integration all existed; there was no way to see or touch it. Draw points on the lane, drag them, nudge with arrows — one gesture is one undoable step, not one per pixel.
  • Clip timeline. A track split by an interior cut used to render as one continuous lane, so the seam was invisible. Clips now appear as chips you can select, move and delete, with move_clip and remove_clip available to the agent too.
  • align_to_beat warps audio. It recorded a beat grid that nothing read and reported success while changing nothing — the last tool in the repo doing that. It now stretches each inter-beat segment by its own ratio in a single vocoder pass, so there is no seam at the beats.
  • Formant preservation. preserve_formants was a documented, accepted, ignored flag on two tools. Shifted voices now keep the resonances of the vocal tract where they were instead of travelling with the pitch.
  • MP3 export, on a pure-Rust encoder — no LAME, no C dependency, no licence interaction. Bitrate is settable and defaults to 192 kbps CBR.
  • normalize_loudness targets LUFS rather than a peak. Two files peak-normalised to the same value can differ by 10 LUFS, so peak normalisation cannot answer 'make this as loud as everything else'. Gain is capped at a true-peak ceiling and the shortfall is reported when the cap bites.
  • Bus routing. Sends, per-bus effect chains, and the tools to reach them, so one reverb can serve several tracks.
  • FLAC export — lossless, about half the size of WAV, sample-identical to the WAV of the same render.
  • A time-stretch bug that could produce a full-scale output. A steady 2 kHz sine stretched 2x came back peaking at 740x the input: the overlap-add divided phase-rewritten frames by a window energy that ramps to zero at the edges. Fixed, with tests asserting that stretching redistributes energy in time and never creates any.
  • A timing drift in every long stretch. Rounding each synthesis hop to an integer accumulated — measured on a 120-to-100 BPM warp, that put the fifth beat 10.5 ms early. Positions are now accumulated in floating point and rounded once.
  • Ollama joins Anthropic, OpenAI, Gemini, Groq and OpenRouter — six providers, and the local one needs no key at all.

v0.1.0-dev (earlier)2026-08

  • Audio fidelity: five tools — fade, reverse, insert_silence, copy_region and paste_region — converted seconds straight into a sample index with no interleave stride. On a stereo track that halved every span, and an odd sample count swapped left and right for the rest of the track. All five now count in frames.
  • stereo_to_mono and mono_to_stereo wrote the source's channel count into the WAV header rather than the converted buffer's, so the result played at double speed an octave high, or half speed an octave low. The conversion maths was right all along; only the write-back was wrong.
  • Filters no longer diverge above Nyquist. low_pass_filter(cutoff_hz: 30000) on a 44.1 kHz track put the biquad poles outside the unit circle and the render saturated into a full-scale square wave. Frequencies are now held just below Nyquist across every filter and every EQ band.
  • Seven tools panicked outright on a reversed time range (end before start) instead of returning an error.
  • Renders no longer drop everything after an interior cut. A track is a list of clips and the render graph only ever read the first one, so cutting ten thousand frames out of the middle of a one-second track rendered 12 000 frames instead of 38 000. Clips now mix the way tracks do, with gaps as silence.
  • Destructive edits cover every clip of a split track. A reverb applied after an interior cut used to treat the first half and leave the second half dry, with a hard seam at the join.
  • Cutting or splitting a clip keeps its volume automation. split_clip copied the curve across without re-basing it, so a fade-out restarted at full volume after the split; cut_range discarded the curve entirely.
  • Extensibility: MCP servers now start automatically at launch, so a registered server contributes its tools without a manual restart. Requests are deadline-bounded and server stderr is surfaced in error messages.
  • Agent profiles that pin a model on another provider now authenticate against that provider instead of reusing the active provider's key.
  • MCP server editor: the args, env, and headers fields accept multi-line input correctly.
  • Plugins: install skills and agent profiles from a GitHub repo (github:org/repo) or a local path.
  • Eight audio skills ship pre-installed — podcast cleanup, vocal chain, loudness mastering, noise reduction, dialog enhancement, music mixing, silence cleanup, and an export guide.
  • Agent profiles: save a model override, a tool whitelist, and a system-prompt addition, then switch between them.
  • Skills: markdown files with always/keyword/regex triggers, editable in Settings.
  • Memory: global and per-project notes spliced into the system prompt.
  • Microphone recording via CPAL, captured straight to WAV.
  • Spectrogram view toggle in the timeline.
  • Plan steps can be edited inline before you approve them.
  • Individual tools can be disabled from the capabilities menu.
  • 69 built-in audio tools, including reverb, echo, noise gate, limiter, de-esser, tone and noise generators, Audacity-format label import/export, and per-track export.
  • OpenAI provider added alongside Anthropic and OpenRouter; model picker is catalogue-backed.
  • Per-provider keychain slots; legacy unsuffixed Anthropic key still read for back-compat.