@libraz/libsonare 1.5.4 → 1.5.5
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/dist/index.d.ts +116 -30
- package/dist/index.js +133 -56
- package/dist/index.js.map +1 -1
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +23 -1
- package/dist/worklet.js +27 -3
- package/dist/worklet.js.map +1 -1
- package/package.json +1 -1
- package/src/_chain_config.ts +0 -20
- package/src/analysis_helpers.ts +23 -0
- package/src/audio.ts +5 -3
- package/src/effects_transform.ts +12 -6
- package/src/feature_core.ts +19 -1
- package/src/feature_music.ts +18 -14
- package/src/feature_pitch.ts +5 -5
- package/src/feature_spectral.ts +3 -3
- package/src/feature_spectrogram.ts +27 -5
- package/src/index.ts +3 -0
- package/src/mastering_core.ts +2 -0
- package/src/metering.ts +45 -4
- package/src/mixer.ts +14 -1
- package/src/project_class.ts +12 -5
- package/src/public_types_mastering.ts +6 -0
- package/src/public_types_music.ts +4 -0
- package/src/public_types_spectral.ts +10 -3
- package/src/quick_analysis.ts +23 -5
- package/src/realtime_engine.ts +9 -1
- package/src/sonare.js.d.ts +29 -3
- package/src/streaming_processors.ts +7 -1
- package/src/validation.ts +6 -0
- package/src/worklet/messages.ts +16 -2
- package/src/worklet/protocol.ts +2 -0
package/src/project_class.ts
CHANGED
|
@@ -449,7 +449,11 @@ export class Project {
|
|
|
449
449
|
this.native.setMidiEvents(clipId, events);
|
|
450
450
|
}
|
|
451
451
|
|
|
452
|
-
/**
|
|
452
|
+
/**
|
|
453
|
+
* Import an in-memory SMF buffer; returns the first added clip id.
|
|
454
|
+
* Malformed or partially truncated tracks are rejected instead of installing
|
|
455
|
+
* a silently shortened clip.
|
|
456
|
+
*/
|
|
453
457
|
importSmf(data: Uint8Array): number {
|
|
454
458
|
return this.native.importSmf(data);
|
|
455
459
|
}
|
|
@@ -498,7 +502,10 @@ export class Project {
|
|
|
498
502
|
this.native.setProgramOnChannel(clipId, group, channel, program, bank);
|
|
499
503
|
}
|
|
500
504
|
|
|
501
|
-
/**
|
|
505
|
+
/**
|
|
506
|
+
* Destructively bake a MIDI-FX chain into all stored events. Large clips are
|
|
507
|
+
* drained without truncation; failure leaves the original clip unchanged.
|
|
508
|
+
*/
|
|
502
509
|
bakeMidiFx(clipId: number, configJson: string): void {
|
|
503
510
|
this.native.bakeMidiFx(clipId, configJson);
|
|
504
511
|
}
|
|
@@ -510,9 +517,9 @@ export class Project {
|
|
|
510
517
|
|
|
511
518
|
/**
|
|
512
519
|
* Pre-flight check for hanging / unmatched notes in a MIDI clip: reports
|
|
513
|
-
* whether every note-on
|
|
514
|
-
*
|
|
515
|
-
* or not a MIDI clip.
|
|
520
|
+
* whether every note-on in the exported half-open playback window has a
|
|
521
|
+
* matching note-off (FIFO per group+channel+note). Useful before bouncing to
|
|
522
|
+
* catch a stuck note. Throws if `clipId` is unknown or not a MIDI clip.
|
|
516
523
|
*/
|
|
517
524
|
validateMidiNotes(clipId: number): ProjectNotePairValidation {
|
|
518
525
|
return this.native.validateMidiNotes(clipId);
|
|
@@ -138,6 +138,8 @@ export interface MasteringResult {
|
|
|
138
138
|
inputLufs: number;
|
|
139
139
|
outputLufs: number;
|
|
140
140
|
appliedGainDb: number;
|
|
141
|
+
/** True when peak headroom prevented the requested LUFS target. */
|
|
142
|
+
loudnessTargetLimited?: boolean;
|
|
141
143
|
latencySamples?: number;
|
|
142
144
|
}
|
|
143
145
|
|
|
@@ -329,6 +331,7 @@ export interface MasteringChainConfig {
|
|
|
329
331
|
monoMaker?: {
|
|
330
332
|
enabled?: boolean;
|
|
331
333
|
amount?: number;
|
|
334
|
+
frequencyHz?: number;
|
|
332
335
|
};
|
|
333
336
|
};
|
|
334
337
|
maximizer?: {
|
|
@@ -407,6 +410,8 @@ export interface MasteringChainResult {
|
|
|
407
410
|
outputTruePeakDbtp: number;
|
|
408
411
|
/** EBU Tech 3342 Loudness Range of the output (LU). */
|
|
409
412
|
outputLra: number;
|
|
413
|
+
/** True when peak headroom prevented the requested LUFS target. */
|
|
414
|
+
loudnessTargetLimited: boolean;
|
|
410
415
|
/** Per-stage gain reductions for the dynamics/maximizer stages (a subset of `stages`). */
|
|
411
416
|
stageGainReductions: StageGainReduction[];
|
|
412
417
|
}
|
|
@@ -422,6 +427,7 @@ export interface MasteringChainStereoResult {
|
|
|
422
427
|
/** See {@link MasteringChainResult} for field semantics. */
|
|
423
428
|
outputTruePeakDbtp: number;
|
|
424
429
|
outputLra: number;
|
|
430
|
+
loudnessTargetLimited: boolean;
|
|
425
431
|
stageGainReductions: StageGainReduction[];
|
|
426
432
|
}
|
|
427
433
|
|
|
@@ -233,6 +233,10 @@ export interface Beat {
|
|
|
233
233
|
export interface Chord {
|
|
234
234
|
root: PitchClass;
|
|
235
235
|
bass: PitchClass;
|
|
236
|
+
/** Canonical core spelling; stable across all language bindings. */
|
|
237
|
+
rootName: string;
|
|
238
|
+
/** Canonical core spelling; stable across all language bindings. */
|
|
239
|
+
bassName: string;
|
|
236
240
|
quality: ChordQuality;
|
|
237
241
|
start: number;
|
|
238
242
|
end: number;
|
|
@@ -30,15 +30,16 @@ export interface PitchCorrectOptions extends ValidateOptions {
|
|
|
30
30
|
export interface NoteStretchOptions {
|
|
31
31
|
/** Note onset position in samples (selects the region). Default 0. */
|
|
32
32
|
onsetSample?: number;
|
|
33
|
-
/** Note offset position in samples (selects the region).
|
|
33
|
+
/** Note offset position in samples (selects the region). Defaults to the input length. */
|
|
34
34
|
offsetSample?: number;
|
|
35
|
-
/** Stretch ratio (0.5 =
|
|
35
|
+
/** Stretch ratio (0.5 = half duration, 2.0 = double duration). Default 1. */
|
|
36
36
|
stretchRatio?: number;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/** Options for `noteMove`. */
|
|
40
40
|
export interface NoteMoveOptions {
|
|
41
41
|
onsetSample?: number;
|
|
42
|
+
/** Defaults to the input length. */
|
|
42
43
|
offsetSample?: number;
|
|
43
44
|
targetOnsetSample?: number;
|
|
44
45
|
}
|
|
@@ -47,7 +48,7 @@ export interface NoteMoveOptions {
|
|
|
47
48
|
export type SpectralEditMode = 'gain' | 'attenuate' | 'mute' | 'heal';
|
|
48
49
|
|
|
49
50
|
/** Analysis/synthesis window used by `spectralEdit`. */
|
|
50
|
-
export type SpectralEditWindow = 'hann' | 'hamming' | 'blackman' | 'rectangular';
|
|
51
|
+
export type SpectralEditWindow = 'hann' | 'hamming' | 'blackman' | 'rectangular' | 'rect';
|
|
51
52
|
|
|
52
53
|
/** One time x frequency rectangle edit op for `spectralEdit`. */
|
|
53
54
|
export interface SpectralRegionOp {
|
|
@@ -186,8 +187,14 @@ export interface PitchResult {
|
|
|
186
187
|
*/
|
|
187
188
|
export interface LufsResult {
|
|
188
189
|
integratedLufs: number;
|
|
190
|
+
/** Final complete 400 ms window, not Max-M. */
|
|
189
191
|
momentaryLufs: number;
|
|
192
|
+
/** Final complete 3 s window, not Max-S. */
|
|
190
193
|
shortTermLufs: number;
|
|
194
|
+
/** Maximum 400 ms window (EBU R128 Max-M). */
|
|
195
|
+
maxMomentaryLufs: number;
|
|
196
|
+
/** Maximum 3 s window (EBU R128 Max-S). */
|
|
197
|
+
maxShortTermLufs: number;
|
|
191
198
|
loudnessRange: number;
|
|
192
199
|
}
|
|
193
200
|
|
package/src/quick_analysis.ts
CHANGED
|
@@ -378,20 +378,38 @@ export function chordFunctionalAnalysis(
|
|
|
378
378
|
* the UI responsive for long inputs, drive this from a Web Worker and use
|
|
379
379
|
* {@link analyzeWithProgress} to report progress.
|
|
380
380
|
*/
|
|
381
|
-
export
|
|
381
|
+
export interface MusicAnalyzeOptions {
|
|
382
|
+
nFft?: number;
|
|
383
|
+
hopLength?: number;
|
|
384
|
+
bpmMin?: number;
|
|
385
|
+
bpmMax?: number;
|
|
386
|
+
startBpm?: number;
|
|
387
|
+
useTriadsOnly?: boolean;
|
|
388
|
+
useHpss?: boolean;
|
|
389
|
+
chromaHighpassHz?: number;
|
|
390
|
+
useBassWeighted?: boolean;
|
|
391
|
+
chromaHopMultiplier?: number;
|
|
392
|
+
useChordHmm?: boolean;
|
|
393
|
+
useChordKeyContext?: boolean;
|
|
394
|
+
chordHmmBeamWidth?: number;
|
|
395
|
+
detectChordInversions?: boolean;
|
|
396
|
+
}
|
|
397
|
+
export interface MusicAnalyzeRequest extends SamplesRequest, MusicAnalyzeOptions {}
|
|
398
|
+
|
|
399
|
+
export function analyze(request: MusicAnalyzeRequest): AnalysisResult;
|
|
382
400
|
export function analyze(
|
|
383
401
|
samples: Float32Array,
|
|
384
402
|
sampleRate?: number,
|
|
385
|
-
options?: GuardedOptions,
|
|
403
|
+
options?: GuardedOptions & MusicAnalyzeOptions,
|
|
386
404
|
): AnalysisResult;
|
|
387
405
|
export function analyze(
|
|
388
|
-
samples: Float32Array |
|
|
406
|
+
samples: Float32Array | MusicAnalyzeRequest,
|
|
389
407
|
sampleRate = 22050,
|
|
390
|
-
options: GuardedOptions = {},
|
|
408
|
+
options: GuardedOptions & MusicAnalyzeOptions = {},
|
|
391
409
|
): AnalysisResult {
|
|
392
410
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
393
411
|
validateAnalysisInput('analyze', request.samples, request.sampleRate ?? 22050, request);
|
|
394
|
-
const result = requireModule().analyze(request.samples, request.sampleRate ?? 22050);
|
|
412
|
+
const result = requireModule().analyze(request.samples, request.sampleRate ?? 22050, request);
|
|
395
413
|
return convertAnalysisResult(result);
|
|
396
414
|
}
|
|
397
415
|
|
package/src/realtime_engine.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { panLawCode, panModeCode, sendTimingCode } from './codes';
|
|
2
2
|
import { ErrorCode, SonareError } from './errors';
|
|
3
3
|
import { getSonareModule } from './module_state';
|
|
4
|
-
import type { SynthPatch } from './project';
|
|
4
|
+
import type { ProjectMidiCcBinding, SynthPatch } from './project';
|
|
5
5
|
import type { EqBand, PanLaw, PanMode, SendTiming } from './public_types';
|
|
6
6
|
import type {
|
|
7
7
|
WasmClipPageRequest,
|
|
@@ -290,6 +290,11 @@ export class RealtimeEngine {
|
|
|
290
290
|
);
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
/** Bind a 7/14-bit CC, RPN, or NRPN descriptor to a live parameter. */
|
|
294
|
+
bindMidiCcBinding(binding: ProjectMidiCcBinding): void {
|
|
295
|
+
this.native.bindMidiCcBinding(binding);
|
|
296
|
+
}
|
|
297
|
+
|
|
293
298
|
clearMidiCcBindings(): void {
|
|
294
299
|
this.native.clearMidiCcBindings();
|
|
295
300
|
}
|
|
@@ -479,6 +484,7 @@ export class RealtimeEngine {
|
|
|
479
484
|
this.native.seekPpq(ppq, renderFrame);
|
|
480
485
|
}
|
|
481
486
|
|
|
487
|
+
/** Set a finite tempo in the range (0, 100000] BPM. */
|
|
482
488
|
setTempo(bpm: number): void {
|
|
483
489
|
this.native.setTempo(bpm);
|
|
484
490
|
}
|
|
@@ -551,6 +557,7 @@ export class RealtimeEngine {
|
|
|
551
557
|
this.native.setLoopFromMarkers(startMarkerId, endMarkerId);
|
|
552
558
|
}
|
|
553
559
|
|
|
560
|
+
/** Set a metronome config; click lengths are limited to one second. */
|
|
554
561
|
setMetronome(config: EngineMetronomeConfig): void {
|
|
555
562
|
this.native.setMetronome(config);
|
|
556
563
|
}
|
|
@@ -833,6 +840,7 @@ export class RealtimeEngine {
|
|
|
833
840
|
this.native.setCaptureSource(source);
|
|
834
841
|
}
|
|
835
842
|
|
|
843
|
+
/** Positive values delay capture relative to the punch window. */
|
|
836
844
|
setRecordOffsetSamples(offsetSamples: number): void {
|
|
837
845
|
this.native.setRecordOffsetSamples(offsetSamples);
|
|
838
846
|
}
|
package/src/sonare.js.d.ts
CHANGED
|
@@ -458,6 +458,8 @@ export interface WasmLufsResult {
|
|
|
458
458
|
integratedLufs: number;
|
|
459
459
|
momentaryLufs: number;
|
|
460
460
|
shortTermLufs: number;
|
|
461
|
+
maxMomentaryLufs: number;
|
|
462
|
+
maxShortTermLufs: number;
|
|
461
463
|
loudnessRange: number;
|
|
462
464
|
}
|
|
463
465
|
|
|
@@ -467,6 +469,7 @@ export interface WasmMasteringResult {
|
|
|
467
469
|
inputLufs: number;
|
|
468
470
|
outputLufs: number;
|
|
469
471
|
appliedGainDb: number;
|
|
472
|
+
loudnessTargetLimited?: boolean;
|
|
470
473
|
latencySamples?: number;
|
|
471
474
|
}
|
|
472
475
|
|
|
@@ -479,6 +482,7 @@ export interface WasmMasteringChainResult extends WasmMasteringResult {
|
|
|
479
482
|
stages: string[];
|
|
480
483
|
outputTruePeakDbtp: number;
|
|
481
484
|
outputLra: number;
|
|
485
|
+
loudnessTargetLimited: boolean;
|
|
482
486
|
stageGainReductions: WasmStageGainReduction[];
|
|
483
487
|
}
|
|
484
488
|
|
|
@@ -492,6 +496,7 @@ export interface WasmMasteringStereoChainResult {
|
|
|
492
496
|
stages: string[];
|
|
493
497
|
outputTruePeakDbtp: number;
|
|
494
498
|
outputLra: number;
|
|
499
|
+
loudnessTargetLimited: boolean;
|
|
495
500
|
stageGainReductions: WasmStageGainReduction[];
|
|
496
501
|
}
|
|
497
502
|
|
|
@@ -624,8 +629,9 @@ export interface WasmEngineMetronomeConfig {
|
|
|
624
629
|
enabled: boolean;
|
|
625
630
|
beatGain?: number;
|
|
626
631
|
accentGain?: number;
|
|
632
|
+
/** Explicit click length in samples (0..384000). The engine caps it to one second at its sample rate. */
|
|
627
633
|
clickSamples?: number;
|
|
628
|
-
/** Optional click length in seconds; > 0 overrides the engine 2 ms default. */
|
|
634
|
+
/** Optional click length in seconds (0..1); > 0 overrides the engine 2 ms default. */
|
|
629
635
|
clickSeconds?: number;
|
|
630
636
|
}
|
|
631
637
|
|
|
@@ -943,6 +949,7 @@ export interface WasmRealtimeEngine {
|
|
|
943
949
|
minValue: number,
|
|
944
950
|
maxValue: number,
|
|
945
951
|
) => void;
|
|
952
|
+
bindMidiCcBinding: (binding: import('./project_types').ProjectMidiCcBinding) => void;
|
|
946
953
|
clearMidiCcBindings: () => void;
|
|
947
954
|
midiCcBindingCount: () => number;
|
|
948
955
|
setMidiFx: (destinationId: number, configJson: string) => void;
|
|
@@ -1100,7 +1107,7 @@ export interface SonareModule {
|
|
|
1100
1107
|
detectInversions: boolean,
|
|
1101
1108
|
chromaMethod: number,
|
|
1102
1109
|
) => string[];
|
|
1103
|
-
analyze: (samples: Float32Array, sampleRate: number) => WasmAnalysisResult;
|
|
1110
|
+
analyze: (samples: Float32Array, sampleRate: number, options: object) => WasmAnalysisResult;
|
|
1104
1111
|
_synthEnumTables: () => WasmSynthEnumTables;
|
|
1105
1112
|
_synthPatchRoundTrip: (patch: unknown) => unknown;
|
|
1106
1113
|
_analysisResultSchemaPaths: () => string[];
|
|
@@ -1182,6 +1189,13 @@ export interface SonareModule {
|
|
|
1182
1189
|
|
|
1183
1190
|
meteringPeakDb: (samples: Float32Array, sampleRate: number) => number;
|
|
1184
1191
|
meteringRmsDb: (samples: Float32Array, sampleRate: number) => number;
|
|
1192
|
+
meteringSilenceRatio: (
|
|
1193
|
+
samples: Float32Array,
|
|
1194
|
+
sampleRate: number,
|
|
1195
|
+
thresholdDb: number,
|
|
1196
|
+
frameLength: number,
|
|
1197
|
+
hopLength: number,
|
|
1198
|
+
) => number;
|
|
1185
1199
|
meteringCrestFactorDb: (samples: Float32Array, sampleRate: number) => number;
|
|
1186
1200
|
meteringDcOffset: (samples: Float32Array, sampleRate: number) => number;
|
|
1187
1201
|
meteringTruePeakDb: (
|
|
@@ -1695,6 +1709,7 @@ export interface SonareModule {
|
|
|
1695
1709
|
nMfcc: number,
|
|
1696
1710
|
nFrames: number,
|
|
1697
1711
|
nMels: number,
|
|
1712
|
+
lifter: number,
|
|
1698
1713
|
) => WasmMelPowerResult;
|
|
1699
1714
|
mfccToAudio: (
|
|
1700
1715
|
mfcc: Float32Array,
|
|
@@ -1708,6 +1723,7 @@ export interface SonareModule {
|
|
|
1708
1723
|
fmax: number,
|
|
1709
1724
|
nIter: number,
|
|
1710
1725
|
htk: boolean,
|
|
1726
|
+
lifter: number,
|
|
1711
1727
|
) => Float32Array;
|
|
1712
1728
|
|
|
1713
1729
|
// Features - Chroma
|
|
@@ -1889,12 +1905,14 @@ export interface SonareModule {
|
|
|
1889
1905
|
sampleRate: number,
|
|
1890
1906
|
hopLength: number,
|
|
1891
1907
|
nChroma: number,
|
|
1908
|
+
binsPerOctave: number,
|
|
1892
1909
|
) => WasmChromaResult;
|
|
1893
1910
|
chromaCqt: (
|
|
1894
1911
|
samples: Float32Array,
|
|
1895
1912
|
sampleRate: number,
|
|
1896
1913
|
hopLength: number,
|
|
1897
1914
|
nChroma: number,
|
|
1915
|
+
binsPerOctave: number,
|
|
1898
1916
|
) => WasmChromaResult;
|
|
1899
1917
|
bassChroma: (
|
|
1900
1918
|
samples: Float32Array,
|
|
@@ -1902,7 +1920,13 @@ export interface SonareModule {
|
|
|
1902
1920
|
hopLength: number,
|
|
1903
1921
|
nChroma: number,
|
|
1904
1922
|
) => WasmChromaResult;
|
|
1905
|
-
nnlsChroma: (
|
|
1923
|
+
nnlsChroma: (
|
|
1924
|
+
samples: Float32Array,
|
|
1925
|
+
sampleRate: number,
|
|
1926
|
+
enableStftBlend: boolean,
|
|
1927
|
+
stftBlendWeight: number,
|
|
1928
|
+
stftBlendNFft: number,
|
|
1929
|
+
) => WasmNnlsChromaResult;
|
|
1906
1930
|
cqt: (
|
|
1907
1931
|
samples: Float32Array,
|
|
1908
1932
|
sampleRate: number,
|
|
@@ -2255,6 +2279,7 @@ export interface WasmMixer {
|
|
|
2255
2279
|
removeSend: (stripIndex: number, sendIndex: number) => void;
|
|
2256
2280
|
meterTap: (stripIndex: number, tap: number) => WasmMixMeterSnapshot;
|
|
2257
2281
|
stripMeter: (stripIndex: number) => WasmMixMeterSnapshot;
|
|
2282
|
+
busMeter: (busId: string) => WasmMixMeterSnapshot;
|
|
2258
2283
|
scheduleFaderAutomation: (
|
|
2259
2284
|
stripIndex: number,
|
|
2260
2285
|
samplePos: number,
|
|
@@ -2286,6 +2311,7 @@ export interface WasmMixer {
|
|
|
2286
2311
|
busCount: () => number;
|
|
2287
2312
|
addVcaGroup: (id: string, gainDb: number, members: string[]) => void;
|
|
2288
2313
|
setVcaGroupGainDb: (id: string, gainDb: number) => void;
|
|
2314
|
+
setVcaGroupMembers: (id: string, members: string[]) => void;
|
|
2289
2315
|
removeVcaGroup: (id: string) => void;
|
|
2290
2316
|
vcaGroupCount: () => number;
|
|
2291
2317
|
toSceneJson: () => string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { flattenChainConfig } from './_chain_config';
|
|
1
2
|
import { getSonareModule } from './module_state';
|
|
2
3
|
import type {
|
|
3
4
|
EqBand,
|
|
@@ -64,7 +65,12 @@ export class StreamingMasteringChain {
|
|
|
64
65
|
|
|
65
66
|
constructor(config: StreamingMasteringChainConfig) {
|
|
66
67
|
const module = getSonareModule();
|
|
67
|
-
|
|
68
|
+
const { loudnessStaticGainDb, loudnessStaticGainPeakDb, ...chainConfig } = config;
|
|
69
|
+
this.chain = module.createStreamingMasteringChain({
|
|
70
|
+
__flatParams: flattenChainConfig(chainConfig),
|
|
71
|
+
loudnessStaticGainDb,
|
|
72
|
+
loudnessStaticGainPeakDb,
|
|
73
|
+
});
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
/**
|
package/src/validation.ts
CHANGED
|
@@ -78,6 +78,12 @@ export function assertSampleRate(fnName: string, sampleRate: number): void {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/** Validate and retain the public Audio.fromBuffer construction contract. */
|
|
82
|
+
export function validateAudioBuffer(samples: Float32Array, sampleRate: number): void {
|
|
83
|
+
assertSamples('Audio.fromBuffer', samples, true);
|
|
84
|
+
assertSampleRate('Audio.fromBuffer', sampleRate);
|
|
85
|
+
}
|
|
86
|
+
|
|
81
87
|
export function assertNonNegativeInteger(fnName: string, value: number, argName: string): void {
|
|
82
88
|
if (!Number.isInteger(value) || value < 0) {
|
|
83
89
|
throw new RangeError(`${fnName}: ${argName} must be a non-negative integer`);
|
package/src/worklet/messages.ts
CHANGED
|
@@ -191,15 +191,29 @@ export interface ResolvedMetronomeConfig {
|
|
|
191
191
|
export const DEFAULT_METRONOME_CONFIG: ResolvedMetronomeConfig = {
|
|
192
192
|
beatGain: 0.35,
|
|
193
193
|
accentGain: 0.7,
|
|
194
|
-
clickSamples:
|
|
194
|
+
clickSamples: 0,
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
export function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedMetronomeConfig {
|
|
198
|
-
|
|
198
|
+
const resolved = {
|
|
199
199
|
beatGain: config.beatGain ?? DEFAULT_METRONOME_CONFIG.beatGain,
|
|
200
200
|
accentGain: config.accentGain ?? DEFAULT_METRONOME_CONFIG.accentGain,
|
|
201
201
|
clickSamples: config.clickSamples ?? DEFAULT_METRONOME_CONFIG.clickSamples,
|
|
202
202
|
};
|
|
203
|
+
if (
|
|
204
|
+
!Number.isFinite(resolved.beatGain) ||
|
|
205
|
+
resolved.beatGain < 0 ||
|
|
206
|
+
!Number.isFinite(resolved.accentGain) ||
|
|
207
|
+
resolved.accentGain < 0 ||
|
|
208
|
+
!Number.isInteger(resolved.clickSamples) ||
|
|
209
|
+
resolved.clickSamples < 0 ||
|
|
210
|
+
resolved.clickSamples > 384000 ||
|
|
211
|
+
(config.clickSeconds !== undefined &&
|
|
212
|
+
(!Number.isFinite(config.clickSeconds) || config.clickSeconds < 0 || config.clickSeconds > 1))
|
|
213
|
+
) {
|
|
214
|
+
throw new RangeError('invalid metronome gains or click length');
|
|
215
|
+
}
|
|
216
|
+
return resolved;
|
|
203
217
|
}
|
|
204
218
|
|
|
205
219
|
// Out-of-band control messages posted from the main-thread SonareEngine facade
|
package/src/worklet/protocol.ts
CHANGED