Commit Graph
40 Commits
Author SHA1 Message Date
Brandon Thomas 582bfb2f7e Merge pull request #423 from webdevtodayjason/thin-step-lanes
Keep mute changes in place when thinning automation
2026-10-19 03:03:29 -04:00
Brandon Thomas 00315b6fb4 Merge pull request #507 from MarekSpodBiedry/issue-468
Count the partial quartet in the base64 decoded-size cap (#468)
2026-10-19 03:02:43 -04:00
Brandon Thomas 47e1b0e523 Merge pull request #629 from Silvertree2010/fix/h1599-session-with-a-meter-change-near
Drop out-of-range tempo and meter events when sanitizing a session
2026-10-19 02:54:27 -04:00
aiongg 86b31e71d3 Sessions: follow stored source paths only on this computer or the session's share
Audio source and movie paths stored in a .scraft session go through
io::stored_path (craft-docpath) before they reach the file system: a
relative path is taken from the session's folder, and paths on other
computers, devices and URLs are refused. A refused source is reported
as missing with the reason; a refused movie is marked offline and the
Video track and Video window show why instead of opening it. Import
Session Data and crash recovery resolve the same way.
2026-10-16 17:32:35 +00:00
NetterSilverandClaude Haiku 5.5 705c2b9077 Drop out-of-range tempo and meter events when sanitizing a session
Found while testing crates/time/src/tempo.rs:254

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 13:46:37 +00:00
MarekSpodBiedry 9209909ff7 Count the partial quartet in the base64 decoded-size cap (#468) 2026-10-13 17:49:23 +02:00
webdevtodayjason e10b245652 Keep mute changes in place when thinning automation 2026-10-13 06:58:16 -05:00
Brandon Thomas e0deb3f4e5 Merge main into #335 2026-10-13 05:55:06 -04:00
Brandon Thomas 857882c740 Merge main into #332 2026-10-13 05:40:16 -04:00
Brandon Thomas 468125aaf4 Merge main into #209 2026-10-13 05:27:22 -04:00
Brandon Thomas 3f3f64746f Merge main into #384 2026-10-13 05:21:33 -04:00
Brandon Thomas 2bba5c334d Merge main into #365 2026-10-13 05:17:58 -04:00
Brandon Thomas b0339a418f Merge pull request #401 from Claudio911015/fix/273-clip-loop-unloop-consistency
Make clip.loop / clip.unloop self-consistent (loop_id tag)
2026-10-13 04:29:19 -04:00
Brandon Thomas 34117efc24 Merge pull request #354 from webdevtodayjason/automation-thin-tolerance
Keep automation thinning within its tolerance
2026-10-13 04:28:36 -04:00
Brandon Thomas 651b9049a8 Merge pull request #353 from webdevtodayjason/trim-keeps-clip-gain
Keep the clip gain line where a clip is trimmed or separated
2026-10-13 04:28:31 -04:00
Claudio bee999584f Make clip.unloop recognise loops made by clip.loop, even after edits
clip.unloop found loop copies only by comparing content of back-to-back
clips. As soon as the source clip's notes were edited, its content no
longer matched the copies and unloop answered "the selection is not a
looped clip" for the very loop that clip.loop had just created.

clip.loop now tags the origin and its copies with a shared `loop_id`
(new optional Clip field, serde default so old sessions load), and
unloop treats equal-length adjacent clips with the same loop_id as one
loop. The content comparison stays as a fallback for loops without a
tag. unloop with mode=flatten clears the tag so the copies become
ordinary independent clips.

Propagating edits from the source to the copies is not part of this
change.
2026-10-12 23:54:33 -06:00
grovebit 1953f2ecc6 Track height: resize live while dragging, Pro Tools modifiers and Ctrl+Up/Down
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.
2026-10-12 22:11:34 +01:00
grovebit 72288fc77e Make the Shuffle, Slip, Spot and Grid edit modes work like Pro Tools
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.
2026-10-12 21:49:31 +01:00
webdevtodayjason c39773b62d Keep automation thinning within its tolerance 2026-10-12 15:32:48 -05:00
webdevtodayjason 34d8488284 Keep the clip gain line where a clip is trimmed or separated 2026-10-12 15:32:40 -05:00
reoniazx 5ec8c21b19 Preview waveform amplitudes during fade drags 2026-10-13 02:48:00 +08:00
reoniazx 4ac47b3a7f Add draggable midpoint curvature for clip fades 2026-10-13 02:48:00 +08:00
grovebit 328760fd70 Keep positions from files within the range commands use
Commands clamp every position they take to ±2^40 samples so the
arithmetic after them can't overflow, but session and clip group files
skipped that. A clip, MIDI note, marker, automation point or selection
near i64::MAX made Duplicate, Insert Silence, Insert Time, Heal, Trim to
File Boundaries, Quantize to Grid, Separate on Grid, Thin Automation,
Copy, Move Selection, Extract Chords and Track Commit overflow: a panic
in debug builds, wrapped positions in release.

MAX_POSITION moves to soundcraft-time so the model can use it. Loading
a session clamps clip starts, lengths, offsets, sync points, gain
envelopes and MIDI notes, automation points, markers, key changes, the
selection, playhead, pre/post-roll, scroll and timecode start. A clip's
repairs are now Clip::sanitize, which clip group import uses too, and
Session::sanitize visits each collection once. The Edit window adds a
clip's offset to its file's time stamp without overflowing.
2026-10-12 18:40:12 +01:00
grovebit 7ca978fdb9 Cut names from files to a length that can be drawn
A MIDI file whose track name was a million characters long imported
fine, and the next frame crashed the app: drawing that name needed a
320 MB vertex buffer, past wgpu's 256 MB limit, and the panic comes
from painting, outside anything that catches it. Saved, the session
crashed again on every open. A 4 MB status line in ui.json did the
same at every launch.

Names read from files are now cut to 256 characters and comments to
4096: everything Session::sanitize repairs on load (session, track,
playlist, clip, marker, bus, output, group, source, video and key
names), MIDI track names on import and clip names from clip group
files. The status bar draws at most 1024 characters.
2026-10-12 18:40:12 +01:00
grovebit a8a36540d6 Name thousands of same-named tracks and files in linear time
Finding a free name tried "Name 1", "Name 2" and so on, rescanning
every track (or every source path) for each try, so each new name cost
time proportional to the square of the session and a bulk import the
cube. Importing a 119 KB MIDI file with 4,095 tracks all named "Piano"
took 28 seconds; a clip group file with 8,000 empty lanes or 8,000
audio files of one name ran for over a minute, and 100,000 lanes never
finished. Import Session Data from a session with 2,000 same-named
tracks took 7 seconds.

unique_track_name and the new audio file name now collect the numbers
already in use once and take the first free one, which gives the same
names. A clip group file also counts each empty lane and each audio
file against its limit of 10,000. The same imports now take 1 second
(MIDI), 2 seconds (8,000 lanes) and a third of a second (Import Session
Data); 100,000 lanes are refused.
2026-10-12 18:40:12 +01:00
grovebit 1617733a98 Repair a session's sample rate and tempo map when it loads
A session file with a sample rate of 0 or a tempo of 4e9 BPM opened
fine, but Strip Silence on the first and Extract Chords on the second
never finished (one also climbed past 1 GiB). Session::sanitize, which
repairs everything else read from a file, skipped both fields.

On load, a sample rate outside what sessions accept becomes 48 kHz, and
the tempo map keeps only the tempos and meters that set_tempo and
set_meter accept, in tick order, with one of each at tick 0.
2026-10-12 18:40:12 +01:00
Marco Arnulfo 5e7ca6de22 Apply the Feet+Frames reference to counters and typed positions (fixes #235)
Setup > Current Feet+Frames Position stored its origin in
feet_frames.start but nothing read it, so every Feet+Frames reading
still counted from sample 0. format_position/parse_position now take
the origin alongside the timecode start, and Session::format_position
and Session::parse_position pass both, so the counters, rulers,
session.format_time and typed positions share one reference.
2026-10-12 16:36:18 +02:00
Brandon ThomasandClaude Opus 5.5 7a1035a3d5 Merge origin/main into sampler-instrument
#181 already pushes instrument params each block, so drop the duplicate
apply_instrument_params. Import Session Data now brings a Sampler's sample
along and remaps its source id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 20:45:12 -04:00
Brandon Thomas 4e846b8f02 Merge pull request #75 from grovebit/clip-list-delete
Clear clips and audio files from the Clip List (#4)
2026-10-11 20:40:53 -04:00
grovebit e26a5f5f42 Zoom Toggle: E zooms in on the edit selection, E again zooms back out
In Pro Tools, E (with Commands Keyboard Focus on) zooms the Edit window
to the edit selection and fits the selected tracks to the window, and
pressing it again brings back the view from before. SoundCraft had no
Zoom Toggle.

view.zoom_toggle, in its own command module, stores the zoom, the
scroll and the selected tracks' heights in the session's new
edit.zoom_toggle, so the view to go back to is saved with the session.
It then zooms so the selection fills the timeline and gives the
selected tracks equal shares of the track area: Pro Tools' Fit To
Window height. Hidden tracks are left alone. Run again, it puts all of
that back. With only an insertion point the zoom stays and its tracks
are fitted. The UI passes the track area's size; agents can pass
width_px and height_px.

TrackHeight::Fit, which nothing could reach and which drew 88 points
tall, now carries its height in points, so every place that sizes a
track row reads it unchanged.

The Edit window scrolls the first fitted track to the top when Zoom
Toggle turns on, and back to where it was when it turns off, whichever
way it was toggled (key, button, control channel, undo).

As in Pro Tools, E works in the Edit window while Commands Keyboard
Focus (the a-z button) is on, on every OS. A Zoom Toggle button left of
the Zoomer lights while it is on and toggles it too.

This follows Pro Tools' Zoom Toggle settings for audio editing:
Selection for both zooms, Fit To Window, no track view change. Its
other preferences, Ctrl+E (Pro Tools' key with the focus off),
Alt+Shift+E (cancel) and following the edit selection are left out.

Tests cover the zoom, the fitted heights, going back, insertion points,
hostile sizes and stored views, and E and the toolbar button on macOS,
Windows and Linux.
2026-10-12 01:22:08 +01:00
grovebit 54e3761d62 Open sessions whose plugin parameters were saved as null
JSON has no NaN or infinity, so serde writes them as null, and loading
null into a plugin parameter failed the whole session with "not a
SoundCraft session: invalid type: null, expected f32". One plugin
reporting a non-finite value, or a value like 1e39 that overflows f32
in an edited file (it loads as infinity), made the session and every
later save and autosave of it unopenable.

Insert and instrument parameters that are null or overflow f32 are now
dropped on load, so they keep the plugin's default and the rest of the
session opens.
2026-10-11 20:03:47 +01:00
grovebit 86824b592a Never overwrite audio files when saving
Audio that exists only in memory (takes, consolidations, AudioSuite
renders, commits) gets the default path `Audio Files/<name>.wav`, and
Save treated an existing file at that path as the source's own and
rewrote it. Names repeat easily: two sessions in one folder both call
their first take on Audio 1 "Audio 1_02", and consolidating twice on
Kick makes two "Kick_consolidated" sources. Saving silently replaced
the earlier audio, so the other session or the earlier clip played the
wrong audio once reopened.

Save As also trusted a same-named file in the target folder for audio
saved elsewhere, so saving into another session's folder could point
the new session at that session's audio.

New audio now goes to the first free name (`<name>.wav`,
`<name>_01.wav`, ...), created with create_new so no existing file is
ever truncated, or to a file that already holds exactly the same bytes,
such as a take saved again after undoing past a save. Saved audio is
reused only when saving into the folder it was saved in, which the
session now remembers, so undoing past a Save As or saving after Save
Copy In can't pick up another session's files either. Audio that
failed to load keeps pointing at its old folder when the session is
saved elsewhere.
2026-10-11 19:59:43 +01:00
Scott Campbell fa88fbb942 Add a built-in Sampler instrument
A third built-in instrument next to Subtractive Synth and Drum Synth. It plays one
sample across the keyboard: root note, transpose and fine tune, key tracking, key and
velocity ranges, amp ADSR with velocity sensitivity, sample start, forward or ping-pong
loops, gate or one-shot playback, 32 voices with cubic interpolation. The sample's own
rate is converted as it plays.

- dsp: `Plugin::set_sample` and the `SampleSource` trait hand an instrument shared
  audio without copying; the Adsr from the synth is reused.
- model: `Insert::sample` names the session source the sampler plays.
- mix: sync hands the pool audio to the instrument when it changes, and built-in
  instruments now get their parameter values applied (they always ran on defaults).
- engine: `mix.sampler_load {track?, path, params?}` decodes WAV, AIFF, FLAC, MP3, OGG
  (anything file.import_audio reads) into a session source, resampled to the session
  rate and saved in Audio Files with the session; `mix.sampler_clear`; and
  `mix.instrument_param {track?, param, value}` for any built-in instrument.

Tests generate their audio in code; no bundled assets.
2026-10-09 22:55:24 -04: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 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 cc86842abe Surround mixing, VST3 hosting, and hardening against hostile inputs
Surround:
- main and bus formats up to 9.1.6 and Ambisonics; pairwise constant-power
  surround panner (divergence, centre, LFE, height) per track and send;
  ITU fold-down; multichannel bounce with correct WAV channel masks;
  multichannel device output; surround panner and multichannel meters in the
  Mix window; setup.main_format, mix.surround_pan, mix.send_surround_pan

VST3:
- soundcraft-vst3-host: isolated unsafe crate (vst3 bindings, MIT), scans
  standard folders, hosts components/processors/controllers, params,
  latency, notes; VST3 menu; engine.vst3_plugins; e2e tests with a fixture

Hardening:
- positions from parameters clamped; offline renders capped and bounded to
  track material; loop/transport limits; hostile-parameter property test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:39:59 -04:00
Brandon ThomasandClaude Opus 5.5 daca626778 Fix fades outliving trimmed clips; property test of random edit sequences with full undo
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:10:53 -04:00
Brandon ThomasandClaude Opus 5.5 720373c0c6 Engine parity batch (76% engine, 90% with UI), comping, fades, universe, automation writing, loop record
- ~200 new commands across Edit/View/Track/Clip/Event/Options/Setup/File
  (copy/paste special, playlists, TCE, tempo operations, beat detective,
  chords, MIDI performance, view flags, setup settings, import session data)
- explicit targets bypass selection-based enablement; undo coalescing for
  gestures (faders, knobs, sliders)
- live Write/Touch/Latch volume automation passes; loop recording into
  playlists; playlist lanes with promote-to-main comping; smart-tool fade
  handles; Universe overview; VCA masters; routing-folder busses; edit groups
- bounce reports true peak; README with screenshots; parity report

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:25:09 -04:00
Brandon ThomasandClaude Opus 5.5 63bf6c5b4b xtask gates, parity report, model flags and full channel-format list
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:02:15 -04:00
Brandon ThomasandClaude Opus 5.5 755f02fc85 Foundation: time, audio-io, midi, dsp, model, mix, engine, playback crates
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>
2026-10-05 22:27:29 -04:00