/ proof-of-concept / audio-spike-sorting
Sign in
proof-of-concept / audio-spike-sorting
Default to original event volumes; rename gain knob to level variation with an explanatory tooltip
Jeremy Magland <jmagland@flatironinstitute.org> committed commit e06c5e1dd5b1 parent 8a76af3 Browse files
4 changed files+22−12
README.mdmodified+12−9View file
@@ -36,11 +36,14 @@ between them.
3636 placement pool used to build the dataset. An algorithm is therefore
3737 always classifying events it has not literally seen.
3838 3. **Synthesis.** Events from the placement pool are placed on a silent
39- timeline, each scaled by a random gain (default 0 to -12 dB). An
40- overlap knob in [0, 1] sets the fraction of events deliberately placed
41- inside another event's span; the rest keep at least one snippet length
42- of separation. Run r uses seed + r, so the whole benchmark is
43- reproducible from the configuration.
39+ timeline at their recorded volumes. A level-variation knob can
40+ optionally scale each placed event by a random gain drawn between
41+ 0 dB and a floor (say -12 dB), so that loudness carries no
42+ information about identity; at the default of 0 dB no adjustment is
43+ made. An overlap knob in [0, 1] sets the fraction of events
44+ deliberately placed inside another event's span; the rest keep at
45+ least one snippet length of separation. Run r uses seed + r, so the
46+ whole benchmark is reproducible from the configuration.
4447 4. **Execution.** Each algorithm is a `.m` file defining
4548 `function [times, labels] = name(x, fs, training)`, where `training`
4649 carries the per-type snippet matrices, the type names, and the onset
@@ -78,14 +81,14 @@ Three built-ins seed the comparison and can be edited or reset in place:
7881 - **onset_knn**: detection on a smoothed energy envelope, classification
7982 by distance-weighted k-nearest-neighbours over spectral shape features
8083 (band-energy ratios, centroid, zero-crossing rate). Levels are used only
81- as ratios, so the random per-event gain carries no information.
84+ as ratios, so level variation, when enabled, carries no information.
8285 - **naive_threshold**: an amplitude threshold and a classifier that looks
8386 only at event duration. A deliberately weak floor; a real method that
8487 fails to clear it is in trouble.
8588
86-On the synthetic demo data (three types, 20% overlap), the baselines land
87-around 0.6 to 0.8 accuracy, with the losses concentrated in the
88-overlapping events. None of the built-ins attempts overlap resolution
89+On the synthetic demo data (three types, 20% overlap, 12 dB of level
90+variation), the baselines land around 0.6 to 0.8 accuracy, with the
91+losses concentrated in the overlapping events. None of the built-ins attempts overlap resolution
8992 (subtraction or joint fitting), which is exactly the direction candidate
9093 algorithms are expected to explore.
9194
src/bench/types.tsmodified+3−1View file
@@ -28,7 +28,9 @@ export interface SynthConfig {
2828 /** Events placed per type (capped by available placement snippets, which
2929 * are reused with replacement when fewer). */
3030 eventsPerType: number;
31- /** Random per-event gain, uniform in dB over [gainMinDb, 0]. */
31+ /** Random per-event level variation: each placed event is scaled by a
32+ * gain drawn uniformly in dB over [gainMinDb, 0]. 0 keeps every event
33+ * at its recorded volume. */
3234 gainMinDb: number;
3335 /** Overlap knob in [0, 1]: fraction of events deliberately placed inside
3436 * another event's span; the rest keep a clean separation. */
src/main.tsmodified+6−1View file
@@ -330,11 +330,15 @@ interface ConfigField {
330330 key: keyof BenchConfig;
331331 label: string;
332332 min: number; max: number; step: number;
333+ title?: string;
333334 }
334335 const CONFIG_FIELDS: ConfigField[] = [
335336 { key: 'durationS', label: 'dataset duration (s)', min: 5, max: 600, step: 1 },
336337 { key: 'eventsPerType', label: 'events per type', min: 1, max: 2000, step: 1 },
337- { key: 'gainMinDb', label: 'gain range floor (dB)', min: -40, max: 0, step: 1 },
338+ {
339+ key: 'gainMinDb', label: 'level variation (dB)', min: -40, max: 0, step: 1,
340+ title: 'Each placed event is scaled by a random gain drawn between this many dB below its recorded volume and 0 dB. 0 keeps every event at its original volume.',
341+ },
338342 { key: 'overlap', label: 'overlap fraction (0-1)', min: 0, max: 1, step: 0.05 },
339343 { key: 'trainFraction', label: 'training fraction (0-1)', min: 0.05, max: 0.95, step: 0.05 },
340344 { key: 'runs', label: 'runs', min: 1, max: 50, step: 1 },
@@ -349,6 +353,7 @@ function renderConfig(): void {
349353 grid.innerHTML = '';
350354 for (const f of CONFIG_FIELDS) {
351355 const label = document.createElement('label');
356+ if (f.title) label.title = f.title;
352357 const span = document.createElement('span');
353358 span.textContent = f.label;
354359 const input = document.createElement('input');
src/store.tsmodified+1−1View file
@@ -32,7 +32,7 @@ export interface BenchConfig extends SynthConfig {
3232 export const DEFAULT_CONFIG: BenchConfig = {
3333 durationS: 30,
3434 eventsPerType: 30,
35- gainMinDb: -12,
35+ gainMinDb: 0,
3636 overlap: 0.2,
3737 trainFraction: 0.3,
3838 seed: 1,
↑↓ move↵openescclose