@libraz/libsonare 1.6.0 → 1.7.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.
Files changed (53) hide show
  1. package/README.md +2 -2
  2. package/dist/analysis.d.ts +139 -11
  3. package/dist/analysis.js +162 -42
  4. package/dist/analysis.js.map +1 -1
  5. package/dist/index.d.ts +211 -39
  6. package/dist/index.js +501 -142
  7. package/dist/index.js.map +1 -1
  8. package/dist/schemas/realtime-voice-changer-preset.schema.json +2 -2
  9. package/dist/sonare-analysis.js +1 -1
  10. package/dist/sonare-analysis.wasm +0 -0
  11. package/dist/sonare.js +1 -1
  12. package/dist/sonare.wasm +0 -0
  13. package/dist/worker.js +56 -29
  14. package/dist/worker.js.map +1 -1
  15. package/dist/worklet.d.ts +67 -18
  16. package/dist/worklet.js +193 -42
  17. package/dist/worklet.js.map +1 -1
  18. package/package.json +3 -3
  19. package/src/_chain_config.ts +6 -1
  20. package/src/analysis_helpers.ts +34 -29
  21. package/src/audio.ts +7 -2
  22. package/src/codes.ts +47 -11
  23. package/src/effects_mastering.ts +5 -0
  24. package/src/effects_transform.ts +202 -22
  25. package/src/feature_music.ts +8 -1
  26. package/src/feature_spectral.ts +64 -2
  27. package/src/feature_spectrogram.ts +44 -3
  28. package/src/index.ts +28 -3
  29. package/src/mastering_core.ts +70 -0
  30. package/src/metering.ts +18 -0
  31. package/src/mixer.ts +3 -3
  32. package/src/project.ts +6 -0
  33. package/src/project_class.ts +143 -16
  34. package/src/project_internal.ts +14 -5
  35. package/src/project_types.ts +50 -9
  36. package/src/public_types_mastering.ts +9 -0
  37. package/src/public_types_mixing.ts +16 -0
  38. package/src/public_types_realtime.ts +23 -5
  39. package/src/public_types_spectral.ts +16 -2
  40. package/src/quick_analysis.ts +21 -3
  41. package/src/realtime_engine.ts +14 -3
  42. package/src/sonare.js.d.ts +87 -0
  43. package/src/stream_analyzer.ts +6 -1
  44. package/src/web_midi.ts +10 -7
  45. package/src/worklet/engine-node.ts +54 -19
  46. package/src/worklet/engine-parameter-facade.ts +30 -1
  47. package/src/worklet/engine-processor.ts +52 -20
  48. package/src/worklet/engine-register.ts +1 -1
  49. package/src/worklet/engine-strips.ts +2 -2
  50. package/src/worklet/engine.ts +10 -0
  51. package/src/worklet/guards.ts +99 -7
  52. package/src/worklet/messages.ts +41 -1
  53. package/src/worklet/protocol.ts +4 -0
package/README.md CHANGED
@@ -38,8 +38,8 @@ mastering, mixing, or realtime-engine APIs, import the smaller analysis entry:
38
38
  import { detectBpm, init } from '@libraz/libsonare/analysis';
39
39
  ```
40
40
 
41
- With emsdk 5.0.2, the analysis binary is 0.86 MiB raw / 347 KiB gzip; the full
42
- entry is 3.76 MiB raw / 1.26 MiB gzip. The analysis entry deliberately has no
41
+ With emsdk 5.0.2, the analysis binary is 0.91 MiB raw / 368 KiB gzip; the full
42
+ entry is 3.88 MiB raw / 1.31 MiB gzip. The analysis entry deliberately has no
43
43
  `masterAudio`, `mixStereo`, `Project`, `Mixer`, or `RealtimeEngine` export.
44
44
 
45
45
  ## Quick Start
@@ -363,6 +363,15 @@ interface MasteringChainConfig {
363
363
  releaseMs?: number;
364
364
  applyGainAtInputRate?: boolean;
365
365
  };
366
+ /**
367
+ * Dot-notation spelling of any leaf above, e.g. `'loudness.targetLufs': -20`
368
+ * beside or instead of `loudness: { targetLufs: -20 }`. It is the form the C
369
+ * ABI carries parameters in, so a caller assembling overrides dynamically can
370
+ * emit it directly; the core validates the key and rejects an unknown one.
371
+ * The nested spelling is canonical — prefer it in hand-written code, where it
372
+ * is checked field by field while a dotted key is only checked at run time.
373
+ */
374
+ [flatKey: `${string}.${string}`]: number | boolean | undefined;
366
375
  }
367
376
  /**
368
377
  * Configuration for the block-by-block {@link StreamingMasteringChain}.
@@ -549,6 +558,10 @@ type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';
549
558
  * remains unity. Maps to the underlying integer code.
550
559
  */
551
560
  type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';
561
+ /** Accepted pan-law name aliases for mixer and realtime-engine inputs. */
562
+ type PanLawName = PanLaw | 'const-3db' | '-3db' | 'const-4.5db' | '-4.5db' | 'const-6db' | '-6db' | 'linear-0db' | 'linear' | '0db';
563
+ /** Pan-law name or raw C ABI ordinal. */
564
+ type PanLawInput = PanLawName | number;
552
565
  /**
553
566
  * Meter tap point for reading a strip's meter snapshot
554
567
  * (see {@link Mixer.meterTap} and {@link Mixer.stripMeter}).
@@ -958,14 +971,21 @@ interface EqMatchOptions {
958
971
  maxBands?: number;
959
972
  }
960
973
  type VoicePresetId = 'neutral-monitor' | 'bright-idol' | 'soft-whisper' | 'deep-narrator' | 'robot-mascot' | 'dark-villain';
961
- interface RealtimeVoiceChangerPreset {
974
+ type VoicePresetCategory = 'monitor' | 'bright' | 'soft' | 'deep' | 'robot' | 'dark' | 'custom';
975
+ interface RealtimeVoiceChangerPresetMetadata {
962
976
  schemaVersion: 1;
963
- id?: string;
964
- name?: string;
977
+ id: string;
978
+ name: string;
965
979
  description?: string;
966
- macros?: Record<string, number>;
967
- dsp?: Record<string, unknown>;
968
- }
980
+ category: VoicePresetCategory;
981
+ }
982
+ type RealtimeVoiceChangerPreset = (RealtimeVoiceChangerPresetMetadata & {
983
+ dsp: Record<string, unknown>;
984
+ macros?: never;
985
+ }) | (RealtimeVoiceChangerPresetMetadata & {
986
+ macros: Record<string, number>;
987
+ dsp?: never;
988
+ });
969
989
  type RealtimeVoiceChangerConfigInput = VoicePresetId | RealtimeVoiceChangerPreset;
970
990
  /**
971
991
  * Flat (POD) realtime voice-changer configuration. Keys are camelCase to match
@@ -1013,6 +1033,14 @@ interface RealtimeVoiceChangerPodConfig {
1013
1033
  limiterIspCeilingDbtp: number;
1014
1034
  }
1015
1035
 
1036
+ /**
1037
+ * Per-frame voicing decision, one entry per `f0Hz` frame. A truthy or non-zero
1038
+ * entry marks the frame voiced. The union covers what the analysis side hands
1039
+ * back — `PitchResult.voicedFlag` is a `boolean[]` — as well as the typed and
1040
+ * plain numeric arrays a caller may build directly, so a pitch track can be fed
1041
+ * straight into pitch correction without a conversion step.
1042
+ */
1043
+ type VoicedFlags = Int32Array | Uint8Array | Float32Array | readonly number[] | readonly boolean[];
1016
1044
  /** Options for `pitchCorrectTimevarying`. All fields are optional. */
1017
1045
  interface PitchCorrectOptions extends ValidateOptions {
1018
1046
  /** `'midi'` retunes toward `targetMidi`; `'scale'` snaps to the key. Default `'midi'`. */
@@ -1033,8 +1061,8 @@ interface PitchCorrectOptions extends ValidateOptions {
1033
1061
  retuneSpeedMs?: number;
1034
1062
  /** Corrections below this are bypassed to preserve vibrato (cents). Default 20. */
1035
1063
  vibratoThresholdCents?: number;
1036
- /** Per-frame voiced flags (non-zero = voiced); omit to treat all frames as voiced. */
1037
- voiced?: Int32Array;
1064
+ /** Per-frame voiced flags (truthy = voiced); omit to treat all frames as voiced. */
1065
+ voiced?: VoicedFlags;
1038
1066
  /** Per-frame voicing probability in `[0, 1]`; omit to derive from `voiced`. */
1039
1067
  voicedProb?: Float32Array;
1040
1068
  }
@@ -2169,6 +2197,7 @@ interface WasmRealtimeEngine {
2169
2197
  setParameterSmoothed: (paramId: number, value: number, renderFrame: number) => void;
2170
2198
  setParamSmoothingMs: (smoothingMs: number) => void;
2171
2199
  setSoloMute: (laneIndex: number, solo: boolean, mute: boolean, renderFrame: number) => void;
2200
+ setTrackMonitorMode: (laneIndex: number, mode: number, renderFrame: number) => void;
2172
2201
  getTransportState: () => WasmEngineTransportState;
2173
2202
  play: (renderFrame: number) => void;
2174
2203
  stop: (renderFrame: number) => void;
@@ -2488,6 +2517,12 @@ interface SonareModule {
2488
2517
  sampleRate: number,
2489
2518
  nOctaveBands: number,
2490
2519
  ) => WasmAcousticResult;
2520
+ analyzeImpulseResponseEx: (
2521
+ samples: Float32Array,
2522
+ sampleRate: number,
2523
+ nOctaveBands: number,
2524
+ minDecayDb: number,
2525
+ ) => WasmAcousticResult;
2491
2526
  detectAcoustic: (
2492
2527
  samples: Float32Array,
2493
2528
  sampleRate: number,
@@ -2571,6 +2606,11 @@ interface SonareModule {
2571
2606
  hopLength: number,
2572
2607
  ) => number;
2573
2608
  meteringCrestFactorDb: (samples: Float32Array, sampleRate: number) => number;
2609
+ meteringCrestFactorDbStereo: (
2610
+ left: Float32Array,
2611
+ right: Float32Array,
2612
+ sampleRate: number,
2613
+ ) => number;
2574
2614
  meteringDcOffset: (samples: Float32Array, sampleRate: number) => number;
2575
2615
  meteringTruePeakDb: (
2576
2616
  samples: Float32Array,
@@ -2727,12 +2767,30 @@ interface SonareModule {
2727
2767
  kernelHarmonic: number,
2728
2768
  kernelPercussive: number,
2729
2769
  ) => WasmHpssResult;
2770
+ hpssEx: (
2771
+ samples: Float32Array,
2772
+ sampleRate: number,
2773
+ kernelHarmonic: number,
2774
+ kernelPercussive: number,
2775
+ nFft: number,
2776
+ hopLength: number,
2777
+ hardMask: boolean,
2778
+ ) => WasmHpssResult;
2730
2779
  hpssWithResidual: (
2731
2780
  samples: Float32Array,
2732
2781
  sampleRate: number,
2733
2782
  kernelHarmonic: number,
2734
2783
  kernelPercussive: number,
2735
2784
  ) => WasmHpssWithResidualResult;
2785
+ hpssWithResidualEx: (
2786
+ samples: Float32Array,
2787
+ sampleRate: number,
2788
+ kernelHarmonic: number,
2789
+ kernelPercussive: number,
2790
+ nFft: number,
2791
+ hopLength: number,
2792
+ hardMask: boolean,
2793
+ ) => WasmHpssWithResidualResult;
2736
2794
  decompose: (
2737
2795
  s: Float32Array,
2738
2796
  nFeatures: number,
@@ -2774,7 +2832,21 @@ interface SonareModule {
2774
2832
  harmonic: (samples: Float32Array, sampleRate: number) => Float32Array;
2775
2833
  percussive: (samples: Float32Array, sampleRate: number) => Float32Array;
2776
2834
  timeStretch: (samples: Float32Array, sampleRate: number, rate: number) => Float32Array;
2835
+ timeStretchEx: (
2836
+ samples: Float32Array,
2837
+ sampleRate: number,
2838
+ rate: number,
2839
+ nFft: number,
2840
+ hopLength: number,
2841
+ ) => Float32Array;
2777
2842
  pitchShift: (samples: Float32Array, sampleRate: number, semitones: number) => Float32Array;
2843
+ pitchShiftEx: (
2844
+ samples: Float32Array,
2845
+ sampleRate: number,
2846
+ semitones: number,
2847
+ nFft: number,
2848
+ hopLength: number,
2849
+ ) => Float32Array;
2778
2850
  pitchCorrectToMidi: (
2779
2851
  samples: Float32Array,
2780
2852
  sampleRate: number,
@@ -2836,6 +2908,12 @@ interface SonareModule {
2836
2908
  channels: number,
2837
2909
  ) => Float32Array;
2838
2910
  normalize: (samples: Float32Array, sampleRate: number, targetDb: number) => Float32Array;
2911
+ normalizeEx: (
2912
+ samples: Float32Array,
2913
+ sampleRate: number,
2914
+ targetDb: number,
2915
+ mode: string,
2916
+ ) => Float32Array;
2839
2917
  mastering: (
2840
2918
  samples: Float32Array,
2841
2919
  sampleRate: number,
@@ -2898,6 +2976,24 @@ interface SonareModule {
2898
2976
  sampleRate: number,
2899
2977
  platforms: Array<{ name: string; targetLufs: number; ceilingDb: number }>,
2900
2978
  ) => string;
2979
+ masteringAssistantSuggestStereo: (
2980
+ left: Float32Array,
2981
+ right: Float32Array,
2982
+ sampleRate: number,
2983
+ params: Record<string, number | boolean>,
2984
+ ) => string;
2985
+ masteringAudioProfileStereo: (
2986
+ left: Float32Array,
2987
+ right: Float32Array,
2988
+ sampleRate: number,
2989
+ params: Record<string, number | boolean>,
2990
+ ) => string;
2991
+ masteringStreamingPreviewStereo: (
2992
+ left: Float32Array,
2993
+ right: Float32Array,
2994
+ sampleRate: number,
2995
+ platforms: Array<{ name: string; targetLufs: number; ceilingDb: number }>,
2996
+ ) => string;
2901
2997
  masteringRepairDeclick: (
2902
2998
  samples: Float32Array,
2903
2999
  sampleRate: number,
@@ -3014,6 +3110,13 @@ interface SonareModule {
3014
3110
  options: Record<string, unknown>,
3015
3111
  ) => WasmMixResult;
3016
3112
  trim: (samples: Float32Array, sampleRate: number, thresholdDb: number) => Float32Array;
3113
+ trimEx: (
3114
+ samples: Float32Array,
3115
+ sampleRate: number,
3116
+ thresholdDb: number,
3117
+ frameLength: number,
3118
+ hopLength: number,
3119
+ ) => Float32Array;
3017
3120
  spectralEdit: (
3018
3121
  samples: Float32Array,
3019
3122
  sampleRate: number,
@@ -3444,6 +3547,14 @@ interface SonareModule {
3444
3547
  stftBlendWeight: number,
3445
3548
  stftBlendNFft: number,
3446
3549
  ) => WasmNnlsChromaResult;
3550
+ nnlsChromaEx: (
3551
+ samples: Float32Array,
3552
+ sampleRate: number,
3553
+ enableStftBlend: boolean,
3554
+ stftBlendWeight: number,
3555
+ stftBlendNFft: number,
3556
+ hopLength: number,
3557
+ ) => WasmNnlsChromaResult;
3447
3558
  cqt: (
3448
3559
  samples: Float32Array,
3449
3560
  sampleRate: number,
@@ -4315,6 +4426,7 @@ interface NnlsChromaRequest extends GuardedOptions$2 {
4315
4426
  enableStftBlend?: boolean;
4316
4427
  stftBlendWeight?: number;
4317
4428
  stftBlendNFft?: number;
4429
+ hopLength?: number;
4318
4430
  }
4319
4431
  /**
4320
4432
  * Compute NNLS (non-negative least squares) chromagram.
@@ -4725,6 +4837,9 @@ interface HpssWithResidualRequest {
4725
4837
  sampleRate?: number;
4726
4838
  kernelHarmonic?: number;
4727
4839
  kernelPercussive?: number;
4840
+ nFft?: number;
4841
+ hopLength?: number;
4842
+ hardMask?: boolean;
4728
4843
  }
4729
4844
  interface LufsInterleavedRequest extends ValidateOptions {
4730
4845
  samples: Float32Array;
@@ -4813,7 +4928,7 @@ declare function phaseVocoder(samples: Float32Array, sampleRate: number, rate: n
4813
4928
  * HPSS into harmonic / percussive / residual signals.
4814
4929
  */
4815
4930
  declare function hpssWithResidual(request: HpssWithResidualRequest): WasmHpssWithResidualResult;
4816
- declare function hpssWithResidual(samples: Float32Array, sampleRate?: number, kernelHarmonic?: number, kernelPercussive?: number): WasmHpssWithResidualResult;
4931
+ declare function hpssWithResidual(samples: Float32Array, sampleRate?: number, kernelHarmonic?: number, kernelPercussive?: number, nFft?: number, hopLength?: number, hardMask?: boolean): WasmHpssWithResidualResult;
4817
4932
  /**
4818
4933
  * Channel-weighted multichannel integrated loudness + LRA (ITU-R BS.1770 /
4819
4934
  * EBU R128) from an interleaved buffer of `frames * channels` samples. The
@@ -4992,6 +5107,8 @@ interface TrimRequest extends GuardedOptions$1 {
4992
5107
  samples: Float32Array;
4993
5108
  sampleRate: number;
4994
5109
  thresholdDb?: number;
5110
+ frameLength?: number;
5111
+ hopLength?: number;
4995
5112
  }
4996
5113
  /**
4997
5114
  * Trim silence from beginning and end of audio.
@@ -5003,6 +5120,7 @@ interface TrimRequest extends GuardedOptions$1 {
5003
5120
  */
5004
5121
  declare function trim(request: TrimRequest): Float32Array;
5005
5122
  declare function trim(samples: Float32Array, sampleRate: number, thresholdDb?: number, options?: GuardedOptions$1): Float32Array;
5123
+ declare function trim(samples: Float32Array, sampleRate: number, thresholdDb?: number, frameLength?: number, hopLength?: number, options?: GuardedOptions$1): Float32Array;
5006
5124
  /**
5007
5125
  * Compute Short-Time Fourier Transform (STFT).
5008
5126
  *
@@ -5262,6 +5380,15 @@ declare function meteringSilenceRatio(request: MeteringSilenceRatioRequest): num
5262
5380
  declare function meteringSilenceRatio(samples: Float32Array, sampleRate?: number, thresholdDb?: number, frameLength?: number, hopLength?: number, options?: ValidateOptions): number;
5263
5381
  declare function meteringCrestFactorDb(request: MeteringSamplesRequest): number;
5264
5382
  declare function meteringCrestFactorDb(samples: Float32Array, sampleRate?: number, options?: ValidateOptions): number;
5383
+ /**
5384
+ * Crest factor in dB across both channels of a stereo pair.
5385
+ *
5386
+ * Takes the peak across both channels and the RMS over both together. An
5387
+ * out-of-phase pair cancels in the `0.5 * (left + right)` downmix
5388
+ * {@link meteringCrestFactorDb} would need, which understates its RMS and so
5389
+ * overstates the crest factor.
5390
+ */
5391
+ declare function meteringCrestFactorDbStereo(request: MeteringStereoRequest): number;
5265
5392
  declare function meteringDcOffset(request: MeteringSamplesRequest): number;
5266
5393
  declare function meteringDcOffset(samples: Float32Array, sampleRate?: number, options?: ValidateOptions): number;
5267
5394
  /**
@@ -5488,6 +5615,7 @@ interface ChordFunctionalAnalysisRequest extends DetectChordsRequest {
5488
5615
  /** Canonical request form for impulse-response analysis. */
5489
5616
  interface AnalyzeImpulseResponseRequest extends SamplesRequest {
5490
5617
  nOctaveBands?: number;
5618
+ minDecayDb?: number;
5491
5619
  }
5492
5620
  /** Canonical request form for acoustic analysis. */
5493
5621
  interface DetectAcousticRequest extends AcousticOptions, SamplesRequest {
@@ -5603,7 +5731,7 @@ interface MusicAnalyzeRequest extends SamplesRequest, MusicAnalyzeOptions {
5603
5731
  declare function analyze(request: MusicAnalyzeRequest): AnalysisResult;
5604
5732
  declare function analyze(samples: Float32Array, sampleRate?: number, options?: GuardedOptions & MusicAnalyzeOptions): AnalysisResult;
5605
5733
  declare function analyzeImpulseResponse(request: AnalyzeImpulseResponseRequest): AcousticResult;
5606
- declare function analyzeImpulseResponse(samples: Float32Array, sampleRate?: number, nOctaveBands?: number): AcousticResult;
5734
+ declare function analyzeImpulseResponse(samples: Float32Array, sampleRate?: number, nOctaveBands?: number, minDecayDb?: number): AcousticResult;
5607
5735
  declare function detectAcoustic(request: DetectAcousticRequest): AcousticResult;
5608
5736
  declare function detectAcoustic(samples: Float32Array, sampleRate?: number, options?: AcousticOptions): AcousticResult;
5609
5737
  /**
@@ -5727,4 +5855,4 @@ declare function engineAbiVersion(): number;
5727
5855
  /** Voice-changer ABI version retained for cross-entry compatibility checks. */
5728
5856
  declare function voiceChangerAbiVersion(): number;
5729
5857
 
5730
- export { type AcousticOptions, type AcousticResult, type AnalysisResult, type AnalyzeBpmOptions, type AnalyzeBpmRequest, type AnalyzeDynamicsOptions, type AnalyzeDynamicsRequest, type AnalyzeImpulseResponseRequest, type AnalyzeMelodyRequest, type AnalyzeRhythmOptions, type AnalyzeRhythmRequest, type AnalyzeSectionsOptions, type AnalyzeSectionsRequest, type AnalyzeTimbreOptions, type AnalyzeTimbreRequest, type AnalyzeWithProgressRequest, type AutomationCurve, type Beat, type BpmAnalysisResult, type BpmCandidate, type BpmHypothesis, type CapabilityCatalog, type CapabilityCatalogParameter, type CapabilityCatalogPresets, type CapabilityCatalogProcessor, type ChirpRequest, type Chord, type ChordAnalysisResult, type ChordDetectionOptions, type ChordFunctionalAnalysisRequest, ChordQuality, type ChromaResult, type ChromaSpectrogramRequest, type ClicksRequest, type ClippingRegion, type ClippingReport, type CqtRequest, type CqtResult, type CqtToAudioRequest, type CyclicTempogramRequest, type DbConversionRequest, type DecomposeRequest, type DecomposeWithInitRequest, type DetectAcousticRequest, type DetectChordsRequest, type DetectKeyRequest, type DynamicRangeReport, type Dynamics, type DynamicsAnalysisResult, type Ebur128LoudnessRangeRequest, type EmphasisRequest, type EqBand, type EqBandPhase, type EqBandType, type EqCoeffMode, type EqMatchOptions, type EqSpectrumSnapshot, type EqStereoPlacement, ErrorCode, type EstimateTuningRequest, type FixFramesRequest, type FixLengthRequest, type FourierTempogramRequest, type FrameSignalRequest, type GoniometerPoint, type GriffinLimRequest, type HpssResult, type HpssWithResidualRequest, type Key, type KeyCandidate, type KeyDetectionOptions, KeyProfile, type KeyProfileName, type LufsInterleavedRequest, type LufsRequest, type LufsResult, type MasteringChainConfig, type MasteringChainResult, type MasteringChainStereoResult, type MasteringLoudnessSummary, type MasteringOptions, type MasteringPreset, type MasteringProcessorParams, type MasteringReport, type MasteringResult, type MasteringStereoChainResult, type MasteringStereoResult, type MelDeltaRequest, type MelPowerResult, type MelSpectrogramRequest, type MelSpectrogramResult, type MelToAudioRequest, type MelToStftRequest, type MelodyContour, type MelodyOptions, type MelodyPoint, type MelodyResult, type MeterTap, type MeteringDetectClippingOptions, type MeteringDetectClippingRequest, type MeteringDynamicRangeOptions, type MeteringDynamicRangeRequest, type MeteringSamplesRequest, type MeteringSilenceRatioRequest, type MeteringSpectrumFrameRequest, type MeteringSpectrumRequest, type MeteringStereoDecimatedRequest, type MeteringStereoRequest, type MeteringTruePeakRequest, type MfccRequest, type MfccResult, type MfccToAudioRequest, type MfccToMelRequest, type MixMeterSnapshot, type MixOptions, type MixResult, type MixerProcessResult, Mode, type MusicAnalyzeOptions, type MusicAnalyzeRequest, type NnFilterRequest, type NnlsChromaRequest, type NoteMoveOptions, type NoteSegment, type NoteSegmentsRequest, type NoteStretchOptions, type OnsetBacktrackRequest, type OnsetEnvelopeRequest, type OnsetStrengthMultiRequest, type OnsetStrengthMultiResult, type PadCenterRequest, type PairAnalysis, type PairProcessor, type PanLaw, type PanMode, type PcenRequest, type PeakPickRequest, type PhaseScopeReport, type PhaseVocoderRequest, type PiptrackRequest, type PiptrackResult, PitchClass, type PitchCorrectOptions, type PitchPyinRequest, type PitchResult, type PitchTuningRequest, type PitchYinRequest, type PlpRequest, type PolyFeaturesRequest, type ProgressCallback, type RealtimeVoiceChangerConfigInput, type RealtimeVoiceChangerPodConfig, type RealtimeVoiceChangerPreset, type ReassignedSpectrogramRequest, type ReassignedSpectrogramResult, type RemixRequest, type ResampleRequest, type RhythmAnalysisResult, type RhythmFeatures, type RirResult, type RirSynthOptions, type RoomEstimateOptions, type RoomEstimateResult, type RoomGeometryOptions, type RoomMorphOptions, type SamplesRequest, type ScopeOptions, type Section, SectionType, type SegmentAgglomerativeRequest, type SegmentCrossSimilarityRequest, type SegmentLagToRecurrenceRequest, type SegmentMatrix, type SegmentPathEnhanceRequest, type SegmentRecurrenceMatrixRequest, type SegmentRecurrenceToLagRequest, type SegmentSubsegmentRequest, type SendTiming, type SilenceRequest, type SoloProcessor, type SonareCapabilities, SonareError, type SpectralContrastRequest, type SpectralEditMode, type SpectralEditOptions, type SpectralEditWindow, type SpectralFrameRequest, type SpectralRegionOp, type SpectralRolloffRequest, type SpectrogramRequest, type SpectrumOptions, type SpectrumReport, type StageGainReduction, type StereoAnalysis, type StftPowerResult, type StftResult, type StreamingEqualizerConfig, type StreamingMasteringChainConfig, type StreamingPlatform, type StreamingRetuneConfig, type SurroundPan, type TempogramMode$1 as TempogramMode, type TempogramRatioRequest, type TempogramRequest, type Timbre, type TimbreAnalysisResult, type TimbreFrame, type TimeSignature, type ToneRequest, type TonnetzRequest, type TrimRequest, type VectorNormalizeRequest, type VectorscopeReport, type VoicePresetId, type VqtRequest, type VqtToAudioRequest, type WaveformPeakPyramidOptions, type WaveformPeakPyramidRequest, type WaveformPeaksOptions, type WaveformPeaksReport, type WaveformPeaksRequest, type ZeroCrossingRateRequest, type ZeroCrossingsRequest, abiVersion, amplitudeToDb, analyze, analyzeBpm, analyzeDynamics, analyzeImpulseResponse, analyzeMelody, analyzeRhythm, analyzeSections, analyzeTimbre, analyzeWithProgress, bassChroma, capabilities, chirp, chordFunctionalAnalysis, chroma, chromaCens, chromaCqt, clicks, cqt, cqtToAudio, cyclicTempogram, dbToAmplitude, dbToPower, decompose, decomposeWithInit, deemphasis, detectAcoustic, detectBeats, detectBpm, detectChords, detectDownbeats, detectKey, detectKeyCandidates, detectOnsets, ebur128LoudnessRange, engineAbiVersion, estimateTuning, fixFrames, fixLength, fourierTempogram, frameSignal, framesToSamples, framesToTime, griffinLim, hasFfmpegSupport, hpssWithResidual, hybridCqt, hzToMel, hzToMidi, hzToNote, init, isInitialized, isSonareError, lufs, lufsInterleaved, melDelta, melSpectrogram, melToAudio, melToHz, melToStft, meteringCrestFactorDb, meteringDcOffset, meteringDetectClipping, meteringDynamicRange, meteringPeakDb, meteringPhaseScope, meteringPhaseScopeDecimated, meteringRmsDb, meteringSilenceRatio, meteringSpectrum, meteringSpectrumFrame, meteringStereoCorrelation, meteringStereoWidth, meteringTruePeakDb, meteringVectorscope, meteringVectorscopeDecimated, mfcc, mfccToAudio, mfccToMel, midiToHz, momentaryLufs, nnFilter, nnlsChroma, noteSegments, noteToHz, onsetBacktrack, onsetEnvelope, onsetStrengthMulti, padCenter, pcen, peakPick, phaseVocoder, piptrack, pitchPyin, pitchTuning, pitchYin, plp, polyFeatures, powerToDb, preemphasis, pseudoCqt, reassignedSpectrogram, remix, resample, rmsEnergy, samplesToFrames, segmentAgglomerative, segmentCrossSimilarity, segmentLagToRecurrence, segmentPathEnhance, segmentRecurrenceMatrix, segmentRecurrenceToLag, segmentSubsegment, shortTermLufs, spectralBandwidth, spectralCentroid, spectralContrast, spectralFlatness, spectralFlux, spectralRolloff, splitSilence, stft, stftDb, tempogram, tempogramRatio, timeToFrames, tone, tonnetz, trim, trimSilence, vectorNormalize, version, voiceChangerAbiVersion, vqt, vqtToAudio, waveformPeakPyramid, waveformPeaks, zeroCrossingRate, zeroCrossings };
5858
+ export { type AcousticOptions, type AcousticResult, type AnalysisResult, type AnalyzeBpmOptions, type AnalyzeBpmRequest, type AnalyzeDynamicsOptions, type AnalyzeDynamicsRequest, type AnalyzeImpulseResponseRequest, type AnalyzeMelodyRequest, type AnalyzeRhythmOptions, type AnalyzeRhythmRequest, type AnalyzeSectionsOptions, type AnalyzeSectionsRequest, type AnalyzeTimbreOptions, type AnalyzeTimbreRequest, type AnalyzeWithProgressRequest, type AutomationCurve, type Beat, type BpmAnalysisResult, type BpmCandidate, type BpmHypothesis, type CapabilityCatalog, type CapabilityCatalogParameter, type CapabilityCatalogPresets, type CapabilityCatalogProcessor, type ChirpRequest, type Chord, type ChordAnalysisResult, type ChordDetectionOptions, type ChordFunctionalAnalysisRequest, ChordQuality, type ChromaResult, type ChromaSpectrogramRequest, type ClicksRequest, type ClippingRegion, type ClippingReport, type CqtRequest, type CqtResult, type CqtToAudioRequest, type CyclicTempogramRequest, type DbConversionRequest, type DecomposeRequest, type DecomposeWithInitRequest, type DetectAcousticRequest, type DetectChordsRequest, type DetectKeyRequest, type DynamicRangeReport, type Dynamics, type DynamicsAnalysisResult, type Ebur128LoudnessRangeRequest, type EmphasisRequest, type EqBand, type EqBandPhase, type EqBandType, type EqCoeffMode, type EqMatchOptions, type EqSpectrumSnapshot, type EqStereoPlacement, ErrorCode, type EstimateTuningRequest, type FixFramesRequest, type FixLengthRequest, type FourierTempogramRequest, type FrameSignalRequest, type GoniometerPoint, type GriffinLimRequest, type HpssResult, type HpssWithResidualRequest, type Key, type KeyCandidate, type KeyDetectionOptions, KeyProfile, type KeyProfileName, type LufsInterleavedRequest, type LufsRequest, type LufsResult, type MasteringChainConfig, type MasteringChainResult, type MasteringChainStereoResult, type MasteringLoudnessSummary, type MasteringOptions, type MasteringPreset, type MasteringProcessorParams, type MasteringReport, type MasteringResult, type MasteringStereoChainResult, type MasteringStereoResult, type MelDeltaRequest, type MelPowerResult, type MelSpectrogramRequest, type MelSpectrogramResult, type MelToAudioRequest, type MelToStftRequest, type MelodyContour, type MelodyOptions, type MelodyPoint, type MelodyResult, type MeterTap, type MeteringDetectClippingOptions, type MeteringDetectClippingRequest, type MeteringDynamicRangeOptions, type MeteringDynamicRangeRequest, type MeteringSamplesRequest, type MeteringSilenceRatioRequest, type MeteringSpectrumFrameRequest, type MeteringSpectrumRequest, type MeteringStereoDecimatedRequest, type MeteringStereoRequest, type MeteringTruePeakRequest, type MfccRequest, type MfccResult, type MfccToAudioRequest, type MfccToMelRequest, type MixMeterSnapshot, type MixOptions, type MixResult, type MixerProcessResult, Mode, type MusicAnalyzeOptions, type MusicAnalyzeRequest, type NnFilterRequest, type NnlsChromaRequest, type NoteMoveOptions, type NoteSegment, type NoteSegmentsRequest, type NoteStretchOptions, type OnsetBacktrackRequest, type OnsetEnvelopeRequest, type OnsetStrengthMultiRequest, type OnsetStrengthMultiResult, type PadCenterRequest, type PairAnalysis, type PairProcessor, type PanLaw, type PanLawInput, type PanLawName, type PanMode, type PcenRequest, type PeakPickRequest, type PhaseScopeReport, type PhaseVocoderRequest, type PiptrackRequest, type PiptrackResult, PitchClass, type PitchCorrectOptions, type PitchPyinRequest, type PitchResult, type PitchTuningRequest, type PitchYinRequest, type PlpRequest, type PolyFeaturesRequest, type ProgressCallback, type RealtimeVoiceChangerConfigInput, type RealtimeVoiceChangerPodConfig, type RealtimeVoiceChangerPreset, type RealtimeVoiceChangerPresetMetadata, type ReassignedSpectrogramRequest, type ReassignedSpectrogramResult, type RemixRequest, type ResampleRequest, type RhythmAnalysisResult, type RhythmFeatures, type RirResult, type RirSynthOptions, type RoomEstimateOptions, type RoomEstimateResult, type RoomGeometryOptions, type RoomMorphOptions, type SamplesRequest, type ScopeOptions, type Section, SectionType, type SegmentAgglomerativeRequest, type SegmentCrossSimilarityRequest, type SegmentLagToRecurrenceRequest, type SegmentMatrix, type SegmentPathEnhanceRequest, type SegmentRecurrenceMatrixRequest, type SegmentRecurrenceToLagRequest, type SegmentSubsegmentRequest, type SendTiming, type SilenceRequest, type SoloProcessor, type SonareCapabilities, SonareError, type SpectralContrastRequest, type SpectralEditMode, type SpectralEditOptions, type SpectralEditWindow, type SpectralFrameRequest, type SpectralRegionOp, type SpectralRolloffRequest, type SpectrogramRequest, type SpectrumOptions, type SpectrumReport, type StageGainReduction, type StereoAnalysis, type StftPowerResult, type StftResult, type StreamingEqualizerConfig, type StreamingMasteringChainConfig, type StreamingPlatform, type StreamingRetuneConfig, type SurroundPan, type TempogramMode$1 as TempogramMode, type TempogramRatioRequest, type TempogramRequest, type Timbre, type TimbreAnalysisResult, type TimbreFrame, type TimeSignature, type ToneRequest, type TonnetzRequest, type TrimRequest, type VectorNormalizeRequest, type VectorscopeReport, type VoicePresetCategory, type VoicePresetId, type VoicedFlags, type VqtRequest, type VqtToAudioRequest, type WaveformPeakPyramidOptions, type WaveformPeakPyramidRequest, type WaveformPeaksOptions, type WaveformPeaksReport, type WaveformPeaksRequest, type ZeroCrossingRateRequest, type ZeroCrossingsRequest, abiVersion, amplitudeToDb, analyze, analyzeBpm, analyzeDynamics, analyzeImpulseResponse, analyzeMelody, analyzeRhythm, analyzeSections, analyzeTimbre, analyzeWithProgress, bassChroma, capabilities, chirp, chordFunctionalAnalysis, chroma, chromaCens, chromaCqt, clicks, cqt, cqtToAudio, cyclicTempogram, dbToAmplitude, dbToPower, decompose, decomposeWithInit, deemphasis, detectAcoustic, detectBeats, detectBpm, detectChords, detectDownbeats, detectKey, detectKeyCandidates, detectOnsets, ebur128LoudnessRange, engineAbiVersion, estimateTuning, fixFrames, fixLength, fourierTempogram, frameSignal, framesToSamples, framesToTime, griffinLim, hasFfmpegSupport, hpssWithResidual, hybridCqt, hzToMel, hzToMidi, hzToNote, init, isInitialized, isSonareError, lufs, lufsInterleaved, melDelta, melSpectrogram, melToAudio, melToHz, melToStft, meteringCrestFactorDb, meteringCrestFactorDbStereo, meteringDcOffset, meteringDetectClipping, meteringDynamicRange, meteringPeakDb, meteringPhaseScope, meteringPhaseScopeDecimated, meteringRmsDb, meteringSilenceRatio, meteringSpectrum, meteringSpectrumFrame, meteringStereoCorrelation, meteringStereoWidth, meteringTruePeakDb, meteringVectorscope, meteringVectorscopeDecimated, mfcc, mfccToAudio, mfccToMel, midiToHz, momentaryLufs, nnFilter, nnlsChroma, noteSegments, noteToHz, onsetBacktrack, onsetEnvelope, onsetStrengthMulti, padCenter, pcen, peakPick, phaseVocoder, piptrack, pitchPyin, pitchTuning, pitchYin, plp, polyFeatures, powerToDb, preemphasis, pseudoCqt, reassignedSpectrogram, remix, resample, rmsEnergy, samplesToFrames, segmentAgglomerative, segmentCrossSimilarity, segmentLagToRecurrence, segmentPathEnhance, segmentRecurrenceMatrix, segmentRecurrenceToLag, segmentSubsegment, shortTermLufs, spectralBandwidth, spectralCentroid, spectralContrast, spectralFlatness, spectralFlux, spectralRolloff, splitSilence, stft, stftDb, tempogram, tempogramRatio, timeToFrames, tone, tonnetz, trim, trimSilence, vectorNormalize, version, voiceChangerAbiVersion, vqt, vqtToAudio, waveformPeakPyramid, waveformPeaks, zeroCrossingRate, zeroCrossings };
package/dist/analysis.js CHANGED
@@ -481,12 +481,18 @@ function nnlsChroma(samples, sampleRate = 22050, options = {}) {
481
481
  return nnlsChroma(samples.samples, samples.sampleRate, samples);
482
482
  }
483
483
  validateMusicSamples("nnlsChroma", samples, sampleRate, options);
484
- return requireModule2().nnlsChroma(
484
+ const hopLength = options.hopLength === void 0 ? 512 : options.hopLength;
485
+ assertPositiveInteger("nnlsChroma", hopLength, "hopLength");
486
+ if (hopLength > 2 ** 31 - 1) {
487
+ throw new RangeError("nnlsChroma: hopLength must fit in a signed 32-bit integer");
488
+ }
489
+ return requireModule2().nnlsChromaEx(
485
490
  samples,
486
491
  sampleRate,
487
492
  options.enableStftBlend ?? true,
488
493
  options.stftBlendWeight ?? 0.55,
489
- options.stftBlendNFft ?? 4096
494
+ options.stftBlendNFft ?? 4096,
495
+ hopLength
490
496
  );
491
497
  }
492
498
  function cqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, options = {}) {
@@ -916,6 +922,35 @@ function resample(samples, srcSr, targetSr) {
916
922
  function requireModule5() {
917
923
  return getSonareModule();
918
924
  }
925
+ function resolveEffectFftOptions(fnName, nFft, hopLength) {
926
+ const resolvedNFft = nFft === void 0 ? 2048 : nFft;
927
+ const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
928
+ if (typeof resolvedNFft !== "number" || !Number.isInteger(resolvedNFft)) {
929
+ throw new TypeError(`${fnName}: nFft must be an integer`);
930
+ }
931
+ if (resolvedNFft < 2 || resolvedNFft > 2 ** 30) {
932
+ throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
933
+ }
934
+ if ((resolvedNFft & resolvedNFft - 1) !== 0) {
935
+ throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
936
+ }
937
+ if (typeof resolvedHopLength !== "number" || !Number.isInteger(resolvedHopLength)) {
938
+ throw new TypeError(`${fnName}: hopLength must be an integer`);
939
+ }
940
+ if (resolvedHopLength <= 0 || resolvedHopLength > 2 ** 31 - 1) {
941
+ throw new RangeError(`${fnName}: hopLength must be a positive integer`);
942
+ }
943
+ return { nFft: resolvedNFft, hopLength: resolvedHopLength };
944
+ }
945
+ function resolveHardMask(fnName, value) {
946
+ if (value === void 0) {
947
+ return false;
948
+ }
949
+ if (typeof value !== "boolean") {
950
+ throw new TypeError(`${fnName}: hardMask must be a boolean`);
951
+ }
952
+ return value;
953
+ }
919
954
  function validateSegmentMatrix(fnName, data, rows, cols, dataName) {
920
955
  assertPositiveInteger(fnName, rows, "rows");
921
956
  assertPositiveInteger(fnName, cols, "cols");
@@ -1047,12 +1082,30 @@ function phaseVocoder(samples, sampleRate = 22050, rate = 1, nFft = 2048, hopLen
1047
1082
  }
1048
1083
  return requireModule5().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);
1049
1084
  }
1050
- function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31) {
1085
+ function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31, nFft, hopLength, hardMask) {
1051
1086
  if (!(samples instanceof Float32Array)) {
1052
1087
  const r = samples;
1053
- return hpssWithResidual(r.samples, r.sampleRate, r.kernelHarmonic, r.kernelPercussive);
1088
+ return hpssWithResidual(
1089
+ r.samples,
1090
+ r.sampleRate,
1091
+ r.kernelHarmonic,
1092
+ r.kernelPercussive,
1093
+ r.nFft,
1094
+ r.hopLength,
1095
+ r.hardMask
1096
+ );
1054
1097
  }
1055
- return requireModule5().hpssWithResidual(samples, sampleRate, kernelHarmonic, kernelPercussive);
1098
+ const fftOptions = resolveEffectFftOptions("hpssWithResidual", nFft, hopLength);
1099
+ const resolvedHardMask = resolveHardMask("hpssWithResidual", hardMask);
1100
+ return requireModule5().hpssWithResidualEx(
1101
+ samples,
1102
+ sampleRate,
1103
+ kernelHarmonic,
1104
+ kernelPercussive,
1105
+ fftOptions.nFft,
1106
+ fftOptions.hopLength,
1107
+ resolvedHardMask
1108
+ );
1056
1109
  }
1057
1110
  function lufsInterleaved(samples, channels = 0, sampleRate = 22050, options = {}) {
1058
1111
  if (!(samples instanceof Float32Array)) {
@@ -1265,14 +1318,35 @@ function validateMatrix(fnName, data, rows, frames, dataName, rowName, options =
1265
1318
  throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);
1266
1319
  }
1267
1320
  }
1268
- function trim(samples, sampleRate = 22050, thresholdDb = -60, options = {}) {
1321
+ function trim(samples, sampleRate = 22050, thresholdDb = -60, frameLengthOrOptions, hopLength, options = {}) {
1269
1322
  if (!(samples instanceof Float32Array)) {
1270
1323
  const r = samples;
1271
- return trim(r.samples, r.sampleRate, r.thresholdDb, r);
1324
+ return trim(r.samples, r.sampleRate, r.thresholdDb, r.frameLength, r.hopLength, r);
1325
+ }
1326
+ if (frameLengthOrOptions === null) {
1327
+ throw new TypeError("trim: frameLength must be an integer or options object");
1328
+ }
1329
+ if (frameLengthOrOptions !== void 0 && typeof frameLengthOrOptions !== "number" && typeof frameLengthOrOptions !== "object") {
1330
+ throw new TypeError("trim: frameLength must be an integer or options object");
1272
1331
  }
1273
- validateSpectrogramSamples("trim", samples, sampleRate, options);
1332
+ const positionalOptions = typeof frameLengthOrOptions === "object" && frameLengthOrOptions !== null ? frameLengthOrOptions : options;
1333
+ const positionalFrameLength = typeof frameLengthOrOptions === "number" ? frameLengthOrOptions : void 0;
1334
+ const resolvedFrameLength = positionalFrameLength ?? 2048;
1335
+ const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
1336
+ validateSpectrogramSamples("trim", samples, sampleRate, positionalOptions);
1274
1337
  assertFiniteScalar("trim", thresholdDb, "thresholdDb");
1275
- return requireModule6().trim(samples, sampleRate, thresholdDb);
1338
+ assertPositiveInteger("trim", resolvedFrameLength, "frameLength");
1339
+ assertPositiveInteger("trim", resolvedHopLength, "hopLength");
1340
+ if (resolvedFrameLength > 2 ** 31 - 1 || resolvedHopLength > 2 ** 31 - 1) {
1341
+ throw new RangeError("trim: frameLength and hopLength must fit in a signed 32-bit integer");
1342
+ }
1343
+ return requireModule6().trimEx(
1344
+ samples,
1345
+ sampleRate,
1346
+ thresholdDb,
1347
+ resolvedFrameLength,
1348
+ resolvedHopLength
1349
+ );
1276
1350
  }
1277
1351
  function stft(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, options = {}) {
1278
1352
  if (!(samples instanceof Float32Array)) {
@@ -1658,6 +1732,15 @@ function meteringCrestFactorDb(samples, sampleRate = 22050, options = {}) {
1658
1732
  assertSamples("meteringCrestFactorDb", request.samples, request.validate !== false);
1659
1733
  return requireModule7().meteringCrestFactorDb(request.samples, request.sampleRate ?? 22050);
1660
1734
  }
1735
+ function meteringCrestFactorDbStereo(request) {
1736
+ assertSamples("meteringCrestFactorDbStereo", request.left, request.validate !== false);
1737
+ assertSamples("meteringCrestFactorDbStereo", request.right, request.validate !== false);
1738
+ return requireModule7().meteringCrestFactorDbStereo(
1739
+ request.left,
1740
+ request.right,
1741
+ request.sampleRate ?? 22050
1742
+ );
1743
+ }
1661
1744
  function meteringDcOffset(samples, sampleRate = 22050, options = {}) {
1662
1745
  const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
1663
1746
  assertSamples("meteringDcOffset", request.samples, request.validate !== false);
@@ -1869,6 +1952,36 @@ var SectionType = {
1869
1952
  Unknown: 7
1870
1953
  };
1871
1954
 
1955
+ // src/codes.ts
1956
+ function resolveOrdinalInRange(value, min, max, enumName) {
1957
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
1958
+ throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
1959
+ }
1960
+ return value;
1961
+ }
1962
+ function resolveEnumOrdinal(value, values, enumName) {
1963
+ if (typeof value === "number") {
1964
+ const ordinals = Object.values(values);
1965
+ const ordinal = resolveOrdinalInRange(
1966
+ value,
1967
+ Math.min(...ordinals),
1968
+ Math.max(...ordinals),
1969
+ enumName
1970
+ );
1971
+ if (!ordinals.includes(ordinal)) {
1972
+ throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
1973
+ }
1974
+ return ordinal;
1975
+ }
1976
+ if (typeof value === "string") {
1977
+ const ordinal = values[value];
1978
+ if (ordinal !== void 0) {
1979
+ return ordinal;
1980
+ }
1981
+ }
1982
+ throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
1983
+ }
1984
+
1872
1985
  // src/analysis_helpers.ts
1873
1986
  var PITCH_CLASS_NAMES = [
1874
1987
  "C",
@@ -1899,6 +2012,30 @@ function convertKeyCandidate(wasm) {
1899
2012
  correlation: wasm.correlation
1900
2013
  };
1901
2014
  }
2015
+ var KEY_MODE_VALUES = {
2016
+ major: Mode.Major,
2017
+ minor: Mode.Minor,
2018
+ dorian: Mode.Dorian,
2019
+ phrygian: Mode.Phrygian,
2020
+ lydian: Mode.Lydian,
2021
+ mixolydian: Mode.Mixolydian,
2022
+ locrian: Mode.Locrian
2023
+ };
2024
+ var KEY_PROFILE_VALUES = {
2025
+ ks: KeyProfile.KrumhanslSchmuckler,
2026
+ krumhansl: KeyProfile.KrumhanslSchmuckler,
2027
+ temperley: KeyProfile.Temperley,
2028
+ shaath: KeyProfile.Shaath,
2029
+ keyfinder: KeyProfile.Shaath,
2030
+ "faraldo-edmt": KeyProfile.FaraldoEDMT,
2031
+ edmt: KeyProfile.FaraldoEDMT,
2032
+ "faraldo-edma": KeyProfile.FaraldoEDMA,
2033
+ edma: KeyProfile.FaraldoEDMA,
2034
+ "faraldo-edmm": KeyProfile.FaraldoEDMM,
2035
+ edmm: KeyProfile.FaraldoEDMM,
2036
+ "bellman-budge": KeyProfile.BellmanBudge,
2037
+ bellman: KeyProfile.BellmanBudge
2038
+ };
1902
2039
  function keyModeValues(modes) {
1903
2040
  if (!modes) {
1904
2041
  return [];
@@ -1917,40 +2054,13 @@ function keyModeValues(modes) {
1917
2054
  Mode.Locrian
1918
2055
  ];
1919
2056
  }
1920
- const names = {
1921
- major: Mode.Major,
1922
- minor: Mode.Minor,
1923
- dorian: Mode.Dorian,
1924
- phrygian: Mode.Phrygian,
1925
- lydian: Mode.Lydian,
1926
- mixolydian: Mode.Mixolydian,
1927
- locrian: Mode.Locrian
1928
- };
1929
- return modes.map((mode) => typeof mode === "number" ? mode : names[mode]);
2057
+ return modes.map((mode) => resolveEnumOrdinal(mode, KEY_MODE_VALUES, "key mode"));
1930
2058
  }
1931
2059
  function keyProfileValue(profile) {
1932
2060
  if (profile === void 0) {
1933
2061
  return -1;
1934
2062
  }
1935
- if (typeof profile === "number") {
1936
- return profile;
1937
- }
1938
- const names = {
1939
- ks: KeyProfile.KrumhanslSchmuckler,
1940
- krumhansl: KeyProfile.KrumhanslSchmuckler,
1941
- temperley: KeyProfile.Temperley,
1942
- shaath: KeyProfile.Shaath,
1943
- keyfinder: KeyProfile.Shaath,
1944
- "faraldo-edmt": KeyProfile.FaraldoEDMT,
1945
- edmt: KeyProfile.FaraldoEDMT,
1946
- "faraldo-edma": KeyProfile.FaraldoEDMA,
1947
- edma: KeyProfile.FaraldoEDMA,
1948
- "faraldo-edmm": KeyProfile.FaraldoEDMM,
1949
- edmm: KeyProfile.FaraldoEDMM,
1950
- "bellman-budge": KeyProfile.BellmanBudge,
1951
- bellman: KeyProfile.BellmanBudge
1952
- };
1953
- return names[profile];
2063
+ return resolveEnumOrdinal(profile, KEY_PROFILE_VALUES, "key profile");
1954
2064
  }
1955
2065
  function convertChordAnalysisResult(wasm) {
1956
2066
  return {
@@ -2156,18 +2266,27 @@ function analyze(samples, sampleRate = 22050, options = {}) {
2156
2266
  const result = requireModule8().analyze(request.samples, request.sampleRate ?? 22050, request);
2157
2267
  return convertAnalysisResult(result);
2158
2268
  }
2159
- function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6) {
2160
- const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands } : samples;
2269
+ function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6, minDecayDb) {
2270
+ const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands, minDecayDb } : samples;
2271
+ if (request.minDecayDb === null) {
2272
+ throw new TypeError("analyzeImpulseResponse: minDecayDb must be a finite number");
2273
+ }
2274
+ const resolvedMinDecayDb = request.minDecayDb === void 0 ? 30 : request.minDecayDb;
2275
+ assertFiniteScalar("analyzeImpulseResponse", resolvedMinDecayDb, "minDecayDb");
2276
+ if (resolvedMinDecayDb <= 0) {
2277
+ throw new RangeError("analyzeImpulseResponse: minDecayDb must be greater than zero");
2278
+ }
2161
2279
  validateAnalysisInput(
2162
2280
  "analyzeImpulseResponse",
2163
2281
  request.samples,
2164
2282
  request.sampleRate ?? 48e3,
2165
2283
  request
2166
2284
  );
2167
- const result = requireModule8().analyzeImpulseResponse(
2285
+ const result = requireModule8().analyzeImpulseResponseEx(
2168
2286
  request.samples,
2169
2287
  request.sampleRate ?? 48e3,
2170
- request.nOctaveBands ?? 6
2288
+ request.nOctaveBands ?? 6,
2289
+ resolvedMinDecayDb
2171
2290
  );
2172
2291
  return result;
2173
2292
  }
@@ -2382,6 +2501,7 @@ export {
2382
2501
  melToHz,
2383
2502
  melToStft,
2384
2503
  meteringCrestFactorDb,
2504
+ meteringCrestFactorDbStereo,
2385
2505
  meteringDcOffset,
2386
2506
  meteringDetectClipping,
2387
2507
  meteringDynamicRange,