* Auto Pan: balance the left and right channels at constant power instead of panning their mono sum
* Strip Silence rectangles: on the web, rescan when a slider drag ends instead of on every frame of it
* Paste: keep the clipboard's remapped Auto Rename keys only when the paste succeeds
* Subharmonic: test that Q 5 filters after the saturator keep the output finite
* AudioSuite window: drop the constant-speed varispeed controls no menu item opens
* docs: gaps: Clip Looping has no loop crossfade and caps Number of Loops at 512
While the Strip Silence window is open, the Edit window draws a
rectangle around each range that Strip would keep on the selected
tracks: the audio above the threshold, padded by Clip Start Pad and
Clip End Pad. The rectangles follow the sliders and stay while Rename
Selected Clips is open. They are removed when the window closes. The
audio and the clips do not change.
The scan runs again when a value or the session changes. Outside the
web build it runs on a worker thread, one scan at a time, and the
rectangles last found stay until it ends. A scan for older values, or
one still running after the window closes, stops before its next
window of audio.
The new query command edit.strip_silence_preview returns the same
ranges for each track. It reads the threshold, minimum strip duration
and pads with the defaults and limits of edit.strip_silence, and both
use the same scan.
Clip List › Auto Rename… opens Rename Selected Clips for the selected
clips. Name, Starting Number, Number of Places and Suffix set the names
that editing gives the clips it separates from them: the name, as many
zeros as Number of Places, a number counting up from Starting Number,
and the suffix. The piece after each cut is the new clip and takes the
next name. The piece before it keeps its name. The clips separated from
one clip, and from every clip that got the scheme together, count up
one number sequence. The guide does not say how Strip Silence's own
Rename fields and Auto Rename combine. Here, when Strip Silence's own
Rename fields are set, they name the audio pieces it cuts inside its
range, and those pieces take no Auto Rename name and do not count the
Auto Rename number up. In Strip and Extract, only the pieces that Strip
Silence keeps take Auto Rename names, in time order, so their numbers
have no gaps.
clip.auto_rename takes clips, name, number, zeros and suffix, with the
same limits and errors as edit.strip_silence. Without a name the clips
get no scheme. Cut and Copy keep a copy of the copied clips' schemes,
and a paste uses the session's scheme with the same id or adds the
copy under a new key, so a pasted copy keeps its names after an undo
or in another session. Saved sessions hold the schemes, and opening a
session repairs them and drops the ones no clip uses. Import Session
Data brings them in under new keys. Clips placed from a clip group file
get no scheme.
edit.fades_create over tracks and a range read a null, boolean or number
shape as absent and made Equal Power fades. It now returns an error that
lists the accepted shapes, as the clip form already did, and leaves the
session and the undo history unchanged.
The Strip Silence window has a Rename… button. It opens Rename Selected
Clips, where Name, Number, Zeros and Suffix set the names that Strip,
Extract and Separate give the clips they leave in the selection: the
name, that many zeros, a number counting up from Number, and the
suffix. SFX, 23, 1 and .Reel1 give SFX023.Reel1, SFX024.Reel1 and so
on. The app keeps the scheme for later uses of Strip Silence until
the app quits, or until Clear and then OK empty it. OK, Cancel and
Escape go back to Strip Silence with its slider values.
edit.strip_silence takes name, number, zeros and suffix. Numbering runs
on from one track to the next, and the result reports how many clips
were named. Without a name the clips keep their names. A name or suffix
that is not text, a number out of range, or a number, zeros or suffix
without a name is an error and leaves the tracks unchanged.
edit.strip_silence read a null, boolean or number mode as no mode and ran Strip. It now returns an error and leaves the track unchanged, as it does for an unknown mode name.
The Strip Silence window had only a Strip button. It now also has
Extract and Separate. Extract removes the parts of the selection that
hold audio and keeps the silent parts. Separate separates the clips at
the same points Strip does and does not remove any clip. Enter on a
focused Extract or Separate runs that button, and Enter presses Strip
only when neither was clicked.
edit.strip_silence takes a mode param: strip (the default), extract or
separate. An unknown mode is an error. The Minimum Strip Duration
slider now goes up to 4,000 ms.
* security: move the release workflow's write permission to the job level (SonarCloud githubactions:S8233)
* style: replace wildcard imports with explicit uses (SonarCloud rust:S2208)
Rewrites every glob `use` Sonar flags into explicit imports, so what each
command module consumes is visible at the top of the file.
* release: the git-sources gate moves into craft-common-actions (PR #78)
The check is shared at release.yml@main now; keep only the reusable call.
---------
Co-authored-by: Dylan Taylor <dylanmtaylor@users.noreply.github.com>
Dragging a track's bottom edge showed nothing until release; then the
track jumped to the nearest height preset. Pro Tools' track height
modifiers and keys were missing too.
Dragging:
- The edge follows the pointer as in Pro Tools: the track steps through
Micro…Extreme while the pointer moves, and the tracks below move with
it. The whole drag is one undo step (execute_merged, ended on release
like fader moves).
- Cmd (Ctrl on Windows and Linux) drags to any height from Micro to
Extreme instead of snapping. The model gains TrackHeight::Custom
(points), and track.height takes a number of points as well as a
preset name.
- Alt resizes every track the Edit window shows; Alt+Shift resizes the
selected tracks too. The track menu's Track Height items follow the
same rule.
- The drag is measured from where it started, not from the edge's
current place: when the tracks above the dragged one resize they move
its edge, and edge-relative math flipped between two heights on every
frame. This also fixes rows showing playlist lanes, which a plain
click on the edge used to make taller.
Keys:
- New commands track.height_up and track.height_down move each track
one preset taller or shorter; a track already at Extreme or Micro is
left alone, with no undo step. Control+Up/Down runs them on macOS, as
in Pro Tools. Windows and Linux use Ctrl+Up/Down, because the Start
key Pro Tools uses there isn't available. Alt steps every shown track,
Alt+Shift the selected ones.
- Ctrl+Up/Down used to run Extend Edit Up/Down, keys Pro Tools doesn't
use for them. Those commands now have Pro Tools' Control+Shift+P and
Control+Shift+; on macOS (macOS sends the latter as Control+:).
Windows and Linux reach them from Edit > Selection.
- Off macOS, menus no longer show Mac Control chords that can't be
pressed there (Time Lock's Ctrl+Alt+L, Toggle Recent Playlist's
Ctrl+Alt+Shift+Left, the new Extend Edit keys); the arrow chords that
fixed() maps to Ctrl keep their labels.
Track headers show each row of controls only once it fits: the keys
from 46 points and the view and automation selectors from 86, where
each row ends. The old 30 and 60 point cutoffs suited the presets only
and cut controls off at heights in between. Every preset draws exactly
as before.
Tests: the model's custom heights, steps and JSON; the engine's point
heights and steps, with no undo step when nothing changes; in the UI,
the live drag and its single undo step, Cmd, Alt and Alt+Shift drags
that hold steady while the pointer does, the height keys on macOS,
Windows and Linux, and the Extend Edit keys on macOS.
The edit modes only partly worked. Shuffle changed Cut, Clear and Paste
but not moves or trims. Spot froze drags and had no dialog. Grid snapped
relative to whichever clip was under the pointer, and Relative Grid
acted like Absolute. Behaviour now follows the Edit Modes chapter of the
Pro Tools Reference Guide.
Shuffle
- Grabber drags lift the clips out (later clips close the gap) and land
them at the nearest clip boundary, pushing later clips right; an empty
track takes them at the session start. The drag outline shows where
each track's clips will land.
- Trims move the later clips (a trimmed start stays put and the material
slides under it). Duplicate, Duplicate and Extend, Repeat and Clip List
drops make room, and Paste over a selection replaces it.
- Moves lift each clip by id and close the hole it leaves, so crossfade
partners and unselected clips keep their audio, and a crossfaded pair
moved together stays a crossfade. Ripples never push clips past the
session start, never split a crossfade (refused with a reason), and
drops never land inside a clip or crossfade.
- A time- or edit-locked clip and everything after it stay put when
Shuffle closes or opens gaps. Edits that would push into one are
refused ("not enough room before a locked clip"), and trims stop short
of it. Insert Time and Cut Time are timeline operations and still move
everything.
- With Automation Follows Edit, automation moves with every ripple, up to
a locked clip, and travels with moved clips; with it off, Shuffle edits
leave automation alone. Shuffle Clear used to move the clips but leave
their automation behind (#232).
- Shuffle Lock: Cmd-click (Ctrl-click on Windows and Linux) the Shuffle
button while in another mode. While it's on, the button shows a padlock
and every way into Shuffle (keys, button, commands) is refused.
- A drag works out every lift and landing point once per target track
(`lift_plan`, `shuffle_slots`, and a `DragPlan` kept for the drag). In a
release build, dragging 100 clips on a track of 20,000 took 29 ms a
frame and a 135 ms drop; now it's under a microsecond a frame and a 5 ms
drop.
Slip, Spot and Grid
- Slip: trims stop at the neighbouring clips instead of overlapping them.
- Spot: a Grabber click or drag, a Trim click or drag and a Clip List drop
open a Spot dialog: Start, Sync Point and End in any time scale, the
Duration, and the clip's Original Time Stamp. Trim clicks pick the
nearer edge.
- Grid: a drag snaps the dragged clip's start (its sync point, when it
has one inside the clip) to the grid. Relative Grid moves by whole grid
steps and keeps the clip's offset from the grid; a cut or copy pasted
in Relative Grid lands as far after a grid line as the copied range
started after one. Holding Cmd (Ctrl on Windows and Linux) while
dragging or dropping from the Clip List swaps Grid and Slip. Grid lines
no longer fall a step short at tempos where a line isn't a whole number
of samples.
- Choosing Grid from another mode picks whichever of Absolute and
Relative Grid was used last; F4 in Grid toggles them, like clicking the
Grid button again. Options > Edit/Tool Mode Keyboard Lock, which did
nothing, now stops F4 and Alt+4 from switching them (toolbar clicks
still do).
- Snap to Grid in Shuffle, Slip and Spot: Shift+F4, Shift-click on the
Grid button or on another mode's button, or hold F4 with F1-F3. The
Edit cursor and selections snap to the grid while clip moves and trims
follow the main mode; the Grid button is outlined while it's on.
- Option+1-4 (Alt+1-4 on Windows and Linux) work like F1-F4, and the `
key cycles Shuffle, Slip, Spot and Grid, skipping a locked Shuffle.
- Insert Silence pushes later material only in Shuffle; in the other
modes it clears the selection, as in Pro Tools.
Also
- Dragging clips from several tracks keeps each track's distance from the
grabbed clip's track. Drops past the last track, or onto a track that
can't play the clips (audio onto MIDI, an aux or the master), are
refused; clips moved onto an aux used to vanish into its unused
playlist.
- Undo and Redo keep the Edit mode, Shuffle Lock, Snap to Grid and the
Grid kind. Start trims keep a clip's sync point on its audio, or drop
it. Imported BWF time stamps are converted from the file's rate (read
from its header) to the session's, and the Original Time Stamp no
longer adds the session start twice. Typed positions that overflow are
ignored instead of panicking.
Commands: `edit.move_clips` follows the mode, and its `track` moves the
first clip's track there and keeps the others' distances. `edit.trim_clip`,
`edit.snap_to_grid` (Shift+F4) and `edit.shuffle_lock` are new, and
`edit.mode` takes `snap_to_grid`. Mode buttons expose their names to
accessibility tools.
Tests: crates/{engine,ui-egui}/tests/edit_modes.rs and the op tests in
edit.rs; the random-edits property test also toggles clip locks.
Commands that already worked but had no key get the ones Pro Tools uses,
on macOS, Windows and Linux alike (Alt is Option on macOS; Cmd is Ctrl
elsewhere):
- Shift+= and Shift+- step the Grid value to the next larger or smaller
one, and Alt+Shift+= and Alt+Shift+- the Nudge value, as the Pro Tools
Reference Guide gives them. `view.grid` and `view.nudge` take `step`.
`GridValue::stepped` walks the note values, keeping a dot or triplet, and
steps seconds, frames and samples by tens. macOS sends Alt+Shift+= as =
(the key under ±), so that arm takes = as well as +. Both commands list
the keys as descriptive shortcuts, like Nudge's Plus/Minus, so they show
wherever commands list their shortcuts; the strings don't parse, so the
registry never dispatches them and `shortcuts::fixed` handles the keys.
- Commands Focus: , and . nudge back and forward, M and / nudge by the next
larger Nudge value (`edit.nudge` takes `next`), 0 copies the Timeline
selection to the Edit selection and O the other way, [ and ] play the
Edit and Timeline selections, and Shift+Z redoes. Shift+P and Shift+;
add the track above or below the selection, keeping its range (P and ;
already move it). They run Extend Edit Up/Down, which now skip tracks
the Edit window doesn't show (hidden, or in a closed folder); before,
they could add an invisible track. Shift+; can arrive as :, so both are
matched.
- Playlists: Alt+Shift+Up and Alt+Shift+Down copy the selection to the
target playlist and to a new one, Alt+Shift+T and Alt+Shift+N move it
there, Shift+Right shows the target playlist and Cmd+Shift+Right
designates the shown one. The MIDI editor's piano roll moved notes on any
arrow key, whatever the modifiers; it now leaves Alt, Cmd and Ctrl arrows,
and Shift+Left/Right, to these shortcuts.
- F12 records, as in Pro Tools. Cmd+Space is Spotlight on macOS.
- Ctrl+Tab goes back to the previous clip boundary off macOS, where Windows,
GNOME and KDE take Alt+Tab; Pro Tools for Windows uses Ctrl+Tab too.
Cmd+Alt+Tab now toggles Tab to Transient: the Tab arm took it as Alt+Tab
and tabbed back instead.
- Windows: Alt+7 Universe, Alt+6 Clip Effects, Alt+= MIDI Event List,
Shift+K MIDI Keyboard, Cmd+Alt+J Window Configuration List, Alt+' Task
Manager, Alt+I Workspace, Alt+J Workspaces to Front.
Tests drive the keys through `shortcuts::handle` for each OS
(tests/pro_tools_keys.rs), plus the piano roll with modifier arrows held.
Strip Silence rendered the whole selection at once, and a render stops
at 2^29 samples over all channels: 93 minutes of stereo at 48 kHz, 46
at 96 kHz. Everything past that read as silence, so the clips there
were deleted. A 105-minute selection on a stereo track lost its clip at
100 minutes.
It now renders at most 2^24 samples at a time, only where unmuted audio
clips play, into a streaming version of the silence detector
(`SilenceScan`, which `non_silent_ranges` now runs on). A window takes
at most 64 MB instead of up to 2 GiB, and more than a day of clips is
refused rather than scanned for minutes. `render_clips` now skips clips
outside its range before looking up their clip effects, so a track of
5,000 clips strips as fast as before. Results are unchanged on the demo
sessions and on 10 minutes of tone bursts that cross window edges.
Trim to File Boundaries and Trim to Fill Selection extended a clip within
its source without looking at the clips around it, leaving two unfaded
clips over the same samples. Both now go through one helper that caps the
extension at the end of the previous clip and the start of the next one on
the same playlist, the way the other commands that grow an existing clip
do (Paste Merge MIDI, step input). An existing crossfade overlap is kept.
Fixes#282: on an empty MIDI or instrument track there was no UI way to
get a MIDI clip, so notes couldn't be entered by hand. `midi.new_clip`
existed but had no menu item, key or tool.
- Consolidate now works on MIDI and instrument tracks. The MIDI in the
selection becomes one clip covering the whole selection, gaps
included. It keeps the sound: muted clips stay silent, and notes are
cut where their clip ended. An empty selection gives an empty clip,
as in Pro Tools. Audio tracks are unchanged.
- The Pencil draws a MIDI clip on an empty part of a MIDI or instrument
track: a click makes one bar, a drag covers the bars it crosses, with
an outline while dragging. Clips start and end on barlines, the rule
Pro Tools uses for MIDI it creates. A clip stops at its neighbour
rather than overwriting it, and clicks on existing clips add nothing.
The new clip is selected, so the MIDI Editor shows it.
- With an empty MIDI or instrument track selected, the MIDI Editor says
so, and a click adds a one-bar clip at the insertion point (or a clip
over the selection).
Consolidate clamped its range to the track's last clip end plus one
second, so on an empty track a 0-5 s selection made a 1 s clip and a
2-7 s selection made nothing. It now renders, clears and places exactly
the selection, and refuses a selection too long to render instead of
placing a shorter clip. Prepare DPE keeps the old per-track bound.
Fixes#164
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes#166: dragging a selection up from the last track deselected it and
selected every track above instead. Fixed, along with related Edit-window drag
problems:
- Drag selection spans exactly the tracks between the press and the pointer,
in either direction, and the whole window updates in the same frame.
- Shift+click in another track adds it to the selection with the same range,
as in Pro Tools, so the selected tracks no longer have to be adjacent. A
click outside the range extends it.
- Track names follow Pro Tools' rules in the Edit window, the Mix window and
the Tracks list: Shift+click selects every track between the nearest
selected one and the clicked one, and Cmd+click (Ctrl+click on Windows and
Linux) adds or removes one. A click on a name used to replace the selection;
only the Edit header's background added, and it treated Shift like Cmd.
- Dropping a track's name plate lower down no longer sends the track to the end.
- Drags act where you pressed: a quick drag from a clip edge now trims instead
of moving the clip.
- Dragging past the edge of the track area scrolls, and a flick past the last
track selects down to it.
- The insertion point moves on press, shows immediately, and only on the
selected tracks.
- edit.select no longer makes a new document revision when nothing changed
(each one is resent to the audio engine).
- Fixes a panic when a fade drag's clip shrinks to zero length.
The command cleared every automation lane in the selection and left the clipboard empty, so the cut could not be pasted. It now uses the same copy-and-clear path as Cut Pan Automation.
Nothing in the Clip List could be removed: neither its files nor its clips
had a delete action, so everything stayed listed.
- New `clip.clear` (Cmd+Shift+B, the Clip List Clear shortcut in Pro Tools),
also offered as Clear… on every Clip List row's right-click menu. A clip
leaves its track; a file leaves the session with its decoded audio and is
never deleted from disk. One undo step brings everything back.
- As in Pro Tools, Clear asks first. The dialog names what goes, including
the clips on any track or playlist that still play a file being removed:
they are removed too. Programmatic calls never open it; they pass
`with_clips: true` to remove a file still in use, and fail without
changing anything otherwise.
- File rows can be selected now (`edit.select {sources}`, kept in
`EditState::selected_sources`); with no ids, `clip.clear` acts on the
Clip List selection.
- Remove Warp and re-warping ignore a stored original whose file has been
cleared, so they never point a clip at a missing file.
- File › Export › Sibelius and File › Send To › Sibelius write MusicXML 4.0 (quantized,
chords, ties across bar lines, meter changes, treble or bass clef per part)
- File › Print Score engraves the MIDI tracks to a printable SVG page; File › Score Setup
sets title, composer, bars per system and track names
- File › Import › Clip Groups and Export Clip Groups (.scgrp with its audio)
- Edit › Paste Special › Merge Markers: copy carries the markers in the copied range
- The UI opens a path prompt for any command that needs a path or folder
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Workspace for SoundCraft, a clean-room pure-Rust Pro Tools-class DAW:
timebases and tempo maps, WAV/AIFF/FLAC/symphonia audio IO with peaks,
SMF and MIDI ops, 26 original DSP plugins, the session model, the mix
engine, ~180 registered commands with undo, a cpal player, and the
agent rules (AGENTS.md, ATTRIBUTION.md).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>