| 1 |
# audiofiles |
| 2 |
|
| 3 |
A sample manager with content-addressed storage and a virtual file system. Standalone desktop app built with [Rust](https://www.rust-lang.org/), [egui](https://github.com/emilk/egui), and [SQLite](https://sqlite.org/). |
| 4 |
|
| 5 |
## Prerequisites |
| 6 |
|
| 7 |
- **[Rust](https://www.rust-lang.org/)** (stable toolchain, 2024 edition) |
| 8 |
|
| 9 |
No platform-specific audio libraries are required. Audio decoding uses [Symphonia](https://github.com/pdeljanov/Symphonia) (pure Rust), SQLite is bundled via [rusqlite](https://github.com/rusqlite/rusqlite), and the standalone app uses [cpal](https://github.com/RustAudio/cpal) for system audio output. |
| 10 |
|
| 11 |
## Build and Run |
| 12 |
|
| 13 |
```sh |
| 14 |
# Standalone app |
| 15 |
cargo run -p audiofiles-app |
| 16 |
|
| 17 |
# Standalone app -- import a folder on launch |
| 18 |
cargo run -p audiofiles-app -- /path/to/samples |
| 19 |
|
| 20 |
# Run all workspace tests |
| 21 |
cargo test --workspace |
| 22 |
|
| 23 |
# Benchmarks (developers only; needs a corpus, see scripts/corpus.py) |
| 24 |
cargo run --release -p audiofiles-bench # analysis pipeline |
| 25 |
cargo run --release -p audiofiles-bench -- ingest # import and query |
| 26 |
cargo run --release -p audiofiles-bench -- accuracy # bpm/key vs ground truth |
| 27 |
cargo run --release -p audiofiles-bench -- layer-eval # classifier layer, cross-validated |
| 28 |
# AF_BENCH_EVAL_LABELS=family (default), |
| 29 |
# family-tom-split, instrument |
| 30 |
``` |
| 31 |
|
| 32 |
## Workspace Architecture |
| 33 |
|
| 34 |
Six crates: |
| 35 |
|
| 36 |
|
| 37 |
|
| 38 |
| `audiofiles-core` | `crates/audiofiles-core/` | Domain library. SQLite database, content-addressed store (SHA-256), audio decoding (Symphonia), analysis pipeline (loudness, BPM, key, spectral features), VFS, tag system, VP-tree similarity index. | |
| 39 |
| `audiofiles-browser` | `crates/audiofiles-browser/` | Shared egui UI. File list, detail panel, waveform display, search/filter, import wizard, analysis progress, export, themes. | |
| 40 |
| `audiofiles-app` | `crates/audiofiles-app/` | Standalone desktop app via eframe. System audio (cpal), drag-and-drop import, native drag-out to Finder/DAWs, system tray, CLI import, OTA updates. | |
| 41 |
| `audiofiles-sync` | `crates/audiofiles-sync/` | Cloud sync via SyncKit. Pushes/pulls sample metadata, tags, and VFS structure across devices. E2E encrypted. | |
| 42 |
| `audiofiles-rhai` | `crates/audiofiles-rhai/` | Rhai scripting engine for device export profiles. Transforms sample metadata and file layout for hardware samplers. | |
| 43 |
| `audiofiles-bench` | `crates/audiofiles-bench/` | Benchmark binary. Analysis-pipeline timing, vault ingest and query latency, BPM/key accuracy against labeled corpora, and cross-validated per-class accuracy for the classifier layer. Not shipped in the app. | |
| 44 |
|
| 45 |
Dependency flow: `audiofiles-core` is the leaf -> `audiofiles-rhai` and `audiofiles-sync` depend on core -> `audiofiles-browser` depends on core, sync, and rhai -> `audiofiles-app` depends on browser and core. `audiofiles-bench` depends on core only. |
| 46 |
|
| 47 |
Theme loading comes from [makeover](https://crates.io/crates/makeover), published to crates.io. Shared libraries from `../../MNW/shared/`: [synckit-client](../../MNW/shared/synckit-client/) (cloud sync SDK). |
| 48 |
|
| 49 |
## Features |
| 50 |
|
| 51 |
### Storage & Organization |
| 52 |
- **Content-addressed storage**: samples stored by SHA-256 hash, automatic deduplication |
| 53 |
- **Virtual file system**: organize samples in virtual directories independent of disk location, multiple VFS roots |
| 54 |
- **Tag system**: hierarchical dot-notation tags with auto-suggestions from analysis results |
| 55 |
- **Smart folders**: saved filter queries that update dynamically |
| 56 |
- **Collections**: cross-VFS sample groupings |
| 57 |
|
| 58 |
### Audio Analysis |
| 59 |
- **Analysis pipeline**: loudness (peak/RMS/LUFS), BPM detection, key detection, spectral analysis |
| 60 |
- **Classification**: deterministic DSP features feed a layered tag pipeline (user-authored rules, then k-NN over the samples you have already tagged). Multi-label, and every tag records where it came from. No trained model ships in the binary. See `docs/ml_classifier.md` |
| 61 |
- **Loop detection**: identifies seamless loops via amplitude envelope analysis |
| 62 |
- **Similarity search**: VP-tree indexed fingerprinting for finding similar and duplicate samples (O(log n) lookup) |
| 63 |
- **Waveform display**: pre-computed peak data with click-to-seek playback |
| 64 |
|
| 65 |
### Search & Filtering |
| 66 |
- **Text search**: FTS5 indexed across filenames, tags, and metadata |
| 67 |
- **Parameter filters**: BPM range, duration range, loudness range, key selector |
| 68 |
- **Tag prefix matching**: type a tag prefix to filter by hierarchy |
| 69 |
|
| 70 |
### Editing |
| 71 |
- **Destructive editing**: trim, fade in/out, normalize, reverse, gain adjust |
| 72 |
- **Edit history**: full undo/redo stack per sample |
| 73 |
- **Bulk operations**: bulk delete, move, rename, tag across selections |
| 74 |
- **Rename engine**: pattern-based renaming with tokens (name, bpm, key, index, etc.) |
| 75 |
|
| 76 |
### Device Export |
| 77 |
- **Rhai export profiles**: scriptable export for 14 hardware samplers: |
| 78 |
M8, Digitakt, Digitakt II, Octatrack, Model:Samples, SP-404 MKII, MPC, Polyend Tracker, Deluge, Blackbox, Volca Sample 2, OP-1, Circuit Rhythm, Maschine+ |
| 79 |
|
| 80 |
### Playback & Integration |
| 81 |
- **MIDI instrument**: chromatic and multi-sample playback modes with 8-voice polyphony and ADSR envelopes |
| 82 |
- **Native drag-out**: drag samples from the file list directly to Finder, Desktop, or any DAW (macOS + Windows) |
| 83 |
- **System tray**: minimize to tray, quick access |
| 84 |
|
| 85 |
### Infrastructure |
| 86 |
- **Cloud sync**: cross-device sync of metadata, tags, and VFS via SyncKit (E2E encrypted, ChaCha20-Poly1305 + Argon2) |
| 87 |
- **OTA updates**: background update checker with consent dialog |
| 88 |
- **Bundled themes**: dark, light, and high-contrast variants in TOML format, from the shared [makeover](https://crates.io/crates/makeover) crate |
| 89 |
- **Audio formats**: WAV, FLAC, MP3, OGG, AIFF (via Symphonia, pure Rust) |
| 90 |
- **Platforms**: macOS, Windows, Linux (standalone, no backend required) |
| 91 |
|
| 92 |
## Key Paths |
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
| Domain library | `crates/audiofiles-core/src/` | |
| 97 |
| Tag rules (Layer A) | `crates/audiofiles-core/src/rules.rs` | |
| 98 |
| Starter filename rule pack | `crates/audiofiles-core/src/starter_rules.rs` | |
| 99 |
| Benchmarks + corpus builder | `crates/audiofiles-bench/`, `scripts/corpus.py` | |
| 100 |
| UI components | `crates/audiofiles-browser/src/` | |
| 101 |
| Desktop app shell | `crates/audiofiles-app/src/` | |
| 102 |
| Device export profiles | `crates/audiofiles-rhai/plugins/bundled/` | |
| 103 |
| Architecture | `docs/architecture.md` | |
| 104 |
|
| 105 |
## Verifying a release |
| 106 |
|
| 107 |
Every Linux release artifact (`.AppImage`, `.deb`) is published with a detached |
| 108 |
[minisign](https://jedisct1.github.io/minisign/) signature beside it, named |
| 109 |
`<artifact>.minisig`. audiofiles does not update itself, so running this check is |
| 110 |
the only thing that tells you a download is the build we published. |
| 111 |
|
| 112 |
Download both files, then: |
| 113 |
|
| 114 |
```bash |
| 115 |
minisign -Vm Audiofiles-<version>-<arch>.AppImage -p makecreative.pub |
| 116 |
``` |
| 117 |
|
| 118 |
The public key is `dist/makecreative.pub` in this repository: |
| 119 |
|
| 120 |
``` |
| 121 |
untrusted comment: Make Creative, LLC release key (minisign) |
| 122 |
RWSMMbsBuZY5GfFRHPd19bZAVcyFAI4zsUlPjC5RaS/5tL7zT45SpjD9 |
| 123 |
``` |
| 124 |
|
| 125 |
You can also pass it inline instead of saving the file: |
| 126 |
|
| 127 |
```bash |
| 128 |
minisign -Vm Audiofiles-<version>-<arch>.AppImage -P 'RWSMMbsBuZY5GfFRHPd19bZAVcyFAI4zsUlPjC5RaS/5tL7zT45SpjD9' |
| 129 |
``` |
| 130 |
|
| 131 |
Expect `Signature and comment signature verified`. Any other result means the |
| 132 |
file is not what we published. Do not run it. |
| 133 |
|
| 134 |
## Contributing |
| 135 |
|
| 136 |
This project is licensed under PolyForm Noncommercial 1.0.0. Make Creative, LLC owns |
| 137 |
the codebase and needs to hold clear title to all of it, so contributions work a |
| 138 |
little differently here than on a permissively licensed project. |
| 139 |
|
| 140 |
**Found a bug, or something small and obviously wrong?** Open a bug report rather |
| 141 |
than sending a patch. A clear report of what you did, what happened, and what you |
| 142 |
expected is worth more to us than a diff, and it saves you the paperwork below. |
| 143 |
|
| 144 |
**Want to build something substantial?** Write to info@makenot.work first. We are |
| 145 |
open to paying for contributions that matter, and we would rather agree on scope and |
| 146 |
terms before you spend your evenings on it than after. |
| 147 |
|
| 148 |
**Sending code directly?** Any code you submit is covered by the Contributor License |
| 149 |
Agreement in `CLA.md`, which assigns copyright in the contribution to Make Creative, |
| 150 |
LLC. Read it before you send anything. Add these lines to your commit message to |
| 151 |
record that you accept it: |
| 152 |
|
| 153 |
Make-Creative-CLA: 1.0.0 |
| 154 |
Signed-off-by: Your Name <your@email> |
| 155 |
|
| 156 |
We may decline a contribution for any reason, including that it is not something we |
| 157 |
want to maintain. |
| 158 |
|
| 159 |
## License |
| 160 |
|
| 161 |
[PolyForm Noncommercial 1.0.0](https://polyformproject.org/licenses/noncommercial/1.0.0/) |
| 162 |
|