@libraz/libsonare 1.7.2 → 1.8.1
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/NOTICE +178 -0
- package/README.md +26 -203
- package/dist/_chain_config.d.ts +14 -0
- package/dist/_chain_config.d.ts.map +1 -0
- package/dist/_effects_common.d.ts +7 -0
- package/dist/_effects_common.d.ts.map +1 -0
- package/dist/_feature_validation.d.ts +8 -0
- package/dist/_feature_validation.d.ts.map +1 -0
- package/dist/_fft_options.d.ts +24 -0
- package/dist/_fft_options.d.ts.map +1 -0
- package/dist/align_take.d.ts +50 -0
- package/dist/align_take.d.ts.map +1 -0
- package/dist/analysis.d.ts +29 -5840
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +874 -722
- package/dist/analysis.js.map +1 -1
- package/dist/analysis_helpers.d.ts +9 -0
- package/dist/analysis_helpers.d.ts.map +1 -0
- package/dist/audio.d.ts +163 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/clip_page_streamer.d.ts +133 -0
- package/dist/clip_page_streamer.d.ts.map +1 -0
- package/dist/codes.d.ts +44 -0
- package/dist/codes.d.ts.map +1 -0
- package/dist/effects_mastering.d.ts +23 -0
- package/dist/effects_mastering.d.ts.map +1 -0
- package/dist/effects_note_ops.d.ts +502 -0
- package/dist/effects_note_ops.d.ts.map +1 -0
- package/dist/effects_percussive.d.ts +185 -0
- package/dist/effects_percussive.d.ts.map +1 -0
- package/dist/effects_separation.d.ts +65 -0
- package/dist/effects_separation.d.ts.map +1 -0
- package/dist/effects_spectral.d.ts +28 -0
- package/dist/effects_spectral.d.ts.map +1 -0
- package/dist/effects_timepitch.d.ts +134 -0
- package/dist/effects_timepitch.d.ts.map +1 -0
- package/dist/effects_voice_change.d.ts +53 -0
- package/dist/effects_voice_change.d.ts.map +1 -0
- package/dist/errors.d.ts +51 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/feature_core.d.ts +341 -0
- package/dist/feature_core.d.ts.map +1 -0
- package/dist/feature_decompose.d.ts +278 -0
- package/dist/feature_decompose.d.ts.map +1 -0
- package/dist/feature_inverse.d.ts +128 -0
- package/dist/feature_inverse.d.ts.map +1 -0
- package/dist/feature_loudness.d.ts +66 -0
- package/dist/feature_loudness.d.ts.map +1 -0
- package/dist/feature_music.d.ts +307 -0
- package/dist/feature_music.d.ts.map +1 -0
- package/dist/feature_pitch.d.ts +108 -0
- package/dist/feature_pitch.d.ts.map +1 -0
- package/dist/feature_resample.d.ts +16 -0
- package/dist/feature_resample.d.ts.map +1 -0
- package/dist/feature_spectral.d.ts +137 -0
- package/dist/feature_spectral.d.ts.map +1 -0
- package/dist/feature_spectrogram.d.ts +198 -0
- package/dist/feature_spectrogram.d.ts.map +1 -0
- package/dist/features.d.ts +10 -0
- package/dist/features.d.ts.map +1 -0
- package/dist/hrtf/default.shrf +0 -0
- package/dist/index.d.ts +74 -7431
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4173 -1621
- package/dist/index.js.map +1 -1
- package/dist/instrument_types.d.ts +517 -0
- package/dist/instrument_types.d.ts.map +1 -0
- package/dist/live_audio.d.ts +35 -0
- package/dist/live_audio.d.ts.map +1 -0
- package/dist/mastering_chain.d.ts +213 -0
- package/dist/mastering_chain.d.ts.map +1 -0
- package/dist/mastering_core.d.ts +483 -0
- package/dist/mastering_core.d.ts.map +1 -0
- package/dist/mastering_dynamics.d.ts +80 -0
- package/dist/mastering_dynamics.d.ts.map +1 -0
- package/dist/metering.d.ts +287 -0
- package/dist/metering.d.ts.map +1 -0
- package/dist/mixer.d.ts +464 -0
- package/dist/mixer.d.ts.map +1 -0
- package/dist/mixing_assistant.d.ts +62 -0
- package/dist/mixing_assistant.d.ts.map +1 -0
- package/dist/mixing_oneshot.d.ts +40 -0
- package/dist/mixing_oneshot.d.ts.map +1 -0
- package/dist/module_state.d.ts +15 -0
- package/dist/module_state.d.ts.map +1 -0
- package/dist/opfs_clip_pages.d.ts +28 -0
- package/dist/opfs_clip_pages.d.ts.map +1 -0
- package/dist/playback_renderer.d.ts +128 -0
- package/dist/playback_renderer.d.ts.map +1 -0
- package/dist/polyphony.d.ts +202 -0
- package/dist/polyphony.d.ts.map +1 -0
- package/dist/project.d.ts +8 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project_class.d.ts +562 -0
- package/dist/project_class.d.ts.map +1 -0
- package/dist/project_internal.d.ts +194 -0
- package/dist/project_internal.d.ts.map +1 -0
- package/dist/project_synth.d.ts +74 -0
- package/dist/project_synth.d.ts.map +1 -0
- package/dist/project_types.d.ts +654 -0
- package/dist/project_types.d.ts.map +1 -0
- package/dist/public_types.d.ts +185 -0
- package/dist/public_types.d.ts.map +1 -0
- package/dist/public_types_acoustic.d.ts +215 -0
- package/dist/public_types_acoustic.d.ts.map +1 -0
- package/dist/public_types_mastering.d.ts +528 -0
- package/dist/public_types_mastering.d.ts.map +1 -0
- package/dist/public_types_mixing.d.ts +436 -0
- package/dist/public_types_mixing.d.ts.map +1 -0
- package/dist/public_types_music.d.ts +619 -0
- package/dist/public_types_music.d.ts.map +1 -0
- package/dist/public_types_playback.d.ts +165 -0
- package/dist/public_types_playback.d.ts.map +1 -0
- package/dist/public_types_realtime.d.ts +174 -0
- package/dist/public_types_realtime.d.ts.map +1 -0
- package/dist/public_types_repair.d.ts +424 -0
- package/dist/public_types_repair.d.ts.map +1 -0
- package/dist/public_types_spectral.d.ts +697 -0
- package/dist/public_types_spectral.d.ts.map +1 -0
- package/dist/quick_analysis.d.ts +445 -0
- package/dist/quick_analysis.d.ts.map +1 -0
- package/dist/realtime_engine.d.ts +893 -0
- package/dist/realtime_engine.d.ts.map +1 -0
- package/dist/realtime_voice_changer.d.ts +158 -0
- package/dist/realtime_voice_changer.d.ts.map +1 -0
- package/dist/repair_dereverb.d.ts +187 -0
- package/dist/repair_dereverb.d.ts.map +1 -0
- package/dist/repair_impulsive.d.ts +186 -0
- package/dist/repair_impulsive.d.ts.map +1 -0
- package/dist/repair_noise.d.ts +239 -0
- package/dist/repair_noise.d.ts.map +1 -0
- package/dist/repair_trim.d.ts +123 -0
- package/dist/repair_trim.d.ts.map +1 -0
- package/dist/sample_bank.d.ts +84 -0
- package/dist/sample_bank.d.ts.map +1 -0
- package/dist/scale.d.ts +10 -0
- package/dist/scale.d.ts.map +1 -0
- package/dist/schemas/mixer-scene.schema.json +393 -0
- package/dist/schemas/playback-renderer-config.schema.json +392 -0
- package/dist/sonare-analysis.d.ts +8 -0
- package/dist/sonare-analysis.js +2 -2
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.d.ts +3945 -0
- package/dist/sonare.js +2 -2
- package/dist/sonare.wasm +0 -0
- package/dist/stream_analyzer.d.ts +163 -0
- package/dist/stream_analyzer.d.ts.map +1 -0
- package/dist/stream_types.d.ts +214 -0
- package/dist/stream_types.d.ts.map +1 -0
- package/dist/streaming_mixing.d.ts +6 -0
- package/dist/streaming_mixing.d.ts.map +1 -0
- package/dist/streaming_processors.d.ts +340 -0
- package/dist/streaming_processors.d.ts.map +1 -0
- package/dist/transcribe.d.ts +77 -0
- package/dist/transcribe.d.ts.map +1 -0
- package/dist/validation.d.ts +140 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/web_midi.d.ts +77 -0
- package/dist/web_midi.d.ts.map +1 -0
- package/dist/worker.d.ts +5 -48
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +94 -41
- package/dist/worker.js.map +1 -1
- package/dist/worker_client.d.ts +96 -0
- package/dist/worker_client.d.ts.map +1 -0
- package/dist/worker_protocol.d.ts +43 -0
- package/dist/worker_protocol.d.ts.map +1 -0
- package/dist/worklet/audio_types.d.ts +21 -0
- package/dist/worklet/audio_types.d.ts.map +1 -0
- package/dist/worklet/engine-automation.d.ts +29 -0
- package/dist/worklet/engine-automation.d.ts.map +1 -0
- package/dist/worklet/engine-capture-facade.d.ts +35 -0
- package/dist/worklet/engine-capture-facade.d.ts.map +1 -0
- package/dist/worklet/engine-clips.d.ts +23 -0
- package/dist/worklet/engine-clips.d.ts.map +1 -0
- package/dist/worklet/engine-markers.d.ts +40 -0
- package/dist/worklet/engine-markers.d.ts.map +1 -0
- package/dist/worklet/engine-mixer-facade.d.ts +164 -0
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
- package/dist/worklet/engine-node.d.ts +83 -0
- package/dist/worklet/engine-node.d.ts.map +1 -0
- package/dist/worklet/engine-offline.d.ts +81 -0
- package/dist/worklet/engine-offline.d.ts.map +1 -0
- package/dist/worklet/engine-options.d.ts +12 -0
- package/dist/worklet/engine-options.d.ts.map +1 -0
- package/dist/worklet/engine-parameter-facade.d.ts +106 -0
- package/dist/worklet/engine-parameter-facade.d.ts.map +1 -0
- package/dist/worklet/engine-processor.d.ts +72 -0
- package/dist/worklet/engine-processor.d.ts.map +1 -0
- package/dist/worklet/engine-register.d.ts +2 -0
- package/dist/worklet/engine-register.d.ts.map +1 -0
- package/dist/worklet/engine-strips.d.ts +75 -0
- package/dist/worklet/engine-strips.d.ts.map +1 -0
- package/dist/worklet/engine-sync.d.ts +39 -0
- package/dist/worklet/engine-sync.d.ts.map +1 -0
- package/dist/worklet/engine-tempo-facade.d.ts +48 -0
- package/dist/worklet/engine-tempo-facade.d.ts.map +1 -0
- package/dist/worklet/engine.d.ts +418 -0
- package/dist/worklet/engine.d.ts.map +1 -0
- package/dist/worklet/guards.d.ts +53 -0
- package/dist/worklet/guards.d.ts.map +1 -0
- package/dist/worklet/messages.d.ts +710 -0
- package/dist/worklet/messages.d.ts.map +1 -0
- package/dist/worklet/mixer-processor.d.ts +46 -0
- package/dist/worklet/mixer-processor.d.ts.map +1 -0
- package/dist/worklet/playback-processor.d.ts +62 -0
- package/dist/worklet/playback-processor.d.ts.map +1 -0
- package/dist/worklet/protocol.d.ts +331 -0
- package/dist/worklet/protocol.d.ts.map +1 -0
- package/dist/worklet/voice-changer-processor.d.ts +41 -0
- package/dist/worklet/voice-changer-processor.d.ts.map +1 -0
- package/dist/worklet.d.ts +16 -2515
- package/dist/worklet.d.ts.map +1 -0
- package/dist/worklet.js +3200 -541
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -12
- package/src/_effects_common.ts +47 -0
- package/src/_feature_validation.ts +34 -0
- package/src/_fft_options.ts +39 -0
- package/src/align_take.ts +64 -0
- package/src/analysis.ts +56 -3
- package/src/analysis_helpers.ts +7 -0
- package/src/audio.ts +106 -3
- package/src/codes.ts +39 -2
- package/src/effects_mastering.ts +101 -22
- package/src/effects_note_ops.ts +683 -0
- package/src/effects_percussive.ts +217 -0
- package/src/effects_separation.ts +150 -0
- package/src/effects_spectral.ts +60 -0
- package/src/effects_timepitch.ts +388 -0
- package/src/errors.ts +23 -1
- package/src/feature_core.ts +127 -2
- package/src/feature_decompose.ts +633 -0
- package/src/feature_inverse.ts +454 -0
- package/src/feature_loudness.ts +125 -0
- package/src/feature_music.ts +107 -14
- package/src/feature_pitch.ts +96 -1
- package/src/feature_spectral.ts +16 -611
- package/src/feature_spectrogram.ts +63 -450
- package/src/features.ts +36 -22
- package/src/index.ts +288 -30
- package/src/instrument_types.ts +645 -0
- package/src/live_audio.ts +27 -1
- package/src/mastering_chain.ts +184 -0
- package/src/mastering_core.ts +441 -32
- package/src/mastering_dynamics.ts +22 -11
- package/src/metering.ts +67 -24
- package/src/mixer.ts +251 -22
- package/src/mixing_assistant.ts +138 -0
- package/src/mixing_oneshot.ts +10 -5
- package/src/module_state.ts +24 -2
- package/src/playback_renderer.ts +252 -0
- package/src/polyphony.ts +279 -0
- package/src/project.ts +61 -24
- package/src/project_class.ts +450 -27
- package/src/project_internal.ts +149 -42
- package/src/project_synth.ts +67 -1
- package/src/project_types.ts +271 -271
- package/src/public_types.ts +122 -3
- package/src/public_types_acoustic.ts +112 -3
- package/src/public_types_mastering.ts +275 -73
- package/src/public_types_mixing.ts +363 -1
- package/src/public_types_music.ts +312 -2
- package/src/public_types_playback.ts +196 -0
- package/src/public_types_realtime.ts +39 -7
- package/src/public_types_repair.ts +446 -0
- package/src/public_types_spectral.ts +491 -5
- package/src/quick_analysis.ts +203 -26
- package/src/realtime_engine.ts +773 -34
- package/src/realtime_voice_changer.ts +55 -1
- package/src/repair_dereverb.ts +299 -0
- package/src/repair_impulsive.ts +395 -0
- package/src/repair_noise.ts +425 -0
- package/src/repair_trim.ts +226 -0
- package/src/sample_bank.ts +113 -0
- package/src/sonare.js.d.ts +1158 -30
- package/src/stream_analyzer.ts +36 -4
- package/src/stream_types.ts +37 -0
- package/src/streaming_mixing.ts +1 -1
- package/src/streaming_processors.ts +202 -10
- package/src/transcribe.ts +89 -0
- package/src/validation.ts +285 -11
- package/src/web_midi.ts +1 -6
- package/src/worker.ts +18 -2
- package/src/worklet/audio_types.ts +37 -0
- package/src/worklet/engine-mixer-facade.ts +800 -32
- package/src/worklet/engine-node.ts +99 -29
- package/src/worklet/engine-offline.ts +14 -8
- package/src/worklet/engine-parameter-facade.ts +21 -0
- package/src/worklet/engine-processor.ts +332 -93
- package/src/worklet/engine-register.ts +32 -18
- package/src/worklet/engine-strips.ts +275 -9
- package/src/worklet/engine-sync.ts +20 -7
- package/src/worklet/engine.ts +394 -48
- package/src/worklet/guards.ts +195 -44
- package/src/worklet/messages.ts +229 -2
- package/src/worklet/mixer-processor.ts +117 -48
- package/src/worklet/playback-processor.ts +300 -0
- package/src/worklet/protocol.ts +82 -11
- package/src/worklet/voice-changer-processor.ts +17 -11
- package/src/worklet.ts +17 -0
- package/src/effects_transform.ts +0 -718
- package/src/mastering_repair.ts +0 -273
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source decomposition and self-similarity segmentation: NMF factorisation and
|
|
3
|
+
* the masks built over it, and the recurrence structure of a track.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { resolveFftOptions } from './_fft_options';
|
|
7
|
+
import { getSonareModule } from './module_state';
|
|
8
|
+
import type { SegmentMatrix } from './public_types';
|
|
9
|
+
import type {
|
|
10
|
+
WasmDecomposeResult,
|
|
11
|
+
WasmHpssWithResidualResult,
|
|
12
|
+
WasmMatrix2dResult,
|
|
13
|
+
} from './sonare.js';
|
|
14
|
+
import {
|
|
15
|
+
assertHpssKernels,
|
|
16
|
+
assertNonNegativeInteger,
|
|
17
|
+
assertPositiveInteger,
|
|
18
|
+
assertSamples,
|
|
19
|
+
toInt32Array,
|
|
20
|
+
} from './validation';
|
|
21
|
+
|
|
22
|
+
function requireModule() {
|
|
23
|
+
return getSonareModule();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function resolveHardMask(fnName: string, value: unknown): boolean {
|
|
27
|
+
if (value === undefined) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (typeof value !== 'boolean') {
|
|
31
|
+
throw new TypeError(`${fnName}: hardMask must be a boolean`);
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface DecomposeRequest {
|
|
37
|
+
s: Float32Array;
|
|
38
|
+
nFeatures: number;
|
|
39
|
+
nFrames: number;
|
|
40
|
+
nComponents: number;
|
|
41
|
+
nIter?: number;
|
|
42
|
+
beta?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface DecomposeWithInitRequest extends DecomposeRequest {
|
|
46
|
+
init?: 'random' | 'nndsvd';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface NnFilterRequest {
|
|
50
|
+
s: Float32Array;
|
|
51
|
+
nFeatures: number;
|
|
52
|
+
nFrames: number;
|
|
53
|
+
aggregate?: string;
|
|
54
|
+
k?: number;
|
|
55
|
+
width?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface SegmentCrossSimilarityRequest {
|
|
59
|
+
x: Float32Array;
|
|
60
|
+
xRows: number;
|
|
61
|
+
xCols: number;
|
|
62
|
+
y: Float32Array;
|
|
63
|
+
yRows: number;
|
|
64
|
+
yCols: number;
|
|
65
|
+
k?: number;
|
|
66
|
+
metric?: 'cosine' | 'euclidean';
|
|
67
|
+
mode?: 'connectivity' | 'affinity';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface SegmentRecurrenceMatrixRequest {
|
|
71
|
+
data: Float32Array;
|
|
72
|
+
rows: number;
|
|
73
|
+
cols: number;
|
|
74
|
+
k?: number;
|
|
75
|
+
width?: number;
|
|
76
|
+
sym?: boolean;
|
|
77
|
+
metric?: 'cosine' | 'euclidean';
|
|
78
|
+
mode?: 'connectivity' | 'affinity';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface SegmentRecurrenceToLagRequest {
|
|
82
|
+
recurrence: Float32Array;
|
|
83
|
+
n: number;
|
|
84
|
+
pad?: boolean;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface SegmentLagToRecurrenceRequest {
|
|
88
|
+
lag: Float32Array;
|
|
89
|
+
rows: number;
|
|
90
|
+
lags: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface SegmentSubsegmentRequest {
|
|
94
|
+
data: Float32Array;
|
|
95
|
+
rows: number;
|
|
96
|
+
cols: number;
|
|
97
|
+
boundaries: Int32Array;
|
|
98
|
+
nSegments?: number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface SegmentAgglomerativeRequest {
|
|
102
|
+
data: Float32Array;
|
|
103
|
+
rows: number;
|
|
104
|
+
cols: number;
|
|
105
|
+
k: number;
|
|
106
|
+
linkage?: 'average' | 'single' | 'complete' | 'ward';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface SegmentPathEnhanceRequest {
|
|
110
|
+
recurrence: Float32Array;
|
|
111
|
+
n: number;
|
|
112
|
+
win: number;
|
|
113
|
+
maxRatio?: number;
|
|
114
|
+
minRatio?: number;
|
|
115
|
+
nFilters?: number;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function validateSegmentMatrix(
|
|
119
|
+
fnName: string,
|
|
120
|
+
data: Float32Array,
|
|
121
|
+
rows: number,
|
|
122
|
+
cols: number,
|
|
123
|
+
dataName: string,
|
|
124
|
+
): void {
|
|
125
|
+
assertPositiveInteger(fnName, rows, 'rows');
|
|
126
|
+
assertPositiveInteger(fnName, cols, 'cols');
|
|
127
|
+
assertSamples(fnName, data, true, dataName);
|
|
128
|
+
const expected = rows * cols;
|
|
129
|
+
if (!Number.isSafeInteger(expected) || data.length !== expected) {
|
|
130
|
+
throw new RangeError(`${fnName}: ${dataName} length must equal rows * cols`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface RemixRequest {
|
|
135
|
+
samples: Float32Array;
|
|
136
|
+
intervals: Int32Array | ArrayLike<number>;
|
|
137
|
+
sampleRate?: number;
|
|
138
|
+
alignZeros?: boolean;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface HpssWithResidualRequest {
|
|
142
|
+
samples: Float32Array;
|
|
143
|
+
sampleRate?: number;
|
|
144
|
+
/**
|
|
145
|
+
* Horizontal median filter size, in STFT frames: a positive odd integer at
|
|
146
|
+
* most 524287. Default 31. The ceiling is 524288 and an even kernel is
|
|
147
|
+
* refused, so 524287 is the largest legal value.
|
|
148
|
+
*/
|
|
149
|
+
kernelHarmonic?: number;
|
|
150
|
+
/** Vertical median filter size, in STFT bins, under the same rule. Default 31. */
|
|
151
|
+
kernelPercussive?: number;
|
|
152
|
+
nFft?: number;
|
|
153
|
+
hopLength?: number;
|
|
154
|
+
hardMask?: boolean;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Non-negative matrix factorisation of a flattened [nFeatures x nFrames]
|
|
159
|
+
* spectrogram (librosa.decompose.decompose). Returns the W and H factors.
|
|
160
|
+
*/
|
|
161
|
+
export function decompose(request: DecomposeRequest): WasmDecomposeResult;
|
|
162
|
+
export function decompose(
|
|
163
|
+
s: Float32Array,
|
|
164
|
+
nFeatures: number,
|
|
165
|
+
nFrames: number,
|
|
166
|
+
nComponents: number,
|
|
167
|
+
nIter?: number,
|
|
168
|
+
beta?: number,
|
|
169
|
+
): WasmDecomposeResult;
|
|
170
|
+
export function decompose(
|
|
171
|
+
s: Float32Array | DecomposeRequest,
|
|
172
|
+
nFeatures = 0,
|
|
173
|
+
nFrames = 0,
|
|
174
|
+
nComponents = 0,
|
|
175
|
+
nIter = 50,
|
|
176
|
+
beta = 2.0,
|
|
177
|
+
): WasmDecomposeResult {
|
|
178
|
+
if (!(s instanceof Float32Array)) {
|
|
179
|
+
const request = s;
|
|
180
|
+
return decompose(
|
|
181
|
+
request.s,
|
|
182
|
+
request.nFeatures,
|
|
183
|
+
request.nFrames,
|
|
184
|
+
request.nComponents,
|
|
185
|
+
request.nIter,
|
|
186
|
+
request.beta,
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
return requireModule().decompose(s, nFeatures, nFrames, nComponents, nIter, beta);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Non-negative matrix factorisation with a selectable initialiser
|
|
194
|
+
* (librosa.decompose.decompose, `init`). Identical to {@link decompose} but
|
|
195
|
+
* exposes the initialisation strategy: `'random'` (default, deterministic seed)
|
|
196
|
+
* or `'nndsvd'` (SVD-based warm start, which tends to converge in fewer
|
|
197
|
+
* iterations). Returns the W and H factors.
|
|
198
|
+
*/
|
|
199
|
+
export function decomposeWithInit(request: DecomposeWithInitRequest): WasmDecomposeResult;
|
|
200
|
+
export function decomposeWithInit(
|
|
201
|
+
s: Float32Array,
|
|
202
|
+
nFeatures: number,
|
|
203
|
+
nFrames: number,
|
|
204
|
+
nComponents: number,
|
|
205
|
+
nIter?: number,
|
|
206
|
+
beta?: number,
|
|
207
|
+
init?: 'random' | 'nndsvd',
|
|
208
|
+
): WasmDecomposeResult;
|
|
209
|
+
export function decomposeWithInit(
|
|
210
|
+
s: Float32Array | DecomposeWithInitRequest,
|
|
211
|
+
nFeatures = 0,
|
|
212
|
+
nFrames = 0,
|
|
213
|
+
nComponents = 0,
|
|
214
|
+
nIter = 50,
|
|
215
|
+
beta = 2.0,
|
|
216
|
+
init: 'random' | 'nndsvd' = 'random',
|
|
217
|
+
): WasmDecomposeResult {
|
|
218
|
+
if (!(s instanceof Float32Array)) {
|
|
219
|
+
const request = s;
|
|
220
|
+
return decomposeWithInit(
|
|
221
|
+
request.s,
|
|
222
|
+
request.nFeatures,
|
|
223
|
+
request.nFrames,
|
|
224
|
+
request.nComponents,
|
|
225
|
+
request.nIter,
|
|
226
|
+
request.beta,
|
|
227
|
+
request.init,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
return requireModule().decomposeWithInit(s, nFeatures, nFrames, nComponents, nIter, beta, init);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** Options for {@link decomposeStems}. */
|
|
234
|
+
export interface DecomposeStemsRequest {
|
|
235
|
+
samples: Float32Array;
|
|
236
|
+
sampleRate?: number;
|
|
237
|
+
/** Number of NMF components (default 4). */
|
|
238
|
+
nComponents?: number;
|
|
239
|
+
/** STFT size (default 2048). */
|
|
240
|
+
nFft?: number;
|
|
241
|
+
/** STFT hop (default 512). */
|
|
242
|
+
hopLength?: number;
|
|
243
|
+
/** NMF multiplicative-update iterations (default 100). */
|
|
244
|
+
nIter?: number;
|
|
245
|
+
/** Beta divergence: 2 = Frobenius (default), 1 = Kullback-Leibler. */
|
|
246
|
+
beta?: number;
|
|
247
|
+
/** NMF initialisation (default `'random'`). */
|
|
248
|
+
init?: 'random' | 'nndsvd';
|
|
249
|
+
/**
|
|
250
|
+
* Soft-mask exponent (default 1). 1 keeps the magnitude ratio; 2 is the
|
|
251
|
+
* Wiener-style power ratio, which separates harder at the cost of more
|
|
252
|
+
* artefacts on overlapping partials. Must be >= 1.
|
|
253
|
+
*/
|
|
254
|
+
maskPower?: number;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** One time-domain signal per NMF component, plus the factorisation. */
|
|
258
|
+
export interface DecomposeStemsResult {
|
|
259
|
+
/** Component signals, each the length of the input. */
|
|
260
|
+
components: Float32Array[];
|
|
261
|
+
/** Component matrix [nBins x nComponents], row-major. */
|
|
262
|
+
w: Float32Array;
|
|
263
|
+
/** Activation matrix [nComponents x nFrames], row-major. */
|
|
264
|
+
h: Float32Array;
|
|
265
|
+
sampleRate: number;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* NMF separation that **carries the original phase**, so each component is
|
|
270
|
+
* directly listenable.
|
|
271
|
+
*
|
|
272
|
+
* {@link decompose} returns the W/H factors of a magnitude spectrogram, which
|
|
273
|
+
* have no phase; reconstructing from them needs a phase estimator
|
|
274
|
+
* ({@link griffinLim}), and an estimated phase does not hold up as a stem. This
|
|
275
|
+
* instead builds a per-component soft mask from the factorisation and applies
|
|
276
|
+
* it to the original complex spectrogram. The masks sum to one wherever the
|
|
277
|
+
* model has energy and the inverse STFT is linear, so the components sum back
|
|
278
|
+
* to the input.
|
|
279
|
+
*/
|
|
280
|
+
export function decomposeStems(request: DecomposeStemsRequest): DecomposeStemsResult {
|
|
281
|
+
return requireModule().decomposeStems(request.samples, request.sampleRate ?? 22050, {
|
|
282
|
+
nComponents: request.nComponents,
|
|
283
|
+
nFft: request.nFft,
|
|
284
|
+
hopLength: request.hopLength,
|
|
285
|
+
nIter: request.nIter,
|
|
286
|
+
beta: request.beta,
|
|
287
|
+
init: request.init,
|
|
288
|
+
maskPower: request.maskPower,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Request form of {@link decomposeStemsLinked}. */
|
|
293
|
+
export interface DecomposeStemsLinkedRequest {
|
|
294
|
+
/** At least one channel; all the same length. */
|
|
295
|
+
channels: Float32Array[];
|
|
296
|
+
sampleRate?: number;
|
|
297
|
+
/** Number of NMF components (default 4). */
|
|
298
|
+
nComponents?: number;
|
|
299
|
+
/** STFT size (default 2048). */
|
|
300
|
+
nFft?: number;
|
|
301
|
+
/** STFT hop (default 512). */
|
|
302
|
+
hopLength?: number;
|
|
303
|
+
/** NMF multiplicative-update iterations (default 100). */
|
|
304
|
+
nIter?: number;
|
|
305
|
+
/** Beta divergence: 2 = Frobenius (default), 1 = Kullback-Leibler. */
|
|
306
|
+
beta?: number;
|
|
307
|
+
/** NMF initialisation (default `'random'`). */
|
|
308
|
+
init?: 'random' | 'nndsvd';
|
|
309
|
+
/** Soft-mask exponent (default 1); see {@link DecomposeStemsRequest.maskPower}. */
|
|
310
|
+
maskPower?: number;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** One time-domain signal per (component, channel), plus the factorisation. */
|
|
314
|
+
export interface DecomposeStemsLinkedResult {
|
|
315
|
+
/**
|
|
316
|
+
* Component signals: `components[k][c]` is component `k`'s signal on
|
|
317
|
+
* channel `c`, each the length of the input.
|
|
318
|
+
*/
|
|
319
|
+
components: Float32Array[][];
|
|
320
|
+
/** Component matrix [nBins x nComponents], row-major. */
|
|
321
|
+
w: Float32Array;
|
|
322
|
+
/** Activation matrix [nComponents x nFrames], row-major. */
|
|
323
|
+
h: Float32Array;
|
|
324
|
+
sampleRate: number;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Multi-channel form of {@link decomposeStems}: one NMF model and one soft
|
|
329
|
+
* mask shared across every channel, built from the channels' averaged
|
|
330
|
+
* magnitude spectrogram and applied UNCHANGED to each channel's own complex
|
|
331
|
+
* spectrum, so no interchannel level or phase difference moves. A single
|
|
332
|
+
* channel reproduces {@link decomposeStems} bit for bit.
|
|
333
|
+
*
|
|
334
|
+
* @throws On a null/empty channel set, mismatched channel lengths, a channel
|
|
335
|
+
* count above the core's ceiling, or an invalid option.
|
|
336
|
+
*/
|
|
337
|
+
export function decomposeStemsLinked(
|
|
338
|
+
request: DecomposeStemsLinkedRequest,
|
|
339
|
+
): DecomposeStemsLinkedResult {
|
|
340
|
+
return requireModule().decomposeStemsLinked(request.channels, request.sampleRate ?? 22050, {
|
|
341
|
+
nComponents: request.nComponents,
|
|
342
|
+
nFft: request.nFft,
|
|
343
|
+
hopLength: request.hopLength,
|
|
344
|
+
nIter: request.nIter,
|
|
345
|
+
beta: request.beta,
|
|
346
|
+
init: request.init,
|
|
347
|
+
maskPower: request.maskPower,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Nearest-neighbour filtering of a flattened [nFeatures x nFrames] spectrogram
|
|
353
|
+
* (librosa.decompose.nn_filter).
|
|
354
|
+
*/
|
|
355
|
+
export function nnFilter(request: NnFilterRequest): WasmMatrix2dResult;
|
|
356
|
+
export function nnFilter(
|
|
357
|
+
s: Float32Array,
|
|
358
|
+
nFeatures: number,
|
|
359
|
+
nFrames: number,
|
|
360
|
+
aggregate?: string,
|
|
361
|
+
k?: number,
|
|
362
|
+
width?: number,
|
|
363
|
+
): WasmMatrix2dResult;
|
|
364
|
+
export function nnFilter(
|
|
365
|
+
s: Float32Array | NnFilterRequest,
|
|
366
|
+
nFeatures = 0,
|
|
367
|
+
nFrames = 0,
|
|
368
|
+
aggregate = 'mean',
|
|
369
|
+
k = 7,
|
|
370
|
+
width = 1,
|
|
371
|
+
): WasmMatrix2dResult {
|
|
372
|
+
if (!(s instanceof Float32Array)) {
|
|
373
|
+
const r = s;
|
|
374
|
+
return nnFilter(r.s, r.nFeatures, r.nFrames, r.aggregate, r.k, r.width);
|
|
375
|
+
}
|
|
376
|
+
return requireModule().nnFilter(s, nFeatures, nFrames, aggregate, k, width);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Reorder/concatenate a signal by interval slices (librosa.effects.remix).
|
|
381
|
+
*
|
|
382
|
+
* With `alignZeros` the boundaries snap to the signal's zero-crossings. That is
|
|
383
|
+
* a per-signal decision, so calling this per channel snaps each channel to a
|
|
384
|
+
* different frame and drifts a stereo take apart; resolve one cut set with
|
|
385
|
+
* {@link remixAlignedIntervals} and apply it to every channel instead.
|
|
386
|
+
*
|
|
387
|
+
* @param intervals - Flat (start, end) sample pairs (even length).
|
|
388
|
+
*/
|
|
389
|
+
export function remix(request: RemixRequest): Float32Array;
|
|
390
|
+
export function remix(
|
|
391
|
+
samples: Float32Array,
|
|
392
|
+
intervals: Int32Array | ArrayLike<number>,
|
|
393
|
+
sampleRate?: number,
|
|
394
|
+
alignZeros?: boolean,
|
|
395
|
+
): Float32Array;
|
|
396
|
+
export function remix(
|
|
397
|
+
samples: Float32Array | RemixRequest,
|
|
398
|
+
intervals?: Int32Array | ArrayLike<number>,
|
|
399
|
+
sampleRate = 22050,
|
|
400
|
+
alignZeros = false,
|
|
401
|
+
): Float32Array {
|
|
402
|
+
if (!(samples instanceof Float32Array)) {
|
|
403
|
+
const r = samples;
|
|
404
|
+
return remix(r.samples, r.intervals, r.sampleRate, r.alignZeros);
|
|
405
|
+
}
|
|
406
|
+
// Sample indices must reach the native side as exact 32-bit integers, and a
|
|
407
|
+
// boundary the conversion changed would cut the slice somewhere the caller
|
|
408
|
+
// never named.
|
|
409
|
+
const intervalsI32 = toInt32Array('remix', intervals as ArrayLike<number>, 'intervals');
|
|
410
|
+
return requireModule().remix(samples, intervalsI32, sampleRate, alignZeros);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Resolve the cut points {@link remix} would use, without cutting.
|
|
415
|
+
*
|
|
416
|
+
* Returns a flat `Int32Array` of one clamped `(start, end)` pair per input
|
|
417
|
+
* interval. With `alignZeros` each boundary snaps to the nearest zero-crossing,
|
|
418
|
+
* with two guards that stop a slice from vanishing: a signal with no sign
|
|
419
|
+
* change at all (silence, a DC offset, any constant) is not snapped, and a
|
|
420
|
+
* slice that had content but collapses to empty after snapping keeps its
|
|
421
|
+
* unsnapped boundaries.
|
|
422
|
+
*
|
|
423
|
+
* Use this to cut a multichannel take on one common frame set: resolve once
|
|
424
|
+
* from one channel, then slice every channel with the returned pairs.
|
|
425
|
+
*
|
|
426
|
+
* @param intervals - Flat (start, end) sample pairs (even length).
|
|
427
|
+
*/
|
|
428
|
+
export function remixAlignedIntervals(request: RemixRequest): Int32Array;
|
|
429
|
+
export function remixAlignedIntervals(
|
|
430
|
+
samples: Float32Array,
|
|
431
|
+
intervals: Int32Array | ArrayLike<number>,
|
|
432
|
+
sampleRate?: number,
|
|
433
|
+
alignZeros?: boolean,
|
|
434
|
+
): Int32Array;
|
|
435
|
+
export function remixAlignedIntervals(
|
|
436
|
+
samples: Float32Array | RemixRequest,
|
|
437
|
+
intervals?: Int32Array | ArrayLike<number>,
|
|
438
|
+
sampleRate = 22050,
|
|
439
|
+
alignZeros = true,
|
|
440
|
+
): Int32Array {
|
|
441
|
+
if (!(samples instanceof Float32Array)) {
|
|
442
|
+
const r = samples;
|
|
443
|
+
return remixAlignedIntervals(r.samples, r.intervals, r.sampleRate, r.alignZeros ?? true);
|
|
444
|
+
}
|
|
445
|
+
const intervalsI32 = toInt32Array(
|
|
446
|
+
'remixAlignedIntervals',
|
|
447
|
+
intervals as ArrayLike<number>,
|
|
448
|
+
'intervals',
|
|
449
|
+
);
|
|
450
|
+
return requireModule().remixAlignedIntervals(samples, intervalsI32, sampleRate, alignZeros);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* HPSS into harmonic / percussive / residual signals.
|
|
455
|
+
*
|
|
456
|
+
* The three outputs always add back up to the input. `residual` is silent under
|
|
457
|
+
* the default soft mask, whose two masks sum to one, so `harmonic` and
|
|
458
|
+
* `percussive` already carry everything; it is returned anyway so the result
|
|
459
|
+
* shape does not change with the mask. Pass `hardMask: true` for a residual that
|
|
460
|
+
* holds signal — its thresholded masks leave the band where neither component
|
|
461
|
+
* dominates, measured at 3 % of the input energy on a voice-plus-kick signal.
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```ts
|
|
465
|
+
* const soft = hpssWithResidual({ samples, sampleRate });
|
|
466
|
+
* // soft.residual is silence
|
|
467
|
+
* const hard = hpssWithResidual({ samples, sampleRate, hardMask: true });
|
|
468
|
+
* // hard.residual carries what neither component claimed
|
|
469
|
+
* ```
|
|
470
|
+
*
|
|
471
|
+
* @throws SonareError (`InvalidParameter`) on a kernel that is not an integer
|
|
472
|
+
* within the signed 32-bit range, or one the core rejects as even,
|
|
473
|
+
* non-positive or above its ceiling
|
|
474
|
+
*/
|
|
475
|
+
export function hpssWithResidual(request: HpssWithResidualRequest): WasmHpssWithResidualResult;
|
|
476
|
+
export function hpssWithResidual(
|
|
477
|
+
samples: Float32Array,
|
|
478
|
+
sampleRate?: number,
|
|
479
|
+
kernelHarmonic?: number,
|
|
480
|
+
kernelPercussive?: number,
|
|
481
|
+
nFft?: number,
|
|
482
|
+
hopLength?: number,
|
|
483
|
+
hardMask?: boolean,
|
|
484
|
+
): WasmHpssWithResidualResult;
|
|
485
|
+
export function hpssWithResidual(
|
|
486
|
+
samples: Float32Array | HpssWithResidualRequest,
|
|
487
|
+
sampleRate = 22050,
|
|
488
|
+
kernelHarmonic = 31,
|
|
489
|
+
kernelPercussive = 31,
|
|
490
|
+
nFft?: number,
|
|
491
|
+
hopLength?: number,
|
|
492
|
+
hardMask?: boolean,
|
|
493
|
+
): WasmHpssWithResidualResult {
|
|
494
|
+
if (!(samples instanceof Float32Array)) {
|
|
495
|
+
const r = samples;
|
|
496
|
+
return hpssWithResidual(
|
|
497
|
+
r.samples,
|
|
498
|
+
r.sampleRate,
|
|
499
|
+
r.kernelHarmonic,
|
|
500
|
+
r.kernelPercussive,
|
|
501
|
+
r.nFft,
|
|
502
|
+
r.hopLength,
|
|
503
|
+
r.hardMask,
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
const fftOptions = resolveFftOptions('hpssWithResidual', nFft, hopLength);
|
|
507
|
+
const resolvedHardMask = resolveHardMask('hpssWithResidual', hardMask);
|
|
508
|
+
assertHpssKernels('hpssWithResidual', kernelHarmonic, kernelPercussive);
|
|
509
|
+
return requireModule().hpssWithResidualEx(
|
|
510
|
+
samples,
|
|
511
|
+
sampleRate,
|
|
512
|
+
kernelHarmonic,
|
|
513
|
+
kernelPercussive,
|
|
514
|
+
fftOptions.nFft,
|
|
515
|
+
fftOptions.hopLength,
|
|
516
|
+
resolvedHardMask,
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/** Column-wise cross-similarity (librosa.segment.cross_similarity). */
|
|
521
|
+
export function segmentCrossSimilarity(request: SegmentCrossSimilarityRequest): SegmentMatrix {
|
|
522
|
+
validateSegmentMatrix('segmentCrossSimilarity', request.x, request.xRows, request.xCols, 'x');
|
|
523
|
+
validateSegmentMatrix('segmentCrossSimilarity', request.y, request.yRows, request.yCols, 'y');
|
|
524
|
+
if (request.xRows !== request.yRows) {
|
|
525
|
+
throw new RangeError('segmentCrossSimilarity: feature dimensions must match');
|
|
526
|
+
}
|
|
527
|
+
assertNonNegativeInteger('segmentCrossSimilarity', request.k ?? 0, 'k');
|
|
528
|
+
return requireModule().segmentCrossSimilarity(
|
|
529
|
+
request.x,
|
|
530
|
+
request.xRows,
|
|
531
|
+
request.xCols,
|
|
532
|
+
request.y,
|
|
533
|
+
request.yRows,
|
|
534
|
+
request.yCols,
|
|
535
|
+
request.k ?? 0,
|
|
536
|
+
request.metric ?? 'cosine',
|
|
537
|
+
request.mode ?? 'connectivity',
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/** Self-similarity recurrence matrix (librosa.segment.recurrence_matrix). */
|
|
542
|
+
export function segmentRecurrenceMatrix(request: SegmentRecurrenceMatrixRequest): SegmentMatrix {
|
|
543
|
+
validateSegmentMatrix(
|
|
544
|
+
'segmentRecurrenceMatrix',
|
|
545
|
+
request.data,
|
|
546
|
+
request.rows,
|
|
547
|
+
request.cols,
|
|
548
|
+
'data',
|
|
549
|
+
);
|
|
550
|
+
assertNonNegativeInteger('segmentRecurrenceMatrix', request.k ?? 0, 'k');
|
|
551
|
+
assertNonNegativeInteger('segmentRecurrenceMatrix', request.width ?? 1, 'width');
|
|
552
|
+
return requireModule().segmentRecurrenceMatrix(
|
|
553
|
+
request.data,
|
|
554
|
+
request.rows,
|
|
555
|
+
request.cols,
|
|
556
|
+
request.k ?? 0,
|
|
557
|
+
request.width ?? 1,
|
|
558
|
+
request.sym ?? false,
|
|
559
|
+
request.metric ?? 'euclidean',
|
|
560
|
+
request.mode ?? 'connectivity',
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/** Convert an `n × n` recurrence matrix to a lag matrix. */
|
|
565
|
+
export function segmentRecurrenceToLag(request: SegmentRecurrenceToLagRequest): SegmentMatrix {
|
|
566
|
+
validateSegmentMatrix(
|
|
567
|
+
'segmentRecurrenceToLag',
|
|
568
|
+
request.recurrence,
|
|
569
|
+
request.n,
|
|
570
|
+
request.n,
|
|
571
|
+
'recurrence',
|
|
572
|
+
);
|
|
573
|
+
return requireModule().segmentRecurrenceToLag(
|
|
574
|
+
request.recurrence,
|
|
575
|
+
request.n,
|
|
576
|
+
request.pad ?? false,
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/** Convert a lag matrix back to an `n × n` recurrence matrix. */
|
|
581
|
+
export function segmentLagToRecurrence(request: SegmentLagToRecurrenceRequest): SegmentMatrix {
|
|
582
|
+
validateSegmentMatrix('segmentLagToRecurrence', request.lag, request.rows, request.lags, 'lag');
|
|
583
|
+
return requireModule().segmentLagToRecurrence(request.lag, request.rows, request.lags);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/** Refine frame boundaries by clustering within each parent segment. */
|
|
587
|
+
export function segmentSubsegment(request: SegmentSubsegmentRequest): Int32Array {
|
|
588
|
+
validateSegmentMatrix('segmentSubsegment', request.data, request.rows, request.cols, 'data');
|
|
589
|
+
assertPositiveInteger('segmentSubsegment', request.nSegments ?? 4, 'nSegments');
|
|
590
|
+
return requireModule().segmentSubsegment(
|
|
591
|
+
request.data,
|
|
592
|
+
request.rows,
|
|
593
|
+
request.cols,
|
|
594
|
+
request.boundaries,
|
|
595
|
+
request.nSegments ?? 4,
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/** Cluster feature columns and return one label per column. */
|
|
600
|
+
export function segmentAgglomerative(request: SegmentAgglomerativeRequest): Int32Array {
|
|
601
|
+
validateSegmentMatrix('segmentAgglomerative', request.data, request.rows, request.cols, 'data');
|
|
602
|
+
assertPositiveInteger('segmentAgglomerative', request.k, 'k');
|
|
603
|
+
return requireModule().segmentAgglomerative(
|
|
604
|
+
request.data,
|
|
605
|
+
request.rows,
|
|
606
|
+
request.cols,
|
|
607
|
+
request.k,
|
|
608
|
+
request.linkage ?? 'average',
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/** Enhance diagonal paths in an `n × n` recurrence matrix. */
|
|
613
|
+
export function segmentPathEnhance(request: SegmentPathEnhanceRequest): SegmentMatrix {
|
|
614
|
+
validateSegmentMatrix(
|
|
615
|
+
'segmentPathEnhance',
|
|
616
|
+
request.recurrence,
|
|
617
|
+
request.n,
|
|
618
|
+
request.n,
|
|
619
|
+
'recurrence',
|
|
620
|
+
);
|
|
621
|
+
assertPositiveInteger('segmentPathEnhance', request.win, 'win');
|
|
622
|
+
assertPositiveInteger('segmentPathEnhance', request.maxRatio ?? 2, 'maxRatio');
|
|
623
|
+
assertNonNegativeInteger('segmentPathEnhance', request.minRatio ?? 0, 'minRatio');
|
|
624
|
+
assertPositiveInteger('segmentPathEnhance', request.nFilters ?? 7, 'nFilters');
|
|
625
|
+
return requireModule().segmentPathEnhance(
|
|
626
|
+
request.recurrence,
|
|
627
|
+
request.n,
|
|
628
|
+
request.win,
|
|
629
|
+
request.maxRatio ?? 2,
|
|
630
|
+
request.minRatio ?? 0,
|
|
631
|
+
request.nFilters ?? 7,
|
|
632
|
+
);
|
|
633
|
+
}
|