Commit Graph
55 Commits
Author SHA1 Message Date
Brandon Thomas 0000566f5e Merge remote-tracking branch 'origin/main' into m/679 2026-10-24 00:51:38 -04:00
Dylan M. Taylor 64669e9a7c chore: resolve SonarCloud maintainability issues (#1003)
* chore: resolve SonarCloud maintainability issues

* fix(packaging): extract verify_sha256 helper in package.sh

* style: apply rustfmt formatting

* fix(video): ensure prefix is i32 in cabac_mb
2026-10-23 22:33:59 -04:00
Marco Arnulfo 16371a8502 Scroll Into View is a UI command, view.scroll_into_view, and the track name menu dispatches it 2026-10-21 10:23:03 +02:00
Brandon Thomas b042a73dbf Merge pull request #666 from marcoarnulfo/feat/remove-sync-point
Clip > Remove Sync Point takes the sync point off the selected clips
2026-10-19 03:03:26 -04:00
Marco Arnulfo f2ae345f20 Clip > Remove Sync Point takes the sync point off the selected clips 2026-10-16 07:46:07 +02:00
Justin JohnandClaude Opus 5.5 606ddac169 Track › Instrument: choose the selected track's instrument from the menu bar (#374)
The submenu under Track › New... opens the same picker as the Mix window's
instrument slot for the first selected instrument track, and is greyed out
with a hint when none is selected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 17:44:34 +05:30
Brandon Thomas c2f052715d Merge main into #319 2026-10-13 06:16:54 -04:00
Brandon Thomas edd1787353 Merge main into #322 2026-10-13 06:13:17 -04:00
Brandon Thomas 5686d61f45 Merge main into #390 2026-10-13 06:04:00 -04:00
Brandon Thomas 46399aa729 Merge main into #368 2026-10-13 04:50:04 -04:00
Brandon Thomas 7347e98e79 Merge pull request #363 from grovebit/more-shortcuts
Pro Tools keys for nudging, Grid and Nudge values, playlists and windows
2026-10-13 04:42:25 -04:00
Brandon Thomas 54254639cc Merge pull request #358 from sajibsrs/fix/282-new-midi-clip-menu
Add Clip › New MIDI Clip so an empty MIDI track can get a clip (#282)
2026-10-13 04:28:22 -04:00
Brandon Thomas 12224df8f5 Merge pull request #277 from marcoarnulfo/fix/hide-floating-automation
fix(window): Hide All Floating Windows also hides Automation (#253)
2026-10-13 04:26:49 -04:00
grovebit 62cb92c4df Never replace or quit a session while it records
Opening, creating, closing or reverting a session in the middle of a
take dropped the recorder: the take was written to disk but never added
to any session. Quitting mid-take did the same, and on_exit didn't
finish the take either.

New, Open, Close, Revert and Quit now wait for the take: the engine
refuses them with "stop recording first", and their menu items are
greyed out while recording, as is Recover in the recovery window. Any
exit that still happens mid-take (closing the window, the system
quitting the app, a remote quit) finishes the take first and keeps the
session, take included, in the autosave folder for the next launch.
2026-10-12 23:33:48 +01:00
woodgrain816andClaude Opus 5.5 1a49fc70fb File › Open Recent: the last 10 sessions, newest first
Pro Tools has File › Open Recent; SoundCraft had no way back to a session but
browsing for it. The list (UiState.recent_sessions) records the engine's
session path whenever it changes, so opening or saving by any route (menu,
control channel, MCP, a dropped file) is covered by one rule.

- Under File › Open; each entry is "name — folder", full path on hover.
- A session that has moved or been deleted is greyed out "(missing)" instead
  of failing on click; existence is re-checked at most every 3 s while the menu
  is open, since a network share costs a round trip per file.
- Opening goes through the dialog layer, so unsaved changes are asked about.
- Clear Recent empties it.
- The desktop host saves ui.json as soon as the list changes, not only on a
  clean exit: the list matters most after a crash.
- An older ui.json without the field still loads (serde default).

The macOS system menu bar (native_menu) does not show it yet; the egui menu
bar on Windows and Linux does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:31:22 -05:00
Sajidur RahmanandClaude Opus 5.5 7a62ab3be0 Add Clip › New MIDI Clip menu entry and command reachability test
midi.new_clip had no UI path, so an empty instrument/MIDI track could
never get a MIDI clip (#282). The menu bar is built from the catalog,
so the entry is added to menus::tree() and placed first in Clip.

The new test checks every mutating command is reachable from the GUI
(built menu tree, shortcut, or UI reference), with today's gaps listed.

Closes #282

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 02:44:59 +06:00
grovebit 3617011342 Pro Tools keys for nudging, Grid and Nudge values, playlists and windows
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.
2026-10-12 21:17:26 +01:00
Limestudio90andClaude Opus 5.5 2e3389178e Mix in a separate window: Edit and Mix on screen at once
Window > Mix in Separate Window (window.mix_separate, kept with the UI
preferences) shows the Mix window in its own native window through an
egui immediate viewport, so Edit and Mix can be seen at once, e.g. one
per monitor. The main window then keeps Edit; Window > Mix and
Cmd/Ctrl+= bring the Mix window to the front; closing it puts Mix back
into the main window. Backends without multiple windows show it as a
floating egui window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:47:18 +02:00
Limestudio90andClaude Opus 5.5 a1e9660e60 Audio device settings: system, devices, sample rate, buffer size; opt-in ASIO
Setup > Playback Engine now chooses the audio system (cpal host), output
and input device, device sample rate and buffer size, kept per machine
with the UI preferences and applied by reopening the devices (refused
while recording; the transport position is kept). ui.audio_device does
the same for agents and lists every system with its devices, channels,
rates and buffer range.

Player and recorder open the chosen device, fall back to the defaults
for anything unavailable (unplugged device, unsupported rate), retry
with the device's default buffer when the chosen one is refused, and
convert 32/16-bit integer devices from and to the f32 mix through
scratch buffers allocated up front (no allocation in the callbacks).

ASIO is behind an opt-in 'asio' feature (playback and app): building it
downloads Steinberg's ASIO SDK (proprietary licence or GPLv3) and needs
LLVM, so it stays off by default. Verified on Windows with an SSL 2+:
WASAPI output/input switching and buffer 256, ASIO duplex at 128.

Docs: G-01 shrunk, hardware-parity rows, roadmap log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:22:41 +02:00
Marco Arnulfo bff9ca1390 fix(window): Hide All Floating Windows also hides Automation (#253) 2026-10-12 12:18:00 +02:00
Marco Arnulfo 4c4414d006 fix(window): keep the MIDI Editor open on Bring to Front (#254) 2026-10-12 11:58:36 +02:00
Brandon Thomas 525f00b719 Merge pull request #157 from grovebit/unsaved-changes
Ask before discarding unsaved changes; Save opens Save As for new sessions
2026-10-11 20:59:57 -04:00
Brandon ThomasandClaude Opus 5.5 d37386721a Merge origin/main into unsaved-changes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:42:42 -04:00
Brandon Thomas 03bebb572d Merge remote-tracking branch 'origin/main' into menu-fixes 2026-10-11 20:41:39 -04:00
Brandon Thomas 7c26ea4f44 Merge remote-tracking branch 'origin/main' into clear-clips 2026-10-11 20:21:45 -04:00
Brandon Thomas cc36a3eba6 Merge remote-tracking branch 'origin/main' into menu-fixes 2026-10-11 20:14:54 -04:00
grovebit 18a2558104 Ask to save changes before closing a modified session
Close Session, New, Open, Revert, Quit, the window's close button,
dropping a session file on the window and opening one from the Workspace
window all replaced or closed the session without asking, so unsaved
edits were lost (#136). They now ask first: Save, Don't Save or Cancel.
Save on a session that has never been saved goes through Save As, then
carries on. Revert asks for confirmation instead, and Revert to Saved is
unavailable until the session has a file. A take being recorded is
stopped first, so it counts as a change. The web build has nowhere to
save, so it offers only Don't Save and Cancel. Calls from the control
channel, MCP and the CLI never ask.

Selecting, locating, zooming and scrolling no longer mark the session
modified, so the question only comes after real edits. Undoing back to
the saved state makes the session clean again. The engine compares the
document with the one last opened or saved, ignoring the selection, the
playhead and the zoom, once per revision.

Fixes #136
2026-10-11 20:13:48 +01:00
skylar taylor-barrick 63b487589c UI.9: preserve SoundCraft workflows with shared docking 2026-10-10 15:37:36 -06:00
grovebit 6b98c21fed Make the Window menu's shortcuts work
The Window menu's keys never fired: Cmd+1 Transport, Cmd+3 Big Counter,
Cmd+4 Automation, Cmd+5 Memory Locations, Cmd+9 Video, Cmd+Alt+M Narrow
Mix, Cmd+W Close Window, Cmd+Ctrl+W Hide All Floating Windows and
Cmd+Ctrl+= Score Editor. The shortcut handler only looked at engine
commands, and these are window commands. It now falls back to them, and
the menus and the Keyboard Shortcuts window show their keys.

On a Mac, Cmd+Ctrl+= toggled Mix/Edit instead of opening the Score
Editor. The Mix/Edit toggle now needs Cmd+= without Control there.

The two Control chords still have no key on Windows and Linux.
2026-10-10 19:27:16 +01:00
grovebit bd00c3855c Name the step in the Edit menu's Undo and Redo
The Edit menu always read "Can't Undo" and "Can't Redo", the incumbent's
labels for an empty history, even when there was something to undo. The
items now name the step they would take ("Undo Mute", "Redo Mute"), in
the in-window menu bar and the macOS system menu alike, and read "Can't
Undo" / "Can't Redo" only when there is nothing.
2026-10-10 19:27:16 +01:00
grovebit aa4f038f1a Open the Rename Clip dialog from Clip > Rename
Clip > Rename... and Cmd+Alt+Shift+R ran clip.rename without a name, so
they only put "`name` required" in the status line. They now open the
Rename Clip dialog, which only the clip's right-click menu opened so
far, for the selected clip (or the first clip the edit selection
touches).

The dialog's name field, and Rename Track's, now opens with the old
name selected, so typing replaces it instead of adding to it.
2026-10-10 19:27:16 +01:00
grovebit 718bb5c7fb Open Save As when saving a session that has never been saved
Cmd+S and File > Save Session on an untitled session only left "no path
yet: pass `path` (Save As)" in the status line. From a menu, the command
palette or the keyboard, Save now opens the Save Session As prompt until
the session has a file. Calls from the control channel, MCP and the CLI
still need a `path`.

The prompt suggests ~/<name>/<name>.scraft, but saving a session without
audio there failed with "No such file or directory", because only
writing audio created the session folder. Saving now creates the folder.
2026-10-10 14:20:55 +01:00
Brandon ThomasandClaude Opus 5.5 3a4f18647f Merge origin/main into fix/97-menu-dialogs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:53:21 -04:00
Brandon Thomas dc2ffda4d6 Merge remote-tracking branch 'origin/main' into HEAD 2026-10-10 03:52:01 -04:00
Vikram Bhaskaran 30347ee42f Open New Tracks and Bounce only from the menu.
engine.execute and app.run of ui.new_tracks_dialog and ui.bounce_dialog were opening modal dialogs, so a script could not create tracks or bounce without a window. Those ids now return an error unless the menu invokes them.
2026-10-10 17:39:46 +11:00
Vikram Bhaskaran 3b9d5b9423 Allocate Mix Window View menu paths once.
The menu bar rebuilt and leaked a fresh alias string for every mix-view section on each redraw. Those fifteen paths are now created the first time the menu catalog is asked for them.
2026-10-10 17:38:53 +11:00
coygeek 1f5bc965fe fix(ui): follow live system appearance
Resolve System appearance from egui on every frame and fall back to Dark when the integration cannot report a theme. Keep receiving OS changes during manual modes and apply the selected palette to both widget style branches and the current root UI.

Remove the cached detector and its unused dependency. Cover startup, live transitions, manual overrides, saved System preferences, and user colors with an application-frame regression. Add reproducible offscreen system-theme inputs and document the fallback.
2026-10-09 18:28:07 -07:00
grovebit 42d08558ab Clear clips and audio files from the Clip List
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.
2026-10-10 02:07:51 +01:00
Brandon ThomasandClaude Opus 5.5 50f885e16b Merge origin/main into feature/session-audio-health
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:48:05 -04:00
Brandon ThomasandClaude Opus 5.5 4216d4f1be Merge origin/main into issue-62
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:41:26 -04:00
21f9b07074 Add a selectable Light theme (#32)
* Add a selectable Light theme

* Apply the active theme to the menu bar

* Use the system theme by default

* Expose Appearance in the Setup menu

* Add Light theme screenshot

* Remove the Light theme screenshot

Repo policy keeps large binary assets out of the tree, and the PNG had no
ATTRIBUTION row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Appearance: ui.theme command, Dark default, non-blocking system lookup

- ThemeMode derives Default with Dark as the default (fixes clippy's
  derivable_impls); System and Light are opt-in. LIGHT_THEME starts false.
- New UI command `ui.theme {"mode": "system|light|dark"}` (label
  "Appearance") in UI_COMMANDS; with no mode it reports the current one.
  The UI Customization combo box dispatches it instead of writing state.
- The choice lives in UiState.theme, so it persists with the existing UI
  prefs (ui.json) and is exposed through ui.set / ui.inspect. Restoring a
  window configuration keeps the current theme.
- dark_light::detect() is only called in System mode, on a background
  thread (an AtomicU8 holds the answer; dark until it arrives, then a
  repaint). On the web it is the synchronous matchMedia lookup.
- theme::apply runs only when the effective palette changes, not every
  frame.
- window.ui_customization keeps its catalog path (Window > UI
  Customization) so parity is unchanged; Setup > Appearance still opens
  it. The combo row is labelled "Theme" so it no longer repeats the title.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Light theme: move hard-coded colours to theme tokens

The Light palette left dark islands and unreadable text where colours
were Color32 literals. New tokens (Dark values are the old literals, so
the Dark theme renders pixel-identical to main):

- menu bar; toolbar group outline; edit-mode cells (no more dark block
  around Shuffle/Spot/Slip/Grid); counter panel outlines, dividers and
  off toggles; Smart-tool bracket
- selected rows in the Tracks/Groups/Clips lists, track-visible dot,
  selected Edit track header, selected Mix strip
- marker names, alternate-playlist lanes, Universe background/outline,
  Big Counter background
- meter background and clip lamp, pan knob body/ring/pointer, Mix insert
  and send slots, Mix section captions

In Light, clip bodies are a paler tint and waveforms a deep shade of the
clip colour instead of black.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Light theme: instrument slot and plugin window text use the current tokens

The instrument picker (#23) landed with Tokens::DARK literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: t <t@t>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-09 18:37:04 -04:00
MarekSpodBiedry 7324e24fae Show Ctrl instead of Cmd in shortcut text off macOS (#62) 2026-10-09 21:27:11 +02:00
Vikram Bhaskaran 42e6b96734 Report session audio health without changing the session.
The window checks every playlist, including inactive takes, for missing audio, rate mismatches, empty buffers, and clips that extend past their source.
2026-10-10 04:37:45 +11:00
reoniazx b44aaade42 macOS: move application menus to the system menu bar 2026-10-08 14:10:03 +08:00
Brandon ThomasandClaude Opus 5.5 cdefc57c91 Video track, Audio Unit hosting, plugin state and editors, Renderer and UI Customization
Video (new standalone crate soundcraft-video):
- Pure-Rust H.264 (Baseline/Main/High), ProRes (all flavours) and Motion JPEG decoding with
  ISO-BMFF demux, adapted from FilmCraft's crates; fuzzed with mutated/truncated movies
- TrackKind::Video with ClipContent::Video referencing Session.videos; file.import_video adds
  the picture track and the movie's audio; relinking on open; video.offset/online/list
- Video and Video Universe windows, thumbnails on the timeline, background decoding

Third-party plugins:
- Plugin state (CLAP state ext, VST3 component + controller state) saved in sessions
- Hosted instances created, state-loaded and dropped on the UI thread, never the audio thread
- Plugin editors: floating CLAP GUIs and VST3 views on macOS (verified with Melodyne)
- New isolated FFI crate soundcraft-au-host: Audio Units on macOS (effects and instruments,
  parameters, latency, MIDI, ClassInfo state), wired into the mixer and plugin browser

UI: Window > Renderer (speaker layout with live levels and object positions), Window > UI
Customization (interface scale, reduce motion), Window > Configurations > Auto-Update.

Fix: saturating sample-index math in clip rendering (hostile stretch values overflowed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:41:05 -04:00
Brandon ThomasandClaude Opus 5.5 c125a79a47 Mix window views: Mic Preamps (input gain), Instruments, Object/Bed
Adds track.object for routing a track as an immersive object or to the bed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:24:05 -04:00
Brandon ThomasandClaude Opus 5.5 0751dd31f1 Score export and print, clip group files, Merge Markers, path dialogs for every file command
- 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>
2026-10-06 01:17:42 -04:00
Brandon ThomasandClaude Opus 5.5 c543c7a781 Search: a command palette over every command (Window › Search, Cmd+Ctrl+S)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:44:35 -04:00
Brandon ThomasandClaude Opus 5.5 9da524fd66 Score Editor: MIDI as notation on a grand staff
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:54:51 -04:00
Brandon ThomasandClaude Opus 5.5 4168882fef Beat Detective, Tempo/Time/MIDI Operations and MIDI Real-Time Properties windows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:34:25 -04:00