* 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>
A track group's name, membership and Edit/Mix flags could only be set
when it was created: nothing in the engine or the UI could change them
afterwards, so a typo in a group name was permanent.
Add track.group_modify {group: id|name, name?, tracks?, edit?, mix?}.
Omitted fields keep their value. `tracks` replaces membership only when
it is an array, so a mistyped param cannot silently swap the members for
whatever happens to be selected; it dedupes, rejects an empty group, and
rejects an empty or duplicate name, since find_group resolves by name.
The group's letter is left alone: it is the stable id in the Groups list.
Dialog::Group gains an optional group id. None creates, as before; Some
pre-fills from the group and dispatches track.group_modify, so one dialog
serves both. Reached from Modify Group... in the Groups list context menu.
OK is now disabled while no track is checked, since both commands reject
an empty group and the old OK could only raise an error.
The command has no menu path, so it adds no menu leaf and the parity
checklist is unchanged.
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.
- mix: independent strips process in parallel (rayon, native), parameter
pushes cached, plugin sync/routing order cached per session structure;
plugin and render benchmarks
- UI: Playback Engine, I/O Setup (bus rename/delete), Keyboard Shortcuts
windows; clip gain line + info; folder open/close; tempo changes from the
ruler; Inserts/Sends F-J, EQ curve and comments sections in the Mix window
- docs: control protocol and MCP guides
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>