@octoseq/mir 0.1.0-main.994cb4e → 0.1.0-main.9ea6d2e

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.
package/src/index.ts CHANGED
@@ -35,8 +35,14 @@ export type {
35
35
  FrequencyKeyframe,
36
36
  // Band-Scoped MIR (F3)
37
37
  BandMirFunctionId,
38
+ BandCqtFunctionId,
39
+ BandEventFunctionId,
38
40
  BandMirDiagnostics,
39
41
  BandMir1DResult,
42
+ BandCqt1DResult,
43
+ BandMirEvent,
44
+ BandEventDiagnostics,
45
+ BandEventsResult,
40
46
  // CQT (F5)
41
47
  CqtConfig,
42
48
  CqtSpectrogram,
@@ -84,7 +90,8 @@ export { spectrogram } from "./dsp/spectrogram";
84
90
  // Derived spectral features (CPU, reuse spectrogram)
85
91
  // ----------------------------
86
92
 
87
- export { spectralCentroid, spectralFlux } from "./dsp/spectral";
93
+ export type { AmplitudeEnvelopeConfig, AmplitudeEnvelopeResult } from "./dsp/spectral";
94
+ export { amplitudeEnvelope, spectralCentroid, spectralFlux } from "./dsp/spectral";
88
95
 
89
96
  // ----------------------------
90
97
  // Onsets / Peaks
@@ -116,6 +123,22 @@ export { generateTempoHypotheses } from "./dsp/tempoHypotheses";
116
123
 
117
124
  export { computePhaseHypotheses, generateBeatTimes } from "./dsp/phaseAlignment";
118
125
 
126
+ // ----------------------------
127
+ // Peak Picking
128
+ // ----------------------------
129
+
130
+ export {
131
+ pickPeaks,
132
+ pickPeaksAdaptive,
133
+ computeAdaptiveThreshold,
134
+ applyHysteresisGate,
135
+ DEFAULT_PEAK_PICKING_PARAMS,
136
+ type PeakPickingParams,
137
+ type PeakPickingResult,
138
+ type AdaptivePeakPickingResult,
139
+ type HysteresisGateParams,
140
+ } from "./dsp/peakPicking";
141
+
119
142
  // ----------------------------
120
143
  // Musical Time (B4)
121
144
  // ----------------------------
@@ -191,10 +214,47 @@ export {
191
214
  bandAmplitudeEnvelope,
192
215
  bandOnsetStrength,
193
216
  bandSpectralFlux,
217
+ bandSpectralCentroid,
194
218
  runBandMirBatch,
195
219
  getBandMirFunctionLabel,
196
220
  } from "./dsp/bandMir";
197
221
 
222
+ // ----------------------------
223
+ // Band Events (F3)
224
+ // ----------------------------
225
+
226
+ export type {
227
+ BandOnsetPeaksOptions,
228
+ BandBeatCandidatesOptions,
229
+ BandEventsBatchRequest,
230
+ BandEventsBatchResult,
231
+ } from "./dsp/bandEvents";
232
+ export {
233
+ bandOnsetPeaks,
234
+ bandBeatCandidates,
235
+ runBandEventsBatch,
236
+ getBandEventFunctionLabel,
237
+ } from "./dsp/bandEvents";
238
+
239
+ // ----------------------------
240
+ // Band CQT (F3)
241
+ // ----------------------------
242
+
243
+ export type {
244
+ BandCqtOptions,
245
+ MaskedCqtSpectrogram,
246
+ BandCqtBatchRequest,
247
+ BandCqtBatchResult,
248
+ } from "./dsp/bandCqt";
249
+ export {
250
+ applyBandMaskToCqt,
251
+ bandCqtHarmonicEnergy,
252
+ bandCqtBassPitchMotion,
253
+ bandCqtTonalStability,
254
+ runBandCqtBatch,
255
+ getBandCqtFunctionLabel,
256
+ } from "./dsp/bandCqt";
257
+
198
258
  // ----------------------------
199
259
  // HPSS
200
260
  // ----------------------------
@@ -248,6 +308,38 @@ export {
248
308
  export type { BandProposalOptions } from "./dsp/bandProposal";
249
309
  export { generateBandProposals } from "./dsp/bandProposal";
250
310
 
311
+ // ----------------------------
312
+ // Custom Signal Reduction
313
+ // ----------------------------
314
+
315
+ export type {
316
+ ReductionInput,
317
+ ReductionAlgorithmId,
318
+ BinRangeOptions,
319
+ OnsetStrengthOptions,
320
+ SpectralFluxOptions,
321
+ ReductionOptions,
322
+ ReductionResult,
323
+ // Polarity
324
+ PolarityMode,
325
+ // Stabilization
326
+ StabilizationMode,
327
+ EnvelopeMode,
328
+ StabilizationOptions,
329
+ } from "./dsp/customSignalReduction";
330
+ export {
331
+ reduce2DToSignal,
332
+ getReductionAlgorithmLabel,
333
+ getReductionAlgorithmDescription,
334
+ // Polarity
335
+ applyPolarity,
336
+ // Stabilization
337
+ stabilizeSignal,
338
+ // Statistics
339
+ computePercentiles,
340
+ computeLocalStats,
341
+ } from "./dsp/customSignalReduction";
342
+
251
343
  // ----------------------------
252
344
  // Visualisation utilities
253
345
  // ----------------------------
@@ -6,7 +6,7 @@ import { onsetEnvelopeFromMel, onsetEnvelopeFromMelGpu } from "../dsp/onset";
6
6
  import { peakPick } from "../dsp/peakPick";
7
7
  import { hpss } from "../dsp/hpss";
8
8
  import { hpssGpu } from "../dsp/hpssGpu";
9
- import { spectralCentroid, spectralFlux } from "../dsp/spectral";
9
+ import { amplitudeEnvelope, spectralCentroid, spectralFlux } from "../dsp/spectral";
10
10
  import { spectrogram, type AudioBufferLike, type Spectrogram, type SpectrogramConfig } from "../dsp/spectrogram";
11
11
  import { cqtSpectrogram, withCqtDefaults } from "../dsp/cqt";
12
12
  import { harmonicEnergy, bassPitchMotion, tonalStability } from "../dsp/cqtSignals";
@@ -88,6 +88,29 @@ export async function runMir(
88
88
  window: "hann",
89
89
  };
90
90
 
91
+ // Amplitude envelope: compute directly from raw audio (no spectrogram needed)
92
+ if (request.fn === "amplitudeEnvelope") {
93
+ const cpuStart = nowMs();
94
+ const result = amplitudeEnvelope(audio.mono, audio.sampleRate, {
95
+ hopSize: specConfig.hopSize,
96
+ windowSize: specConfig.fftSize,
97
+ });
98
+ const cpuEnd = nowMs();
99
+ return {
100
+ kind: "1d",
101
+ times: result.times,
102
+ values: result.values,
103
+ meta: {
104
+ backend: "cpu",
105
+ usedGpu: false,
106
+ timings: {
107
+ totalMs: cpuEnd - t0,
108
+ cpuMs: cpuEnd - cpuStart,
109
+ },
110
+ },
111
+ };
112
+ }
113
+
91
114
  // CPU: spectrogram + centroid/flux are CPU-only today.
92
115
  const cpuStart = nowMs();
93
116
  const spec: Spectrogram = await spectrogram(asAudioBufferLike(audio), specConfig, undefined, {
package/src/types.ts CHANGED
@@ -349,6 +349,8 @@ export type FrequencyBand = {
349
349
  id: string;
350
350
  /** Human-readable label (editable). */
351
351
  label: string;
352
+ /** The audio source this band belongs to ("mixdown" or stem ID). */
353
+ sourceId: string;
352
354
  /** Whether the band is currently active for processing. */
353
355
  enabled: boolean;
354
356
  /** Time scope for this band. */
@@ -375,7 +377,7 @@ export type FrequencyBand = {
375
377
  */
376
378
  export type FrequencyBandStructure = {
377
379
  /** Schema version for future migrations. */
378
- version: 1;
380
+ version: 2;
379
381
  /** Ordered list of frequency bands (by sortOrder). */
380
382
  bands: FrequencyBand[];
381
383
  /** ISO timestamp when the structure was created. */
@@ -424,12 +426,28 @@ export type FrequencyKeyframe = {
424
426
  // ----------------------------
425
427
 
426
428
  /**
427
- * Band MIR function identifiers.
429
+ * Band MIR function identifiers (STFT-based).
428
430
  */
429
431
  export type BandMirFunctionId =
430
432
  | "bandAmplitudeEnvelope"
431
433
  | "bandOnsetStrength"
432
- | "bandSpectralFlux";
434
+ | "bandSpectralFlux"
435
+ | "bandSpectralCentroid";
436
+
437
+ /**
438
+ * Band CQT function identifiers (CQT-based).
439
+ */
440
+ export type BandCqtFunctionId =
441
+ | "bandCqtHarmonicEnergy"
442
+ | "bandCqtBassPitchMotion"
443
+ | "bandCqtTonalStability";
444
+
445
+ /**
446
+ * Band event function identifiers (derived from 1D signals).
447
+ */
448
+ export type BandEventFunctionId =
449
+ | "bandOnsetPeaks"
450
+ | "bandBeatCandidates";
433
451
 
434
452
  /**
435
453
  * Diagnostics for band MIR computation.
@@ -449,7 +467,7 @@ export type BandMirDiagnostics = {
449
467
  };
450
468
 
451
469
  /**
452
- * Result of a band-scoped MIR computation.
470
+ * Result of a band-scoped MIR computation (STFT-based).
453
471
  */
454
472
  export type BandMir1DResult = {
455
473
  kind: "bandMir1d";
@@ -469,7 +487,80 @@ export type BandMir1DResult = {
469
487
  diagnostics: BandMirDiagnostics;
470
488
  };
471
489
 
490
+ /**
491
+ * Result of a band-scoped CQT computation.
492
+ */
493
+ export type BandCqt1DResult = {
494
+ kind: "bandCqt1d";
495
+ /** ID of the band this result is for. */
496
+ bandId: string;
497
+ /** Label of the band (for display). */
498
+ bandLabel: string;
499
+ /** The CQT function that produced this result. */
500
+ fn: BandCqtFunctionId;
501
+ /** Frame times aligned to CQT timebase. */
502
+ times: Float32Array;
503
+ /** Signal values per frame. */
504
+ values: Float32Array;
505
+ /** Execution metadata. */
506
+ meta: MirRunMeta;
507
+ /** Diagnostics about energy retention and potential issues. */
508
+ diagnostics: BandMirDiagnostics;
509
+ };
510
+
511
+ /**
512
+ * A band event (onset peak or beat candidate within a band).
513
+ */
514
+ export type BandMirEvent = {
515
+ /** Time in seconds. */
516
+ time: number;
517
+ /** Relative weight/strength (0-1 normalized). */
518
+ weight: number;
519
+ /** Optional beat position if beat grid exists. */
520
+ beatPosition?: number;
521
+ /** Optional beat phase if beat grid exists. */
522
+ beatPhase?: number;
523
+ };
524
+
525
+ /**
526
+ * Diagnostics for band event extraction.
527
+ */
528
+ export type BandEventDiagnostics = {
529
+ /** Total number of events extracted. */
530
+ eventCount: number;
531
+ /** Events per second (density). */
532
+ eventsPerSecond: number;
533
+ /** Warning messages (e.g., too sparse or too dense). */
534
+ warnings: string[];
535
+ };
536
+
537
+ /**
538
+ * Result of band event extraction.
539
+ */
540
+ export type BandEventsResult = {
541
+ kind: "bandEvents";
542
+ /** ID of the band this result is for. */
543
+ bandId: string;
544
+ /** Label of the band (for display). */
545
+ bandLabel: string;
546
+ /** The event function that produced this result. */
547
+ fn: BandEventFunctionId;
548
+ /** Extracted events. */
549
+ events: BandMirEvent[];
550
+ /** Source signal used for extraction (for debugging). */
551
+ sourceSignal?: {
552
+ fn: BandMirFunctionId;
553
+ times: Float32Array;
554
+ values: Float32Array;
555
+ };
556
+ /** Execution metadata. */
557
+ meta: MirRunMeta;
558
+ /** Diagnostics about extraction quality. */
559
+ diagnostics: BandEventDiagnostics;
560
+ };
561
+
472
562
  export type MirFunctionId =
563
+ | "amplitudeEnvelope"
473
564
  | "spectralCentroid"
474
565
  | "spectralFlux"
475
566
  | "melSpectrogram"
@@ -691,6 +782,8 @@ export type BandProposalConfig = {
691
782
  minSalience?: number;
692
783
  /** Minimum separation in octaves between proposals. Default: 0.5. */
693
784
  minSeparationOctaves?: number;
785
+ /** Minimum band width (Hz). Prevents implausibly narrow proposals. Default: 20. */
786
+ minBandwidthHz?: number;
694
787
  /** Time window for analysis in seconds (0 = full track). Default: 0. */
695
788
  analysisWindow?: number;
696
789
  };