@octoseq/mir 0.1.0-main.2e286ce

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/chunk-DUWYCAVG.js +1525 -0
  2. package/dist/chunk-DUWYCAVG.js.map +1 -0
  3. package/dist/index.d.ts +450 -0
  4. package/dist/index.js +1234 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/runMir-CSIBwNZ3.d.ts +84 -0
  7. package/dist/runner/runMir.d.ts +2 -0
  8. package/dist/runner/runMir.js +3 -0
  9. package/dist/runner/runMir.js.map +1 -0
  10. package/dist/runner/workerProtocol.d.ts +169 -0
  11. package/dist/runner/workerProtocol.js +11 -0
  12. package/dist/runner/workerProtocol.js.map +1 -0
  13. package/dist/types-BE3py4fZ.d.ts +83 -0
  14. package/package.json +55 -0
  15. package/src/dsp/fft.ts +22 -0
  16. package/src/dsp/fftBackend.ts +53 -0
  17. package/src/dsp/fftBackendFftjs.ts +60 -0
  18. package/src/dsp/hpss.ts +152 -0
  19. package/src/dsp/hpssGpu.ts +101 -0
  20. package/src/dsp/mel.ts +219 -0
  21. package/src/dsp/mfcc.ts +119 -0
  22. package/src/dsp/onset.ts +205 -0
  23. package/src/dsp/peakPick.ts +112 -0
  24. package/src/dsp/spectral.ts +95 -0
  25. package/src/dsp/spectrogram.ts +176 -0
  26. package/src/gpu/README.md +34 -0
  27. package/src/gpu/context.ts +44 -0
  28. package/src/gpu/helpers.ts +87 -0
  29. package/src/gpu/hpssMasks.ts +116 -0
  30. package/src/gpu/kernels/hpssMasks.wgsl.ts +137 -0
  31. package/src/gpu/kernels/melProject.wgsl.ts +48 -0
  32. package/src/gpu/kernels/onsetEnvelope.wgsl.ts +56 -0
  33. package/src/gpu/melProject.ts +98 -0
  34. package/src/gpu/onsetEnvelope.ts +81 -0
  35. package/src/gpu/webgpu.d.ts +176 -0
  36. package/src/index.ts +121 -0
  37. package/src/runner/runMir.ts +431 -0
  38. package/src/runner/workerProtocol.ts +189 -0
  39. package/src/search/featureVectorV1.ts +123 -0
  40. package/src/search/fingerprintV1.ts +230 -0
  41. package/src/search/refinedModelV1.ts +321 -0
  42. package/src/search/searchTrackV1.ts +206 -0
  43. package/src/search/searchTrackV1Guided.ts +863 -0
  44. package/src/search/similarity.ts +98 -0
  45. package/src/types.ts +105 -0
  46. package/src/util/display.ts +80 -0
  47. package/src/util/normalise.ts +58 -0
  48. package/src/util/stats.ts +25 -0
@@ -0,0 +1,450 @@
1
+ export { c as Mir1DResult, d as Mir2DResult, h as MirAudioPayload, M as MirBackend, f as MirFunctionId, e as MirResult, b as MirRunMeta, g as MirRunRequest, a as MirRunTimings } from './types-BE3py4fZ.js';
2
+ import { S as Spectrogram, M as MirGPU } from './runMir-CSIBwNZ3.js';
3
+ export { a as SpectrogramConfig, r as runMir, s as spectrogram } from './runMir-CSIBwNZ3.js';
4
+
5
+ /**
6
+ * Spectral centroid per frame (Hz).
7
+ *
8
+ * Output is aligned 1:1 with `spec.times`.
9
+ */
10
+ declare function spectralCentroid(spec: Spectrogram): Float32Array;
11
+ /**
12
+ * Spectral flux per frame (unitless).
13
+ *
14
+ * Definition used here:
15
+ * - L1 distance between successive *normalised* magnitude spectra.
16
+ * - First frame flux is 0.
17
+ *
18
+ * Output is aligned 1:1 with `spec.times`.
19
+ */
20
+ declare function spectralFlux(spec: Spectrogram): Float32Array;
21
+
22
+ type MelConfig = {
23
+ nMels: number;
24
+ fMin?: number;
25
+ fMax?: number;
26
+ };
27
+ type MelSpectrogram = {
28
+ times: Float32Array;
29
+ melBands: Float32Array[];
30
+ /** Optional observability. Present when GPU path runs. */
31
+ gpuTimings?: {
32
+ gpuSubmitToReadbackMs: number;
33
+ };
34
+ };
35
+ /**
36
+ * Compute a (log) mel spectrogram by projecting an existing spectrogram.
37
+ *
38
+ * Design rule compliance:
39
+ * - The caller provides the spectrogram (we do not hide STFT internally).
40
+ * - Output is aligned to `spec.times`.
41
+ */
42
+ declare function melSpectrogram(spec: Spectrogram, config: MelConfig, gpu?: MirGPU): Promise<MelSpectrogram>;
43
+
44
+ type OnsetEnvelope = {
45
+ times: Float32Array;
46
+ values: Float32Array;
47
+ };
48
+ type OnsetEnvelopeOptions = {
49
+ /** If true, log-compress magnitudes/energies before differencing. */
50
+ useLog?: boolean;
51
+ /** Moving-average smoothing window length in milliseconds. 0 disables smoothing. */
52
+ smoothMs?: number;
53
+ /** How to convert temporal differences into novelty. */
54
+ diffMethod?: "rectified" | "abs";
55
+ };
56
+ declare function onsetEnvelopeFromSpectrogram(spec: Spectrogram, options?: OnsetEnvelopeOptions): OnsetEnvelope;
57
+ declare function onsetEnvelopeFromMel(mel: MelSpectrogram, options?: OnsetEnvelopeOptions): OnsetEnvelope;
58
+ type OnsetEnvelopeGpuResult = {
59
+ times: Float32Array;
60
+ values: Float32Array;
61
+ gpuTimings: {
62
+ gpuSubmitToReadbackMs: number;
63
+ };
64
+ };
65
+ /**
66
+ * GPU-accelerated onset envelope from mel spectrogram.
67
+ *
68
+ * Notes:
69
+ * - This bypasses JS loops for the diff+reduction step.
70
+ * - Smoothing/log options are intentionally limited for v0.1 (keeps WGSL simple).
71
+ * - Callers should fall back to CPU on errors.
72
+ */
73
+ declare function onsetEnvelopeFromMelGpu(mel: MelSpectrogram, gpu: MirGPU, options?: Pick<OnsetEnvelopeOptions, "diffMethod">): Promise<OnsetEnvelopeGpuResult>;
74
+
75
+ type PeakPickEvent = {
76
+ time: number;
77
+ strength: number;
78
+ index: number;
79
+ };
80
+ type PeakPickOptions = {
81
+ /** Minimum peak height (absolute). */
82
+ threshold?: number;
83
+ /** Minimum inter-peak interval (seconds). */
84
+ minIntervalSec?: number;
85
+ /** If provided, use adaptive threshold: mean(values) + factor*std(values). */
86
+ adaptive?: {
87
+ method?: "meanStd" | "median";
88
+ factor?: number;
89
+ };
90
+ /** If true, prefer strict maxima (> neighbors); else allow flat plateaus. */
91
+ strict?: boolean;
92
+ };
93
+ declare function peakPick(times: Float32Array, values: Float32Array, options?: PeakPickOptions): PeakPickEvent[];
94
+
95
+ type SpectrogramLike2D = {
96
+ times: Float32Array;
97
+ bins: number;
98
+ frames: number;
99
+ magnitudes: Float32Array[];
100
+ };
101
+ type HpssOptions = {
102
+ /** Median filter kernel size along time axis (frames). Must be odd. */
103
+ timeMedian?: number;
104
+ /** Median filter kernel size along frequency axis (bins). Must be odd. */
105
+ freqMedian?: number;
106
+ /** If true, use soft masks; else hard mask. */
107
+ softMask?: boolean;
108
+ /** Cancellation hook for long loops. */
109
+ isCancelled?: () => boolean;
110
+ };
111
+ declare function hpss(spec: Spectrogram, options?: HpssOptions): {
112
+ harmonic: SpectrogramLike2D;
113
+ percussive: SpectrogramLike2D;
114
+ };
115
+
116
+ type MfccOptions = {
117
+ nCoeffs?: number;
118
+ };
119
+ type MfccResult = {
120
+ times: Float32Array;
121
+ coeffs: Float32Array[];
122
+ };
123
+ declare function mfcc(mel: MelSpectrogram, options?: MfccOptions): MfccResult;
124
+ type DeltaOptions = {
125
+ /** Regression window size N (frames). Standard choice is 2. */
126
+ window?: number;
127
+ };
128
+ type Features2D = {
129
+ times: Float32Array;
130
+ values: Float32Array[];
131
+ };
132
+ declare function delta(features: Features2D, options?: DeltaOptions): Features2D;
133
+ declare function deltaDelta(features: Features2D, options?: DeltaOptions): Features2D;
134
+
135
+ type NormaliseForWaveformOptions = {
136
+ min?: number;
137
+ max?: number;
138
+ center?: boolean;
139
+ };
140
+ /**
141
+ * Normalise a time-aligned feature array into a waveform-friendly range.
142
+ *
143
+ * Typical uses:
144
+ * - Map spectralFlux or centroid to [-1, 1] to re-use a waveform renderer.
145
+ *
146
+ * Defaults:
147
+ * - If `center` is true: range [-1, 1] (zero-centered)
148
+ * - Else: range [0, 1]
149
+ */
150
+ declare function normaliseForWaveform(data: Float32Array, options?: NormaliseForWaveformOptions): Float32Array;
151
+
152
+ /**
153
+ * Display-only transforms for spectrogram-like (magnitude) data.
154
+ *
155
+ * These helpers are intentionally *not* used inside core MIR algorithms.
156
+ * They exist so applications can apply established visualisation practices
157
+ * (e.g. dB conversion, clamping) without mutating or rescaling the analysis
158
+ * outputs.
159
+ *
160
+ * Shape conventions:
161
+ * - 2D arrays are `[frame][bin]`.
162
+ */
163
+ type Spectrogram2D = Float32Array[];
164
+ type SpectrogramToDbOptions = {
165
+ /**
166
+ * Optional floor (minimum) dB value applied during conversion.
167
+ * This is a display convenience only.
168
+ */
169
+ floorDb?: number;
170
+ /** Epsilon used to avoid log(0). Defaults to 1e-12. */
171
+ epsilon?: number;
172
+ };
173
+ /**
174
+ * Convert linear magnitudes to dB.
175
+ *
176
+ * Formula: `db = 20 * log10(max(eps, magnitude))`
177
+ *
178
+ * Notes:
179
+ * - This does *not* normalise or re-reference the values.
180
+ * - The input is not mutated.
181
+ * - Intended for visualisation only.
182
+ */
183
+ declare function spectrogramToDb(magnitudes2d: Spectrogram2D, options?: SpectrogramToDbOptions): Spectrogram2D;
184
+ /**
185
+ * Clamp a dB-scaled 2D array to a fixed range.
186
+ *
187
+ * The input is not mutated.
188
+ * Intended for visualisation only.
189
+ */
190
+ declare function clampDb(db2d: Spectrogram2D, minDb: number, maxDb: number): Spectrogram2D;
191
+
192
+ type MinMax = {
193
+ min: number;
194
+ max: number;
195
+ };
196
+ /**
197
+ * Compute min/max in a single pass without using spread / Math.min(...arr).
198
+ *
199
+ * Safe for very large arrays (millions of samples).
200
+ */
201
+ declare function minMax(values: ArrayLike<number>): MinMax;
202
+
203
+ type MirFingerprintV1 = {
204
+ version: "v1";
205
+ /** Query window time bounds (seconds) – informational/debug only. */
206
+ t0: number;
207
+ t1: number;
208
+ mel: {
209
+ /** Mean mel vector across frames (weighted by frame energy, then unit-normalised). */
210
+ mean: Float32Array;
211
+ /** Variance mel vector across frames (weighted by frame energy). */
212
+ variance: Float32Array;
213
+ };
214
+ onset: {
215
+ mean: number;
216
+ max: number;
217
+ /** Peaks per second, computed using peakPick() on the onset envelope. */
218
+ peakDensityHz: number;
219
+ };
220
+ mfcc?: {
221
+ mean: Float32Array;
222
+ variance: Float32Array;
223
+ };
224
+ };
225
+ /**
226
+ * Compute a deterministic v1 fingerprint for a time region [t0, t1].
227
+ *
228
+ * Loudness independence:
229
+ * - Uses energy-weighted statistics. Loud frames contribute more to the shape.
230
+ * - Resulting mean vector is effectively the average energy distribution direction.
231
+ */
232
+ declare function fingerprintV1(params: {
233
+ t0: number;
234
+ t1: number;
235
+ mel: MelSpectrogram;
236
+ onsetEnvelope: {
237
+ times: Float32Array;
238
+ values: Float32Array;
239
+ };
240
+ mfcc?: Features2D;
241
+ peakPick?: {
242
+ minIntervalSec?: number;
243
+ threshold?: number;
244
+ adaptiveFactor?: number;
245
+ };
246
+ }): MirFingerprintV1;
247
+
248
+ type MirFingerprintVectorWeights = {
249
+ /** Weight for mel(mean+variance) block. */
250
+ mel?: number;
251
+ /** Weight for transient/onset scalars block. */
252
+ transient?: number;
253
+ /** Weight for MFCC(mean+variance) block (if present). */
254
+ mfcc?: number;
255
+ };
256
+ /**
257
+ * Convert a v1 fingerprint into a concatenated feature vector suitable for cosine similarity.
258
+ *
259
+ * Rules:
260
+ * - mel and mfcc blocks are L2-normalised separately (mean+var concatenated per-block)
261
+ * - transient scalars are treated as a small vector and L2-normalised too
262
+ * - blocks are then concatenated with optional weights applied per-block
263
+ */
264
+ declare function fingerprintToVectorV1(fp: MirFingerprintV1, weights?: MirFingerprintVectorWeights): Float32Array;
265
+ declare function similarityFingerprintV1(a: MirFingerprintV1, b: MirFingerprintV1, weights?: MirFingerprintVectorWeights): number;
266
+
267
+ type MirSearchCandidate = {
268
+ timeSec: number;
269
+ score: number;
270
+ windowStartSec: number;
271
+ windowEndSec: number;
272
+ };
273
+ type MirSearchResultV1 = {
274
+ times: Float32Array;
275
+ similarity: Float32Array;
276
+ candidates: MirSearchCandidate[];
277
+ meta: {
278
+ fingerprintMs: number;
279
+ scanMs: number;
280
+ totalMs: number;
281
+ windowSec: number;
282
+ hopSec: number;
283
+ skippedWindows: number;
284
+ scannedWindows: number;
285
+ };
286
+ };
287
+ type MirSearchOptionsV1 = {
288
+ /** Sliding window hop size in seconds. Default ~0.03s. */
289
+ hopSec?: number;
290
+ /** Similarity threshold for candidate detection. Default 0.75. */
291
+ threshold?: number;
292
+ /**
293
+ * Min spacing between candidates (seconds). Default is selectionDuration*0.8.
294
+ * Implemented via peakPick(minIntervalSec).
295
+ */
296
+ minCandidateSpacingSec?: number;
297
+ /** If provided, windows overlapping [skipT0, skipT1] are skipped. */
298
+ skipWindowOverlap?: {
299
+ t0: number;
300
+ t1: number;
301
+ };
302
+ /** Optional weights for similarity vector blocks. */
303
+ weights?: MirFingerprintVectorWeights;
304
+ /** Peak-pick settings for query fingerprint peak density. */
305
+ queryPeakPick?: {
306
+ minIntervalSec?: number;
307
+ threshold?: number;
308
+ adaptiveFactor?: number;
309
+ };
310
+ /** Peak-pick settings for candidate detection on the similarity curve. */
311
+ candidatePeakPick?: {
312
+ strict?: boolean;
313
+ };
314
+ /** Cooperative cancellation hook (called frequently in scan loop). */
315
+ isCancelled?: () => boolean;
316
+ };
317
+ declare function searchTrackV1(params: {
318
+ queryRegion: {
319
+ t0: number;
320
+ t1: number;
321
+ };
322
+ mel: MelSpectrogram;
323
+ onsetEnvelope: {
324
+ times: Float32Array;
325
+ values: Float32Array;
326
+ };
327
+ mfcc?: Features2D;
328
+ options?: MirSearchOptionsV1;
329
+ }): Promise<MirSearchResultV1>;
330
+
331
+ type MirRefinedModelKindV1 = "baseline" | "prototype" | "logistic";
332
+ type MirRefinedModelExplainV1 = {
333
+ kind: MirRefinedModelKindV1;
334
+ positives: number;
335
+ negatives: number;
336
+ /** L2 norms per feature group (useful as a cheap, stable explainability hook). */
337
+ weightL2?: {
338
+ mel: number;
339
+ melForeground: number;
340
+ melContrast?: number;
341
+ onset: number;
342
+ onsetForeground: number;
343
+ onsetContrast?: number;
344
+ mfcc?: number;
345
+ mfccForeground?: number;
346
+ mfccContrast?: number;
347
+ };
348
+ /** Training diagnostics (only for logistic). */
349
+ training?: {
350
+ iterations: number;
351
+ finalLoss: number;
352
+ };
353
+ };
354
+ type MirLogitContributionsByGroupV1 = {
355
+ logit: number;
356
+ bias: number;
357
+ mel: number;
358
+ melForeground: number;
359
+ melContrast?: number;
360
+ onset: number;
361
+ onsetForeground: number;
362
+ onsetContrast?: number;
363
+ mfcc?: number;
364
+ mfccForeground?: number;
365
+ mfccContrast?: number;
366
+ };
367
+
368
+ type MirRefinementCandidateLabelV1 = {
369
+ t0: number;
370
+ t1: number;
371
+ status: "accepted" | "rejected";
372
+ source: "auto" | "manual";
373
+ };
374
+ type MirSearchGuidedOptionsV1 = MirSearchOptionsV1 & {
375
+ /**
376
+ * Local contrast features: foreground (query-length) vs surrounding background.
377
+ * Enabled by default because it improves discrimination in dense mixes.
378
+ */
379
+ localContrast?: {
380
+ enabled?: boolean;
381
+ /** Background duration multiplier relative to the foreground. Default 3. */
382
+ backgroundScale?: number;
383
+ };
384
+ refinement?: {
385
+ enabled?: boolean;
386
+ /**
387
+ * Human labels (accepted/rejected). Unreviewed candidates should not be sent.
388
+ */
389
+ labels?: MirRefinementCandidateLabelV1[];
390
+ /** Optional: include the query as an extra positive exemplar once enough positives exist. */
391
+ includeQueryAsPositive?: boolean;
392
+ };
393
+ };
394
+ type MirSearchCurveKindV1 = "similarity" | "confidence";
395
+ type MirGuidedCandidateExplainV1 = {
396
+ /** Only present for logistic models; values are in logit space (sum + bias = total logit). */
397
+ groupLogit?: MirLogitContributionsByGroupV1;
398
+ };
399
+ type MirSearchCandidateV1Guided = MirSearchCandidate & {
400
+ explain?: MirGuidedCandidateExplainV1;
401
+ };
402
+ type MirSearchResultV1Guided = {
403
+ times: Float32Array;
404
+ scores: Float32Array;
405
+ candidates: MirSearchCandidateV1Guided[];
406
+ curveKind: MirSearchCurveKindV1;
407
+ model: MirRefinedModelExplainV1;
408
+ meta: {
409
+ /** Feature prep time (legacy name retained for UI compatibility). */
410
+ fingerprintMs: number;
411
+ scanMs: number;
412
+ modelMs: number;
413
+ totalMs: number;
414
+ windowSec: number;
415
+ hopSec: number;
416
+ skippedWindows: number;
417
+ scannedWindows: number;
418
+ };
419
+ };
420
+ declare function searchTrackV1Guided(params: {
421
+ queryRegion: {
422
+ t0: number;
423
+ t1: number;
424
+ };
425
+ mel: MelSpectrogram;
426
+ onsetEnvelope: {
427
+ times: Float32Array;
428
+ values: Float32Array;
429
+ };
430
+ mfcc?: Features2D;
431
+ options?: MirSearchGuidedOptionsV1;
432
+ }): Promise<MirSearchResultV1Guided>;
433
+
434
+ type MirVersion = "0.1.0";
435
+
436
+ declare const MIR_VERSION: MirVersion;
437
+ type AudioBufferLike = {
438
+ sampleRate: number;
439
+ getChannelData(channel: number): Float32Array;
440
+ numberOfChannels: number;
441
+ };
442
+
443
+ /**
444
+ * Backwards-compat placeholder from the initial skeleton.
445
+ *
446
+ * Note: kept so existing internal references/tests don't break.
447
+ */
448
+ declare function helloMir(name?: string): string;
449
+
450
+ export { type AudioBufferLike, type DeltaOptions, type Features2D, type HpssOptions, MIR_VERSION, type MelConfig, type MelSpectrogram, type MfccOptions, type MfccResult, type MinMax, type MirFingerprintV1, type MirFingerprintVectorWeights, MirGPU, type MirRefinementCandidateLabelV1, type MirSearchCandidate, type MirSearchCurveKindV1, type MirSearchGuidedOptionsV1, type MirSearchOptionsV1, type MirSearchResultV1, type MirSearchResultV1Guided, type MirVersion, type OnsetEnvelope, type OnsetEnvelopeGpuResult, type OnsetEnvelopeOptions, type PeakPickEvent, type PeakPickOptions, Spectrogram, type Spectrogram2D, type SpectrogramLike2D, type SpectrogramToDbOptions, clampDb, delta, deltaDelta, fingerprintToVectorV1, fingerprintV1, helloMir, hpss, melSpectrogram, mfcc, minMax, normaliseForWaveform, onsetEnvelopeFromMel, onsetEnvelopeFromMelGpu, onsetEnvelopeFromSpectrogram, peakPick, searchTrackV1, searchTrackV1Guided, similarityFingerprintV1, spectralCentroid, spectralFlux, spectrogramToDb };