@octoseq/mir 0.1.0-main.0d2814e → 0.1.0-main.4baa7cd

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/gpu/helpers.ts","../src/gpu/kernels/onsetEnvelope.wgsl.ts","../src/gpu/onsetEnvelope.ts","../src/dsp/onset.ts","../src/dsp/spectral.ts","../src/dsp/beatCandidates.ts","../src/dsp/tempoHypotheses.ts","../src/gpu/kernels/melProject.wgsl.ts","../src/gpu/melProject.ts","../src/dsp/mel.ts","../src/dsp/mfcc.ts","../src/dsp/peakPick.ts","../src/dsp/hpss.ts","../src/gpu/kernels/hpssMasks.wgsl.ts","../src/gpu/hpssMasks.ts","../src/dsp/hpssGpu.ts","../src/dsp/fft.ts","../src/dsp/fftBackendFftjs.ts","../src/dsp/fftBackend.ts","../src/dsp/spectrogram.ts","../src/runner/runMir.ts"],"names":["movingAverage","assertPositiveInt","meanStd","nowMs","mel","usedGpu","gpuMs","cpuExtraMs","end","melCpuMs","hpssStart","chosen"],"mappings":"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","file":"chunk-KIGWMJLC.js","sourcesContent":["import type { MirGPU } from \"./context\";\n\nexport function nowMs(): number {\n return typeof performance !== \"undefined\" ? performance.now() : Date.now();\n}\n\nexport type GpuStageTiming = {\n /** wall-clock time from queue.submit() to readback completion */\n gpuSubmitToReadbackMs: number;\n};\n\nexport type GpuDispatchResult<T> = {\n value: T;\n timing: GpuStageTiming;\n};\n\nexport function byteSizeF32(n: number): number {\n return n * 4;\n}\n\nexport function createAndWriteStorageBuffer(gpu: MirGPU, data: Float32Array): GPUBuffer {\n const buf = gpu.device.createBuffer({\n size: byteSizeF32(data.length),\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n // Some TS lib definitions make BufferSource incompatible with ArrayBufferLike.\n // WebGPU implementations accept typed arrays; cast to keep this package dependency-free.\n gpu.queue.writeBuffer(buf, 0, data as unknown as BufferSource);\n return buf;\n}\n\nexport function createUniformBufferU32x4(gpu: MirGPU, u32x4: Uint32Array): GPUBuffer {\n if (u32x4.length !== 4) throw new Error(\"@octoseq/mir: uniform buffer must be 4 u32 values\");\n const buf = gpu.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n gpu.queue.writeBuffer(buf, 0, u32x4 as unknown as BufferSource);\n return buf;\n}\n\nexport function createStorageOutBuffer(gpu: MirGPU, byteLength: number): GPUBuffer {\n return gpu.device.createBuffer({\n size: byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,\n });\n}\n\nexport function createReadbackBuffer(gpu: MirGPU, byteLength: number): GPUBuffer {\n return gpu.device.createBuffer({\n size: byteLength,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n}\n\n/**\n * Submit an encoder that copies `outBuffer` to a MAP_READ buffer and returns the mapped bytes.\n *\n * Note: mapping is the completion signal; we intentionally measure submit->map to validate\n * real GPU work end-to-end.\n */\nexport async function submitAndReadback(\n gpu: MirGPU,\n encoder: GPUCommandEncoder,\n outBuffer: GPUBuffer,\n readback: GPUBuffer,\n byteLength: number\n): Promise<GpuDispatchResult<ArrayBuffer>> {\n encoder.copyBufferToBuffer(outBuffer, 0, readback, 0, byteLength);\n\n const tSubmit = nowMs();\n gpu.queue.submit([encoder.finish()]);\n\n await readback.mapAsync(GPUMapMode.READ);\n const tDone = nowMs();\n\n const mapped = readback.getMappedRange();\n const copy = mapped.slice(0); // copies to standalone ArrayBuffer\n readback.unmap();\n\n return {\n value: copy,\n timing: {\n gpuSubmitToReadbackMs: tDone - tSubmit,\n },\n };\n}\n","export const onsetEnvelopeWGSL = /* wgsl */ `\n// Compute onset strength envelope from a (log) mel spectrogram.\n//\n// Input layout: melFlat[t*nMels + m]\n// Output layout: out[t]\n//\n// We compute novelty per frame:\n// novelty[t] = sum_m max(0, mel[t,m] - mel[t-1,m]) (rectified)\n// or sum_m abs(...)\n//\n// One invocation computes one frame index (t). This is memory-bound but reduces a full\n// (frames*mels) loop to the GPU and provides an end-to-end submit->readback timing.\n\nstruct Params {\n nMels: u32,\n nFrames: u32,\n diffMethod: u32, // 0=rectified, 1=abs\n _pad: u32,\n};\n\n@group(0) @binding(0) var<storage, read> melFlat: array<f32>;\n@group(0) @binding(1) var<storage, read_write> out: array<f32>;\n@group(0) @binding(2) var<uniform> params: Params;\n\n@compute @workgroup_size(256)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let t = gid.x;\n if (t >= params.nFrames) { return; }\n\n if (t == 0u) {\n out[t] = 0.0;\n return;\n }\n\n let nMels = params.nMels;\n var sum: f32 = 0.0;\n\n // Linear loop: nMels is small (e.g. 64). Keeping it serial per-frame is fine.\n // (Future optimisation: parallelise reduction within workgroup.)\n for (var m: u32 = 0u; m < nMels; m = m + 1u) {\n let a = melFlat[t * nMels + m];\n let b = melFlat[(t - 1u) * nMels + m];\n let d = a - b;\n\n if (params.diffMethod == 1u) {\n // abs\n sum = sum + abs(d);\n } else {\n // rectified\n sum = sum + max(0.0, d);\n }\n }\n\n out[t] = sum / max(1.0, f32(nMels));\n}\n`;\n","import type { MirGPU } from \"./context\";\n\nimport {\n byteSizeF32,\n createAndWriteStorageBuffer,\n createReadbackBuffer,\n createStorageOutBuffer,\n createUniformBufferU32x4,\n submitAndReadback,\n type GpuDispatchResult,\n} from \"./helpers\";\n\nimport { onsetEnvelopeWGSL } from \"./kernels/onsetEnvelope.wgsl\";\n\nexport type GpuOnsetEnvelopeInput = {\n nFrames: number;\n nMels: number;\n melFlat: Float32Array; // length=nFrames*nMels\n diffMethod: \"rectified\" | \"abs\";\n};\n\nexport type GpuOnsetEnvelopeOutput = {\n out: Float32Array; // length=nFrames\n};\n\nexport async function gpuOnsetEnvelopeFromMelFlat(\n gpu: MirGPU,\n input: GpuOnsetEnvelopeInput\n): Promise<GpuDispatchResult<GpuOnsetEnvelopeOutput>> {\n const { device } = gpu;\n\n const { nFrames, nMels, melFlat, diffMethod } = input;\n if (melFlat.length !== nFrames * nMels) {\n throw new Error(\"@octoseq/mir: melFlat length mismatch\");\n }\n\n const melBuffer = createAndWriteStorageBuffer(gpu, melFlat);\n\n const outByteLen = byteSizeF32(nFrames);\n const outBuffer = createStorageOutBuffer(gpu, outByteLen);\n const readback = createReadbackBuffer(gpu, outByteLen);\n\n const shader = device.createShaderModule({ code: onsetEnvelopeWGSL });\n const pipeline = device.createComputePipeline({\n layout: \"auto\",\n compute: { module: shader, entryPoint: \"main\" },\n });\n\n const diffU32 = diffMethod === \"abs\" ? 1 : 0;\n const params = createUniformBufferU32x4(gpu, new Uint32Array([nMels, nFrames, diffU32, 0]));\n\n const bindGroup = device.createBindGroup({\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: melBuffer } },\n { binding: 1, resource: { buffer: outBuffer } },\n { binding: 2, resource: { buffer: params } },\n ],\n });\n\n const encoder = device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n\n const wg = Math.ceil(nFrames / 256);\n pass.dispatchWorkgroups(wg);\n pass.end();\n\n const { value: bytes, timing } = await submitAndReadback(gpu, encoder, outBuffer, readback, outByteLen);\n\n melBuffer.destroy();\n outBuffer.destroy();\n params.destroy();\n readback.destroy();\n\n return {\n value: { out: new Float32Array(bytes) },\n timing,\n };\n}\n","import type { MirGPU } from \"../gpu/context\";\nimport { gpuOnsetEnvelopeFromMelFlat } from \"../gpu/onsetEnvelope\";\n\nimport type { MelSpectrogram } from \"./mel\";\nimport type { Spectrogram } from \"./spectrogram\";\n\nexport type OnsetEnvelope = {\n times: Float32Array;\n values: Float32Array;\n};\n\nexport type OnsetEnvelopeOptions = {\n /** If true, log-compress magnitudes/energies before differencing. */\n useLog?: boolean;\n /** Moving-average smoothing window length in milliseconds. 0 disables smoothing. */\n smoothMs?: number;\n /** How to convert temporal differences into novelty. */\n diffMethod?: \"rectified\" | \"abs\";\n};\n\nfunction movingAverage(values: Float32Array, windowFrames: number): Float32Array {\n if (windowFrames <= 1) return values;\n\n const n = values.length;\n const out = new Float32Array(n);\n\n // Centered window.\n const half = Math.floor(windowFrames / 2);\n\n // Prefix sums for stable, bug-free O(n) moving average.\n const prefix = new Float64Array(n + 1);\n prefix[0] = 0;\n for (let i = 0; i < n; i++) {\n prefix[i + 1] = (prefix[i] ?? 0) + (values[i] ?? 0);\n }\n\n for (let i = 0; i < n; i++) {\n const start = Math.max(0, i - half);\n const end = Math.min(n, i + half + 1);\n const sum = (prefix[end] ?? 0) - (prefix[start] ?? 0);\n const count = Math.max(1, end - start);\n out[i] = sum / count;\n }\n\n return out;\n}\n\nfunction defaultOptions(opts?: OnsetEnvelopeOptions): Required<OnsetEnvelopeOptions> {\n return {\n useLog: opts?.useLog ?? false,\n smoothMs: opts?.smoothMs ?? 30,\n diffMethod: opts?.diffMethod ?? \"rectified\",\n };\n}\n\nfunction logCompress(x: number): number {\n // Stable compression without -Inf.\n // We use ln(1+x) so it behaves well for both linear mags and log-mel (already log10).\n return Math.log1p(Math.max(0, x));\n}\n\nexport function onsetEnvelopeFromSpectrogram(spec: Spectrogram, options?: OnsetEnvelopeOptions): OnsetEnvelope {\n const opts = defaultOptions(options);\n\n const nFrames = spec.times.length;\n const out = new Float32Array(nFrames);\n\n const nBins = (spec.fftSize >>> 1) + 1;\n\n // First frame has no previous frame.\n out[0] = 0;\n\n for (let t = 1; t < nFrames; t++) {\n const cur = spec.magnitudes[t];\n const prev = spec.magnitudes[t - 1];\n if (!cur || !prev) {\n out[t] = 0;\n continue;\n }\n\n let sum = 0;\n for (let k = 0; k < nBins; k++) {\n let a = cur[k] ?? 0;\n let b = prev[k] ?? 0;\n if (opts.useLog) {\n a = logCompress(a);\n b = logCompress(b);\n }\n const d = a - b;\n sum += opts.diffMethod === \"abs\" ? Math.abs(d) : Math.max(0, d);\n }\n\n // Use an average over frequency bins so the overall scale is not tied to FFT size.\n out[t] = nBins > 0 ? sum / nBins : 0;\n }\n\n // Optional smoothing based on average frame spacing.\n const smoothMs = opts.smoothMs;\n if (smoothMs > 0 && nFrames >= 2) {\n const dt = (spec.times[1] ?? 0) - (spec.times[0] ?? 0);\n const windowFrames = Math.max(1, Math.round((smoothMs / 1000) / Math.max(1e-9, dt)));\n return {\n times: spec.times,\n values: movingAverage(out, windowFrames | 1),\n };\n }\n\n return { times: spec.times, values: out };\n}\n\nexport function onsetEnvelopeFromMel(mel: MelSpectrogram, options?: OnsetEnvelopeOptions): OnsetEnvelope {\n const opts = defaultOptions(options);\n\n const nFrames = mel.times.length;\n const out = new Float32Array(nFrames);\n\n out[0] = 0;\n\n for (let t = 1; t < nFrames; t++) {\n const cur = mel.melBands[t];\n const prev = mel.melBands[t - 1];\n if (!cur || !prev) {\n out[t] = 0;\n continue;\n }\n\n const nBands = cur.length;\n\n let sum = 0;\n for (let m = 0; m < nBands; m++) {\n let a = cur[m] ?? 0;\n let b = prev[m] ?? 0;\n\n // Note: melSpectrogram currently outputs log10(eps + energy).\n // If useLog is requested, we apply an additional stable compression.\n if (opts.useLog) {\n a = logCompress(a);\n b = logCompress(b);\n }\n\n const d = a - b;\n sum += opts.diffMethod === \"abs\" ? Math.abs(d) : Math.max(0, d);\n }\n\n // Use an average over bands so the overall scale is not tied to nMels.\n out[t] = nBands > 0 ? sum / nBands : 0;\n }\n\n const smoothMs = opts.smoothMs;\n if (smoothMs > 0 && nFrames >= 2) {\n const dt = (mel.times[1] ?? 0) - (mel.times[0] ?? 0);\n const windowFrames = Math.max(1, Math.round((smoothMs / 1000) / Math.max(1e-9, dt)));\n return {\n times: mel.times,\n values: movingAverage(out, windowFrames | 1),\n };\n }\n\n return { times: mel.times, values: out };\n}\n\nexport type OnsetEnvelopeGpuResult = {\n times: Float32Array;\n values: Float32Array;\n gpuTimings: { gpuSubmitToReadbackMs: number };\n};\n\n/**\n * GPU-accelerated onset envelope from mel spectrogram.\n *\n * Notes:\n * - This bypasses JS loops for the diff+reduction step.\n * - Smoothing/log options are intentionally limited for v0.1 (keeps WGSL simple).\n * - Callers should fall back to CPU on errors.\n */\nexport async function onsetEnvelopeFromMelGpu(\n mel: MelSpectrogram,\n gpu: MirGPU,\n options?: Pick<OnsetEnvelopeOptions, \"diffMethod\">\n): Promise<OnsetEnvelopeGpuResult> {\n const nFrames = mel.times.length;\n const nMels = mel.melBands[0]?.length ?? 0;\n\n const melFlat = new Float32Array(nFrames * nMels);\n for (let t = 0; t < nFrames; t++) {\n const row = mel.melBands[t];\n if (!row) continue;\n melFlat.set(row, t * nMels);\n }\n\n const diffMethod = options?.diffMethod ?? \"rectified\";\n\n const { value, timing } = await gpuOnsetEnvelopeFromMelFlat(gpu, {\n nFrames,\n nMels,\n melFlat,\n diffMethod,\n });\n\n return {\n times: mel.times,\n values: value.out,\n gpuTimings: { gpuSubmitToReadbackMs: timing.gpuSubmitToReadbackMs },\n };\n}\n","import type { Spectrogram } from \"./spectrogram\";\n\n/**\n * Spectral centroid per frame (Hz).\n *\n * Output is aligned 1:1 with `spec.times`.\n */\nexport function spectralCentroid(spec: Spectrogram): Float32Array {\n const nFrames = spec.times.length;\n const out = new Float32Array(nFrames);\n\n const nBins = (spec.fftSize >>> 1) + 1;\n const binHz = spec.sampleRate / spec.fftSize;\n\n for (let t = 0; t < nFrames; t++) {\n const mags = spec.magnitudes[t];\n if (!mags) {\n out[t] = 0;\n continue;\n }\n\n let num = 0;\n let den = 0;\n\n // DC..Nyquist inclusive.\n for (let k = 0; k < nBins; k++) {\n const m = mags[k] ?? 0;\n const f = k * binHz;\n num += f * m;\n den += m;\n }\n\n out[t] = den > 0 ? num / den : 0;\n }\n\n return out;\n}\n\n/**\n * Spectral flux per frame (unitless).\n *\n * Definition used here:\n * - L1 distance between successive *normalised* magnitude spectra.\n * - First frame flux is 0.\n *\n * Output is aligned 1:1 with `spec.times`.\n */\nexport function spectralFlux(spec: Spectrogram): Float32Array {\n const nFrames = spec.times.length;\n const out = new Float32Array(nFrames);\n\n const nBins = (spec.fftSize >>> 1) + 1;\n\n let prev: Float32Array | null = null;\n\n for (let t = 0; t < nFrames; t++) {\n const mags = spec.magnitudes[t];\n if (!mags) {\n out[t] = 0;\n prev = null;\n continue;\n }\n\n // Normalise to reduce sensitivity to overall level.\n let sum = 0;\n for (let k = 0; k < nBins; k++) sum += mags[k] ?? 0;\n\n if (sum <= 0) {\n out[t] = 0;\n prev = null;\n continue;\n }\n\n const cur = new Float32Array(nBins);\n const inv = 1 / sum;\n for (let k = 0; k < nBins; k++) cur[k] = (mags[k] ?? 0) * inv;\n\n if (!prev) {\n out[t] = 0;\n prev = cur;\n continue;\n }\n\n let flux = 0;\n for (let k = 0; k < nBins; k++) {\n const d = (cur[k] ?? 0) - (prev[k] ?? 0);\n flux += Math.abs(d);\n }\n\n out[t] = flux;\n prev = cur;\n }\n\n return out;\n}\n","import type { MelSpectrogram } from \"./mel\";\nimport type { OnsetEnvelope } from \"./onset\";\nimport { onsetEnvelopeFromMel } from \"./onset\";\nimport type { Spectrogram } from \"./spectrogram\";\nimport { spectralFlux } from \"./spectral\";\nimport type { BeatCandidate, BeatCandidateSource } from \"../types\";\n\n/**\n * Configuration for beat candidate detection.\n */\nexport type BeatCandidatesOptions = {\n /** Minimum inter-candidate interval in seconds. Default: 0.1 (100ms). */\n minIntervalSec?: number;\n /** Threshold factor for adaptive peak detection. Lower = more candidates. Default: 0.5. */\n thresholdFactor?: number;\n /** Smoothing window for salience signal in ms. Default: 50. */\n smoothMs?: number;\n};\n\n/**\n * Result of beat candidate detection.\n */\nexport type BeatCandidatesOutput = {\n candidates: BeatCandidate[];\n /** The computed salience signal (for debugging/visualization). */\n salience: {\n times: Float32Array;\n values: Float32Array;\n };\n};\n\n/**\n * Compute a beat-oriented salience signal from mel spectrogram.\n *\n * This combines:\n * - Onset envelope (captures transients/attacks)\n * - Spectral flux from the underlying spectrogram (captures spectral change)\n *\n * The signals are normalized and combined to produce a single salience curve\n * suitable for peak picking.\n *\n * Key design choices:\n * - Whole-track normalization (z-score) for consistent behavior\n * - Gentle smoothing to suppress micro-transients while preserving beat structure\n * - No BPM inference or grid assumptions\n */\nexport type BeatSalienceSignal = {\n times: Float32Array;\n values: Float32Array;\n};\n\nfunction movingAverage(values: Float32Array, windowFrames: number): Float32Array {\n if (windowFrames <= 1) return values;\n\n const n = values.length;\n const out = new Float32Array(n);\n\n const half = Math.floor(windowFrames / 2);\n\n // Prefix sums for O(n) moving average.\n const prefix = new Float64Array(n + 1);\n prefix[0] = 0;\n for (let i = 0; i < n; i++) {\n prefix[i + 1] = (prefix[i] ?? 0) + (values[i] ?? 0);\n }\n\n for (let i = 0; i < n; i++) {\n const start = Math.max(0, i - half);\n const end = Math.min(n, i + half + 1);\n const sum = (prefix[end] ?? 0) - (prefix[start] ?? 0);\n const count = Math.max(1, end - start);\n out[i] = sum / count;\n }\n\n return out;\n}\n\nfunction meanStd(values: Float32Array): { mean: number; std: number } {\n const n = values.length;\n if (n <= 0) return { mean: 0, std: 0 };\n\n let mean = 0;\n for (let i = 0; i < n; i++) mean += values[i] ?? 0;\n mean /= n;\n\n let varSum = 0;\n for (let i = 0; i < n; i++) {\n const d = (values[i] ?? 0) - mean;\n varSum += d * d;\n }\n\n const std = Math.sqrt(varSum / n);\n return { mean, std };\n}\n\n/**\n * Z-score normalize a signal (whole-track normalization).\n * Result has mean ~0 and std ~1.\n */\nfunction zScoreNormalize(values: Float32Array): Float32Array {\n const { mean, std } = meanStd(values);\n const n = values.length;\n const out = new Float32Array(n);\n\n if (std === 0 || !Number.isFinite(std)) {\n // Degenerate case: all values are the same\n out.fill(0);\n return out;\n }\n\n for (let i = 0; i < n; i++) {\n out[i] = ((values[i] ?? 0) - mean) / std;\n }\n\n return out;\n}\n\n/**\n * Min-max normalize to [0, 1] range.\n */\nfunction minMaxNormalize(values: Float32Array): Float32Array {\n const n = values.length;\n if (n === 0) return new Float32Array(0);\n\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < n; i++) {\n const v = values[i] ?? 0;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n\n const out = new Float32Array(n);\n const range = max - min;\n\n if (range === 0 || !Number.isFinite(range)) {\n out.fill(0.5);\n return out;\n }\n\n for (let i = 0; i < n; i++) {\n out[i] = ((values[i] ?? 0) - min) / range;\n }\n\n return out;\n}\n\n/**\n * Compute beat salience signal from mel spectrogram.\n *\n * This is an intermediate signal suitable for peak picking to extract\n * beat candidates. It combines onset envelope with additional smoothing\n * tuned for beat-like (rather than onset-like) detection.\n */\nexport function beatSalienceFromMel(\n mel: MelSpectrogram,\n spec: Spectrogram,\n options?: { smoothMs?: number }\n): BeatSalienceSignal {\n const smoothMs = options?.smoothMs ?? 50;\n\n // Compute onset envelope with more smoothing than default onset detection.\n // We want to capture the \"attack envelope\" of beats, not individual onsets.\n const onset = onsetEnvelopeFromMel(mel, {\n smoothMs: smoothMs,\n diffMethod: \"rectified\",\n useLog: false,\n });\n\n // Compute spectral flux from the spectrogram.\n const flux = spectralFlux(spec);\n\n // Ensure times align (they should, but be defensive).\n const n = Math.min(onset.times.length, flux.length);\n\n // Z-score normalize both signals for equal contribution.\n const onsetNorm = zScoreNormalize(onset.values.subarray(0, n));\n const fluxNorm = zScoreNormalize(flux.subarray(0, n));\n\n // Combine: weighted sum favoring onset envelope (it's more beat-specific).\n const combined = new Float32Array(n);\n const onsetWeight = 0.7;\n const fluxWeight = 0.3;\n\n for (let i = 0; i < n; i++) {\n combined[i] = onsetWeight * (onsetNorm[i] ?? 0) + fluxWeight * (fluxNorm[i] ?? 0);\n }\n\n // Apply final smoothing to reduce micro-peaks.\n const dt = n >= 2 ? ((onset.times[1] ?? 0) - (onset.times[0] ?? 0)) : 0.01;\n const windowFrames = Math.max(1, Math.round((smoothMs / 1000) / Math.max(1e-9, dt)));\n const smoothed = movingAverage(combined, windowFrames | 1);\n\n // Normalize to [0, 1] for consistent interpretation.\n const normalized = minMaxNormalize(smoothed);\n\n return {\n times: onset.times.subarray(0, n),\n values: normalized,\n };\n}\n\n/**\n * Pick peaks from the salience signal to extract beat candidates.\n *\n * Uses relaxed parameters to err on the side of too many candidates.\n * The goal is coverage, not precision.\n */\nfunction pickBeatCandidates(\n salience: BeatSalienceSignal,\n options: BeatCandidatesOptions,\n source: BeatCandidateSource\n): BeatCandidate[] {\n const minIntervalSec = options.minIntervalSec ?? 0.1;\n const thresholdFactor = options.thresholdFactor ?? 0.5;\n\n const { times, values } = salience;\n const n = values.length;\n\n if (n < 3) return [];\n\n // Compute adaptive threshold based on signal statistics.\n const { mean, std } = meanStd(values);\n // Low threshold to get dense candidates.\n // thresholdFactor of 0.5 means: mean + 0.5*std (quite low).\n const threshold = mean + thresholdFactor * std;\n\n const candidates: BeatCandidate[] = [];\n let lastPeakTime = -Infinity;\n\n for (let i = 1; i < n - 1; i++) {\n const v = values[i] ?? 0;\n\n // Must be above threshold.\n if (v < threshold) continue;\n\n // Must be a local maximum.\n const prev = values[i - 1] ?? 0;\n const next = values[i + 1] ?? 0;\n if (!(v > prev && v > next)) continue;\n\n const t = times[i] ?? 0;\n\n // Enforce minimum interval.\n if (t - lastPeakTime < minIntervalSec) {\n // If within interval, keep the stronger peak.\n const last = candidates[candidates.length - 1];\n if (last && v > last.strength) {\n last.time = t;\n last.strength = v;\n }\n continue;\n }\n\n candidates.push({\n time: t,\n strength: v,\n source,\n });\n lastPeakTime = t;\n }\n\n return candidates;\n}\n\n/**\n * Detect beat candidates from mel spectrogram and spectrogram.\n *\n * This is the main entry point for beat candidate detection.\n *\n * Design principles:\n * - Dense candidates (err on side of too many)\n * - No BPM inference\n * - No grid assumptions\n * - Whole-track normalization for consistency\n * - Deterministic (same input -> same output)\n */\nexport function detectBeatCandidates(\n mel: MelSpectrogram,\n spec: Spectrogram,\n options?: BeatCandidatesOptions\n): BeatCandidatesOutput {\n const opts: BeatCandidatesOptions = {\n minIntervalSec: options?.minIntervalSec ?? 0.1,\n thresholdFactor: options?.thresholdFactor ?? 0.5,\n smoothMs: options?.smoothMs ?? 50,\n };\n\n // Compute beat salience signal.\n const salience = beatSalienceFromMel(mel, spec, { smoothMs: opts.smoothMs });\n\n // Pick peaks from salience.\n const candidates = pickBeatCandidates(salience, opts, \"combined\");\n\n return {\n candidates,\n salience,\n };\n}\n","import type { BeatCandidate, TempoHypothesis, TempoHypothesisEvidence } from \"../types\";\n\n/**\n * Configuration for tempo hypothesis generation.\n */\nexport type TempoHypothesesOptions = {\n /** Minimum BPM to consider. Default: 24. */\n minBpm?: number;\n /** Maximum BPM to consider. Default: 300. */\n maxBpm?: number;\n /** Histogram bin size in BPM. Default: 1.0. */\n binSizeBpm?: number;\n /** Maximum hypotheses to return. Default: 10. */\n maxHypotheses?: number;\n /** Minimum confidence threshold (0-1). Default: 0.05. */\n minConfidence?: number;\n /** Weight IOIs by candidate strength. Default: true. */\n weightByStrength?: boolean;\n /** Include histogram data in output. Default: false. */\n includeHistogram?: boolean;\n};\n\nexport type TempoHypothesesOutput = {\n hypotheses: TempoHypothesis[];\n inputCandidateCount: number;\n histogram?: {\n bpmBins: Float32Array;\n counts: Float32Array;\n };\n};\n\n/**\n * Convert interval (seconds) to BPM.\n */\nfunction intervalToBpm(intervalSec: number): number {\n return 60.0 / intervalSec;\n}\n\n/**\n * Convert BPM to interval (seconds).\n */\nfunction bpmToInterval(bpm: number): number {\n return 60.0 / bpm;\n}\n\ntype IOI = { intervalSec: number; weight: number };\n\n/**\n * Compute inter-onset intervals from beat candidates.\n *\n * @param candidates - Beat candidates sorted by time\n * @param weightByStrength - Whether to weight by candidate strength\n * @returns Array of { intervalSec, weight } pairs\n */\nfunction computeIOIs(candidates: BeatCandidate[], weightByStrength: boolean): IOI[] {\n if (candidates.length < 2) return [];\n\n const iois: IOI[] = [];\n\n // Sort candidates by time (should already be sorted, but be defensive)\n const sorted = [...candidates].sort((a, b) => a.time - b.time);\n\n for (let i = 1; i < sorted.length; i++) {\n const prev = sorted[i - 1]!;\n const curr = sorted[i]!;\n const interval = curr.time - prev.time;\n\n // Skip invalid intervals\n if (interval <= 0) continue;\n\n // Weight is geometric mean of adjacent strengths, or 1.0 if not weighting\n const weight = weightByStrength\n ? Math.sqrt(prev.strength * curr.strength)\n : 1.0;\n\n iois.push({ intervalSec: interval, weight });\n }\n\n return iois;\n}\n\n/**\n * Build a weighted histogram of BPM values from IOIs.\n *\n * @param iois - Inter-onset intervals with weights\n * @param minBpm - Minimum BPM (determines max interval)\n * @param maxBpm - Maximum BPM (determines min interval)\n * @param binSizeBpm - Size of each histogram bin in BPM\n * @returns { bins: center BPM of each bin, counts: weighted counts }\n */\nfunction buildBpmHistogram(\n iois: IOI[],\n minBpm: number,\n maxBpm: number,\n binSizeBpm: number\n): { bpmBins: Float32Array; counts: Float32Array } {\n const numBins = Math.ceil((maxBpm - minBpm) / binSizeBpm);\n const counts = new Float32Array(numBins);\n const bpmBins = new Float32Array(numBins);\n\n // Initialize bin centers\n for (let i = 0; i < numBins; i++) {\n bpmBins[i] = minBpm + (i + 0.5) * binSizeBpm;\n }\n\n // Convert interval range to BPM range\n const minInterval = bpmToInterval(maxBpm);\n const maxInterval = bpmToInterval(minBpm);\n\n for (const { intervalSec, weight } of iois) {\n // Filter to plausible range\n if (intervalSec < minInterval || intervalSec > maxInterval) continue;\n\n const bpm = intervalToBpm(intervalSec);\n const binIndex = Math.floor((bpm - minBpm) / binSizeBpm);\n\n if (binIndex >= 0 && binIndex < numBins) {\n counts[binIndex] = (counts[binIndex] ?? 0) + weight;\n }\n }\n\n return { bpmBins, counts };\n}\n\n/**\n * Find peaks in the histogram using local maximum detection.\n *\n * @param counts - Weighted counts per bin\n * @param minHeight - Minimum peak height (absolute)\n * @returns Array of peak indices sorted by height descending\n */\nfunction findHistogramPeaks(counts: Float32Array, minHeight: number): number[] {\n const peaks: Array<{ index: number; height: number }> = [];\n\n for (let i = 1; i < counts.length - 1; i++) {\n const curr = counts[i]!;\n const prev = counts[i - 1]!;\n const next = counts[i + 1]!;\n\n // Local maximum\n if (curr > prev && curr > next && curr >= minHeight) {\n peaks.push({ index: i, height: curr });\n }\n }\n\n // Also check boundary bins if they're high enough\n if (counts.length > 0 && counts[0]! >= minHeight && counts[0]! > (counts[1] ?? 0)) {\n peaks.push({ index: 0, height: counts[0]! });\n }\n if (counts.length > 1) {\n const last = counts.length - 1;\n if (counts[last]! >= minHeight && counts[last]! > (counts[last - 1] ?? 0)) {\n peaks.push({ index: last, height: counts[last]! });\n }\n }\n\n // Sort by height descending\n peaks.sort((a, b) => b.height - a.height);\n\n return peaks.map((p) => p.index);\n}\n\n/**\n * Merge adjacent peak bins to get refined BPM estimate.\n * Uses weighted centroid of adjacent bins.\n */\nfunction refinePeakBpm(\n peakIndex: number,\n bpmBins: Float32Array,\n counts: Float32Array,\n binSizeBpm: number\n): { bpm: number; peakHeight: number; binRange: [number, number]; totalWeight: number } {\n // Consider the peak bin and immediate neighbors\n let totalWeight = 0;\n let weightedBpm = 0;\n let minBinBpm = bpmBins[peakIndex]! - binSizeBpm / 2;\n let maxBinBpm = bpmBins[peakIndex]! + binSizeBpm / 2;\n\n for (let offset = -1; offset <= 1; offset++) {\n const idx = peakIndex + offset;\n if (idx < 0 || idx >= bpmBins.length) continue;\n\n const w = counts[idx]!;\n const bpm = bpmBins[idx]!;\n\n totalWeight += w;\n weightedBpm += w * bpm;\n\n if (w > 0) {\n minBinBpm = Math.min(minBinBpm, bpm - binSizeBpm / 2);\n maxBinBpm = Math.max(maxBinBpm, bpm + binSizeBpm / 2);\n }\n }\n\n const refinedBpm = totalWeight > 0 ? weightedBpm / totalWeight : bpmBins[peakIndex]!;\n\n return {\n bpm: refinedBpm,\n peakHeight: counts[peakIndex]!,\n binRange: [minBinBpm, maxBinBpm],\n totalWeight,\n };\n}\n\n/**\n * Check if two BPMs are harmonically related (within tolerance).\n * Returns the harmonic ratio if related, null otherwise.\n */\nfunction getHarmonicRatio(bpm1: number, bpm2: number, tolerance: number = 0.03): number | null {\n const ratios = [0.5, 1 / 3, 2 / 3, 1.0, 1.5, 2.0, 3.0];\n\n for (const ratio of ratios) {\n const expected = bpm1 * ratio;\n const relativeError = Math.abs(bpm2 - expected) / expected;\n if (relativeError <= tolerance) {\n return ratio;\n }\n }\n\n return null;\n}\n\n/**\n * Group hypotheses into harmonic families.\n * Assigns familyId and harmonicRatio to each hypothesis.\n *\n * Uses deterministic family IDs based on the root BPM.\n */\nfunction assignHarmonicFamilies(hypotheses: TempoHypothesis[]): void {\n if (hypotheses.length === 0) return;\n\n const families: Map<string, { rootBpm: number; members: TempoHypothesis[] }> = new Map();\n\n for (const hyp of hypotheses) {\n let foundFamily = false;\n\n for (const [familyId, family] of families) {\n const ratio = getHarmonicRatio(family.rootBpm, hyp.bpm);\n if (ratio !== null) {\n hyp.familyId = familyId;\n hyp.harmonicRatio = ratio;\n family.members.push(hyp);\n foundFamily = true;\n break;\n }\n }\n\n if (!foundFamily) {\n // Create new family with this hypothesis as root\n // Use deterministic family ID based on root BPM\n const familyId = `fam-${Math.round(hyp.bpm)}`;\n hyp.familyId = familyId;\n hyp.harmonicRatio = 1.0;\n families.set(familyId, { rootBpm: hyp.bpm, members: [hyp] });\n }\n }\n}\n\n/**\n * Normalize confidence scores to [0, 1] range.\n */\nfunction normalizeConfidence(hypotheses: TempoHypothesis[]): void {\n if (hypotheses.length === 0) return;\n\n const maxHeight = Math.max(...hypotheses.map((h) => h.evidence.peakHeight));\n if (maxHeight <= 0) return;\n\n for (const hyp of hypotheses) {\n hyp.confidence = hyp.evidence.peakHeight / maxHeight;\n }\n}\n\n/**\n * Generate tempo hypotheses from beat candidates.\n *\n * Algorithm:\n * 1. Compute inter-onset intervals (IOIs) from beat candidates\n * 2. Filter IOIs to musically plausible range (0.2s-2.5s -> 24-300 BPM)\n * 3. Build weighted histogram with configurable bin size\n * 4. Extract peaks as tempo candidates\n * 5. Refine BPM estimates using weighted centroid\n * 6. Group into harmonic families\n * 7. Normalize confidence scores\n *\n * @param candidates - Beat candidates from B1\n * @param options - Configuration options\n * @returns Tempo hypotheses with confidence and family groupings\n */\nexport function generateTempoHypotheses(\n candidates: BeatCandidate[],\n options?: TempoHypothesesOptions\n): TempoHypothesesOutput {\n const minBpm = options?.minBpm ?? 24;\n const maxBpm = options?.maxBpm ?? 300;\n const binSizeBpm = options?.binSizeBpm ?? 1.0;\n const maxHypotheses = options?.maxHypotheses ?? 10;\n const minConfidence = options?.minConfidence ?? 0.05;\n const weightByStrength = options?.weightByStrength ?? true;\n const includeHistogram = options?.includeHistogram ?? false;\n\n // Early return if insufficient candidates\n if (candidates.length < 2) {\n return {\n hypotheses: [],\n inputCandidateCount: candidates.length,\n histogram: includeHistogram\n ? {\n bpmBins: new Float32Array(0),\n counts: new Float32Array(0),\n }\n : undefined,\n };\n }\n\n // Step 1: Compute IOIs\n const iois = computeIOIs(candidates, weightByStrength);\n\n if (iois.length === 0) {\n return {\n hypotheses: [],\n inputCandidateCount: candidates.length,\n histogram: includeHistogram\n ? {\n bpmBins: new Float32Array(0),\n counts: new Float32Array(0),\n }\n : undefined,\n };\n }\n\n // Step 2-3: Build histogram (filtering happens during binning)\n const { bpmBins, counts } = buildBpmHistogram(iois, minBpm, maxBpm, binSizeBpm);\n\n // Calculate minimum height threshold based on minConfidence\n const maxCount = Math.max(...counts);\n const minHeight = maxCount * minConfidence;\n\n // Step 4: Find peaks\n const peakIndices = findHistogramPeaks(counts, minHeight);\n\n // Step 5: Create hypotheses with refined BPM\n const hypotheses: TempoHypothesis[] = [];\n\n for (const peakIndex of peakIndices.slice(0, maxHypotheses * 2)) {\n // Get extra for filtering\n const { bpm, peakHeight, binRange, totalWeight } = refinePeakBpm(\n peakIndex,\n bpmBins,\n counts,\n binSizeBpm\n );\n\n // Skip if below confidence threshold\n if (maxCount > 0 && peakHeight / maxCount < minConfidence) continue;\n\n const evidence: TempoHypothesisEvidence = {\n supportingIntervalCount: Math.round(totalWeight),\n weightedSupport: totalWeight,\n peakHeight,\n binRange,\n };\n\n hypotheses.push({\n id: \"\", // Will be assigned after sorting\n bpm: Math.round(bpm * 10) / 10, // Round to 0.1 BPM precision\n confidence: 0, // Will be normalized\n evidence,\n familyId: \"\", // Will be assigned\n harmonicRatio: 1.0, // Will be assigned\n });\n }\n\n // Step 6: Group into harmonic families\n assignHarmonicFamilies(hypotheses);\n\n // Step 7: Normalize confidence\n normalizeConfidence(hypotheses);\n\n // Filter by minConfidence and sort by confidence descending\n const filtered = hypotheses\n .filter((h) => h.confidence >= minConfidence)\n .sort((a, b) => b.confidence - a.confidence)\n .slice(0, maxHypotheses);\n\n // Assign deterministic IDs based on rank\n for (let i = 0; i < filtered.length; i++) {\n filtered[i]!.id = `hyp-${i}`;\n }\n\n return {\n hypotheses: filtered,\n inputCandidateCount: candidates.length,\n histogram: includeHistogram ? { bpmBins, counts } : undefined,\n };\n}\n","/**\n * WGSL kernel: mel filterbank projection.\n *\n * Computes per-frame mel band energies:\n * out[frame, mel] = log10(eps + sum_k mags[frame, k] * filters[mel, k])\n *\n * Notes:\n * - FFT/STFT stays on CPU (spectrogram()). This kernel only accelerates the dense projection.\n * - Numerical differences vs CPU are expected to be small (floating point order-of-ops).\n */\nexport const melProjectWGSL = /* wgsl */ `\nstruct Params {\n nBins: u32,\n nMels: u32,\n nFrames: u32,\n _pad: u32,\n};\n\n@group(0) @binding(0) var<storage, read> mags : array<f32>;\n@group(0) @binding(1) var<storage, read> filters : array<f32>;\n@group(0) @binding(2) var<storage, read_write> out : array<f32>;\n@group(0) @binding(3) var<uniform> params : Params;\n\nfn log10(x: f32) -> f32 {\n return log(x) / log(10.0);\n}\n\n@compute @workgroup_size(16, 16)\nfn main(@builtin(global_invocation_id) gid : vec3<u32>) {\n let frame = gid.x;\n let mel = gid.y;\n if (frame >= params.nFrames || mel >= params.nMels) {\n return;\n }\n\n var sum: f32 = 0.0;\n let bins = params.nBins;\n let magBase = frame * bins;\n let filBase = mel * bins;\n\n for (var k: u32 = 0u; k < bins; k = k + 1u) {\n sum = sum + mags[magBase + k] * filters[filBase + k];\n }\n\n let eps: f32 = 1e-12;\n out[frame * params.nMels + mel] = log10(eps + sum);\n}\n`;\n","import type { MirGPU } from \"./context\";\n\nimport {\n byteSizeF32,\n createAndWriteStorageBuffer,\n createReadbackBuffer,\n createStorageOutBuffer,\n createUniformBufferU32x4,\n submitAndReadback,\n type GpuDispatchResult,\n} from \"./helpers\";\n\nimport { melProjectWGSL } from \"./kernels/melProject.wgsl\";\n\nexport type GpuMelProjectInput = {\n nFrames: number;\n nBins: number;\n nMels: number;\n magsFlat: Float32Array; // length = nFrames*nBins\n filterFlat: Float32Array; // length = nMels*nBins\n};\n\nexport type GpuMelProjectOutput = {\n outFlat: Float32Array; // length = nFrames*nMels\n};\n\n/**\n * Real WebGPU compute stage: dense mel projection.\n *\n * Returns outFlat plus GPU timing that measures submit->readback.\n */\nexport async function gpuMelProjectFlat(\n gpu: MirGPU,\n input: GpuMelProjectInput\n): Promise<GpuDispatchResult<GpuMelProjectOutput>> {\n const { device } = gpu;\n\n const { nFrames, nBins, nMels, magsFlat, filterFlat } = input;\n if (magsFlat.length !== nFrames * nBins) {\n throw new Error(\"@octoseq/mir: magsFlat length mismatch\");\n }\n if (filterFlat.length !== nMels * nBins) {\n throw new Error(\"@octoseq/mir: filterFlat length mismatch\");\n }\n\n const magsBuffer = createAndWriteStorageBuffer(gpu, magsFlat);\n const filterBuffer = createAndWriteStorageBuffer(gpu, filterFlat);\n\n const outByteLen = byteSizeF32(nFrames * nMels);\n const outBuffer = createStorageOutBuffer(gpu, outByteLen);\n const readback = createReadbackBuffer(gpu, outByteLen);\n\n const shader = device.createShaderModule({ code: melProjectWGSL });\n const pipeline = device.createComputePipeline({\n layout: \"auto\",\n compute: {\n module: shader,\n entryPoint: \"main\",\n },\n });\n\n const params = createUniformBufferU32x4(gpu, new Uint32Array([nBins, nMels, nFrames, 0]));\n\n const bindGroup = device.createBindGroup({\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: magsBuffer } },\n { binding: 1, resource: { buffer: filterBuffer } },\n { binding: 2, resource: { buffer: outBuffer } },\n { binding: 3, resource: { buffer: params } },\n ],\n });\n\n const encoder = device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n\n const wgX = Math.ceil(nFrames / 16);\n const wgY = Math.ceil(nMels / 16);\n pass.dispatchWorkgroups(wgX, wgY);\n pass.end();\n\n const { value: bytes, timing } = await submitAndReadback(gpu, encoder, outBuffer, readback, outByteLen);\n\n // Cleanup (simple; no pooling in v0.1)\n magsBuffer.destroy();\n filterBuffer.destroy();\n outBuffer.destroy();\n params.destroy();\n readback.destroy();\n\n const outFlat = new Float32Array(bytes);\n return {\n value: { outFlat },\n timing,\n };\n}\n","import type { MirGPU } from \"../gpu/context\";\nimport { gpuMelProjectFlat } from \"../gpu/melProject\";\n\nimport type { Spectrogram } from \"./spectrogram\";\n\nexport type MelConfig = {\n nMels: number;\n fMin?: number;\n fMax?: number;\n};\n\nexport type MelSpectrogram = {\n times: Float32Array;\n melBands: Float32Array[]; // [frame][mel]\n /** Optional observability. Present when GPU path runs. */\n gpuTimings?: {\n gpuSubmitToReadbackMs: number;\n };\n};\n\nfunction assertPositiveInt(name: string, value: number): void {\n if (!Number.isFinite(value) || value <= 0 || (value | 0) !== value) {\n throw new Error(`@octoseq/mir: ${name} must be a positive integer`);\n }\n}\n\nfunction hzToMel(hz: number): number {\n // Slaney-style mel approximation (HTK-like).\n return 2595 * Math.log10(1 + hz / 700);\n}\n\nfunction melToHz(mel: number): number {\n return 700 * (Math.pow(10, mel / 2595) - 1);\n}\n\nfunction buildMelFilterBank(\n sampleRate: number,\n fftSize: number,\n nMels: number,\n fMin: number,\n fMax: number\n): Float32Array[] {\n const nBins = (fftSize >>> 1) + 1;\n const nyquist = sampleRate / 2;\n\n const fMinClamped = Math.max(0, Math.min(fMin, nyquist));\n const fMaxClamped = Math.max(0, Math.min(fMax, nyquist));\n if (fMaxClamped <= fMinClamped) {\n throw new Error(\"@octoseq/mir: mel fMax must be > fMin\");\n }\n\n // We create nMels triangular filters defined by nMels+2 mel points.\n const melMin = hzToMel(fMinClamped);\n const melMax = hzToMel(fMaxClamped);\n\n const melPoints = new Float32Array(nMels + 2);\n for (let i = 0; i < melPoints.length; i++) {\n melPoints[i] = melMin + (i * (melMax - melMin)) / (nMels + 1);\n }\n\n const hzPoints = new Float32Array(melPoints.length);\n for (let i = 0; i < hzPoints.length; i++) hzPoints[i] = melToHz(melPoints[i] ?? 0);\n\n const binHz = sampleRate / fftSize;\n const binPoints = new Int32Array(hzPoints.length);\n for (let i = 0; i < binPoints.length; i++) {\n binPoints[i] = Math.max(0, Math.min(nBins - 1, Math.round((hzPoints[i] ?? 0) / binHz)));\n }\n\n const filters: Float32Array[] = new Array(nMels);\n for (let m = 0; m < nMels; m++) {\n const left = binPoints[m] ?? 0;\n const center = binPoints[m + 1] ?? 0;\n const right = binPoints[m + 2] ?? 0;\n\n const w = new Float32Array(nBins);\n if (center === left || right === center) {\n filters[m] = w;\n continue;\n }\n\n for (let k = left; k < center; k++) {\n w[k] = (k - left) / (center - left);\n }\n for (let k = center; k < right; k++) {\n w[k] = (right - k) / (right - center);\n }\n\n filters[m] = w;\n }\n\n return filters;\n}\n\nfunction cpuMelProject(\n spec: Spectrogram,\n filters: Float32Array[]\n): MelSpectrogram {\n const nFrames = spec.times.length;\n const nMels = filters.length;\n const out: Float32Array[] = new Array(nFrames);\n\n const eps = 1e-12;\n\n for (let t = 0; t < nFrames; t++) {\n const mags = spec.magnitudes[t];\n if (!mags) {\n out[t] = new Float32Array(nMels);\n continue;\n }\n\n const bands = new Float32Array(nMels);\n for (let m = 0; m < nMels; m++) {\n const w = filters[m];\n if (!w) continue;\n\n let sum = 0;\n // Project linear magnitudes onto mel filters.\n for (let k = 0; k < mags.length; k++) {\n sum += (mags[k] ?? 0) * (w[k] ?? 0);\n }\n\n // Log scaling for visualisation / downstream features.\n bands[m] = Math.log10(eps + sum);\n }\n out[t] = bands;\n }\n\n return {\n times: spec.times,\n melBands: out\n };\n}\n\nasync function gpuMelProject(\n spec: Spectrogram,\n filters: Float32Array[],\n gpu: MirGPU\n): Promise<MelSpectrogram> {\n const nFrames = spec.times.length;\n const nBins = (spec.fftSize >>> 1) + 1;\n const nMels = filters.length;\n\n const magsFlat = new Float32Array(nFrames * nBins);\n for (let t = 0; t < nFrames; t++) {\n const mags = spec.magnitudes[t];\n if (!mags) continue;\n magsFlat.set(mags, t * nBins);\n }\n\n const filterFlat = new Float32Array(nMels * nBins);\n for (let m = 0; m < nMels; m++) {\n filterFlat.set(filters[m] ?? new Float32Array(nBins), m * nBins);\n }\n\n // GPU stage timing (submission -> readback) is surfaced for validation/debug.\n const { value, timing } = await gpuMelProjectFlat(gpu, {\n nFrames,\n nBins,\n nMels,\n magsFlat,\n filterFlat,\n });\n\n const outFlat = value.outFlat;\n\n const melBands: Float32Array[] = new Array(nFrames);\n for (let t = 0; t < nFrames; t++) {\n // Keep zero-copy views into the single flat buffer.\n melBands[t] = outFlat.subarray(t * nMels, (t + 1) * nMels);\n }\n\n return {\n times: spec.times,\n melBands,\n gpuTimings: {\n gpuSubmitToReadbackMs: timing.gpuSubmitToReadbackMs,\n },\n };\n}\n\n/**\n * Compute a (log) mel spectrogram by projecting an existing spectrogram.\n *\n * Design rule compliance:\n * - The caller provides the spectrogram (we do not hide STFT internally).\n * - Output is aligned to `spec.times`.\n */\nexport async function melSpectrogram(\n spec: Spectrogram,\n config: MelConfig,\n gpu?: MirGPU\n): Promise<MelSpectrogram> {\n assertPositiveInt(\"config.nMels\", config.nMels);\n\n const fMin = config.fMin ?? 0;\n const fMax = config.fMax ?? spec.sampleRate / 2;\n\n const filters = buildMelFilterBank(\n spec.sampleRate,\n spec.fftSize,\n config.nMels,\n fMin,\n fMax\n );\n\n if (gpu) {\n // Try GPU; if anything goes wrong, fall back to CPU.\n try {\n return await gpuMelProject(spec, filters, gpu);\n } catch {\n // GPU can fail due to missing features, adapter resets, etc.\n // v0.1 prioritises correctness: we silently fall back.\n return cpuMelProject(spec, filters);\n }\n }\n\n return cpuMelProject(spec, filters);\n}\n","import type { MelSpectrogram } from \"./mel\";\n\nexport type MfccOptions = {\n nCoeffs?: number;\n};\n\nexport type MfccResult = {\n times: Float32Array;\n coeffs: Float32Array[]; // [frame][coeff]\n};\n\nfunction assertPositiveInt(name: string, v: number): void {\n if (!Number.isFinite(v) || v <= 0 || (v | 0) !== v) {\n throw new Error(`@octoseq/mir: ${name} must be a positive integer`);\n }\n}\n\nfunction buildDctMatrix(nCoeffs: number, nMels: number): Float32Array {\n // DCT-II (ortho-ish scaling). Many MFCC refs use a scaled DCT; for visualisation and\n // relative features this is sufficient and stable.\n // Shape: [nCoeffs][nMels]\n const out = new Float32Array(nCoeffs * nMels);\n\n const scale0 = Math.sqrt(1 / nMels);\n const scale = Math.sqrt(2 / nMels);\n\n for (let i = 0; i < nCoeffs; i++) {\n for (let j = 0; j < nMels; j++) {\n const c = Math.cos((Math.PI / nMels) * (j + 0.5) * i);\n out[i * nMels + j] = (i === 0 ? scale0 : scale) * c;\n }\n }\n\n return out;\n}\n\nexport function mfcc(mel: MelSpectrogram, options: MfccOptions = {}): MfccResult {\n const nFrames = mel.times.length;\n const nMels = mel.melBands[0]?.length ?? 0;\n\n const nCoeffs = options.nCoeffs ?? 13;\n assertPositiveInt(\"options.nCoeffs\", nCoeffs);\n if (nMels <= 0) {\n return { times: mel.times, coeffs: new Array(nFrames).fill(0).map(() => new Float32Array(nCoeffs)) };\n }\n\n const dct = buildDctMatrix(nCoeffs, nMels);\n\n const out: Float32Array[] = new Array(nFrames);\n for (let t = 0; t < nFrames; t++) {\n const x = mel.melBands[t] ?? new Float32Array(nMels);\n\n // melSpectrogram already returns log10 energies. For MFCC we typically use ln energies.\n // We keep it simple here: treat the existing log-scaled values as log-energy features.\n const c = new Float32Array(nCoeffs);\n\n for (let i = 0; i < nCoeffs; i++) {\n let sum = 0;\n const rowOff = i * nMels;\n for (let j = 0; j < nMels; j++) {\n sum += (dct[rowOff + j] ?? 0) * (x[j] ?? 0);\n }\n c[i] = sum;\n }\n\n out[t] = c;\n }\n\n return { times: mel.times, coeffs: out };\n}\n\nexport type DeltaOptions = {\n /** Regression window size N (frames). Standard choice is 2. */\n window?: number;\n};\n\nexport type Features2D = {\n times: Float32Array;\n values: Float32Array[]; // [frame][feature]\n};\n\nexport function delta(features: Features2D, options: DeltaOptions = {}): Features2D {\n const N = options.window ?? 2;\n assertPositiveInt(\"options.window\", N);\n\n const nFrames = features.times.length;\n const nFeat = features.values[0]?.length ?? 0;\n\n const out: Float32Array[] = new Array(nFrames);\n\n // denom = 2 * sum_{n=1..N} n^2\n let denom = 0;\n for (let n = 1; n <= N; n++) denom += n * n;\n denom *= 2;\n\n for (let t = 0; t < nFrames; t++) {\n const d = new Float32Array(nFeat);\n\n for (let f = 0; f < nFeat; f++) {\n let num = 0;\n for (let n = 1; n <= N; n++) {\n const tPlus = Math.min(nFrames - 1, t + n);\n const tMinus = Math.max(0, t - n);\n const a = features.values[tPlus]?.[f] ?? 0;\n const b = features.values[tMinus]?.[f] ?? 0;\n num += n * (a - b);\n }\n d[f] = denom > 0 ? num / denom : 0;\n }\n\n out[t] = d;\n }\n\n return { times: features.times, values: out };\n}\n\nexport function deltaDelta(features: Features2D, options: DeltaOptions = {}): Features2D {\n return delta(delta(features, options), options);\n}\n","export type PeakPickEvent = {\n time: number;\n strength: number;\n index: number;\n};\n\nexport type PeakPickOptions = {\n /** Minimum peak height (absolute). */\n threshold?: number;\n /** Minimum inter-peak interval (seconds). */\n minIntervalSec?: number;\n\n /** If provided, use adaptive threshold: mean(values) + factor*std(values). */\n adaptive?: {\n method?: \"meanStd\" | \"median\";\n factor?: number;\n };\n\n /** If true, prefer strict maxima (> neighbors); else allow flat plateaus. */\n strict?: boolean;\n};\n\nfunction meanStd(values: Float32Array): { mean: number; std: number } {\n const n = values.length;\n if (n <= 0) return { mean: 0, std: 0 };\n\n let mean = 0;\n for (let i = 0; i < n; i++) mean += values[i] ?? 0;\n mean /= n;\n\n let varSum = 0;\n for (let i = 0; i < n; i++) {\n const d = (values[i] ?? 0) - mean;\n varSum += d * d;\n }\n\n const std = Math.sqrt(varSum / n);\n return { mean, std };\n}\n\nfunction median(values: Float32Array): number {\n const arr = Array.from(values);\n arr.sort((a, b) => a - b);\n const n = arr.length;\n if (n === 0) return 0;\n const mid = n >>> 1;\n if (n % 2 === 1) return arr[mid] ?? 0;\n return ((arr[mid - 1] ?? 0) + (arr[mid] ?? 0)) / 2;\n}\n\nexport function peakPick(\n times: Float32Array,\n values: Float32Array,\n options: PeakPickOptions = {}\n): PeakPickEvent[] {\n if (times.length !== values.length) {\n throw new Error(\"@octoseq/mir: peakPick times/values length mismatch\");\n }\n\n const n = values.length;\n if (n === 0) return [];\n\n const strict = options.strict ?? true;\n\n let thr = options.threshold ?? 0;\n if (options.adaptive) {\n const method = options.adaptive.method ?? \"meanStd\";\n const factor = options.adaptive.factor ?? 1;\n\n if (method === \"median\") {\n thr = median(values) * factor;\n } else {\n const { mean, std } = meanStd(values);\n thr = mean + factor * std;\n }\n }\n\n const minIntervalSec = options.minIntervalSec ?? 0;\n\n const out: PeakPickEvent[] = [];\n\n let lastPeakTime = -Infinity;\n\n for (let i = 1; i < n - 1; i++) {\n const v = values[i] ?? 0;\n if (!(v >= thr)) continue;\n\n const prev = values[i - 1] ?? 0;\n const next = values[i + 1] ?? 0;\n\n const isMax = strict ? v > prev && v > next : v >= prev && v >= next;\n if (!isMax) continue;\n\n const t = times[i] ?? 0;\n if (t - lastPeakTime < minIntervalSec) {\n // If we're within the minimum interval, keep the stronger peak.\n const last = out[out.length - 1];\n if (last && v > last.strength) {\n last.time = t;\n last.strength = v;\n last.index = i;\n lastPeakTime = t;\n }\n continue;\n }\n\n out.push({ time: t, strength: v, index: i });\n lastPeakTime = t;\n }\n\n return out;\n}\n","import type { Spectrogram } from \"./spectrogram\";\n\nexport type SpectrogramLike2D = {\n times: Float32Array;\n bins: number;\n frames: number;\n magnitudes: Float32Array[]; // [frame][bin]\n};\n\nexport type HpssOptions = {\n /** Median filter kernel size along time axis (frames). Must be odd. */\n timeMedian?: number;\n /** Median filter kernel size along frequency axis (bins). Must be odd. */\n freqMedian?: number;\n /** If true, use soft masks; else hard mask. */\n softMask?: boolean;\n /** Cancellation hook for long loops. */\n isCancelled?: () => boolean;\n};\n\nfunction assertOddPositiveInt(name: string, v: number): void {\n if (!Number.isFinite(v) || v <= 0 || (v | 0) !== v) {\n throw new Error(`@octoseq/mir: ${name} must be a positive integer`);\n }\n if (v % 2 !== 1) {\n throw new Error(`@octoseq/mir: ${name} must be odd`);\n }\n}\n\nfunction medianOfWindow(values: Float32Array): number {\n // Small-kernel median: copy + sort. CPU-heavy but fine for v0.1.\n // Isolated here so a future GPU / histogram-based median can replace it.\n const arr = Array.from(values);\n arr.sort((a, b) => a - b);\n const mid = arr.length >>> 1;\n return arr[mid] ?? 0;\n}\n\nfunction medianFilterTime(spec: Spectrogram, kTime: number, options: HpssOptions): Float32Array[] {\n const nFrames = spec.times.length;\n const nBins = (spec.fftSize >>> 1) + 1;\n\n const half = kTime >>> 1;\n const out: Float32Array[] = new Array(nFrames);\n\n const window = new Float32Array(kTime);\n\n for (let t = 0; t < nFrames; t++) {\n if (options.isCancelled?.()) throw new Error(\"@octoseq/mir: cancelled\");\n\n const row = new Float32Array(nBins);\n for (let k = 0; k < nBins; k++) {\n // Build temporal window for bin k.\n for (let i = -half, wi = 0; i <= half; i++, wi++) {\n const tt = Math.max(0, Math.min(nFrames - 1, t + i));\n const mags = spec.magnitudes[tt];\n window[wi] = mags ? (mags[k] ?? 0) : 0;\n }\n row[k] = medianOfWindow(window);\n }\n out[t] = row;\n }\n\n return out;\n}\n\nfunction medianFilterFreq(spec: Spectrogram, kFreq: number, options: HpssOptions): Float32Array[] {\n const nFrames = spec.times.length;\n const nBins = (spec.fftSize >>> 1) + 1;\n\n const half = kFreq >>> 1;\n const out: Float32Array[] = new Array(nFrames);\n\n const window = new Float32Array(kFreq);\n\n for (let t = 0; t < nFrames; t++) {\n if (options.isCancelled?.()) throw new Error(\"@octoseq/mir: cancelled\");\n\n const mags = spec.magnitudes[t] ?? new Float32Array(nBins);\n const row = new Float32Array(nBins);\n\n for (let k = 0; k < nBins; k++) {\n for (let i = -half, wi = 0; i <= half; i++, wi++) {\n const kk = Math.max(0, Math.min(nBins - 1, k + i));\n window[wi] = mags[kk] ?? 0;\n }\n row[k] = medianOfWindow(window);\n }\n\n out[t] = row;\n }\n\n return out;\n}\n\nexport function hpss(spec: Spectrogram, options: HpssOptions = {}): { harmonic: SpectrogramLike2D; percussive: SpectrogramLike2D } {\n const timeMedian = options.timeMedian ?? 17;\n const freqMedian = options.freqMedian ?? 17;\n assertOddPositiveInt(\"options.timeMedian\", timeMedian);\n assertOddPositiveInt(\"options.freqMedian\", freqMedian);\n\n const nFrames = spec.times.length;\n const nBins = (spec.fftSize >>> 1) + 1;\n\n // Median along time -> harmonic estimate\n const H = medianFilterTime(spec, timeMedian, options);\n // Median along freq -> percussive estimate\n const P = medianFilterFreq(spec, freqMedian, options);\n\n const harmonic: Float32Array[] = new Array(nFrames);\n const percussive: Float32Array[] = new Array(nFrames);\n\n const soft = options.softMask ?? true;\n const eps = 1e-12;\n\n for (let t = 0; t < nFrames; t++) {\n if (options.isCancelled?.()) throw new Error(\"@octoseq/mir: cancelled\");\n\n const mags = spec.magnitudes[t] ?? new Float32Array(nBins);\n const hRow = H[t] ?? new Float32Array(nBins);\n const pRow = P[t] ?? new Float32Array(nBins);\n\n const outH = new Float32Array(nBins);\n const outP = new Float32Array(nBins);\n\n for (let k = 0; k < nBins; k++) {\n const x = mags[k] ?? 0;\n const h = hRow[k] ?? 0;\n const p = pRow[k] ?? 0;\n\n if (soft) {\n const denom = Math.max(eps, h + p);\n const mh = h / denom;\n const mp = p / denom;\n outH[k] = x * mh;\n outP[k] = x * mp;\n } else {\n const isH = h >= p;\n outH[k] = isH ? x : 0;\n outP[k] = isH ? 0 : x;\n }\n }\n\n harmonic[t] = outH;\n percussive[t] = outP;\n }\n\n return {\n harmonic: { times: spec.times, bins: nBins, frames: nFrames, magnitudes: harmonic },\n percussive: { times: spec.times, bins: nBins, frames: nFrames, magnitudes: percussive },\n };\n}\n","/**\n * WGSL kernel: HPSS mask estimation (harmonic/percussive) from a linear magnitude spectrogram.\n *\n * CPU reference path in `src/dsp/hpss.ts` uses true median filters with configurable kernels\n * (defaults 17x17). That is too slow, and implementing a general median on GPU would require\n * per-pixel sorting / dynamic allocation.\n *\n * GPU strategy (approximation, intentionally fixed):\n * - Use a fixed 9-tap 1D robust smoother in time (harmonic estimate) and in frequency\n * (percussive estimate).\n * - Robust smoother is implemented as the exact median-of-9 via a fixed compare–swap\n * sorting network (no dynamic memory, no data-dependent branches, fixed cost).\n *\n * This yields masks that are structurally faithful for visualisation / musical use, while\n * allowing a large performance win from GPU parallelism.\n *\n * Shapes:\n * - Input mags: flattened row-major [frame][bin], length = nFrames * nBins\n * - Output harmonicMask, percussiveMask: same layout and length\n */\nexport const hpssMasksWGSL = /* wgsl */ `\nstruct Params {\n nBins: u32,\n nFrames: u32,\n softMask: u32, // 1 => soft, 0 => hard\n _pad: u32,\n};\n\n@group(0) @binding(0) var<storage, read> mags : array<f32>;\n@group(0) @binding(1) var<storage, read_write> harmonicMask : array<f32>;\n@group(0) @binding(2) var<storage, read_write> percussiveMask : array<f32>;\n@group(0) @binding(3) var<uniform> params : Params;\n\nfn clamp_i32(x: i32, lo: i32, hi: i32) -> i32 {\n return max(lo, min(hi, x));\n}\n\nfn swap_if_greater(a: ptr<function, f32>, b: ptr<function, f32>) {\n // Branchless compare–swap.\n let av = *a;\n let bv = *b;\n *a = min(av, bv);\n *b = max(av, bv);\n}\n\n// Sorting network for 9 values; returns the 5th smallest (median).\n//\n// Notes:\n// - This is fixed-cost and data-independent.\n// - For our HPSS approximation we only need a robust center value, and exact median-of-9\n// is a good tradeoff vs kernel size.\nfn median9(v0: f32, v1: f32, v2: f32, v3: f32, v4: f32, v5: f32, v6: f32, v7: f32, v8: f32) -> f32 {\n var a0 = v0; var a1 = v1; var a2 = v2;\n var a3 = v3; var a4 = v4; var a5 = v5;\n var a6 = v6; var a7 = v7; var a8 = v8;\n\n // 9-input sorting network (compare–swap stages). This is a known minimal-ish network.\n // We fully sort then take middle; cost is acceptable for 9.\n // Stage 1\n swap_if_greater(&a0,&a1); swap_if_greater(&a3,&a4); swap_if_greater(&a6,&a7);\n // Stage 2\n swap_if_greater(&a1,&a2); swap_if_greater(&a4,&a5); swap_if_greater(&a7,&a8);\n // Stage 3\n swap_if_greater(&a0,&a1); swap_if_greater(&a3,&a4); swap_if_greater(&a6,&a7);\n // Stage 4\n swap_if_greater(&a0,&a3); swap_if_greater(&a3,&a6); swap_if_greater(&a0,&a3);\n // Stage 5\n swap_if_greater(&a1,&a4); swap_if_greater(&a4,&a7); swap_if_greater(&a1,&a4);\n // Stage 6\n swap_if_greater(&a2,&a5); swap_if_greater(&a5,&a8); swap_if_greater(&a2,&a5);\n // Stage 7\n swap_if_greater(&a1,&a3); swap_if_greater(&a5,&a7);\n // Stage 8\n swap_if_greater(&a2,&a6);\n // Stage 9\n swap_if_greater(&a2,&a3); swap_if_greater(&a4,&a6);\n // Stage 10\n swap_if_greater(&a2,&a4); swap_if_greater(&a4,&a6);\n // Stage 11\n swap_if_greater(&a3,&a5); swap_if_greater(&a5,&a7);\n // Stage 12\n swap_if_greater(&a3,&a4); swap_if_greater(&a5,&a6);\n // Stage 13\n swap_if_greater(&a4,&a5);\n\n return a4;\n}\n\nfn mag_at(frame: i32, bin: i32) -> f32 {\n let f = clamp_i32(frame, 0, i32(params.nFrames) - 1);\n let b = clamp_i32(bin, 0, i32(params.nBins) - 1);\n let idx = u32(f) * params.nBins + u32(b);\n return mags[idx];\n}\n\n@compute @workgroup_size(16, 16)\nfn main(@builtin(global_invocation_id) gid : vec3<u32>) {\n let frame = gid.x;\n let bin = gid.y;\n\n if (frame >= params.nFrames || bin >= params.nBins) {\n return;\n }\n\n let f = i32(frame);\n let b = i32(bin);\n\n // Harmonic estimate: median in time over 9 taps.\n let h = median9(\n mag_at(f-4,b), mag_at(f-3,b), mag_at(f-2,b), mag_at(f-1,b), mag_at(f,b),\n mag_at(f+1,b), mag_at(f+2,b), mag_at(f+3,b), mag_at(f+4,b)\n );\n\n // Percussive estimate: median in frequency over 9 taps.\n let p = median9(\n mag_at(f,b-4), mag_at(f,b-3), mag_at(f,b-2), mag_at(f,b-1), mag_at(f,b),\n mag_at(f,b+1), mag_at(f,b+2), mag_at(f,b+3), mag_at(f,b+4)\n );\n\n let eps: f32 = 1e-12;\n let denom = max(eps, h + p);\n\n var mh = h / denom;\n var mp = p / denom;\n\n // Optional hard mask (kept for compatibility with CPU options).\n if (params.softMask == 0u) {\n let isH = h >= p;\n mh = select(0.0, 1.0, isH);\n mp = select(1.0, 0.0, isH);\n }\n\n let idx = frame * params.nBins + bin;\n harmonicMask[idx] = mh;\n percussiveMask[idx] = mp;\n}\n`;\n","import type { MirGPU } from \"./context\";\n\nimport {\n byteSizeF32,\n createAndWriteStorageBuffer,\n createReadbackBuffer,\n createStorageOutBuffer,\n createUniformBufferU32x4,\n nowMs,\n type GpuDispatchResult,\n} from \"./helpers\";\n\nimport { hpssMasksWGSL } from \"./kernels/hpssMasks.wgsl\";\n\nexport type GpuHpssMasksInput = {\n nFrames: number;\n nBins: number;\n magsFlat: Float32Array; // [frame][bin] row-major, length=nFrames*nBins\n softMask: boolean;\n};\n\nexport type GpuHpssMasksOutput = {\n harmonicMaskFlat: Float32Array; // length=nFrames*nBins\n percussiveMaskFlat: Float32Array; // length=nFrames*nBins\n};\n\n/**\n * Compute HPSS masks on the GPU.\n *\n * Notes:\n * - This stage intentionally only estimates masks. Applying masks to the original magnitude\n * spectrogram is done on CPU for clarity and to preserve existing output shapes/types.\n * - Kernel uses a fixed median-of-9 approximation (see WGSL source for details).\n */\nexport async function gpuHpssMasks(\n gpu: MirGPU,\n input: GpuHpssMasksInput\n): Promise<GpuDispatchResult<GpuHpssMasksOutput>> {\n const { device } = gpu;\n\n const { nFrames, nBins, magsFlat, softMask } = input;\n\n if (magsFlat.length !== nFrames * nBins) {\n throw new Error(\"@octoseq/mir: magsFlat length mismatch\");\n }\n\n const magsBuffer = createAndWriteStorageBuffer(gpu, magsFlat);\n\n const outByteLen = byteSizeF32(nFrames * nBins);\n const harmonicOutBuffer = createStorageOutBuffer(gpu, outByteLen);\n const percussiveOutBuffer = createStorageOutBuffer(gpu, outByteLen);\n\n const harmonicReadback = createReadbackBuffer(gpu, outByteLen);\n const percussiveReadback = createReadbackBuffer(gpu, outByteLen);\n\n const shader = device.createShaderModule({ code: hpssMasksWGSL });\n const pipeline = device.createComputePipeline({\n layout: \"auto\",\n compute: { module: shader, entryPoint: \"main\" },\n });\n\n // Params matches WGSL: (nBins, nFrames, softMaskU32, _pad)\n const params = createUniformBufferU32x4(gpu, new Uint32Array([nBins, nFrames, softMask ? 1 : 0, 0]));\n\n const bindGroup = device.createBindGroup({\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: magsBuffer } },\n { binding: 1, resource: { buffer: harmonicOutBuffer } },\n { binding: 2, resource: { buffer: percussiveOutBuffer } },\n { binding: 3, resource: { buffer: params } },\n ],\n });\n\n const encoder = device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n\n const wgX = Math.ceil(nFrames / 16);\n const wgY = Math.ceil(nBins / 16);\n pass.dispatchWorkgroups(wgX, wgY);\n pass.end();\n\n // Read back both masks from a single submission.\n encoder.copyBufferToBuffer(harmonicOutBuffer, 0, harmonicReadback, 0, outByteLen);\n encoder.copyBufferToBuffer(percussiveOutBuffer, 0, percussiveReadback, 0, outByteLen);\n\n const tSubmit = nowMs();\n gpu.queue.submit([encoder.finish()]);\n\n await Promise.all([harmonicReadback.mapAsync(GPUMapMode.READ), percussiveReadback.mapAsync(GPUMapMode.READ)]);\n const tDone = nowMs();\n\n const hBytes = harmonicReadback.getMappedRange().slice(0);\n const pBytes = percussiveReadback.getMappedRange().slice(0);\n harmonicReadback.unmap();\n percussiveReadback.unmap();\n\n magsBuffer.destroy();\n harmonicOutBuffer.destroy();\n percussiveOutBuffer.destroy();\n params.destroy();\n harmonicReadback.destroy();\n percussiveReadback.destroy();\n\n return {\n value: {\n harmonicMaskFlat: new Float32Array(hBytes),\n percussiveMaskFlat: new Float32Array(pBytes),\n },\n timing: {\n gpuSubmitToReadbackMs: tDone - tSubmit,\n },\n };\n}\n","import type { Spectrogram } from \"./spectrogram\";\nimport type { SpectrogramLike2D, HpssOptions } from \"./hpss\";\n\nimport type { MirGPU } from \"../gpu/context\";\nimport { gpuHpssMasks } from \"../gpu/hpssMasks\";\n\nexport type HpssGpuResult = {\n harmonic: SpectrogramLike2D;\n percussive: SpectrogramLike2D;\n gpuMs: number;\n};\n\nfunction flattenMagnitudes(mags: Float32Array[], nFrames: number, nBins: number): Float32Array {\n const flat = new Float32Array(nFrames * nBins);\n for (let t = 0; t < nFrames; t++) {\n const row = mags[t] ?? new Float32Array(nBins);\n flat.set(row, t * nBins);\n }\n return flat;\n}\n\nfunction assertFiniteMask(name: string, v: number): void {\n if (!Number.isFinite(v)) {\n throw new Error(`@octoseq/mir: GPU HPSS produced non-finite ${name}`);\n }\n}\n\n/**\n * GPU-accelerated HPSS (mask estimation on GPU, apply on CPU).\n *\n * Important:\n * - CPU median HPSS remains the reference implementation.\n * - GPU uses fixed median-of-9 approximation, regardless of CPU options.\n * Mapping (documented): CPU defaults (17) -> GPU fixed (9).\n */\nexport async function hpssGpu(\n spec: Spectrogram,\n gpu: MirGPU,\n options: HpssOptions = {}\n): Promise<HpssGpuResult> {\n const nFrames = spec.times.length;\n const nBins = (spec.fftSize >>> 1) + 1;\n\n if (options.isCancelled?.()) throw new Error(\"@octoseq/mir: cancelled\");\n\n // Flatten spectrogram magnitudes for GPU.\n const magsFlat = flattenMagnitudes(spec.magnitudes, nFrames, nBins);\n\n const soft = options.softMask ?? true;\n\n const masks = await gpuHpssMasks(gpu, {\n nFrames,\n nBins,\n magsFlat,\n softMask: soft,\n });\n\n if (options.isCancelled?.()) throw new Error(\"@octoseq/mir: cancelled\");\n\n const hMask = masks.value.harmonicMaskFlat;\n const pMask = masks.value.percussiveMaskFlat;\n\n const harmonic: Float32Array[] = new Array(nFrames);\n const percussive: Float32Array[] = new Array(nFrames);\n\n // Apply masks on CPU to preserve exact output shape/type.\n // We also do a best-effort cancellation check per frame.\n for (let t = 0; t < nFrames; t++) {\n if (options.isCancelled?.()) throw new Error(\"@octoseq/mir: cancelled\");\n\n const mags = spec.magnitudes[t] ?? new Float32Array(nBins);\n const outH = new Float32Array(nBins);\n const outP = new Float32Array(nBins);\n\n const base = t * nBins;\n for (let k = 0; k < nBins; k++) {\n const x = mags[k] ?? 0;\n const mh = hMask[base + k] ?? 0;\n const mp = pMask[base + k] ?? 0;\n\n assertFiniteMask(\"mask\", mh);\n assertFiniteMask(\"mask\", mp);\n\n // masks are expected in [0,1] (kernel outputs that), but clamp defensively.\n const ch = Math.max(0, Math.min(1, mh));\n const cp = Math.max(0, Math.min(1, mp));\n\n outH[k] = x * ch;\n outP[k] = x * cp;\n }\n\n harmonic[t] = outH;\n percussive[t] = outP;\n }\n\n return {\n harmonic: { times: spec.times, bins: nBins, frames: nFrames, magnitudes: harmonic },\n percussive: { times: spec.times, bins: nBins, frames: nFrames, magnitudes: percussive },\n gpuMs: masks.timing.gpuSubmitToReadbackMs,\n };\n}\n","/**\n * Windowing utilities.\n *\n * Note:\n * - The FFT implementation previously lived in this file.\n * - As of v0.1.x we use `fft.js` behind an internal backend abstraction (see `fftBackend.ts`).\n * - We keep only the window function here because it is part of the STFT behaviour that downstream\n * stages depend on.\n */\n\n// (Complex FFT implementation removed; kept intentionally empty.)\n\nexport function hannWindow(size: number): Float32Array {\n const w = new Float32Array(size);\n // Periodic Hann (common for STFT overlap-add).\n for (let n = 0; n < size; n++) {\n w[n] = 0.5 - 0.5 * Math.cos((2 * Math.PI * n) / size);\n }\n return w;\n}\n\n// FFT and magnitude helpers removed.\n","/**\n * `fft.js` backend.\n *\n * Notes:\n * - We intentionally keep this file small and self-contained so we can replace it later with a GPU FFT.\n * - `fft.js` performs an unnormalised forward FFT (same convention as our previous radix-2 code).\n * - We allocate the plan once per fftSize and reuse internal buffers across frames.\n */\n\nimport FFT from \"fft.js\";\n\nimport type { FftBackend, FftComplexOutput } from \"./fftBackend\";\n\nexport function createFftJsBackend(fftSize: number): FftBackend {\n if (!Number.isFinite(fftSize) || fftSize <= 0 || (fftSize | 0) !== fftSize) {\n throw new Error(\"@octoseq/mir: fftSize must be a positive integer\");\n }\n\n const fft = new FFT(fftSize);\n\n // `fft.js` uses interleaved complex arrays [re0, im0, re1, im1, ...]\n // It accepts input for realTransform as a real array of length N.\n const inReal = new Float32Array(fftSize);\n const outComplexInterleaved = fft.createComplexArray() as unknown as Float32Array;\n\n const outReal = new Float32Array(fftSize);\n const outImag = new Float32Array(fftSize);\n\n return {\n fftSize,\n forwardReal(frame: Float32Array): FftComplexOutput {\n if (frame.length !== fftSize) {\n throw new Error(\n `@octoseq/mir: FFT input length (${frame.length}) must equal fftSize (${fftSize})`\n );\n }\n\n // Copy to stable buffer to avoid fft.js mutating user-owned arrays.\n inReal.set(frame);\n\n // Real-input FFT.\n // `realTransform(out, data)` fills out with interleaved complex spectrum.\n // `completeSpectrum(out)` fills the negative frequencies so we get full N complex bins.\n fft.realTransform(outComplexInterleaved as unknown as number[], inReal as unknown as number[]);\n fft.completeSpectrum(outComplexInterleaved as unknown as number[]);\n\n // De-interleave into (real, imag) arrays.\n // Note: we keep full spectrum even though most consumers only need 0..N/2.\n for (let k = 0; k < fftSize; k++) {\n const re = outComplexInterleaved[2 * k] ?? 0;\n const im = outComplexInterleaved[2 * k + 1] ?? 0;\n // Canonicalise -0 -> +0 so silence tests and downstream comparisons are stable.\n outReal[k] = re === 0 ? 0 : re;\n outImag[k] = im === 0 ? 0 : im;\n }\n\n return { real: outReal, imag: outImag };\n }\n };\n}\n","/**\n * Internal FFT backend abstraction.\n *\n * Why:\n * - The rest of the STFT pipeline should not care about the FFT implementation.\n * - We want to be able to swap this layer for a future WebGPU FFT without touching callers.\n */\n\nexport type FftComplexOutput = {\n /** Full-length FFT output (length = fftSize). */\n real: Float32Array;\n /** Full-length FFT output (length = fftSize). */\n imag: Float32Array;\n};\n\nexport interface FftBackend {\n readonly fftSize: number;\n\n /**\n * Forward FFT for real-valued input.\n *\n * Contract:\n * - input length must equal fftSize.\n * - returns full complex spectrum (not just rfft half-spectrum) to keep the interface generic.\n *\n * Scaling:\n * - No normalisation is applied (same convention as typical FFT libraries, incl. fft.js).\n * - Therefore magnitude values scale roughly with window sum and fftSize.\n * This matches the previous hand-rolled FFT behaviour and is close to librosa's default\n * `np.abs(np.fft.rfft(...))` magnitude semantics (also unnormalised).\n */\n forwardReal(input: Float32Array): FftComplexOutput;\n}\n\n/**\n * Internal cache to avoid re-creating FFT plans for the same size.\n * Safe for Web Workers (per-worker module instance). Not shared across threads.\n */\nconst backendCache = new Map<number, FftBackend>();\n\nexport function getFftBackend(fftSize: number): FftBackend {\n const existing = backendCache.get(fftSize);\n if (existing) return existing;\n\n // Note: ESM static import is OK in browsers and Web Workers.\n // The cache ensures the plan is only created once per fftSize per worker.\n const created = createFftJsBackend(fftSize);\n backendCache.set(fftSize, created);\n return created;\n}\n\n// Implemented in separate file to keep the public surface minimal.\nimport { createFftJsBackend } from \"./fftBackendFftjs\";\n","import type { MirGPU } from \"../gpu/context\";\n\nimport { hannWindow } from \"./fft\";\nimport { getFftBackend } from \"./fftBackend\";\n\n// AudioBufferLike is re-exported from the package root.\n// Keeping this local type avoids importing from ../index (which can create circular deps).\nexport type AudioBufferLike = {\n sampleRate: number;\n getChannelData(channel: number): Float32Array;\n numberOfChannels: number;\n};\n\nexport type SpectrogramConfig = {\n fftSize: number;\n hopSize: number;\n window: \"hann\";\n};\n\nexport type SpectrogramOptions = {\n /** Optional cancellation hook; checked once per frame. */\n isCancelled?: () => boolean;\n};\n\nexport type Spectrogram = {\n sampleRate: number;\n fftSize: number;\n hopSize: number;\n times: Float32Array; // seconds (center of each frame)\n magnitudes: Float32Array[]; // [frame][bin]\n};\n\nfunction assertPositiveInt(name: string, value: number): void {\n if (!Number.isFinite(value) || value <= 0 || (value | 0) !== value) {\n throw new Error(`@octoseq/mir: ${name} must be a positive integer`);\n }\n}\n\nfunction mixToMono(audio: AudioBufferLike): Float32Array {\n const nCh = audio.numberOfChannels;\n if (nCh <= 0) {\n throw new Error(\"@octoseq/mir: audio.numberOfChannels must be >= 1\");\n }\n\n if (nCh === 1) {\n return audio.getChannelData(0);\n }\n\n const length = audio.getChannelData(0).length;\n const out = new Float32Array(length);\n\n for (let ch = 0; ch < nCh; ch++) {\n const data = audio.getChannelData(ch);\n if (data.length !== length) {\n throw new Error(\n \"@octoseq/mir: all channels must have equal length (AudioBuffer-like invariant)\"\n );\n }\n for (let i = 0; i < length; i++) {\n // `out[i]` is `number|undefined` under `noUncheckedIndexedAccess`.\n out[i] = (out[i] ?? 0) + (data[i] ?? 0);\n }\n }\n\n const inv = 1 / nCh;\n for (let i = 0; i < length; i++) out[i] = (out[i] ?? 0) * inv;\n\n return out;\n}\n\n/**\n * Compute a magnitude spectrogram.\n *\n * v0.1 implementation:\n * - CPU STFT + FFT for correctness.\n * - The function accepts an optional MirGPU to match the future API.\n * (STFT/FFT is the largest dense math block and can be ported to WebGPU later.)\n */\nexport async function spectrogram(\n audio: AudioBufferLike,\n config: SpectrogramConfig,\n gpu?: MirGPU,\n options: SpectrogramOptions = {}\n): Promise<Spectrogram> {\n // Keep the parameter to make the expensive step explicitly reusable.\n // (v0.1 computes FFT on CPU; GPU is accepted for future acceleration.)\n void gpu;\n\n assertPositiveInt(\"config.fftSize\", config.fftSize);\n assertPositiveInt(\"config.hopSize\", config.hopSize);\n\n if (config.window !== \"hann\") {\n throw new Error(\n `@octoseq/mir: unsupported window '${config.window}'. v0.1 supports only 'hann'.`\n );\n }\n\n const fftSize = config.fftSize;\n if ((fftSize & (fftSize - 1)) !== 0) {\n throw new Error(\"@octoseq/mir: config.fftSize must be a power of two\");\n }\n\n const hopSize = config.hopSize;\n if (hopSize > fftSize) {\n throw new Error(\n \"@octoseq/mir: config.hopSize must be <= config.fftSize\"\n );\n }\n\n const sr = audio.sampleRate;\n const mono = mixToMono(audio);\n\n // Number of frames with 'valid' windows.\n // We prefer explicitness over padding for v0.1.\n const nFrames = Math.max(0, 1 + Math.floor((mono.length - fftSize) / hopSize));\n\n const times = new Float32Array(nFrames);\n const mags: Float32Array[] = new Array(nFrames);\n\n const window = hannWindow(fftSize);\n\n // Reuse FFT plan and buffers across frames.\n const fft = getFftBackend(fftSize);\n\n // Preallocate frame buffer so we don't allocate per frame.\n const windowedFrame = new Float32Array(fftSize);\n\n // Minimal timing instrumentation. This is deliberately lightweight and only used\n // for optional debug logging by callers (e.g. worker). We don't expose this in the public API.\n let totalFftMs = 0;\n const nowMs = (): number =>\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\n\n for (let frame = 0; frame < nFrames; frame++) {\n if (options.isCancelled?.()) {\n throw new Error(\"@octoseq/mir: cancelled\");\n }\n const start = frame * hopSize;\n\n // time is the center of the analysis window.\n times[frame] = (start + fftSize / 2) / sr;\n\n // Apply windowing before FFT (same as previous implementation).\n for (let i = 0; i < fftSize; i++) {\n const s = mono[start + i] ?? 0;\n windowedFrame[i] = s * (window[i] ?? 0);\n }\n\n const t0 = nowMs();\n const { real, imag } = fft.forwardReal(windowedFrame);\n totalFftMs += nowMs() - t0;\n\n // Magnitudes: only keep the real-input half-spectrum [0..N/2] inclusive.\n const nBins = (fftSize >>> 1) + 1;\n const out = new Float32Array(nBins);\n for (let k = 0; k < nBins; k++) {\n const re = real[k] ?? 0;\n const im = imag[k] ?? 0;\n out[k] = Math.hypot(re, im);\n }\n mags[frame] = out;\n }\n\n // Attach as a non-enumerable debug field to avoid API changes.\n // Consumers can optionally read it for profiling in development.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (mags as any).cpuFftTotalMs = totalFftMs;\n\n return {\n sampleRate: sr,\n fftSize,\n hopSize,\n times,\n magnitudes: mags\n };\n}\n","import { detectBeatCandidates } from \"../dsp/beatCandidates\";\nimport { generateTempoHypotheses } from \"../dsp/tempoHypotheses\";\nimport { melSpectrogram, type MelConfig, type MelSpectrogram } from \"../dsp/mel\";\nimport { mfcc, delta, deltaDelta } from \"../dsp/mfcc\";\nimport { onsetEnvelopeFromMel, onsetEnvelopeFromMelGpu } from \"../dsp/onset\";\nimport { peakPick } from \"../dsp/peakPick\";\nimport { hpss } from \"../dsp/hpss\";\nimport { hpssGpu } from \"../dsp/hpssGpu\";\nimport { spectralCentroid, spectralFlux } from \"../dsp/spectral\";\nimport { spectrogram, type AudioBufferLike, type Spectrogram, type SpectrogramConfig } from \"../dsp/spectrogram\";\nimport type { MirGPU } from \"../gpu/context\";\nimport type { MirAudioPayload, MirBackend, MirResult, MirRunRequest } from \"../types\";\n\nfunction nowMs(): number {\n return typeof performance !== \"undefined\" ? performance.now() : Date.now();\n}\n\nfunction asAudioBufferLike(audio: MirAudioPayload): AudioBufferLike {\n return {\n sampleRate: audio.sampleRate,\n numberOfChannels: 1,\n getChannelData: () => audio.mono,\n };\n}\n\nexport type RunMirOptions = {\n gpu?: MirGPU;\n /** If provided, long loops should periodically call this and abort if true. */\n isCancelled?: () => boolean;\n /** If true and backend==='gpu', do not silently fall back to CPU on GPU errors. */\n strictGpu?: boolean;\n\n // v0.1 feature-specific options (kept minimal; UI provides basic controls)\n onset?: {\n smoothMs?: number;\n diffMethod?: \"rectified\" | \"abs\";\n useLog?: boolean;\n };\n peakPick?: {\n minIntervalSec?: number;\n threshold?: number;\n adaptiveFactor?: number;\n };\n hpss?: {\n timeMedian?: number;\n freqMedian?: number;\n spectrogram?: SpectrogramConfig;\n };\n mfcc?: {\n nCoeffs?: number;\n spectrogram?: SpectrogramConfig;\n };\n};\n\n// Backwards-compat export alias (some earlier tasks referenced this name).\nexport type RunMirBackendOptions = RunMirOptions;\n\n/**\n * Shared MIR execution entrypoint used by the main thread and by the worker.\n *\n * Notes:\n * - We keep FFT/STFT on CPU for now (spectrogram()), but allow one downstream stage\n * (mel projection) to run on real WebGPU via `melSpectrogram(spec, config, gpu)`.\n */\nexport async function runMir(\n audio: MirAudioPayload,\n request: MirRunRequest,\n options: RunMirOptions = {}\n): Promise<MirResult> {\n // Allow callers to pass per-run config via the request (needed for worker runs).\n // If both are provided, `options.*` wins.\n options = {\n ...options,\n onset: { ...request.onset, ...options.onset },\n peakPick: { ...request.peakPick, ...options.peakPick },\n hpss: { ...request.hpss, ...options.hpss },\n mfcc: { ...request.mfcc, ...options.mfcc },\n };\n const t0 = nowMs();\n\n const backend: MirBackend = request.backend ?? \"cpu\";\n\n const specConfig: SpectrogramConfig = request.spectrogram ?? {\n fftSize: 2048,\n hopSize: 512,\n window: \"hann\",\n };\n\n // CPU: spectrogram + centroid/flux are CPU-only today.\n const cpuStart = nowMs();\n const spec: Spectrogram = await spectrogram(asAudioBufferLike(audio), specConfig, undefined, {\n isCancelled: options.isCancelled,\n });\n const cpuAfterSpec = nowMs();\n\n if (options.isCancelled?.()) {\n throw new Error(\"@octoseq/mir: cancelled\");\n }\n\n if (request.fn === \"spectralCentroid\") {\n const values = spectralCentroid(spec);\n const cpuEnd = nowMs();\n return {\n kind: \"1d\",\n times: spec.times,\n values,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: {\n totalMs: cpuEnd - t0,\n cpuMs: cpuEnd - cpuStart,\n },\n },\n };\n }\n\n if (request.fn === \"spectralFlux\") {\n const values = spectralFlux(spec);\n const cpuEnd = nowMs();\n return {\n kind: \"1d\",\n times: spec.times,\n values,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: {\n totalMs: cpuEnd - t0,\n cpuMs: cpuEnd - cpuStart,\n },\n },\n };\n }\n\n // melSpectrogram\n const melConfig: MelConfig = request.mel ?? { nMels: 64 };\n\n // Helper: compute mel (possibly GPU-accelerated projection).\n const computeMel = async (useGpu: boolean): Promise<{ mel: MelSpectrogram; usedGpu: boolean; gpuMs?: number; cpuExtraMs: number }> => {\n const melCpuStart = nowMs();\n\n if (useGpu) {\n if (!options.gpu) {\n throw new Error(\"@octoseq/mir: backend='gpu' requested but no MirGPU provided\");\n }\n\n const gpuStart = nowMs();\n try {\n const mel = await melSpectrogram(spec, melConfig, options.gpu);\n const gpuEnd = nowMs();\n const gpuKernelMs = mel.gpuTimings?.gpuSubmitToReadbackMs;\n\n return {\n mel,\n usedGpu: true,\n gpuMs: gpuKernelMs ?? gpuEnd - gpuStart,\n cpuExtraMs: nowMs() - melCpuStart - (gpuEnd - gpuStart),\n };\n } catch (e) {\n if (options.strictGpu) throw e;\n // fall back to CPU\n }\n }\n\n const mel = await melSpectrogram(spec, melConfig, undefined);\n const melCpuEnd = nowMs();\n\n return {\n mel,\n usedGpu: false,\n cpuExtraMs: melCpuEnd - melCpuStart,\n };\n };\n\n // Branch by fn.\n if (request.fn === \"melSpectrogram\") {\n const { mel, usedGpu, gpuMs, cpuExtraMs } = await computeMel(backend === \"gpu\");\n const end = nowMs();\n\n return {\n kind: \"2d\",\n times: mel.times,\n data: mel.melBands,\n meta: {\n backend: usedGpu ? \"gpu\" : \"cpu\",\n usedGpu,\n timings: {\n totalMs: end - t0,\n cpuMs: cpuAfterSpec - cpuStart + cpuExtraMs,\n gpuMs,\n },\n },\n };\n }\n\n if (request.fn === \"onsetEnvelope\") {\n // For this milestone we compute onset from mel by default.\n // GPU path: diff+reduction kernel on melFlat.\n if (backend === \"gpu\") {\n if (!options.gpu) throw new Error(\"@octoseq/mir: backend='gpu' requested but no MirGPU provided\");\n\n const { mel, usedGpu: usedGpuForMel, gpuMs: melGpuMs, cpuExtraMs: melCpuMs } = await computeMel(true);\n\n const onsetStart = nowMs();\n try {\n const onsetGpu = await onsetEnvelopeFromMelGpu(mel, options.gpu, {\n diffMethod: options.onset?.diffMethod,\n });\n const end = nowMs();\n\n return {\n kind: \"1d\",\n times: onsetGpu.times,\n values: onsetGpu.values,\n meta: {\n backend: \"gpu\",\n usedGpu: true,\n timings: {\n totalMs: end - t0,\n cpuMs: cpuAfterSpec - cpuStart + melCpuMs,\n gpuMs: (melGpuMs ?? 0) + onsetGpu.gpuTimings.gpuSubmitToReadbackMs,\n },\n },\n };\n } catch (e) {\n if (options.strictGpu) throw e;\n // fallback to CPU onset\n void usedGpuForMel;\n } finally {\n void onsetStart;\n }\n }\n\n const { mel, cpuExtraMs: melCpuMs } = await computeMel(false);\n const onset = onsetEnvelopeFromMel(mel, {\n smoothMs: options.onset?.smoothMs,\n diffMethod: options.onset?.diffMethod,\n useLog: options.onset?.useLog,\n });\n const end = nowMs();\n\n return {\n kind: \"1d\",\n times: onset.times,\n values: onset.values,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: {\n totalMs: end - t0,\n cpuMs: cpuAfterSpec - cpuStart + melCpuMs,\n },\n },\n };\n }\n\n if (request.fn === \"onsetPeaks\") {\n const { mel, cpuExtraMs: melCpuMs } = await computeMel(false);\n const onset = onsetEnvelopeFromMel(mel, {\n smoothMs: options.onset?.smoothMs,\n diffMethod: options.onset?.diffMethod,\n useLog: options.onset?.useLog,\n });\n\n const events = peakPick(onset.times, onset.values, {\n minIntervalSec: options.peakPick?.minIntervalSec,\n threshold: options.peakPick?.threshold,\n adaptive: options.peakPick?.adaptiveFactor\n ? { method: \"meanStd\", factor: options.peakPick.adaptiveFactor }\n : undefined,\n });\n\n const end = nowMs();\n return {\n kind: \"events\",\n times: onset.times,\n events,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: {\n totalMs: end - t0,\n cpuMs: cpuAfterSpec - cpuStart + melCpuMs,\n },\n },\n };\n }\n\n if (request.fn === \"beatCandidates\") {\n // Beat candidate detection requires both mel spectrogram and raw spectrogram.\n const { mel, cpuExtraMs: melCpuMs } = await computeMel(false);\n\n const beatOpts = request.beatCandidates ?? {};\n const result = detectBeatCandidates(mel, spec, {\n minIntervalSec: beatOpts.minIntervalSec,\n thresholdFactor: beatOpts.thresholdFactor,\n smoothMs: beatOpts.smoothMs,\n });\n\n const end = nowMs();\n return {\n kind: \"beatCandidates\",\n times: result.salience.times,\n candidates: result.candidates,\n salience: beatOpts.includeSalience ? result.salience : undefined,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: {\n totalMs: end - t0,\n cpuMs: cpuAfterSpec - cpuStart + melCpuMs,\n },\n },\n };\n }\n\n if (request.fn === \"tempoHypotheses\") {\n // Tempo hypothesis generation requires beat candidates.\n // We compute them internally (could accept pre-computed in future).\n const { mel, cpuExtraMs: melCpuMs } = await computeMel(false);\n\n const beatOpts = request.beatCandidates ?? {};\n const beatResult = detectBeatCandidates(mel, spec, {\n minIntervalSec: beatOpts.minIntervalSec,\n thresholdFactor: beatOpts.thresholdFactor,\n smoothMs: beatOpts.smoothMs,\n });\n\n const tempoStart = nowMs();\n const tempoOpts = request.tempoHypotheses ?? {};\n const result = generateTempoHypotheses(beatResult.candidates, {\n minBpm: tempoOpts.minBpm,\n maxBpm: tempoOpts.maxBpm,\n binSizeBpm: tempoOpts.binSizeBpm,\n maxHypotheses: tempoOpts.maxHypotheses,\n minConfidence: tempoOpts.minConfidence,\n weightByStrength: tempoOpts.weightByStrength,\n includeHistogram: tempoOpts.includeHistogram,\n });\n\n const end = nowMs();\n return {\n kind: \"tempoHypotheses\",\n times: spec.times,\n hypotheses: result.hypotheses,\n inputCandidateCount: result.inputCandidateCount,\n histogram: result.histogram,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: {\n totalMs: end - t0,\n cpuMs: cpuAfterSpec - cpuStart + melCpuMs + (end - tempoStart),\n },\n },\n };\n }\n\n if (request.fn === \"hpssHarmonic\" || request.fn === \"hpssPercussive\") {\n // HPSS may use a custom spectrogram config\n const hpssSpecConfig = options.hpss?.spectrogram ?? specConfig;\n const needsHpssSpec = hpssSpecConfig.fftSize !== specConfig.fftSize || hpssSpecConfig.hopSize !== specConfig.hopSize;\n\n let hpssSpec: Spectrogram;\n let hpssCpuStart = cpuAfterSpec;\n\n if (needsHpssSpec) {\n hpssCpuStart = nowMs();\n hpssSpec = await spectrogram(asAudioBufferLike(audio), hpssSpecConfig, undefined, {\n isCancelled: options.isCancelled,\n });\n } else {\n hpssSpec = spec;\n }\n const hpssAfterSpec = nowMs();\n\n // HPSS is CPU-heavy; we optionally accelerate mask estimation with WebGPU.\n // CPU path remains the reference implementation and is used as fallback.\n if (backend === \"gpu\") {\n if (!options.gpu) throw new Error(\"@octoseq/mir: backend='gpu' requested but no MirGPU provided\");\n\n const hpssStart = nowMs();\n try {\n const out = await hpssGpu(hpssSpec, options.gpu, {\n timeMedian: options.hpss?.timeMedian,\n freqMedian: options.hpss?.freqMedian,\n softMask: true, // preserve CPU default\n isCancelled: options.isCancelled,\n });\n const end = nowMs();\n\n const chosen = request.fn === \"hpssHarmonic\" ? out.harmonic : out.percussive;\n return {\n kind: \"2d\",\n times: chosen.times,\n data: chosen.magnitudes,\n meta: {\n backend: \"gpu\",\n usedGpu: true,\n timings: {\n totalMs: end - t0,\n cpuMs: (needsHpssSpec ? hpssAfterSpec - hpssCpuStart : cpuAfterSpec - cpuStart) + ((end - hpssStart) - out.gpuMs),\n gpuMs: out.gpuMs,\n },\n },\n };\n } catch (e) {\n if (options.strictGpu) throw e;\n // fall back to CPU HPSS\n }\n }\n\n const hpssStart = nowMs();\n const { harmonic, percussive } = hpss(hpssSpec, {\n timeMedian: options.hpss?.timeMedian,\n freqMedian: options.hpss?.freqMedian,\n isCancelled: options.isCancelled,\n });\n const end = nowMs();\n const cpuMs = (needsHpssSpec ? hpssAfterSpec - hpssCpuStart : cpuAfterSpec - cpuStart) + (end - hpssStart);\n\n const chosen = request.fn === \"hpssHarmonic\" ? harmonic : percussive;\n return {\n kind: \"2d\",\n times: chosen.times,\n data: chosen.magnitudes,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: { totalMs: end - t0, cpuMs },\n },\n };\n }\n\n if (request.fn === \"mfcc\" || request.fn === \"mfccDelta\" || request.fn === \"mfccDeltaDelta\") {\n // MFCC may use a custom spectrogram config\n const mfccSpecConfig = options.mfcc?.spectrogram ?? specConfig;\n const needsMfccSpec = mfccSpecConfig.fftSize !== specConfig.fftSize || mfccSpecConfig.hopSize !== specConfig.hopSize;\n\n let mfccMel: MelSpectrogram;\n let mfccCpuMs: number;\n\n if (needsMfccSpec) {\n const mfccCpuStart = nowMs();\n const mfccSpec = await spectrogram(asAudioBufferLike(audio), mfccSpecConfig, undefined, {\n isCancelled: options.isCancelled,\n });\n const mfccMelResult = await melSpectrogram(mfccSpec, melConfig, undefined);\n mfccMel = mfccMelResult;\n mfccCpuMs = nowMs() - mfccCpuStart;\n } else {\n const { mel, cpuExtraMs } = await computeMel(false);\n mfccMel = mel;\n mfccCpuMs = cpuAfterSpec - cpuStart + cpuExtraMs;\n }\n\n const mfccStart = nowMs();\n const base = mfcc(mfccMel, { nCoeffs: options.mfcc?.nCoeffs });\n\n const features = { times: base.times, values: base.coeffs };\n const chosen =\n request.fn === \"mfcc\"\n ? features\n : request.fn === \"mfccDelta\"\n ? delta(features)\n : deltaDelta(features);\n\n const end = nowMs();\n return {\n kind: \"2d\",\n times: chosen.times,\n data: chosen.values,\n meta: {\n backend: \"cpu\",\n usedGpu: false,\n timings: {\n totalMs: end - t0,\n cpuMs: mfccCpuMs + (end - mfccStart),\n },\n },\n };\n }\n\n // Fallback: keep old behaviour (melSpectrogram) if unknown fn.\n const { mel, usedGpu, gpuMs, cpuExtraMs } = await computeMel(backend === \"gpu\");\n const end = nowMs();\n\n return {\n kind: \"2d\",\n times: mel.times,\n data: mel.melBands,\n meta: {\n backend: usedGpu ? \"gpu\" : \"cpu\",\n usedGpu,\n timings: {\n totalMs: end - t0,\n cpuMs: cpuAfterSpec - cpuStart + cpuExtraMs,\n gpuMs,\n },\n },\n };\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
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';
1
+ import { B as BeatCandidate, T as TempoHypothesis } from './types-4bAZI4F7.js';
2
+ export { i as BeatCandidateSource, j as BeatCandidatesResult, 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, l as TempoHypothesesResult, k as TempoHypothesisEvidence } from './types-4bAZI4F7.js';
3
+ import { S as Spectrogram, M as MirGPU } from './runMir-CVEIxPd3.js';
4
+ export { a as SpectrogramConfig, r as runMir, s as spectrogram } from './runMir-CVEIxPd3.js';
4
5
 
5
6
  /**
6
7
  * Spectral centroid per frame (Hz).
@@ -92,6 +93,116 @@ type PeakPickOptions = {
92
93
  };
93
94
  declare function peakPick(times: Float32Array, values: Float32Array, options?: PeakPickOptions): PeakPickEvent[];
94
95
 
96
+ /**
97
+ * Configuration for beat candidate detection.
98
+ */
99
+ type BeatCandidatesOptions = {
100
+ /** Minimum inter-candidate interval in seconds. Default: 0.1 (100ms). */
101
+ minIntervalSec?: number;
102
+ /** Threshold factor for adaptive peak detection. Lower = more candidates. Default: 0.5. */
103
+ thresholdFactor?: number;
104
+ /** Smoothing window for salience signal in ms. Default: 50. */
105
+ smoothMs?: number;
106
+ };
107
+ /**
108
+ * Result of beat candidate detection.
109
+ */
110
+ type BeatCandidatesOutput = {
111
+ candidates: BeatCandidate[];
112
+ /** The computed salience signal (for debugging/visualization). */
113
+ salience: {
114
+ times: Float32Array;
115
+ values: Float32Array;
116
+ };
117
+ };
118
+ /**
119
+ * Compute a beat-oriented salience signal from mel spectrogram.
120
+ *
121
+ * This combines:
122
+ * - Onset envelope (captures transients/attacks)
123
+ * - Spectral flux from the underlying spectrogram (captures spectral change)
124
+ *
125
+ * The signals are normalized and combined to produce a single salience curve
126
+ * suitable for peak picking.
127
+ *
128
+ * Key design choices:
129
+ * - Whole-track normalization (z-score) for consistent behavior
130
+ * - Gentle smoothing to suppress micro-transients while preserving beat structure
131
+ * - No BPM inference or grid assumptions
132
+ */
133
+ type BeatSalienceSignal = {
134
+ times: Float32Array;
135
+ values: Float32Array;
136
+ };
137
+ /**
138
+ * Compute beat salience signal from mel spectrogram.
139
+ *
140
+ * This is an intermediate signal suitable for peak picking to extract
141
+ * beat candidates. It combines onset envelope with additional smoothing
142
+ * tuned for beat-like (rather than onset-like) detection.
143
+ */
144
+ declare function beatSalienceFromMel(mel: MelSpectrogram, spec: Spectrogram, options?: {
145
+ smoothMs?: number;
146
+ }): BeatSalienceSignal;
147
+ /**
148
+ * Detect beat candidates from mel spectrogram and spectrogram.
149
+ *
150
+ * This is the main entry point for beat candidate detection.
151
+ *
152
+ * Design principles:
153
+ * - Dense candidates (err on side of too many)
154
+ * - No BPM inference
155
+ * - No grid assumptions
156
+ * - Whole-track normalization for consistency
157
+ * - Deterministic (same input -> same output)
158
+ */
159
+ declare function detectBeatCandidates(mel: MelSpectrogram, spec: Spectrogram, options?: BeatCandidatesOptions): BeatCandidatesOutput;
160
+
161
+ /**
162
+ * Configuration for tempo hypothesis generation.
163
+ */
164
+ type TempoHypothesesOptions = {
165
+ /** Minimum BPM to consider. Default: 24. */
166
+ minBpm?: number;
167
+ /** Maximum BPM to consider. Default: 300. */
168
+ maxBpm?: number;
169
+ /** Histogram bin size in BPM. Default: 1.0. */
170
+ binSizeBpm?: number;
171
+ /** Maximum hypotheses to return. Default: 10. */
172
+ maxHypotheses?: number;
173
+ /** Minimum confidence threshold (0-1). Default: 0.05. */
174
+ minConfidence?: number;
175
+ /** Weight IOIs by candidate strength. Default: true. */
176
+ weightByStrength?: boolean;
177
+ /** Include histogram data in output. Default: false. */
178
+ includeHistogram?: boolean;
179
+ };
180
+ type TempoHypothesesOutput = {
181
+ hypotheses: TempoHypothesis[];
182
+ inputCandidateCount: number;
183
+ histogram?: {
184
+ bpmBins: Float32Array;
185
+ counts: Float32Array;
186
+ };
187
+ };
188
+ /**
189
+ * Generate tempo hypotheses from beat candidates.
190
+ *
191
+ * Algorithm:
192
+ * 1. Compute inter-onset intervals (IOIs) from beat candidates
193
+ * 2. Filter IOIs to musically plausible range (0.2s-2.5s -> 24-300 BPM)
194
+ * 3. Build weighted histogram with configurable bin size
195
+ * 4. Extract peaks as tempo candidates
196
+ * 5. Refine BPM estimates using weighted centroid
197
+ * 6. Group into harmonic families
198
+ * 7. Normalize confidence scores
199
+ *
200
+ * @param candidates - Beat candidates from B1
201
+ * @param options - Configuration options
202
+ * @returns Tempo hypotheses with confidence and family groupings
203
+ */
204
+ declare function generateTempoHypotheses(candidates: BeatCandidate[], options?: TempoHypothesesOptions): TempoHypothesesOutput;
205
+
95
206
  type SpectrogramLike2D = {
96
207
  times: Float32Array;
97
208
  bins: number;
@@ -447,4 +558,4 @@ type AudioBufferLike = {
447
558
  */
448
559
  declare function helloMir(name?: string): string;
449
560
 
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 };
561
+ export { type AudioBufferLike, BeatCandidate, type BeatCandidatesOptions, type BeatCandidatesOutput, type BeatSalienceSignal, 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, type TempoHypothesesOptions, type TempoHypothesesOutput, TempoHypothesis, beatSalienceFromMel, clampDb, delta, deltaDelta, detectBeatCandidates, fingerprintToVectorV1, fingerprintV1, generateTempoHypotheses, helloMir, hpss, melSpectrogram, mfcc, minMax, normaliseForWaveform, onsetEnvelopeFromMel, onsetEnvelopeFromMelGpu, onsetEnvelopeFromSpectrogram, peakPick, searchTrackV1, searchTrackV1Guided, similarityFingerprintV1, spectralCentroid, spectralFlux, spectrogramToDb };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { peakPick } from './chunk-DUWYCAVG.js';
2
- export { delta, deltaDelta, hpss, melSpectrogram, mfcc, onsetEnvelopeFromMel, onsetEnvelopeFromMelGpu, onsetEnvelopeFromSpectrogram, peakPick, runMir, spectralCentroid, spectralFlux, spectrogram } from './chunk-DUWYCAVG.js';
1
+ import { peakPick } from './chunk-KIGWMJLC.js';
2
+ export { beatSalienceFromMel, delta, deltaDelta, detectBeatCandidates, generateTempoHypotheses, hpss, melSpectrogram, mfcc, onsetEnvelopeFromMel, onsetEnvelopeFromMelGpu, onsetEnvelopeFromSpectrogram, peakPick, runMir, spectralCentroid, spectralFlux, spectrogram } from './chunk-KIGWMJLC.js';
3
3
 
4
4
  // src/gpu/context.ts
5
5
  var MirGPU = class _MirGPU {