Skip to main content

max / audiofiles

exorcise: convert ASCII '--' prose dashes to colons Uniform '--' dash pass: 35 conversions across README, architecture, database_schema, ml_classifier. Cargo arg separators (in code fences) and numeric ranges left intact. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-12 16:56 UTC
Commit: 667d2be667b36fdad754fbd79a8a2df9fb9d7b22
Parent: 529b97f
4 files changed, +36 insertions, -36 deletions
M README.md +26 -26
@@ -44,45 +44,45 @@ Shared libraries from `../../MNW/shared/`: [theme-common](../../MNW/shared/theme
44 44 ## Features
45 45
46 46 ### Storage & Organization
47 - - **Content-addressed storage** -- samples stored by SHA-256 hash, automatic deduplication
48 - - **Virtual file system** -- organize samples in virtual directories independent of disk location, multiple VFS roots
49 - - **Tag system** -- hierarchical dot-notation tags with auto-suggestions from analysis results
50 - - **Smart folders** -- saved filter queries that update dynamically
51 - - **Collections** -- cross-VFS sample groupings
47 + - **Content-addressed storage**: samples stored by SHA-256 hash, automatic deduplication
48 + - **Virtual file system**: organize samples in virtual directories independent of disk location, multiple VFS roots
49 + - **Tag system**: hierarchical dot-notation tags with auto-suggestions from analysis results
50 + - **Smart folders**: saved filter queries that update dynamically
51 + - **Collections**: cross-VFS sample groupings
52 52
53 53 ### Audio Analysis
54 - - **Analysis pipeline** -- loudness (peak/RMS/LUFS), BPM detection, key detection, spectral analysis
55 - - **ML classification** -- two-layer system: rule-based broad categories, then 200-tree random forest for drum sub-classification (94.4% accuracy on 4,343 samples)
56 - - **Loop detection** -- identifies seamless loops via amplitude envelope analysis
57 - - **Similarity search** -- VP-tree indexed fingerprinting for finding similar and duplicate samples (O(log n) lookup)
58 - - **Waveform display** -- pre-computed peak data with click-to-seek playback
54 + - **Analysis pipeline**: loudness (peak/RMS/LUFS), BPM detection, key detection, spectral analysis
55 + - **ML classification**: two-layer system: rule-based broad categories, then 200-tree random forest for drum sub-classification (94.4% accuracy on 4,343 samples)
56 + - **Loop detection**: identifies seamless loops via amplitude envelope analysis
57 + - **Similarity search**: VP-tree indexed fingerprinting for finding similar and duplicate samples (O(log n) lookup)
58 + - **Waveform display**: pre-computed peak data with click-to-seek playback
59 59
60 60 ### Search & Filtering
61 - - **Text search** -- FTS5 indexed across filenames, tags, and metadata
62 - - **Parameter filters** -- BPM range, duration range, key selector, classification category
63 - - **Tag prefix matching** -- type a tag prefix to filter by hierarchy
61 + - **Text search**: FTS5 indexed across filenames, tags, and metadata
62 + - **Parameter filters**: BPM range, duration range, key selector, classification category
63 + - **Tag prefix matching**: type a tag prefix to filter by hierarchy
64 64
65 65 ### Editing
66 - - **Destructive editing** -- trim, fade in/out, normalize, reverse, gain adjust
67 - - **Edit history** -- full undo/redo stack per sample
68 - - **Bulk operations** -- bulk delete, move, rename, tag across selections
69 - - **Rename engine** -- pattern-based renaming with tokens (name, bpm, key, index, etc.)
66 + - **Destructive editing**: trim, fade in/out, normalize, reverse, gain adjust
67 + - **Edit history**: full undo/redo stack per sample
68 + - **Bulk operations**: bulk delete, move, rename, tag across selections
69 + - **Rename engine**: pattern-based renaming with tokens (name, bpm, key, index, etc.)
70 70
71 71 ### Device Export
72 - - **Rhai export profiles** -- scriptable export for 14 hardware samplers:
72 + - **Rhai export profiles**: scriptable export for 14 hardware samplers:
73 73 M8, Digitakt, Digitakt II, Octatrack, Model:Samples, SP-404 MKII, MPC, Polyend Tracker, Deluge, Blackbox, Volca Sample 2, OP-1, Circuit Rhythm, Maschine+
74 74
75 75 ### Playback & Integration
76 - - **MIDI instrument** -- chromatic and multi-sample playback modes with 8-voice polyphony and ADSR envelopes
77 - - **Native drag-out** -- drag samples from the file list directly to Finder, Desktop, or any DAW (macOS + Windows)
78 - - **System tray** -- minimize to tray, quick access
76 + - **MIDI instrument**: chromatic and multi-sample playback modes with 8-voice polyphony and ADSR envelopes
77 + - **Native drag-out**: drag samples from the file list directly to Finder, Desktop, or any DAW (macOS + Windows)
78 + - **System tray**: minimize to tray, quick access
79 79
80 80 ### Infrastructure
81 - - **Cloud sync** -- cross-device sync of metadata, tags, and VFS via SyncKit (E2E encrypted, ChaCha20-Poly1305 + Argon2)
82 - - **OTA updates** -- background update checker with consent dialog
83 - - **Bundled themes** -- dark, light, and high-contrast variants in TOML format (see `crates/audiofiles-browser/themes/`)
84 - - **Audio formats** -- WAV, FLAC, MP3, OGG, AIFF (via Symphonia, pure Rust)
85 - - **Platforms** -- macOS, Windows, Linux (standalone, no backend required)
81 + - **Cloud sync**: cross-device sync of metadata, tags, and VFS via SyncKit (E2E encrypted, ChaCha20-Poly1305 + Argon2)
82 + - **OTA updates**: background update checker with consent dialog
83 + - **Bundled themes**: dark, light, and high-contrast variants in TOML format (see `crates/audiofiles-browser/themes/`)
84 + - **Audio formats**: WAV, FLAC, MP3, OGG, AIFF (via Symphonia, pure Rust)
85 + - **Platforms**: macOS, Windows, Linux (standalone, no backend required)
86 86
87 87 ## Key Paths
88 88
@@ -34,7 +34,7 @@ The `Backend` trait in `audiofiles-browser::backend` defines every operation tha
34 34
35 35 One implementation exists:
36 36
37 - - **DirectBackend** -- wraps `Mutex<Database>` + `SampleStore`, calls core functions directly. Used in the app and tests.
37 + - **DirectBackend**: wraps `Mutex<Database>` + `SampleStore`, calls core functions directly. Used in the app and tests.
38 38
39 39 This trait boundary keeps the browser UI decoupled from the data layer.
40 40
@@ -74,7 +74,7 @@ Foreign keys with CASCADE ensure referential integrity. Triggers on `samples`, `
74 74
75 75 The analysis system in `audiofiles-core::analysis` decodes audio to mono f32 via Symphonia, then runs configurable stages:
76 76
77 - - **Basic**: Duration, sample rate, channel count -- always computed.
77 + - **Basic**: Duration, sample rate, channel count, always computed.
78 78 - **Loudness**: Peak dBFS, RMS dB, integrated LUFS (via bs1770).
79 79 - **Spectral**: Centroid, flatness, rolloff, zero-crossing rate, bandwidth, centroid variance (via FFT with realfft).
80 80 - **Waveform**: Crest factor (peak/RMS ratio), attack time (seconds to 90% of peak via 1ms RMS envelope).
@@ -118,7 +118,7 @@ Sample classification colors are hardcoded (not theme-driven) so that semantic c
118 118
119 119 The cpal audio output callback runs on a real-time thread where blocking should be avoided. The design uses `parking_lot::Mutex` with `try_lock`:
120 120
121 - - **Preview playback**: The GUI thread decodes audio and writes the buffer into `PreviewPlayback` behind a mutex. The cpal callback calls `try_lock()` -- if the GUI holds the lock (decoding), the callback outputs silence instead of blocking.
121 + - **Preview playback**: The GUI thread decodes audio and writes the buffer into `PreviewPlayback` behind a mutex. The cpal callback calls `try_lock()`. If the GUI holds the lock (decoding), the callback outputs silence instead of blocking.
122 122
123 123 Voice stealing in the instrument engine uses a monotonic age counter to find the oldest voice without sorting.
124 124
@@ -139,7 +139,7 @@ Folder import runs in a background thread with its own database connection:
139 139
140 140 1. **Walk**: Recursively scan the source directory, collecting paths with recognized audio extensions (wav, aiff, mp3, flac, ogg).
141 141 2. **Strategy selection**: User chooses flat (all links in current directory), new VFS (preserve directory structure), or merge into existing VFS.
142 - 3. **Import loop**: For each file -- hash, copy to store, create VFS node. Duplicates (name conflicts) are counted but not errors. Progress and errors are reported back to the GUI via channel events.
142 + 3. **Import loop**: For each file: hash, copy to store, create VFS node. Duplicates (name conflicts) are counted but not errors. Progress and errors are reported back to the GUI via channel events.
143 143 4. **Folder tagging**: After import completes, the user can assign comma-separated tags to each imported top-level folder, applied to all samples within.
144 144 5. **Analysis**: Optionally run configurable analysis (loudness, BPM, key, spectral, classification, loop detection, fingerprint, auto-suggest tags) on imported samples.
145 145 6. **Tag review**: If auto-suggest was enabled, the user reviews suggested tags with accept/reject per suggestion before committing.
@@ -152,7 +152,7 @@ Cancellation is checked between files, keeping the UI responsive during large im
152 152 - **VFS abstraction** decouples user-visible organization from on-disk storage. Users can create multiple independent directory trees, rename and restructure freely, without moving files.
153 153 - **Backend trait** keeps the browser UI decoupled from the data layer, making it testable with mock backends.
154 154 - **Synchronous core** keeps the data layer simple and predictable. Async is confined to the sync layer (tokio) and the app.
155 - - **try_lock on audio thread** guarantees real-time safety. The cpal callback never blocks -- it either gets the lock and produces audio, or outputs silence.
155 + - **try_lock on audio thread** guarantees real-time safety. The cpal callback never blocks. It either gets the lock and produces audio, or outputs silence.
156 156 - **Strongly-typed IDs** (VfsId, NodeId, SampleHash) prevent accidental mixups at compile time. Integer IDs use a macro-generated newtype; SampleHash wraps a hex string.
157 157 - **Device plugin system** with Rhai scripting allows hardware sampler export profiles to be extended by users without recompiling, while keeping the sandbox constrained.
158 158 - **Trigger-based sync changelog** captures all local mutations automatically without requiring callers to manually record changes, making sync integration transparent to the rest of the codebase.
@@ -1,6 +1,6 @@
1 1 # audiofiles Database Schema
2 2
3 - SQLite schema reference. 23 inline migrations. Migrations are embedded as Rust string constants in `crates/audiofiles-core/src/db.rs` and applied via `PRAGMA user_version` tracking -- not separate SQL files.
3 + SQLite schema reference. 23 inline migrations. Migrations are embedded as Rust string constants in `crates/audiofiles-core/src/db.rs` and applied via `PRAGMA user_version` tracking, not separate SQL files.
4 4
5 5 ## Domain Map
6 6
@@ -19,7 +19,7 @@ SQLite schema reference. 23 inline migrations. Migrations are embedded as Rust s
19 19 ## Samples
20 20
21 21 ### samples
22 - Content-addressed sample storage. The hash (of file content) is the primary key -- duplicate files are impossible by design.
22 + Content-addressed sample storage. The hash (of file content) is the primary key. Duplicate files are impossible by design.
23 23
24 24 | Column | Type | Notes |
25 25 |--------|------|-------|
@@ -274,8 +274,8 @@ Indexes: `source_hash`, `result_hash`.
274 274
275 275 ## Design Patterns
276 276
277 - - **Content-addressed storage:** `samples.hash` is a content hash -- the same file always produces the same PK, making deduplication automatic
278 - - **Inline migrations:** All schema DDL is embedded as Rust `const` strings in `db.rs`, applied transactionally via `PRAGMA user_version` -- no external SQL files
277 + - **Content-addressed storage:** `samples.hash` is a content hash. The same file always produces the same PK, making deduplication automatic
278 + - **Inline migrations:** All schema DDL is embedded as Rust `const` strings in `db.rs`, applied transactionally via `PRAGMA user_version`, no external SQL files
279 279 - **VFS abstraction:** Virtual file systems decouple organization from disk layout; one sample can appear in multiple VFS trees via `vfs_nodes.sample_hash`
280 280 - **Self-referential tree:** `vfs_nodes.parent_id` references `vfs_nodes.id` for arbitrary directory nesting
281 281 - **Dot-namespaced tags:** Flat `tag` strings with dot convention (e.g., `genre.techno`) replace the original key-value tag model (migration 002)
@@ -1,4 +1,4 @@
1 - # audiofiles -- Sample Classification
1 + # audiofiles: Sample Classification
2 2
3 3 audiofiles classifies samples from deterministic DSP features only. No trained model
4 4 ships in the binary: the feature extraction is plain signal measurement, and tagging is