Commit Graph
346 Commits
Author SHA1 Message Date
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
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
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
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 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 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
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
dotCooCoo d5be1e6de3 Clip > Loop... opens Clip Looping: Number of Loops, Loop Length, or until the next clip or the session end
Clip > Loop... and Cmd+Alt+L looped the selected clip four times at once.
They now open the Clip Looping dialog. Number of Loops counts the clip and
its loops together, 4 by default as before. Loop Length is typed in the
main counter's time format, and the last loop is cut short when the
length is not a whole number of loops. Loop Until End of Session or Next
Clip loops up to the next clip on the track, or else to the end of the
last clip in the session.

clip.loop takes the new fill option, and its length option now cuts the
last loop short instead of rounding down to whole loops. A fill or a
length that needs more than 1,000 loops is refused with an error instead
of stopping at 1,000 loops. The cut-short loop is trimmed with
Clip::trim_end_to, which shortens its fades to fit and removes a sync
point that falls past the cut.

Unloop takes a shorter last clip as part of the loop when it shares the
loop, no clip of the loop starts where it ends, and either a whole copy
comes before it or it holds the same material as the origin just before
it. It removes a short last loop too, and leaves both halves of a split
clip in place.
2026-10-24 09:14:06 -07:00
dotCooCoo 02b153797d Merge main into feat/vari-fi-speed-ramps 2026-10-24 07:44:44 -07:00
dotCooCoo c5ddbbafd1 Autosave: allow the Unix-only mut, so clippy passes on Windows
Autosave::create builds each session folder with a DirBuilder that only
the #[cfg(unix)] mode call mutates. On Windows, clippy -D warnings
reports the binding as unused_mut, and cargo xtask ci stops at its
clippy step. The binding now carries
#[cfg_attr(not(unix), allow(unused_mut))], as the recovery test's paths
in the same file does. Nothing changes at run time.
2026-10-24 02:55:17 -07:00
dotCooCoo f0f9addd16 AudioSuite: Vari-Fi slows a clip down to a stop or speeds it up from one
AudioSuite > Pitch Shift > Vari-Fi resampled the clip at a constant
speed. It now ramps the speed between normal and a complete stop, so
the pitch falls or rises with it. Slow Down and Speed Up set the
direction. Fit To keeps the clip's length and plays two thirds of it;
Extend plays all of it and makes the clip 150 % long. Fades On fades
the audio out with the slowdown or in with the speedup.

The ramp is offline::vari_fi, run by audiosuite.process as vari_fi
with change, selection and fades params. The constant-speed varispeed
process stays available to commands.
2026-10-24 02:24:30 -07:00
aiongg f6a27c2ccf Integration: automation: hold clip gain envelope ends to the clip edges 2026-10-24 09:13:19 +00:00
aiongg b47f544c7a Merge track r1-t02
# Conflicts:
#	contributors/people.toml
#	docs/plugin-parity.md
2026-10-24 06:54:04 +00:00
aiongg de206f46b6 Merge PR #798: Fix saved audio trust test on Windows by joining path parts separately (#789) 2026-10-24 06:53:57 +00:00
aiongg d33563ebe2 Merge PR #521: Keep MIDI note selection valid across clip, session and note-order changes (#443)
# Conflicts:
#	crates/engine/src/cmd/midi.rs
2026-10-24 06:53:56 +00:00
aiongg 4240873586 Merge PR #551: Bounce: a Dither option in the dialog and for stems (#522) 2026-10-24 06:40:52 +00:00
aiongg 3fe53ee834 Integration: #595 pass BUNDLE_LIMITS in main's sources_sharing_one_file test 2026-10-24 06:19:20 +00:00
aiongg 9e7583d99b Merge PR #595: Save a session bundle only if it opens again (#433)
crates/engine/src/io.rs: kept both bundle tests.
2026-10-24 06:19:17 +00:00
aiongg 045938728f Integration: #674 advance the source offset by delta/stretch on start trims and compare heal offsets in source time 2026-10-24 06:19:09 +00:00
aiongg 2e17315d5d Merge PR #674: Fix source offset when trimming the start of a stretched audio clip
crates/engine/src/edit.rs: kept main's gap-aware heal comparison and doc comment, the PR's source_len helper, and both sets of tests.
crates/model/src/clip.rs: kept main's clamped trim_start_to body (the stretch-aware offset follows in the Integration commit) and both tests.
2026-10-24 06:19:06 +00:00
aiongg 678cb0f57d Integration: #517 join_gain_env places the right envelope at the seam when heal bridges a gap 2026-10-24 06:18:49 +00:00
aiongg a1eafbd1c5 Merge PR #517: Heal keeps each clip's gain envelope and skips clips whose mute or stretch differ (#450)
crates/engine/src/edit.rs: heal combines main's gap-aware join (contiguous, gap, saturating adds) with the PR's same_playback check and join_gain_env call; both heal tests kept.
2026-10-24 06:18:46 +00:00
aiongg c8f44fbbef Merge PR #518: Keep unrelated overlapping clips untouched when deleting fades (#449)
crates/engine/src/edit.rs: kept both tests; delete_fades body merged without conflict.
2026-10-24 06:17:53 +00:00
aiongg 0cb3c692ac Merge PR #716: Keep the existing volume lane in automation.clip_gain_to_volume 2026-10-24 06:17:18 +00:00
aiongg bb990d9bfa Merge PR #663: Fix Split into Mono repeating the left channel
ROADMAP.md, docs/gaps.md: kept the newer header line, union of log, table and G-04 entries
crates/engine/src/cmd/track.rs: kept main's explicit imports, added ClipContent
2026-10-24 06:16:56 +00:00
aiongg 038c4c0ca7 Merge PR #636: Import audio off the UI thread (#597)
crates/engine/src/io.rs: kept the PR's decode_import_bytes split; main's OsStr::to_str spelling.
crates/engine/src/cmd/file.rs: kept the PR's take_import path; main's OsStr::to_str spelling.
2026-10-24 06:16:25 +00:00
aiongg fc87f5a5c6 Merge PR #346: Prevent track-name collisions after truncation
# Conflicts:
#	contributors/people.toml
2026-10-24 06:16:17 +00:00
aiongg a851761270 Merge PR #340: Preserve exact channel formats when committing tracks
contributors/people.toml: union of both entries
2026-10-24 06:16:10 +00:00
Brandon ThomasandClaude Opus 5.5 7ae583895d audiosuite: saturating budget product; the budget test expects the total-budget error
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 01:02:01 -04:00
Brandon Thomas b7fe88a72e Merge pull request #996 from sbacaro/fix/896-offline-render-budget
Bound offline render commands: dedupe tracks and a total sample budget (fixes #896)
2026-10-24 01:01:52 -04:00
Brandon Thomas 16c3e222b7 Merge pull request #983 from Silvertree2010/fix/908-audit-panic-rollback-is-partial
Restore all engine side-effect state when a command panics
2026-10-24 01:01:49 -04:00
Brandon Thomas 04d014b662 Merge pull request #981 from Silvertree2010/fix/920-audit-a-punch-that-misses-the-ta
Don't register a source for a take that a punch range misses
2026-10-24 01:01:45 -04:00
Brandon Thomas ffd88ee73d Merge pull request #868 from oracola91/fix/autosave-folders-owner-only
Autosave: the autosave folders are owner-only on Unix
2026-10-24 01:01:42 -04:00