// AUDIO_HAXOR — WALKTHROUGH

Tutorial index Docs hub
Progress
05 / 19

05.Audio samples tab

Streaming table, waveform + spectrogram previews, context-menu actions, chromaprint fingerprints, find-similar, content-hash duplicates, smart playlists, and the heatmap dashboard. The largest tab in the app.

Samples tab with waveform preview and floating player active
assets/samples.png · Samples tab

Header controls

  • Scan (scanAudioBtn) — dispatches scan_audio_samples({ customRoots, excludePaths }).
  • Resume / Stop — same pattern as plugins.
  • Search — fuzzy search (or regex via the toggle). Supports the full FZF query language ('exact, ^prefix, suffix$, !term, a | b).
  • Format filter — multi-select over WAV, MP3, AIFF, FLAC, OGG, M4A, AAC, OPUS, WMA, REX, RX2, SF2, SFZ.
  • Additional filters on sample rate, channel count, folder path — all multi-select widgets.

Table columns

Built by buildAudioRow() in frontend/js/audio.js:3516:

  • Checkbox — batch selection for export, delete, favorite, tag.
  • Name — with highlight on search match.
  • Duration — HH:MM:SS or MM:SS.
  • Format — chip-coded.
  • Sample rate — e.g. "44.1 kHz", "48 kHz", "96 kHz".
  • Channels — mono / stereo / 5.1 / etc.
  • Size.
  • Modified.
  • Path.
  • BPM / Key / LUFS — populated by the analysis jobs in step 06.
  • Actions — expand metadata, play, reveal in Finder.

Row interactions

  • Click — select. If Single-click sample playback is on (Settings → Playback), also starts playback.
  • Double-click — if Expand sample row is on, expand the row to reveal the full metadata panel (waveform canvas + spectrogram + BPM / key / LUFS / tags / notes).
  • Arrow keys / j / k — navigate. If Play on keyboard selection is on, each selection auto-previews.
  • Enter — play.
  • Space — play/pause the floating player.
  • Drag — native OS drag. Drop into a DAW, another app, or the Files tab (see step 13). Multi-row drag works if you've checkboxed rows.
  • Right-click — context menu: Reveal, Copy path, Favorite, Add note, Tag, Find similar, Delete, Export selection, and more.

Waveform preview

Expanding a row triggers decodePeaksViaWorker() at frontend/js/audio.js:202. The decode pipeline has three fallbacks:

  1. Worker fetch + decode — off-main-thread.
  2. Main-thread fetch → worker decode — if the worker can't fetch directly.
  3. Main-thread decode — last resort.

Decoded peaks are cached in _waveformCache (capped by the Max cached waveforms setting). resolveWaveformBoxSize() at frontend/js/audio.js:452 wraps getBoundingClientRect() in an 8-frame rAF retry loop because WKWebView release builds can return 0×0 for briefly-unattached elements.

Spectrogram preview

The expanded row also renders a spectrogram via computeSpectrogramData() in frontend/js/audio-decode-worker.js (~line 34). Algorithm: sliding-window FFT, 1024 bins per frame with 50% hop, mapped to 64 log-spaced frequency bins from ~0 Hz up to Nyquist. Output is a Float32Array heatmap of shape [time][freq], rendered to canvas with an accent-color ramp.

Content duplicates — SHA-256 by size group

Open the Duplicates modal from the tab header or context menu (shortcut Cmd+D). It has two tabs:

  • Name duplicates — groups rows by (name, format). Instant, no scanning.
  • Content duplicates — click Scan to dispatch find_content_duplicates. The backend groups files by size first, then SHA-256-hashes any size-collisions (the vast majority of files are unique by size and skip hashing entirely). Progress streams via the content-dup-progress event.

Output: { groups: [{ hash_hex, size_bytes, paths: [{ kind, path }] }], files_hashed, skipped }. Each group is a card listing every duplicate path so you can pick which copy to keep.

Find similar — chromaprint fingerprints

Context menu → Find similar to this (shortcut W). Calls find_similar_samples(filePath, candidatePaths, maxResults: 20) against the fingerprint cache built by build_fingerprint_cache. The backend uses a chromaprint-style acoustic fingerprint so different files that sound the same (different formats, re-encodings, subtle edits) surface as hits, unlike byte-level duplicates.

Build the cache with Cmd+Shift+B or the Build Fingerprint Cache palette action. Cache lives in SQLite and is reused across launches.

Hits land in the Similar Search floating panel — a draggable dock that snaps to any of four corners (similarDock pref: dock-tl / dock-tr / dock-bl / dock-br, default bottom-left). The dock emits a toast.similar_panel_docked toast each time you snap it to a new corner.

Native drag-out to DAW / Finder

Drag any row (or multi-selection) off the table and onto Ableton, Logic, Finder, or any other native OS target. The plumbing lives in frontend/js/native-file-drag.js and uses the tauri-plugin-drag sidecar; on a successful drag-out the app emits a toast.fb_drag_started_n toast so you can see exactly how many files just left the app. Single-file drag works without a checkbox selection — drag the row directly. Multi-file drag fires whenever 2+ rows are checked.

Secure delete

Right-click → Securely delete on any sample row runs a 3-pass DoD 5220.22-M overwrite through the fs_secure_delete Tauri command (src-tauri/src/lib.rs:8567). The same item is available from every inventory tab via the shared _pathDeleteItems() helper (frontend/js/context-menu.js:14). A confirmation dialog (confirm.fb_secure_delete_title) is shown before the wipe; the row is removed from the table only after the file is gone from disk.

Smart playlists

frontend/js/smart-playlists.js. Create a playlist with a rule set; the view is recomputed every time the Samples table re-renders.

Rule types (from matchesSmartRule(), ~line 75):

  • format — comma-separated formats (WAV,FLAC).
  • bpm_rangemin-max (e.g. 120-130).
  • tag — note-tag match.
  • favorite — is favorited.
  • recently_played — in the floating player history.
  • name_contains / path_contains — substring.
  • size_min / size_max — MB bounds.
  • key — musical key match (C Major, F# Minor, …).
  • duration_max — seconds.

Set matchMode: 'all' (AND) or 'any' (OR). Playlists persist in prefs, export via Export Smart Playlists (Cmd+Shift+\).

Heatmap dashboard

Press D or run Show Heatmap Dashboard. frontend/js/heatmap-dashboard.js pulls per-type aggregates from db_audio_filter_stats, db_plugin_filter_stats, db_daw_filter_stats, db_preset_filter_stats and renders a draggable grid of cards:

  • Format distribution (top 10 by count).
  • Size distribution histogram (<100 KB, 100 KB–1 MB, 1–10 MB, 10–50 MB, 50–100 MB, >100 MB).
  • Folder heatmap — top directories by file count.
  • BPM distribution histogram.
  • Key distribution wheel.
  • Activity timeline — files per modified month.
  • Plugin-type breakdown.
  • DAW-format breakdown.

Import / export

  • Export JSONexport_audio_json.
  • Export DSV (TSV/CSV) — export_audio_dsv.
  • Import JSONimport_audio_json.
TipThe Samples tab streams up to 100 000 rows into an in-memory buffer during scans, but always paginates from SQLite for display. If you filter or search, filter stats (db_audio_filter_stats) refreshes the header count so you know how many results match your current query.