mirror of
https://github.com/storytold/soundcraft.git
synced 2026-11-02 06:56:53 -06:00
The web build could not reach any file: File > Open Session…, Import > Audio… and Import > MIDI… showed a text box for a path the browser can't read, and every save or export failed with «operation not supported on this platform», so work was lost on close. On the web now: - Open Session…, Import Audio… and Import MIDI… show the browser's file picker; files dropped on the page open (sessions) or import (audio, MIDI) by extension. Files travel as bytes; imports are one undo step each, like the import commands. - A session is saved as ONE file, a bundle `<name>.scraftz`: a zip (stored entries) holding the `.scraft` and its `Audio Files/` as 32-bit float WAV — the same layout as a session folder, since the browser has no folders. `io::open_session_bytes` opens a bundle or a bare `.scraft` (its audio is then reported missing). Bundles are hostile input: entry count and size are capped, and declared sizes are never read past. - Every single-file output (save, Save As Template, bounce, MIDI/score/text export, track presets) goes through `io::write_file`: a file natively, a download in the browser via a delivery hook (`io::set_deliver`) that only the web app installs. - In the browser Save As asks for the bundle's name (`<name>.scraftz`) instead of a folder path. Native builds keep writing files and session folders as before. Folder outputs (stems, clip exports) are still not available on the web. Pairs with #157 (Save on a never-saved session opens Save As), which the browser needs too: the web app always starts on the unsaved demo. New dependency: `zip` (MIT), default features off (stored entries only). Checked: engine tests for the bundle round trip (every sample identical), same-named sources, bare sessions and hostile bundles; `cargo xtask ci`. In Chromium on the packaged web build: ⌘⇧I picks and imports a WAV; WAV, MP3, FLAC, OGG, M4A, AIFF and MIDI import by drop; Save As → `Midnight Groove.scraftz` downloads with the imported audio inside; that bundle reopens in a fresh page with all tracks and no missing media, and saves again with the same content. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
72 lines
2.0 KiB
TOML
72 lines
2.0 KiB
TOML
[workspace]
|
|
resolver = "3"
|
|
members = ["crates/*", "apps/*", "xtask"]
|
|
default-members = ["crates/*", "apps/*", "xtask"]
|
|
|
|
[workspace.package]
|
|
version = "0.4.0"
|
|
edition = "2024"
|
|
license = "MIT OR Apache-2.0"
|
|
rust-version = "1.90"
|
|
repository = "https://github.com/storytold/soundcraft"
|
|
|
|
[workspace.dependencies]
|
|
# internal
|
|
soundcraft-time = { path = "crates/time" }
|
|
soundcraft-audio-io = { path = "crates/audio-io" }
|
|
soundcraft-midi = { path = "crates/midi" }
|
|
soundcraft-video = { path = "crates/video" }
|
|
soundcraft-dsp = { path = "crates/dsp" }
|
|
soundcraft-clap-host = { path = "crates/clap-host" }
|
|
soundcraft-vst3-host = { path = "crates/vst3-host" }
|
|
soundcraft-au-host = { path = "crates/au-host" }
|
|
soundcraft-model = { path = "crates/model" }
|
|
soundcraft-mix = { path = "crates/mix" }
|
|
soundcraft-engine = { path = "crates/engine" }
|
|
soundcraft-playback = { path = "crates/playback" }
|
|
soundcraft-automation = { path = "crates/automation" }
|
|
soundcraft-ui-egui = { path = "crates/ui-egui" }
|
|
|
|
# foundation
|
|
thiserror = "2"
|
|
serde = { version = "1", features = ["derive", "rc"] }
|
|
serde_json = { version = "1", features = ["float_roundtrip"] }
|
|
log = "0.4"
|
|
rayon = "1"
|
|
proptest = "1"
|
|
|
|
# audio
|
|
symphonia = { version = "0.5", default-features = false, features = ["mp3", "flac", "vorbis", "ogg", "wav", "pcm", "aiff", "isomp4", "aac", "alac", "adpcm", "caf", "mkv"] }
|
|
rustfft = "6"
|
|
# Session bundles (one file holding a session and its audio, for the browser): stored entries only.
|
|
zip = { version = "9", default-features = false }
|
|
cpal = "0.16"
|
|
|
|
# ui
|
|
egui = "0.36"
|
|
eframe = { version = "0.36", default-features = false }
|
|
egui_kittest = "0.36"
|
|
rfd = "0.17"
|
|
image = { version = "0.25", default-features = false, features = ["png"] }
|
|
|
|
[workspace.lints.rust]
|
|
unsafe_code = "forbid"
|
|
|
|
[workspace.lints.clippy]
|
|
dbg_macro = "warn"
|
|
todo = "warn"
|
|
too_many_arguments = "allow"
|
|
type_complexity = "allow"
|
|
|
|
[profile.dev.package."*"]
|
|
opt-level = 2
|
|
|
|
[profile.dev]
|
|
opt-level = 1
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "thin"
|
|
codegen-units = 16
|
|
debug = 0
|