Spaces:
Sleeping
Sleeping
File size: 16,136 Bytes
eb1a122 f026127 eb1a122 e33cc90 f026127 e33cc90 ce84147 f026127 ce84147 f026127 f08496f f026127 f08496f f026127 e33cc90 5a90820 f026127 5a90820 e33cc90 f026127 f08496f eb1a122 f026127 eb1a122 f026127 e33cc90 f026127 e33cc90 0b5f0f0 e33cc90 f026127 e33cc90 f026127 e33cc90 f08496f eb1a122 f026127 eb1a122 f026127 f08496f f026127 fa35534 f026127 0b5f0f0 f026127 5a90820 f026127 f08496f e33cc90 eb1a122 f026127 f08496f e33cc90 f08496f f026127 3e9170f f026127 e33cc90 f026127 e33cc90 3e9170f f026127 e33cc90 f08496f f026127 eb1a122 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Sample Extractor</title>
<link rel="stylesheet" href="/web/styles.css" />
</head>
<body>
<div id="globalDropOverlay" class="global-drop-overlay" aria-hidden="true">
<div>
<strong>Drop audio to extract samples</strong>
<span>The waveform appears immediately and processing starts automatically.</span>
</div>
</div>
<div id="errorBanner" class="error-banner" role="alert" hidden>
<div class="error-copy">
<strong id="errorTitle">Request failed</strong>
<span id="errorMessage">Something went wrong.</span>
<small id="errorDetail"></small>
</div>
<button id="dismissErrorButton" class="icon-button" type="button" aria-label="Dismiss error">×</button>
</div>
<div class="app-shell">
<header class="topbar">
<div class="brand">
<span class="brand-mark" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i></span>
<strong>Sample Extractor</strong>
<span class="beta-pill">BETA</span>
</div>
<div id="dropzone" class="file-picker" title="Choose audio, or drop audio anywhere" role="button" tabindex="0">
<input id="fileInput" type="file" accept="audio/*,.wav,.mp3,.flac,.aiff,.ogg,.m4a,.aac" aria-label="Choose audio file" />
<button id="chooseAudioButton" class="file-picker-button" type="button">Choose audio</button>
<span class="file-picker-copy"><span id="dropTitle">Drop audio anywhere</span><small id="dropMeta">Processing starts automatically</small></span>
<span aria-hidden="true">⌄</span>
</div>
<div class="top-actions">
<div class="backend-pill" aria-live="polite">
<span class="status-dot" id="healthDot"></span>
<span><strong id="healthText">Connecting</strong><small id="healthSubtext">FastAPI backend</small></span>
</div>
<button id="runButton" class="secondary-action" type="button" disabled>↻ Reprocess</button>
<button id="exportAllButton" class="secondary-action" type="button" disabled>⇧ Export All</button>
<button id="exportSelectedButton" class="primary-action" type="button" disabled>⇄ Export Selected <span id="selectedCountTop">(0)</span></button>
</div>
</header>
<main class="main-grid">
<section class="canvas-pane" aria-label="Waveform and samples">
<section class="wave-panel" aria-label="Waveform overview">
<div class="wave-toolbar">
<div class="zoom-tools" aria-label="Waveform zoom controls">
<button id="zoomInspectButton" class="tool-button" type="button" title="Zoom with pinch or wheel">⌕</button>
<button id="zoomOutButton" class="tool-button" type="button" title="Zoom out">−</button>
<button id="zoomInButton" class="tool-button" type="button" title="Zoom in">+</button>
<button id="zoomFitButton" class="tool-button fit" type="button" title="Fit waveform">Fit</button>
</div>
<div class="wave-status">
<strong id="waveTitle">Load audio</strong>
<span id="waveProgressText">Drop a file anywhere. Extraction starts automatically.</span>
</div>
<time id="transportTime" class="top-time">0:00 / 0:00</time>
</div>
<canvas id="waveform" class="waveform" height="360"></canvas>
<div class="transport-row" aria-label="Preview transport">
<button id="transportPlayButton" class="round-play" type="button" aria-label="Play preview">▶</button>
<input id="transportSeek" class="transport-seek" type="range" min="0" max="1000" value="0" step="1" aria-label="Seek preview" />
<div class="preview-tabs" aria-label="Preview source">
<button id="previewSourceButton" class="preview-tab active" type="button" data-preview-mode="source">Source</button>
<button id="previewStemButton" class="preview-tab" type="button" data-preview-mode="stem">Stem</button>
<button id="previewReproductionButton" class="preview-tab" type="button" data-preview-mode="reproduction">Reproduced</button>
</div>
</div>
<div class="hidden-audio-bank" aria-hidden="true">
<audio id="sourcePreview"></audio>
<audio id="stemAudio"></audio>
<audio id="reconAudio"></audio>
<audio id="hitAudio"></audio>
<audio id="sampleAudio"></audio>
</div>
</section>
<section class="sample-board" aria-label="Extracted samples">
<div class="board-header">
<h2>Extracted Samples <span id="sampleCountLabel">(0)</span></h2>
<span id="resultSummary">Drop audio. The app uploads, separates stems, tunes parameters, and deals sample cards.</span>
</div>
<div id="samplesGrid" class="sample-grid"></div>
</section>
</section>
<aside class="settings-pane" aria-label="Settings">
<header class="settings-head">
<strong>Advanced Settings</strong>
<button class="icon-button" type="button" aria-label="Hide settings">×</button>
</header>
<section class="settings-section simple-section">
<h3>Detection</h3>
<label class="control-line">Stem
<select id="stem"></select>
</label>
<label class="range-line">Sensitivity
<span class="range-wrap"><input id="onset_delta" type="range" min="0.01" max="0.35" step="0.005" /><output id="sensitivityOutput">Auto</output></span>
</label>
<label class="range-line">Minimum interval
<span class="range-wrap"><input id="min_gap" type="range" min="0.001" max="1" step="0.005" /><output id="minGapOutput">Auto</output></span>
</label>
<label class="range-line">Minimum amplitude
<span class="range-wrap"><input id="energy_threshold_db" type="range" min="-100" max="0" step="1" /><output id="energyOutput">Auto</output></span>
</label>
</section>
<section class="settings-section simple-section">
<h3>Grouping</h3>
<label class="toggle-line"><span>Group Similar Hits</span><input id="groupSimilarToggle" type="checkbox" checked /></label>
<label class="range-line">Max groups
<span class="range-wrap"><input id="target_max" type="range" min="1" max="64" step="1" /><output id="targetMaxOutput">Auto</output></span>
</label>
<label class="range-line">Max group distance
<span class="range-wrap"><input id="ncc_threshold" type="range" min="0" max="1" step="0.01" /><output id="nccOutput">Auto</output></span>
</label>
</section>
<section class="settings-section simple-section">
<h3>Waveform</h3>
<label class="control-line">Resolution
<select id="waveformResolution"><option>High</option><option>Medium</option><option>Low</option></select>
</label>
<label class="control-line">Channels
<select id="waveformChannels"><option>Left & Right</option><option>Mono</option></select>
</label>
</section>
<details class="settings-section advanced-fold">
<summary>Expert pipeline controls</summary>
<div class="expert-grid">
<label>Separation engine<select id="separation_backend"><option value="spleeter">Spleeter (default)</option><option value="demucs">Demucs</option><option value="none">No separation / full mix</option></select></label>
<label>Spleeter model<select id="spleeter_model"></select></label>
<label>Demucs model<select id="demucs_model"></select></label>
<label>Clustering mode<select id="clustering_mode"><option value="batch_quality">batch quality</option><option value="online_preview">online preview</option></select></label>
<label>Shifts<input id="demucs_shifts" type="number" min="0" max="8" step="1" /></label>
<label>Overlap<input id="demucs_overlap" type="number" min="0" max="0.9" step="0.05" /></label>
<label>Onset mode<select id="onset_mode"><option value="auto">auto / multiband</option><option value="percussive">percussive</option><option value="harmonic">harmonic</option><option value="broadband">broadband</option></select></label>
<label>Pre-pad<input id="pre_pad" type="number" min="0" max="0.25" step="0.001" /></label>
<label>Min duration<input id="min_dur" type="number" min="0.001" max="10" step="0.005" /></label>
<label>Max duration<input id="max_dur" type="number" min="0.01" max="10" step="0.1" /></label>
<label>Target min<input id="target_min" type="number" min="0" max="256" step="1" /></label>
<label>Attack ms<input id="attack_ms" type="number" min="1" max="250" step="1" /></label>
<label>Mel prefilter<input id="mel_threshold" type="number" min="0" max="1" step="0.01" /></label>
<label>Linkage<select id="linkage"><option value="average">average</option><option value="complete">complete</option><option value="single">single</option></select></label>
<label>MIDI grid<select id="subdivision"><option value="4">4th</option><option value="8">8th</option><option value="16">16th</option><option value="32">32nd</option><option value="64">64th</option></select></label>
</div>
<div class="toggles">
<label><input id="synthesize" type="checkbox" /> synthesize alternates</label>
<label><input id="quantize_midi" type="checkbox" /> quantize MIDI</label>
<label><input id="auto_tune" type="checkbox" checked /> automatic parameter tuning</label>
<label><input id="use_disk_cache" type="checkbox" /> disk cache stems/source loads</label>
<label><input id="allow_backend_fallback" type="checkbox" /> fallback to full mix if separation is unavailable</label>
</div>
<div class="preset-row">
<button id="usePreviewButton" class="secondary-action" type="button">Fast preview</button>
<button id="useQualityButton" class="secondary-action" type="button">Best quality</button>
<button id="clearCacheButton" class="secondary-action" type="button">Clear cache</button>
</div>
</details>
<button id="resetUiButton" class="reset-button" type="button">Reset to Defaults</button>
</aside>
</main>
<footer class="bottom-bar" aria-label="Selection and tools">
<div class="selection-count"><span class="checked-box">✓</span><strong id="selectedCountBottom">0 Selected</strong></div>
<div class="bottom-zoom"><button class="tool-button" type="button" data-zoom-command="out">⌕ −</button><input class="mini-slider" type="range" min="1" max="64" value="1" /><button class="tool-button" type="button" data-zoom-command="in">+</button></div>
<div class="bottom-actions"><button id="selectAllSamplesButton" class="secondary-action" type="button">☑ Select All</button><button id="clearSelectionButton" class="secondary-action" type="button">🗑 Clear</button><button id="openToolsButton" class="help-button" type="button">?</button></div>
</footer>
<section id="toolsDrawer" class="tools-drawer" aria-label="Review tools" hidden>
<div class="drawer-grid">
<article>
<h3>Pipeline</h3>
<span id="jobPill" class="job-pill">idle</span>
<div id="stageList" class="stage-list"></div>
<pre id="logs" class="logs" aria-live="polite"></pre>
</article>
<article>
<h3>Exports</h3>
<div id="downloads" class="downloads compact-downloads"></div>
<div id="editedDownloads" class="downloads edited-downloads"></div>
<button id="exportStateButton" class="secondary-action" type="button" disabled>Export edited pack</button>
</article>
<article>
<h3>Selection</h3>
<p id="selectedHitMeta">Click an onset marker or hit row to audition the detected slice.</p>
<p id="selectedSampleMeta">Click a sample card to hear the representative sample.</p>
<div id="supervisionSummary" class="state-summary">No interactive state loaded.</div>
</article>
<article>
<h3>Run history</h3>
<button id="refreshHistoryButton" class="secondary-action" type="button">Refresh history</button>
<div id="historyList" class="history-list"></div>
</article>
</div>
<details class="drawer-advanced">
<summary>Review & edit state</summary>
<div class="supervision-actions">
<button id="refreshStateButton" class="secondary-action" type="button">Refresh state</button>
<button id="forceOnsetButton" class="secondary-action" type="button" disabled>Add-onset mode off</button>
<button id="undoButton" class="secondary-action" type="button" disabled>Undo edit</button>
</div>
<div class="supervision-tools">
<label>Target cluster<select id="targetClusterSelect"></select></label>
<button id="moveHitButton" class="secondary-action" type="button" disabled>Move selected hit</button>
<button id="pullHitButton" class="secondary-action" type="button" disabled>Pull into new cluster</button>
<button id="acceptHitButton" class="secondary-action" type="button" disabled>Accept hit</button>
<button id="favoriteHitButton" class="secondary-action" type="button" disabled>Favorite</button>
<button id="suppressHitButton" class="secondary-action danger" type="button" disabled>Suppress</button>
<button id="restoreHitButton" class="secondary-action" type="button" disabled>Restore</button>
<button id="lockClusterButton" class="secondary-action" type="button" disabled>Lock cluster</button>
<button id="explainClusterButton" class="secondary-action" type="button" disabled>Explain</button>
</div>
<div class="supervision-grid">
<article><h4>Outlier-first review queue</h4><div id="reviewQueue" class="compact-list"></div></article>
<article><h4>Cluster board</h4><div id="clusterBoard" class="compact-list"></div></article>
<article><h4>Suggestion inbox</h4><div id="suggestionInbox" class="compact-list"></div></article>
<article><h4>Constraint / event log</h4><div id="stateLog" class="compact-list"></div></article>
</div>
<pre id="clusterExplanation" class="explanation empty">Select a cluster and click Explain.</pre>
</details>
<details class="drawer-advanced">
<summary>Raw tables</summary>
<div class="result-columns">
<section><h3>Representative samples</h3><div class="table-wrap"><table id="samplesTable"><thead><tr><th>Audition</th><th>Sample</th><th>Class</th><th>Hits</th><th>Score</th><th>Duration</th><th>First hit</th><th>File</th></tr></thead><tbody></tbody></table></div></section>
<section><h3>Detected hit review</h3><div class="table-wrap hit-table-wrap"><table id="hitsTable"><thead><tr><th>Audition</th><th>#</th><th>Label</th><th>Cluster</th><th>Confidence</th><th>Flags</th><th>Onset</th><th>Duration</th><th>Energy</th><th>File</th></tr></thead><tbody></tbody></table></div></section>
</div>
</details>
</section>
</div>
<script type="module" src="/web/app.js"></script>
</body>
</html>
|