@libraz/libsonare 1.7.2 → 1.8.0
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 +6 -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 +873 -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 +477 -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 +129 -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 +3758 -1362
- 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 +457 -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 +652 -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 +510 -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 +164 -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 +850 -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 +3909 -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 +335 -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 +128 -0
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
- package/dist/worklet/engine-node.d.ts +81 -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 +68 -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 +73 -0
- package/dist/worklet/engine-strips.d.ts.map +1 -0
- package/dist/worklet/engine-sync.d.ts +37 -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 +397 -0
- package/dist/worklet/engine.d.ts.map +1 -0
- package/dist/worklet/guards.d.ts +47 -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 +323 -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 +2763 -501
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -12
- package/src/_effects_common.ts +17 -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 +97 -22
- package/src/effects_note_ops.ts +635 -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 +377 -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 +282 -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 +346 -32
- package/src/mastering_dynamics.ts +22 -11
- package/src/metering.ts +67 -24
- package/src/mixer.ts +212 -3
- 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 +268 -270
- package/src/public_types.ts +122 -3
- package/src/public_types_acoustic.ts +112 -3
- package/src/public_types_mastering.ts +254 -73
- package/src/public_types_mixing.ts +363 -1
- package/src/public_types_music.ts +312 -2
- package/src/public_types_playback.ts +195 -0
- package/src/public_types_realtime.ts +39 -7
- package/src/public_types_repair.ts +446 -0
- package/src/public_types_spectral.ts +487 -1
- package/src/quick_analysis.ts +203 -26
- package/src/realtime_engine.ts +711 -28
- 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 +1122 -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 +194 -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 +444 -10
- package/src/worklet/engine-node.ts +78 -26
- package/src/worklet/engine-offline.ts +14 -8
- package/src/worklet/engine-parameter-facade.ts +21 -0
- package/src/worklet/engine-processor.ts +272 -83
- package/src/worklet/engine-register.ts +32 -18
- package/src/worklet/engine-strips.ts +280 -9
- package/src/worklet/engine-sync.ts +14 -6
- package/src/worklet/engine.ts +365 -31
- package/src/worklet/guards.ts +140 -44
- package/src/worklet/messages.ts +227 -2
- package/src/worklet/mixer-processor.ts +109 -47
- package/src/worklet/playback-processor.ts +300 -0
- package/src/worklet/protocol.ts +53 -3
- 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,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-call validation options accepted by guarded wrappers. Empty-buffer
|
|
3
|
+
* checks are always performed; pass `{ validate: false }` to opt out of the
|
|
4
|
+
* O(n) NaN/Inf scan on hot paths.
|
|
5
|
+
*
|
|
6
|
+
* `{ validate: false }` only skips this JS-side pre-scan (which raises a
|
|
7
|
+
* `RangeError` naming the exact offending index). It is NOT a way to push
|
|
8
|
+
* non-finite samples into the core: the native layer always re-validates the
|
|
9
|
+
* buffer — through `validate_offline_audio_input` for the offline-analysis
|
|
10
|
+
* entry points, and through the computation's own per-sample guard where a call
|
|
11
|
+
* takes no sample rate to validate against (the waveform bucket kernels) —
|
|
12
|
+
* matching the C ABI / Node / Python surfaces, so an NaN/Inf buffer still
|
|
13
|
+
* throws, just with a generic native message instead of the indexed JS one.
|
|
14
|
+
*/
|
|
15
|
+
export interface ValidateOptions {
|
|
16
|
+
validate?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Offline-analysis sample-rate bounds, mirroring the C++ core limits
|
|
20
|
+
* (`sonare::kMinAudioSampleRate` / `kMaxAudioSampleRate` in `core/audio.h`).
|
|
21
|
+
* Every guarded WASM entry point rejects the same out-of-range rates the C ABI,
|
|
22
|
+
* Node, and Python surfaces do.
|
|
23
|
+
*/
|
|
24
|
+
export declare const MIN_AUDIO_SAMPLE_RATE = 8000;
|
|
25
|
+
export declare const MAX_AUDIO_SAMPLE_RATE = 384000;
|
|
26
|
+
export declare function assertSamples(fnName: string, samples: ArrayLike<number>, validate: boolean, argName?: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* `assertSamples` restricted to the span a windowed entry point actually reads.
|
|
29
|
+
*
|
|
30
|
+
* The emptiness check still covers the whole buffer, and the reported index is
|
|
31
|
+
* the absolute one, so the message keeps naming the sample the caller passed.
|
|
32
|
+
* What narrows is the scan: a windowed call refuses a non-finite sample inside
|
|
33
|
+
* its frame and is indifferent to one outside it, which is the contract the C
|
|
34
|
+
* ABI states and the cost model it promises -- per call the scan is bounded by
|
|
35
|
+
* the frame, not by the length of the buffer being polled.
|
|
36
|
+
*/
|
|
37
|
+
export declare function assertSamplesInWindow(fnName: string, samples: ArrayLike<number>, validate: boolean, windowStart: number, windowLength: number, argName?: string): void;
|
|
38
|
+
export declare function assertFiniteScalar(fnName: string, value: number, argName: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* A NaN gamma is the automatic-bandwidth sentinel the variable-Q transform
|
|
41
|
+
* documents, alongside a negative value, so only an infinity is out of domain.
|
|
42
|
+
*/
|
|
43
|
+
export declare function assertVqtGamma(fnName: string, gamma: number): void;
|
|
44
|
+
export declare function assertSampleRate(fnName: string, sampleRate: number, argName?: string): void;
|
|
45
|
+
/** Validate and retain the public Audio.fromBuffer construction contract. */
|
|
46
|
+
export declare function validateAudioBuffer(samples: Float32Array, sampleRate: number): void;
|
|
47
|
+
/** Bounds of the native `int` every embind argument below is narrowed into. */
|
|
48
|
+
export declare const C_INT_MIN = -2147483648;
|
|
49
|
+
export declare const C_INT_MAX = 2147483647;
|
|
50
|
+
/**
|
|
51
|
+
* Reject an argument embind's declared-`int` narrowing would wrap.
|
|
52
|
+
*
|
|
53
|
+
* A positional embind parameter declared `int` WRAPS rather than saturates, so
|
|
54
|
+
* a kernel of `2 ** 32` arrives as 0 and `2 ** 32 + 1` as 1 — both values the
|
|
55
|
+
* native guards accept, so the call succeeds having separated on a setting the
|
|
56
|
+
* caller never asked for. (The options-object path narrows through
|
|
57
|
+
* `checkedIntFromVal`, which refuses the same inputs in the module; this is the
|
|
58
|
+
* positional path's equivalent.)
|
|
59
|
+
*
|
|
60
|
+
* Reported as the branded `SonareError` carrying `InvalidParameter` rather than
|
|
61
|
+
* a `RangeError`, because the class follows what the rejection stands in for: a
|
|
62
|
+
* `RangeError` is this surface refusing an argument on its own authority, while
|
|
63
|
+
* this one pre-empts a native refusal the caller would have received under that
|
|
64
|
+
* code had the narrowing not wrapped the value into the accepted domain first.
|
|
65
|
+
* The agreement with the Node and Python surfaces is asserted by the Node
|
|
66
|
+
* package's `tests/narrowing-code-parity.test.ts`, which drives one value
|
|
67
|
+
* through all three — weakening this check turns that red.
|
|
68
|
+
*/
|
|
69
|
+
export declare function assertInt32(fnName: string, value: number, argName: string): void;
|
|
70
|
+
/**
|
|
71
|
+
* Check both HPSS kernels before embind narrows them.
|
|
72
|
+
*
|
|
73
|
+
* Parity, positivity and the ceiling stay the core's to enforce, and it names
|
|
74
|
+
* the median filter that rejected the value. What cannot be deferred is the
|
|
75
|
+
* narrowing itself: a wrapped kernel arrives as a legal one and separates on it.
|
|
76
|
+
*
|
|
77
|
+
* These two arrive POSITIONALLY, so they never pass through the options-bag
|
|
78
|
+
* reader and inherit none of its checks. That is what separates this from
|
|
79
|
+
* {@link assertPercussiveSeparation}, which duplicates a reader check to improve
|
|
80
|
+
* a message; here there is no reader to duplicate.
|
|
81
|
+
*/
|
|
82
|
+
export declare function assertHpssKernels(fnName: string, kernelHarmonic: number, kernelPercussive: number): void;
|
|
83
|
+
/**
|
|
84
|
+
* Percussive-event separation fields, as the request objects carry them.
|
|
85
|
+
*/
|
|
86
|
+
export interface PercussiveSeparationFields {
|
|
87
|
+
nFft?: number;
|
|
88
|
+
hopLength?: number;
|
|
89
|
+
hpssKernelHarmonic?: number;
|
|
90
|
+
hpssKernelPercussive?: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check the percussive-event separation's framing and kernels for integrality.
|
|
94
|
+
*
|
|
95
|
+
* All four fields reach the module through one options-bag reader, which now
|
|
96
|
+
* refuses a fractional value itself, so this is the diagnostic rather than the
|
|
97
|
+
* guarantee: it fires first and names the function, where the reader can only
|
|
98
|
+
* name the field. Both reject the same set, so they cannot disagree about an
|
|
99
|
+
* input — only about how the message reads. Do not narrow this to fields the
|
|
100
|
+
* reader misses; there are none, and a check scoped to a gap that no longer
|
|
101
|
+
* exists is how a stale justification outlives its divergence.
|
|
102
|
+
*
|
|
103
|
+
* The fields are iterated rather than named at each call site so a new one is
|
|
104
|
+
* visible here. Absence means the default, so an omitted field is not resolved.
|
|
105
|
+
*/
|
|
106
|
+
export declare function assertPercussiveSeparation(fnName: string, options: PercussiveSeparationFields): void;
|
|
107
|
+
export declare function assertNonNegativeInteger(fnName: string, value: number, argName: string): void;
|
|
108
|
+
/** Integer strictly greater than zero, up to the native `int` ceiling. */
|
|
109
|
+
export declare function assertPositiveInteger(fnName: string, value: number, argName: string): void;
|
|
110
|
+
/**
|
|
111
|
+
* Split "not an integer" into the two mistakes it can be: `TypeError` when the
|
|
112
|
+
* value is not a `number` at all, `RangeError` when it is a number but not
|
|
113
|
+
* integral -- the right-type, wrong-domain half of the same message.
|
|
114
|
+
*
|
|
115
|
+
* `Number.isInteger` alone answers both, which is why a single check reads as
|
|
116
|
+
* sufficient; what it cannot do is say which one happened, and a caller can act
|
|
117
|
+
* only on the mistake they made. The classes are the contract on this surface,
|
|
118
|
+
* so a sibling argument in the same call must not report a fraction differently
|
|
119
|
+
* from this one.
|
|
120
|
+
*/
|
|
121
|
+
export declare function assertIntegerValue(fnName: string, value: unknown, argName: string): asserts value is number;
|
|
122
|
+
/** Even integer in `[min, max]`, for an FFT-style size where only parity matters. */
|
|
123
|
+
export declare function assertEvenIntegerAtLeast(fnName: string, value: number, argName: string, min: number, max: number): void;
|
|
124
|
+
/** General integer-in-`[min, max]` check, for a bound {@link assertU7}/{@link assertNibble} don't cover. */
|
|
125
|
+
export declare function assertBoundedInteger(fnName: string, value: number, argName: string, min: number, max: number): void;
|
|
126
|
+
export declare function assertU7(fnName: string, value: number, argName: string): number;
|
|
127
|
+
export declare function assertNibble(fnName: string, value: number, argName: string): number;
|
|
128
|
+
export declare function assertU32(fnName: string, value: number, argName: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Convert a caller-supplied index array to `Int32Array`, refusing any element
|
|
131
|
+
* the conversion would change rather than folding it.
|
|
132
|
+
*
|
|
133
|
+
* `Int32Array.from(values, Math.trunc)` turns the sample index `1000.7` into
|
|
134
|
+
* `1000` and `2 ** 31` into `-2 ** 31`. The C ABI takes `const int*`, so both
|
|
135
|
+
* arrive as values nothing downstream can separate from ones the caller chose.
|
|
136
|
+
* An `Int32Array` is returned as-is: its elements are already exact.
|
|
137
|
+
*/
|
|
138
|
+
export declare function toInt32Array(fnName: string, values: Int32Array | ArrayLike<number>, argName: string): Int32Array;
|
|
139
|
+
export declare function assertInterleavedSamples(fnName: string, samples: ArrayLike<number>, channels: number, validate: boolean): void;
|
|
140
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { MidiCcBindOptions } from './realtime_engine';
|
|
2
|
+
export interface WebMidiEngine {
|
|
3
|
+
bindMidiCc(channel: number, controller: number, paramId: number, options?: MidiCcBindOptions): void;
|
|
4
|
+
setMidiInputSource(destinationId?: number): void;
|
|
5
|
+
clearMidiInputSource(): void;
|
|
6
|
+
pushMidiInputNoteOn(group: number, channel: number, note: number, velocity: number, time?: number): void;
|
|
7
|
+
pushMidiInputNoteOff(group: number, channel: number, note: number, velocity?: number, time?: number): void;
|
|
8
|
+
pushMidiInputCc(group: number, channel: number, controller: number, value: number, time?: number): void;
|
|
9
|
+
}
|
|
10
|
+
type MidiInputState = 'connected' | 'disconnected';
|
|
11
|
+
interface MidiPortLike {
|
|
12
|
+
id: string;
|
|
13
|
+
name?: string | null;
|
|
14
|
+
manufacturer?: string | null;
|
|
15
|
+
state?: MidiInputState;
|
|
16
|
+
}
|
|
17
|
+
interface MidiMessageEventLike {
|
|
18
|
+
data: ArrayLike<number>;
|
|
19
|
+
timeStamp?: number;
|
|
20
|
+
receivedTime?: number;
|
|
21
|
+
target?: MidiPortLike;
|
|
22
|
+
currentTarget?: MidiPortLike;
|
|
23
|
+
}
|
|
24
|
+
interface MidiInputLike extends MidiPortLike {
|
|
25
|
+
type?: 'input';
|
|
26
|
+
onmidimessage: ((event: MidiMessageEventLike) => void) | null;
|
|
27
|
+
addEventListener?: (type: 'midimessage', listener: (event: MidiMessageEventLike) => void) => void;
|
|
28
|
+
removeEventListener?: (type: 'midimessage', listener: (event: MidiMessageEventLike) => void) => void;
|
|
29
|
+
}
|
|
30
|
+
interface MidiConnectionEventLike {
|
|
31
|
+
port?: MidiPortLike | null;
|
|
32
|
+
}
|
|
33
|
+
interface MidiAccessLike {
|
|
34
|
+
inputs: Map<string, MidiInputLike> | Iterable<[string, MidiInputLike]>;
|
|
35
|
+
onstatechange: ((event: MidiConnectionEventLike) => void) | null;
|
|
36
|
+
addEventListener?: (type: 'statechange', listener: (event: MidiConnectionEventLike) => void) => void;
|
|
37
|
+
removeEventListener?: (type: 'statechange', listener: (event: MidiConnectionEventLike) => void) => void;
|
|
38
|
+
}
|
|
39
|
+
export interface WebMidiCcBinding {
|
|
40
|
+
channel: number;
|
|
41
|
+
controller: number;
|
|
42
|
+
paramId: number;
|
|
43
|
+
options?: MidiCcBindOptions;
|
|
44
|
+
}
|
|
45
|
+
export interface WebMidiInputInfo {
|
|
46
|
+
id: string;
|
|
47
|
+
name: string;
|
|
48
|
+
manufacturer: string;
|
|
49
|
+
state: MidiInputState;
|
|
50
|
+
}
|
|
51
|
+
export interface BindWebMidiOptions {
|
|
52
|
+
/** Realtime-engine MIDI destination receiving the live input source. Default `0`. */
|
|
53
|
+
destinationId?: number;
|
|
54
|
+
/** UMP group used for MIDI 1.0 channel voice events. Default `0`. */
|
|
55
|
+
group?: number;
|
|
56
|
+
/** Restrict binding to specific Web MIDI input ids. Omit or empty = all connected inputs. */
|
|
57
|
+
inputIds?: readonly string[];
|
|
58
|
+
/** Request SysEx-capable access from the browser. Default `false`. */
|
|
59
|
+
sysex?: boolean;
|
|
60
|
+
/** Request software ports from the browser where supported. Default `true`. */
|
|
61
|
+
software?: boolean;
|
|
62
|
+
/** Bind CC-to-parameter mappings before ports are connected. */
|
|
63
|
+
ccBindings?: readonly WebMidiCcBinding[];
|
|
64
|
+
/** Convert a Web MIDI event timestamp to engine port-time samples. */
|
|
65
|
+
timestampToSamples?: (eventTimeMs: number) => number;
|
|
66
|
+
/** Observe hot-plug updates after the helper rebinds matching inputs. */
|
|
67
|
+
onInputsChanged?: (inputs: WebMidiInputInfo[]) => void;
|
|
68
|
+
}
|
|
69
|
+
export interface WebMidiBinding {
|
|
70
|
+
access: MidiAccessLike;
|
|
71
|
+
inputs(): WebMidiInputInfo[];
|
|
72
|
+
close(): void;
|
|
73
|
+
}
|
|
74
|
+
export declare function isWebMidiAvailable(): boolean;
|
|
75
|
+
export declare function bindWebMidi(engine: WebMidiEngine, options?: BindWebMidiOptions): Promise<WebMidiBinding>;
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=web_midi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web_midi.d.ts","sourceRoot":"","sources":["../src/web_midi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,MAAM,WAAW,aAAa;IAC5B,UAAU,CACR,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,iBAAiB,GAC1B,IAAI,CAAC;IACR,kBAAkB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,oBAAoB,IAAI,IAAI,CAAC;IAC7B,mBAAmB,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAAC;IACR,oBAAoB,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAAC;IACR,eAAe,CACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,GACZ,IAAI,CAAC;CACT;AAED,KAAK,cAAc,GAAG,WAAW,GAAG,cAAc,CAAC;AAEnD,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED,UAAU,aAAc,SAAQ,YAAY;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,KAAK,IAAI,CAAC;IAClG,mBAAmB,CAAC,EAAE,CACpB,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,KAC5C,IAAI,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,IAAI,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5B;AAED,UAAU,cAAc;IACtB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IACvE,aAAa,EAAE,CAAC,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACjE,gBAAgB,CAAC,EAAE,CACjB,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,KAC/C,IAAI,CAAC;IACV,mBAAmB,CAAC,EAAE,CACpB,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,KAC/C,IAAI,CAAC;CACX;AASD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gEAAgE;IAChE,UAAU,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACzC,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;IACrD,yEAAyE;IACzE,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACxD;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,IAAI,gBAAgB,EAAE,CAAC;IAC7B,KAAK,IAAI,IAAI,CAAC;CACf;AAQD,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,cAAc,CAAC,CAqIzB"}
|
package/dist/worker.d.ts
CHANGED
|
@@ -1,46 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal structured-clone protocol for the offline Web Worker bridge.
|
|
3
|
-
*
|
|
4
|
-
* Keep this deliberately limited to one-shot operations. Embind handles own
|
|
5
|
-
* native resources and cannot safely cross a worker boundary.
|
|
6
|
-
*/
|
|
7
|
-
type OfflineWorkerOperation = 'analyze' | 'detectBpm' | 'detectKey' | 'detectChords' | 'masterAudio' | 'masterAudioStereo';
|
|
8
|
-
interface OfflineWorkerRunMessage {
|
|
9
|
-
type: 'sonare:offline-run';
|
|
10
|
-
id: number;
|
|
11
|
-
operation: OfflineWorkerOperation;
|
|
12
|
-
request: Record<string, unknown>;
|
|
13
|
-
/** A shared flag lets cancellation reach synchronous WASM progress callbacks. */
|
|
14
|
-
cancelBuffer?: SharedArrayBuffer;
|
|
15
|
-
}
|
|
16
|
-
interface OfflineWorkerCancelMessage {
|
|
17
|
-
type: 'sonare:offline-cancel';
|
|
18
|
-
id: number;
|
|
19
|
-
}
|
|
20
|
-
type OfflineWorkerRequestMessage = OfflineWorkerRunMessage | OfflineWorkerCancelMessage;
|
|
21
|
-
interface OfflineWorkerProgressMessage {
|
|
22
|
-
type: 'sonare:offline-progress';
|
|
23
|
-
id: number;
|
|
24
|
-
progress: number;
|
|
25
|
-
stage: string;
|
|
26
|
-
}
|
|
27
|
-
interface OfflineWorkerResultMessage {
|
|
28
|
-
type: 'sonare:offline-result';
|
|
29
|
-
id: number;
|
|
30
|
-
result: unknown;
|
|
31
|
-
}
|
|
32
|
-
interface OfflineWorkerErrorMessage {
|
|
33
|
-
type: 'sonare:offline-error';
|
|
34
|
-
id: number;
|
|
35
|
-
error: {
|
|
36
|
-
name: string;
|
|
37
|
-
message: string;
|
|
38
|
-
code?: number;
|
|
39
|
-
codeName?: string;
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
type OfflineWorkerResponseMessage = OfflineWorkerProgressMessage | OfflineWorkerResultMessage | OfflineWorkerErrorMessage;
|
|
43
|
-
|
|
44
1
|
/**
|
|
45
2
|
* Offline one-shot operations hosted inside a dedicated Web Worker.
|
|
46
3
|
*
|
|
@@ -49,9 +6,10 @@ type OfflineWorkerResponseMessage = OfflineWorkerProgressMessage | OfflineWorker
|
|
|
49
6
|
* bound to one JavaScript realm, so moving them across a Worker boundary would
|
|
50
7
|
* make ownership and `delete()` semantics unsound.
|
|
51
8
|
*/
|
|
52
|
-
|
|
9
|
+
import type { OfflineWorkerRequestMessage, OfflineWorkerResponseMessage } from './worker_protocol';
|
|
10
|
+
export type { OfflineWorkerOperation } from './worker_protocol';
|
|
53
11
|
/** Minimal endpoint shared by browser Workers and the Node worker-thread test bridge. */
|
|
54
|
-
interface OfflineWorkerEndpoint {
|
|
12
|
+
export interface OfflineWorkerEndpoint {
|
|
55
13
|
postMessage(message: OfflineWorkerResponseMessage, transfer?: Transferable[]): void;
|
|
56
14
|
addEventListener(type: 'message', listener: (event: MessageEvent<OfflineWorkerRequestMessage>) => void): void;
|
|
57
15
|
}
|
|
@@ -60,6 +18,5 @@ interface OfflineWorkerEndpoint {
|
|
|
60
18
|
* the Node `worker_threads` test adapter; browsers install it automatically
|
|
61
19
|
* when this module is loaded as a Worker entry point.
|
|
62
20
|
*/
|
|
63
|
-
declare function installOfflineWorkerEndpoint(endpoint: OfflineWorkerEndpoint): void;
|
|
64
|
-
|
|
65
|
-
export { type OfflineWorkerEndpoint, type OfflineWorkerOperation, installOfflineWorkerEndpoint };
|
|
21
|
+
export declare function installOfflineWorkerEndpoint(endpoint: OfflineWorkerEndpoint): void;
|
|
22
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,OAAO,KAAK,EAEV,2BAA2B,EAC3B,4BAA4B,EAE7B,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEhE,yFAAyF;AACzF,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,OAAO,EAAE,4BAA4B,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IACpF,gBAAgB,CACd,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,2BAA2B,CAAC,KAAK,IAAI,GACnE,IAAI,CAAC;CACT;AAyDD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CA0FlF"}
|
package/dist/worker.js
CHANGED
|
@@ -6,7 +6,21 @@ var SonareError = class extends Error {
|
|
|
6
6
|
this.code = code;
|
|
7
7
|
this.codeName = codeName;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Brand-based `instanceof`: an error that carries the shape narrows here even
|
|
11
|
+
* when it is not literally an instance of this class. That is not a
|
|
12
|
+
* hypothetical — an error posted from the analysis worker arrives as a
|
|
13
|
+
* structured clone with its prototype gone, which a prototype-based
|
|
14
|
+
* `instanceof` would silently miss. Delegates to {@link isSonareError} so the
|
|
15
|
+
* two never disagree.
|
|
16
|
+
*/
|
|
17
|
+
static [Symbol.hasInstance](value) {
|
|
18
|
+
return isSonareError(value);
|
|
19
|
+
}
|
|
9
20
|
};
|
|
21
|
+
function isSonareError(value) {
|
|
22
|
+
return value instanceof Error && value.name === "SonareError" && typeof value.code === "number";
|
|
23
|
+
}
|
|
10
24
|
|
|
11
25
|
// src/module_state.ts
|
|
12
26
|
var wrappedModule = null;
|
|
@@ -34,6 +48,11 @@ function makeSonareError(raw, thrown) {
|
|
|
34
48
|
message = info.message || message;
|
|
35
49
|
}
|
|
36
50
|
} catch {
|
|
51
|
+
} finally {
|
|
52
|
+
try {
|
|
53
|
+
raw.sonareReleaseException(thrown);
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
37
56
|
}
|
|
38
57
|
return new SonareError(code, codeName, message);
|
|
39
58
|
}
|
|
@@ -54,6 +73,10 @@ function wrapModuleErrors(raw) {
|
|
|
54
73
|
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof Promise) {
|
|
55
74
|
return value;
|
|
56
75
|
}
|
|
76
|
+
const proto = Object.getPrototypeOf(value);
|
|
77
|
+
if (Array.isArray(value) || proto === Object.prototype || proto === null) {
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
57
80
|
const objectValue = value;
|
|
58
81
|
const cached = objectCache.get(objectValue);
|
|
59
82
|
if (cached) {
|
|
@@ -150,6 +173,46 @@ function getSonareModule() {
|
|
|
150
173
|
return wrappedModule;
|
|
151
174
|
}
|
|
152
175
|
|
|
176
|
+
// src/codes.ts
|
|
177
|
+
function resolveOrdinalInRange(value, min, max, enumName) {
|
|
178
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
|
|
179
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
180
|
+
}
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
183
|
+
function resolveEnumOrdinal(value, values, enumName) {
|
|
184
|
+
if (typeof value === "number") {
|
|
185
|
+
const ordinals = Object.values(values);
|
|
186
|
+
const ordinal = resolveOrdinalInRange(
|
|
187
|
+
value,
|
|
188
|
+
Math.min(...ordinals),
|
|
189
|
+
Math.max(...ordinals),
|
|
190
|
+
enumName
|
|
191
|
+
);
|
|
192
|
+
if (!ordinals.includes(ordinal)) {
|
|
193
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
194
|
+
}
|
|
195
|
+
return ordinal;
|
|
196
|
+
}
|
|
197
|
+
if (typeof value === "string") {
|
|
198
|
+
const ordinal = values[value];
|
|
199
|
+
if (ordinal !== void 0) {
|
|
200
|
+
return ordinal;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
204
|
+
}
|
|
205
|
+
var AUTOMATION_CURVE_VALUES = {
|
|
206
|
+
linear: 0,
|
|
207
|
+
exponential: 1,
|
|
208
|
+
hold: 2,
|
|
209
|
+
"s-curve": 3
|
|
210
|
+
};
|
|
211
|
+
var PROJECT_AUTOMATION_CURVE_VALUES = {
|
|
212
|
+
...AUTOMATION_CURVE_VALUES,
|
|
213
|
+
scurve: 3
|
|
214
|
+
};
|
|
215
|
+
|
|
153
216
|
// src/validation.ts
|
|
154
217
|
var MIN_AUDIO_SAMPLE_RATE = 8e3;
|
|
155
218
|
var MAX_AUDIO_SAMPLE_RATE = 384e3;
|
|
@@ -173,10 +236,13 @@ function assertSamples(fnName, samples, validate, argName = "samples") {
|
|
|
173
236
|
assertNonEmptySamples(fnName, samples, argName);
|
|
174
237
|
assertFiniteSamples(fnName, samples, validate, argName);
|
|
175
238
|
}
|
|
176
|
-
function assertSampleRate(fnName, sampleRate) {
|
|
177
|
-
if (!Number.isInteger(sampleRate)
|
|
239
|
+
function assertSampleRate(fnName, sampleRate, argName = "sampleRate") {
|
|
240
|
+
if (!Number.isInteger(sampleRate)) {
|
|
241
|
+
throw new RangeError(`${fnName}: ${argName} must be an integer`);
|
|
242
|
+
}
|
|
243
|
+
if (sampleRate < MIN_AUDIO_SAMPLE_RATE || sampleRate > MAX_AUDIO_SAMPLE_RATE) {
|
|
178
244
|
throw new RangeError(
|
|
179
|
-
`${fnName}:
|
|
245
|
+
`${fnName}: ${argName} out of supported range [${MIN_AUDIO_SAMPLE_RATE}, ${MAX_AUDIO_SAMPLE_RATE}]`
|
|
180
246
|
);
|
|
181
247
|
}
|
|
182
248
|
}
|
|
@@ -284,36 +350,6 @@ function masterAudioStereo(left, right = void 0, sampleRate = 22050, presetName
|
|
|
284
350
|
);
|
|
285
351
|
}
|
|
286
352
|
|
|
287
|
-
// src/codes.ts
|
|
288
|
-
function resolveOrdinalInRange(value, min, max, enumName) {
|
|
289
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
|
|
290
|
-
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
291
|
-
}
|
|
292
|
-
return value;
|
|
293
|
-
}
|
|
294
|
-
function resolveEnumOrdinal(value, values, enumName) {
|
|
295
|
-
if (typeof value === "number") {
|
|
296
|
-
const ordinals = Object.values(values);
|
|
297
|
-
const ordinal = resolveOrdinalInRange(
|
|
298
|
-
value,
|
|
299
|
-
Math.min(...ordinals),
|
|
300
|
-
Math.max(...ordinals),
|
|
301
|
-
enumName
|
|
302
|
-
);
|
|
303
|
-
if (!ordinals.includes(ordinal)) {
|
|
304
|
-
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
305
|
-
}
|
|
306
|
-
return ordinal;
|
|
307
|
-
}
|
|
308
|
-
if (typeof value === "string") {
|
|
309
|
-
const ordinal = values[value];
|
|
310
|
-
if (ordinal !== void 0) {
|
|
311
|
-
return ordinal;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
353
|
// src/public_types_music.ts
|
|
318
354
|
var PitchClass = {
|
|
319
355
|
C: 0,
|
|
@@ -426,6 +462,7 @@ function convertChordAnalysisResult(wasm) {
|
|
|
426
462
|
quality: c.quality,
|
|
427
463
|
start: c.start,
|
|
428
464
|
end: c.end,
|
|
465
|
+
duration: c.end - c.start,
|
|
429
466
|
confidence: c.confidence,
|
|
430
467
|
name: c.name
|
|
431
468
|
}))
|
|
@@ -464,6 +501,10 @@ function convertAnalysisResult(wasm) {
|
|
|
464
501
|
timeSignatureCandidates: wasm.timeSignatureCandidates,
|
|
465
502
|
beatTimes,
|
|
466
503
|
beats: wasm.beats,
|
|
504
|
+
downbeatIndices: wasm.downbeatIndices,
|
|
505
|
+
downbeatPhase: wasm.downbeatPhase,
|
|
506
|
+
beatObservations: wasm.beatObservations,
|
|
507
|
+
beatLocalBpm: wasm.beatLocalBpm,
|
|
467
508
|
chords: wasm.chords.map((c) => ({
|
|
468
509
|
root: c.root,
|
|
469
510
|
bass: c.bass,
|
|
@@ -472,8 +513,10 @@ function convertAnalysisResult(wasm) {
|
|
|
472
513
|
quality: c.quality,
|
|
473
514
|
start: c.start,
|
|
474
515
|
end: c.end,
|
|
516
|
+
duration: c.end - c.start,
|
|
475
517
|
confidence: c.confidence,
|
|
476
|
-
name: c.name
|
|
518
|
+
name: c.name,
|
|
519
|
+
romanNumeral: c.romanNumeral
|
|
477
520
|
})),
|
|
478
521
|
sections: wasm.sections.map((s) => ({
|
|
479
522
|
type: s.type,
|
|
@@ -546,12 +589,13 @@ function detectChords(samples, sampleRate = 22050, options = {}) {
|
|
|
546
589
|
request.keyRoot ?? PitchClass.C,
|
|
547
590
|
request.keyMode ?? Mode.Major,
|
|
548
591
|
request.detectInversions ?? false,
|
|
549
|
-
chordChromaMethodValue(request.chromaMethod ?? "stft")
|
|
592
|
+
chordChromaMethodValue(request.chromaMethod ?? "stft"),
|
|
593
|
+
request.tuning ?? 0
|
|
550
594
|
);
|
|
551
595
|
return convertChordAnalysisResult(result);
|
|
552
596
|
}
|
|
553
|
-
function analyzeWithProgress(samples, sampleRate = 22050, onProgress) {
|
|
554
|
-
const request = samples instanceof Float32Array ? { samples, sampleRate, onProgress } : samples;
|
|
597
|
+
function analyzeWithProgress(samples, sampleRate = 22050, onProgress, options) {
|
|
598
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, onProgress, options } : samples;
|
|
555
599
|
validateAnalysisInput(
|
|
556
600
|
"analyzeWithProgress",
|
|
557
601
|
request.samples,
|
|
@@ -561,6 +605,7 @@ function analyzeWithProgress(samples, sampleRate = 22050, onProgress) {
|
|
|
561
605
|
const result = requireModule2().analyzeWithProgress(
|
|
562
606
|
request.samples,
|
|
563
607
|
request.sampleRate ?? 22050,
|
|
608
|
+
request.options ?? {},
|
|
564
609
|
request.onProgress ?? (() => {
|
|
565
610
|
}),
|
|
566
611
|
request.cancel ?? (() => false)
|
|
@@ -646,7 +691,9 @@ function cancelledError() {
|
|
|
646
691
|
}
|
|
647
692
|
function installOfflineWorkerEndpoint(endpoint2) {
|
|
648
693
|
const cancelled = /* @__PURE__ */ new Set();
|
|
694
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
649
695
|
const run = async (message) => {
|
|
696
|
+
inFlight.add(message.id);
|
|
650
697
|
const cancelFlag = message.cancelBuffer ? new Int32Array(message.cancelBuffer) : void 0;
|
|
651
698
|
const isCancelled = () => cancelled.has(message.id) || cancelFlag !== void 0 && Atomics.load(cancelFlag, 0) !== 0;
|
|
652
699
|
const onProgress = (progress, stage) => {
|
|
@@ -663,7 +710,8 @@ function installOfflineWorkerEndpoint(endpoint2) {
|
|
|
663
710
|
case "analyze":
|
|
664
711
|
result = analyzeWithProgress({
|
|
665
712
|
...message.request,
|
|
666
|
-
onProgress
|
|
713
|
+
onProgress,
|
|
714
|
+
cancel: isCancelled
|
|
667
715
|
});
|
|
668
716
|
break;
|
|
669
717
|
case "detectBpm":
|
|
@@ -678,13 +726,15 @@ function installOfflineWorkerEndpoint(endpoint2) {
|
|
|
678
726
|
case "masterAudio":
|
|
679
727
|
result = masterAudio({
|
|
680
728
|
...message.request,
|
|
681
|
-
onProgress
|
|
729
|
+
onProgress,
|
|
730
|
+
cancel: isCancelled
|
|
682
731
|
});
|
|
683
732
|
break;
|
|
684
733
|
case "masterAudioStereo":
|
|
685
734
|
result = masterAudioStereo({
|
|
686
735
|
...message.request,
|
|
687
|
-
onProgress
|
|
736
|
+
onProgress,
|
|
737
|
+
cancel: isCancelled
|
|
688
738
|
});
|
|
689
739
|
break;
|
|
690
740
|
}
|
|
@@ -703,12 +753,15 @@ function installOfflineWorkerEndpoint(endpoint2) {
|
|
|
703
753
|
});
|
|
704
754
|
} finally {
|
|
705
755
|
cancelled.delete(message.id);
|
|
756
|
+
inFlight.delete(message.id);
|
|
706
757
|
}
|
|
707
758
|
};
|
|
708
759
|
endpoint2.addEventListener("message", (event) => {
|
|
709
760
|
const message = event.data;
|
|
710
761
|
if (message.type === "sonare:offline-cancel") {
|
|
711
|
-
|
|
762
|
+
if (inFlight.has(message.id)) {
|
|
763
|
+
cancelled.add(message.id);
|
|
764
|
+
}
|
|
712
765
|
return;
|
|
713
766
|
}
|
|
714
767
|
void run(message);
|