Commit Graph
1121 Commits
Author SHA1 Message Date
skylar 37dbadfc04 ci: require nextest 0.9.150
Use the fixed release for GHSA-vc25-qg58-w57c.
2026-10-26 14:13:06 -06:00
aiongg 7dc56a4dbe ui: Tracks and Groups and Clips in full-height dock columns (#1088)
* ui: keep SoundCraft's beside-the-session-view place for panels craft-ui has no record of

* ui: Tracks and Groups and Clips in full-height dock columns

The Edit window docks Tracks and Groups (168 pt) at its start edge and Clips
(230 pt) at its end edge, with the MIDI editor under the session view between
them; Mix docks Tracks and Groups at its start edge. Panels dragged to an
empty window edge make a dock there.

Saved preferences and window configurations carry docking_version. Split-frame
layouts saved without it load as the new defaults, keeping every other
setting. A list with no recorded place reopens in its dock group, making the
dock again at its side and width when it is gone.

Pins craft-ui, craft-docpath and craft-media to craft-libs#312.

* Pin craft-libs at d24e4bc for the Mac round 3

* ui: test that a floating list reopens floating while its dock is shown; ui-parity revision
2026-10-25 21:33:15 -04:00
Dylan M. Taylor 088e270a5e refactor: split auto_pan process and audiosuite frame limit into helpers (#1104)
Reduces cognitive complexity flagged by SonarCloud (rust:S3776). Behaviour is unchanged:
per-sample order is envelope update, envelope trigger, LFO phase, modulator, width/manual/position
smoothing, output write.
2026-10-25 21:14:17 -04:00
aiongg 23f90a9164 chore(deps): safe dependency refresh (#1102) 2026-10-25 20:49:42 -04:00
Dylan M. Taylor 1c63b2a5b9 tests(clap-host): answer nextest's --list for the custom-harness editor test (#1100) 2026-10-25 20:14:33 -04:00
Dylan M. Taylor cf0f4d2f6a tests(vst3-host): answer nextest's --list for custom-harness tests (#1099) 2026-10-25 19:49:11 -04:00
Dylan M. Taylor e14cea42b2 Linux: default to XWayland for file drag-and-drop on Wayland desktops (#150)
* Linux: default to XWayland for file drag-and-drop on Wayland desktops

* Ignore an empty DISPLAY before forcing X11
2026-10-25 19:37:13 -04:00
Dylan M. Taylor d683aee3eb refactor: reduce cognitive complexity in audio-io, midi, dsp, engine, playback, plugin hosts (S3776) (#1097)
* refactor: reduce cognitive complexity in audio-io, midi, dsp, engine, playback, plugin hosts (S3776)

Extract helpers; behavior-preserving.

* fix: clippy lints in extracted helpers
2026-10-25 19:32:34 -04:00
Dylan M. Taylor 0197e27fc4 build: pin craft-update to craft-libs main (495e597) (#1096)
Picks up the startup prompt without the glyphs a font may lack (storytold/craft-libs#343, #344): the close mark is painted and the version pill is ASCII, so apps that panic on a missing glyph no longer take the prompt down.

Part of tracking issue storytold/craft-libs#319
2026-10-25 17:50:34 -04:00
Dylan M. TaylorandCodebuff 5bbefeae62 build: pin craft-update to craft-libs main (495e597) (#1092)
Picks up the update prompt fix that draws its close mark and version pill
without glyphs a font may lack, so the prompt no longer takes the app down
when a bundled face has no ✕ or →.

Part of tracking issue storytold/craft-libs#319

🤖 Generated with Codebuff

Co-authored-by: Codebuff <noreply@codebuff.com>
2026-10-25 17:37:38 -04:00
Dylan M. Taylor a44d1b830b Merge pull request #1014 from storytold/fix/sonar-s107
refactor: bundle parameters of long signatures (Sonar S107)
2026-10-25 16:35:58 -04:00
Dylan M. Taylor eec559f057 build: pin craft-update to craft-libs main (db19c37) (#1090)
Picks up the fix that keeps the close request pending while the app holds unsaved work, the executable-name check in the Windows update helper, and the zip 9 / dirs-free build.

Part of tracking issue storytold/craft-libs#319
2026-10-25 15:34:58 -04:00
Dylan M. Taylor b854771251 feat: startup update prompt modal and direct self-updating (#1073)
* feat: startup update prompt modal and direct self-updating

Integrate `craft-update` pinned to storytold/craft-libs fe61243 to check for
updates on startup, display the standard suite update modal with changelog notes,
and support one-click in-app updating and restart.

Ref: storytold/craft-libs#319

* wip

* build: refresh the lock

* refactor(updates): drive the flow with craft-update's Updater

The check at start is opt-in for the desktop app, a successful update closes through the app's own close path, and no update starts over unsaved work.

* fix(updates): register the update command and hold the install back during a recording

Help ▸ Check for Updates… goes through the shared command id, and an active recording counts as work the update must not interrupt.
2026-10-25 14:38:14 -04:00
aiongg 0a95b6dadf Merge pull request #1045 from forwardaudio/meters-accumulate
Meters: keep every block's peak until the UI takes it
2026-10-25 12:12:08 -04:00
aiongg cf96cb888c Follow-ups to #1058: Auto Pan keeps the stereo image, paste and Strip Silence fixes (#1060)
* 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
2026-10-25 12:06:36 -04:00
skylar taylor-barrick e0951aecf9 Migrate SoundCraft to egui 0.37 (#1063)
* fix(ui): preserve host keys during scripted input and clarify mixer labels

* Preserve host input while expiring scripted gestures

* Document migrated audio and UI behavior and regression invariants
2026-10-25 10:48:56 -04:00
Brandon ThomasandClaude Opus 5.5 01b39850ad Release 0.13.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.13.1
2026-10-25 09:29:18 -04:00
Brandon ThomasandClaude Opus 5.5 b48df2a8b9 Release workflow: grant contents: write on the release job
#988 dropped the workflow-level permission for SonarCloud S8233 but never added the job-level one, so the 0.13.0 release run failed at startup: the shared workflow's draft-release job asks for contents: write.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 09:29:08 -04:00
Brandon ThomasandClaude Opus 5.5 106678471f Release 0.13.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 09:26:25 -04:00
Forward AudioandClaude Opus 5.5 7d4ae23202 Meters: a channel-count change takes the new stereo peaks; takes drop deleted tracks
When a strip's channel count changes, the first-two-channel peaks now take the new values
along with the per-channel ones. A take that finds no new block still drops the meters of
deleted tracks from the UI's copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 10:26:03 +01:00
aiongg 541096d2cb Merge pull request #1058 from aiongg/dotcoocoo-batch
Merge 13 open PRs (tested batch)
2026-10-25 00:54:45 -04:00
aiongg 353ea145aa Integration: AudioSuite speed ramp: Fit To plays the first two thirds for Slow Down and the last for Speed Up 2026-10-25 04:36:02 +00:00
aiongg 35905fb90b Integration: Auto Rename: a loaded scheme leaves room for its number 2026-10-25 03:53:11 +00:00
aiongg d7b1562cc1 Integration: Strip Silence naming: rustfmt 2026-10-25 02:54:13 +00:00
aiongg 9048e04d60 Integration: AudioSuite speed ramp: the clip suffix is speeramp
AudioSuite clip suffixes take four letters from each word of the process
id, so speed_ramp gives -speeramp.
2026-10-25 02:46:30 +00:00
aiongg e954639900 Integration: docs: built-in plugin counts are 27 processors + 3 instruments
The registry holds Auto Pan and Subharmonic as well; the 3bc2d92 snapshot
keeps its own count.
2026-10-25 02:33:30 +00:00
aiongg bbebfa1a6e Merge PR #1023: Docs: the built-in plugin counts match the registry, and the sampler is no longer listed as missing 2026-10-25 02:33:05 +00:00
aiongg 9821168bc4 Merge PR #1054: Clip List: Auto Rename sets the names of the clips separated from a clip
# Conflicts:
#	ROADMAP.md
2026-10-25 02:33:05 +00:00
aiongg e46339606a Merge PR #1055: Strip Silence: rectangles show what Strip keeps while the window is open
# Conflicts:
#	ROADMAP.md
2026-10-25 02:32:58 +00:00
aiongg 835de9f038 Integration: Strip Silence naming: refuse a name and suffix too long for a clip name
A name and suffix longer than MAX_NAME_CHARS - 29 leave no room for the
number, and a session truncates such names on open.
2026-10-25 02:32:54 +00:00
aiongg e910e72940 Merge PR #1044: Strip Silence: Rename sets the names of the clips it leaves
# Conflicts:
#	ROADMAP.md
2026-10-25 02:32:31 +00:00
aiongg 54467f544b Merge PR #1040: Strip Silence: Extract keeps the silence, and Separate cuts the clips without removing any
# Conflicts:
#	ROADMAP.md
2026-10-25 02:32:22 +00:00
aiongg 4311742624 Merge PR #1030: Clip > Loop... opens Clip Looping: Number of Loops, Loop Length, or until the next clip or the session end
# Conflicts:
#	ROADMAP.md
2026-10-25 02:32:11 +00:00
aiongg a8ca533b9b Merge PR #1053: Fades: Create refuses a shape that is not a string over a selection 2026-10-25 02:31:53 +00:00
aiongg 3a139d4bed Integration: AudioSuite speed ramp: name SoundCraft's ids speed_ramp
The process id, types, function, test module and clip suffix use
speed_ramp; the menu label stays as the catalog has it.
2026-10-25 02:31:48 +00:00
aiongg 092122b49c Merge PR #1016: AudioSuite: Vari-Fi slows a clip down to a stop or speeds it up from one
# Conflicts:
#	ROADMAP.md
#	docs/plugin-parity.md
2026-10-25 02:31:05 +00:00
aiongg be75be896a Merge PR #1013: Add a built-in Auto Pan plugin
# Conflicts:
#	README.md
#	ROADMAP.md
#	docs/plugin-parity.md
2026-10-25 02:30:52 +00:00
aiongg f77c360f94 Merge PR #1019: Add a built-in Subharmonic plugin
# Conflicts:
#	docs/plugin-parity.md
2026-10-25 02:30:22 +00:00
aiongg a6cec46275 Merge PR #1010: Add a built-in Ring Modulator plugin 2026-10-25 02:30:09 +00:00
aiongg 10e26f6fe2 Merge PR #1018: CLI tests: the several-roots test uses plain paths, so it passes on Windows 2026-10-25 02:30:09 +00:00
aiongg c0dc2c3ec6 Merge PR #1017: Autosave: allow the Unix-only mut, so clippy passes on Windows 2026-10-25 02:30:09 +00:00
dotCooCoo 06f30628bb Clip List: a paste reuses a held Auto Rename scheme only when its text matches too
A paste reused the scheme of the session it went into whenever the
copied scheme's id matched, so an unrelated scheme that had the same id
could rename the pasted clip and count its numbers on. A scheme is now
reused only when its name, zeros and suffix match as well; any other is
added under a new key.
2026-10-24 18:37:54 -07:00
dotCooCoo 746a825ed5 Strip Silence: rectangles show what Strip keeps while the window is open
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.
2026-10-24 18:17:53 -07:00
dotCooCoo fe4cd8095d Clip List: Auto Rename sets the names of the clips separated from a clip
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.
2026-10-24 17:12:22 -07:00
dotCooCoo a41f254aa0 Fades: Create refuses a shape that is not a string over a selection
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.
2026-10-24 15:19:28 -07:00
dotCooCoo 698507cf30 Strip Silence: Rename sets the names of the clips it leaves
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.
2026-10-24 14:18:26 -07:00
dotCooCoo 1e9a0e9c88 Strip Silence: a mode that is not a string is refused
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.
2026-10-24 13:46:21 -07:00
aiongg ee050db59c ui: move panel docking onto craft-ui's shared Workspace and DockCommand (#1035)
* ui: move panel docking onto craft-ui's shared Workspace and DockCommand

Pin every craft-libs crate at 16fb3d4 (craft-libs main after #285).

The Edit and Mix workspaces are craft_ui::docking::Workspace<Panel>.
ui.dock and ui.dock.reset parse into DockCommand; the app keeps its
panels, permissions, defaults, the document-view and Mix rules, the
beside-the-canvas fallback for panels without a recorded place, and
Arrange. The canvas accepts splits so panels still open beside it.

Saved v1 workspaces (no version, floating windows as
{panels, active, rect}) load unchanged. Tests cover loading one and
dragging a group by its drag bar.

* ui: test that activating a hidden panel shows it

* ui: name the field in ui.dock operation errors; document the shared panel menu and zones
2026-10-24 16:18:19 -04:00
Forward AudioandClaude Opus 5.5 37e155c828 Meters: keep every block's peak until the UI takes it
The audio thread overwrote the shared meter snapshot every block (~94 blocks/s at 512
frames, 48 kHz) while the UI read it 20-60 times a second, so it only ever saw the latest
block and short transients were under-read. Blocks are now folded together (max of each
channel's peak and of the gain reduction; plugin failures keep the latest count) until the UI
takes them with Player::take_meters, which also starts a new period. Blocks rendered while the
UI holds the lock wait in an audio-side accumulator instead of being lost; the audio thread
still only try_locks.

Stopping, starting and locating now zero the meters in place instead of clearing the maps,
so playing again no longer re-allocates every track's entry on the audio thread. The UI
thread works out which tracks a session update deleted and tells the audio thread, which
drops just their entries.

The Mix window and the Renderer now read the snapshot the app takes once per poll instead of
reading the player themselves, so a period's peaks are not split between readers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 22:14:52 +02:00
dotCooCoo 0ca492e0ab Strip Silence: Extract keeps the silence, and Separate cuts the clips without removing any
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.
2026-10-24 12:57:38 -07:00