@libraz/libsonare 1.6.0 → 1.7.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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/analysis.d.ts +88 -9
  3. package/dist/analysis.js +152 -42
  4. package/dist/analysis.js.map +1 -1
  5. package/dist/index.d.ts +129 -24
  6. package/dist/index.js +455 -140
  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 +62 -10
  16. package/dist/worklet.js +193 -42
  17. package/dist/worklet.js.map +1 -1
  18. package/package.json +3 -3
  19. package/src/analysis_helpers.ts +34 -29
  20. package/src/audio.ts +7 -2
  21. package/src/codes.ts +47 -11
  22. package/src/effects_transform.ts +179 -10
  23. package/src/feature_music.ts +8 -1
  24. package/src/feature_spectral.ts +64 -2
  25. package/src/feature_spectrogram.ts +44 -3
  26. package/src/index.ts +21 -3
  27. package/src/mixer.ts +3 -3
  28. package/src/project.ts +6 -0
  29. package/src/project_class.ts +143 -16
  30. package/src/project_internal.ts +14 -5
  31. package/src/project_types.ts +45 -1
  32. package/src/public_types_mixing.ts +16 -0
  33. package/src/public_types_realtime.ts +23 -5
  34. package/src/quick_analysis.ts +21 -3
  35. package/src/realtime_engine.ts +14 -3
  36. package/src/sonare.js.d.ts +64 -0
  37. package/src/stream_analyzer.ts +6 -1
  38. package/src/web_midi.ts +10 -7
  39. package/src/worklet/engine-node.ts +54 -19
  40. package/src/worklet/engine-parameter-facade.ts +30 -1
  41. package/src/worklet/engine-processor.ts +52 -20
  42. package/src/worklet/engine-register.ts +1 -1
  43. package/src/worklet/engine-strips.ts +2 -2
  44. package/src/worklet/engine.ts +10 -0
  45. package/src/worklet/guards.ts +99 -7
  46. package/src/worklet/messages.ts +41 -1
  47. 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
@@ -549,6 +549,10 @@ type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';
549
549
  * remains unity. Maps to the underlying integer code.
550
550
  */
551
551
  type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';
552
+ /** Accepted pan-law name aliases for mixer and realtime-engine inputs. */
553
+ type PanLawName = PanLaw | 'const-3db' | '-3db' | 'const-4.5db' | '-4.5db' | 'const-6db' | '-6db' | 'linear-0db' | 'linear' | '0db';
554
+ /** Pan-law name or raw C ABI ordinal. */
555
+ type PanLawInput = PanLawName | number;
552
556
  /**
553
557
  * Meter tap point for reading a strip's meter snapshot
554
558
  * (see {@link Mixer.meterTap} and {@link Mixer.stripMeter}).
@@ -958,14 +962,21 @@ interface EqMatchOptions {
958
962
  maxBands?: number;
959
963
  }
960
964
  type VoicePresetId = 'neutral-monitor' | 'bright-idol' | 'soft-whisper' | 'deep-narrator' | 'robot-mascot' | 'dark-villain';
961
- interface RealtimeVoiceChangerPreset {
965
+ type VoicePresetCategory = 'monitor' | 'bright' | 'soft' | 'deep' | 'robot' | 'dark' | 'custom';
966
+ interface RealtimeVoiceChangerPresetMetadata {
962
967
  schemaVersion: 1;
963
- id?: string;
964
- name?: string;
968
+ id: string;
969
+ name: string;
965
970
  description?: string;
966
- macros?: Record<string, number>;
967
- dsp?: Record<string, unknown>;
968
- }
971
+ category: VoicePresetCategory;
972
+ }
973
+ type RealtimeVoiceChangerPreset = (RealtimeVoiceChangerPresetMetadata & {
974
+ dsp: Record<string, unknown>;
975
+ macros?: never;
976
+ }) | (RealtimeVoiceChangerPresetMetadata & {
977
+ macros: Record<string, number>;
978
+ dsp?: never;
979
+ });
969
980
  type RealtimeVoiceChangerConfigInput = VoicePresetId | RealtimeVoiceChangerPreset;
970
981
  /**
971
982
  * Flat (POD) realtime voice-changer configuration. Keys are camelCase to match
@@ -2169,6 +2180,7 @@ interface WasmRealtimeEngine {
2169
2180
  setParameterSmoothed: (paramId: number, value: number, renderFrame: number) => void;
2170
2181
  setParamSmoothingMs: (smoothingMs: number) => void;
2171
2182
  setSoloMute: (laneIndex: number, solo: boolean, mute: boolean, renderFrame: number) => void;
2183
+ setTrackMonitorMode: (laneIndex: number, mode: number, renderFrame: number) => void;
2172
2184
  getTransportState: () => WasmEngineTransportState;
2173
2185
  play: (renderFrame: number) => void;
2174
2186
  stop: (renderFrame: number) => void;
@@ -2488,6 +2500,12 @@ interface SonareModule {
2488
2500
  sampleRate: number,
2489
2501
  nOctaveBands: number,
2490
2502
  ) => WasmAcousticResult;
2503
+ analyzeImpulseResponseEx: (
2504
+ samples: Float32Array,
2505
+ sampleRate: number,
2506
+ nOctaveBands: number,
2507
+ minDecayDb: number,
2508
+ ) => WasmAcousticResult;
2491
2509
  detectAcoustic: (
2492
2510
  samples: Float32Array,
2493
2511
  sampleRate: number,
@@ -2727,12 +2745,30 @@ interface SonareModule {
2727
2745
  kernelHarmonic: number,
2728
2746
  kernelPercussive: number,
2729
2747
  ) => WasmHpssResult;
2748
+ hpssEx: (
2749
+ samples: Float32Array,
2750
+ sampleRate: number,
2751
+ kernelHarmonic: number,
2752
+ kernelPercussive: number,
2753
+ nFft: number,
2754
+ hopLength: number,
2755
+ hardMask: boolean,
2756
+ ) => WasmHpssResult;
2730
2757
  hpssWithResidual: (
2731
2758
  samples: Float32Array,
2732
2759
  sampleRate: number,
2733
2760
  kernelHarmonic: number,
2734
2761
  kernelPercussive: number,
2735
2762
  ) => WasmHpssWithResidualResult;
2763
+ hpssWithResidualEx: (
2764
+ samples: Float32Array,
2765
+ sampleRate: number,
2766
+ kernelHarmonic: number,
2767
+ kernelPercussive: number,
2768
+ nFft: number,
2769
+ hopLength: number,
2770
+ hardMask: boolean,
2771
+ ) => WasmHpssWithResidualResult;
2736
2772
  decompose: (
2737
2773
  s: Float32Array,
2738
2774
  nFeatures: number,
@@ -2774,7 +2810,21 @@ interface SonareModule {
2774
2810
  harmonic: (samples: Float32Array, sampleRate: number) => Float32Array;
2775
2811
  percussive: (samples: Float32Array, sampleRate: number) => Float32Array;
2776
2812
  timeStretch: (samples: Float32Array, sampleRate: number, rate: number) => Float32Array;
2813
+ timeStretchEx: (
2814
+ samples: Float32Array,
2815
+ sampleRate: number,
2816
+ rate: number,
2817
+ nFft: number,
2818
+ hopLength: number,
2819
+ ) => Float32Array;
2777
2820
  pitchShift: (samples: Float32Array, sampleRate: number, semitones: number) => Float32Array;
2821
+ pitchShiftEx: (
2822
+ samples: Float32Array,
2823
+ sampleRate: number,
2824
+ semitones: number,
2825
+ nFft: number,
2826
+ hopLength: number,
2827
+ ) => Float32Array;
2778
2828
  pitchCorrectToMidi: (
2779
2829
  samples: Float32Array,
2780
2830
  sampleRate: number,
@@ -2836,6 +2886,12 @@ interface SonareModule {
2836
2886
  channels: number,
2837
2887
  ) => Float32Array;
2838
2888
  normalize: (samples: Float32Array, sampleRate: number, targetDb: number) => Float32Array;
2889
+ normalizeEx: (
2890
+ samples: Float32Array,
2891
+ sampleRate: number,
2892
+ targetDb: number,
2893
+ mode: string,
2894
+ ) => Float32Array;
2839
2895
  mastering: (
2840
2896
  samples: Float32Array,
2841
2897
  sampleRate: number,
@@ -3014,6 +3070,13 @@ interface SonareModule {
3014
3070
  options: Record<string, unknown>,
3015
3071
  ) => WasmMixResult;
3016
3072
  trim: (samples: Float32Array, sampleRate: number, thresholdDb: number) => Float32Array;
3073
+ trimEx: (
3074
+ samples: Float32Array,
3075
+ sampleRate: number,
3076
+ thresholdDb: number,
3077
+ frameLength: number,
3078
+ hopLength: number,
3079
+ ) => Float32Array;
3017
3080
  spectralEdit: (
3018
3081
  samples: Float32Array,
3019
3082
  sampleRate: number,
@@ -3444,6 +3507,14 @@ interface SonareModule {
3444
3507
  stftBlendWeight: number,
3445
3508
  stftBlendNFft: number,
3446
3509
  ) => WasmNnlsChromaResult;
3510
+ nnlsChromaEx: (
3511
+ samples: Float32Array,
3512
+ sampleRate: number,
3513
+ enableStftBlend: boolean,
3514
+ stftBlendWeight: number,
3515
+ stftBlendNFft: number,
3516
+ hopLength: number,
3517
+ ) => WasmNnlsChromaResult;
3447
3518
  cqt: (
3448
3519
  samples: Float32Array,
3449
3520
  sampleRate: number,
@@ -4315,6 +4386,7 @@ interface NnlsChromaRequest extends GuardedOptions$2 {
4315
4386
  enableStftBlend?: boolean;
4316
4387
  stftBlendWeight?: number;
4317
4388
  stftBlendNFft?: number;
4389
+ hopLength?: number;
4318
4390
  }
4319
4391
  /**
4320
4392
  * Compute NNLS (non-negative least squares) chromagram.
@@ -4725,6 +4797,9 @@ interface HpssWithResidualRequest {
4725
4797
  sampleRate?: number;
4726
4798
  kernelHarmonic?: number;
4727
4799
  kernelPercussive?: number;
4800
+ nFft?: number;
4801
+ hopLength?: number;
4802
+ hardMask?: boolean;
4728
4803
  }
4729
4804
  interface LufsInterleavedRequest extends ValidateOptions {
4730
4805
  samples: Float32Array;
@@ -4813,7 +4888,7 @@ declare function phaseVocoder(samples: Float32Array, sampleRate: number, rate: n
4813
4888
  * HPSS into harmonic / percussive / residual signals.
4814
4889
  */
4815
4890
  declare function hpssWithResidual(request: HpssWithResidualRequest): WasmHpssWithResidualResult;
4816
- declare function hpssWithResidual(samples: Float32Array, sampleRate?: number, kernelHarmonic?: number, kernelPercussive?: number): WasmHpssWithResidualResult;
4891
+ declare function hpssWithResidual(samples: Float32Array, sampleRate?: number, kernelHarmonic?: number, kernelPercussive?: number, nFft?: number, hopLength?: number, hardMask?: boolean): WasmHpssWithResidualResult;
4817
4892
  /**
4818
4893
  * Channel-weighted multichannel integrated loudness + LRA (ITU-R BS.1770 /
4819
4894
  * EBU R128) from an interleaved buffer of `frames * channels` samples. The
@@ -4992,6 +5067,8 @@ interface TrimRequest extends GuardedOptions$1 {
4992
5067
  samples: Float32Array;
4993
5068
  sampleRate: number;
4994
5069
  thresholdDb?: number;
5070
+ frameLength?: number;
5071
+ hopLength?: number;
4995
5072
  }
4996
5073
  /**
4997
5074
  * Trim silence from beginning and end of audio.
@@ -5003,6 +5080,7 @@ interface TrimRequest extends GuardedOptions$1 {
5003
5080
  */
5004
5081
  declare function trim(request: TrimRequest): Float32Array;
5005
5082
  declare function trim(samples: Float32Array, sampleRate: number, thresholdDb?: number, options?: GuardedOptions$1): Float32Array;
5083
+ declare function trim(samples: Float32Array, sampleRate: number, thresholdDb?: number, frameLength?: number, hopLength?: number, options?: GuardedOptions$1): Float32Array;
5006
5084
  /**
5007
5085
  * Compute Short-Time Fourier Transform (STFT).
5008
5086
  *
@@ -5488,6 +5566,7 @@ interface ChordFunctionalAnalysisRequest extends DetectChordsRequest {
5488
5566
  /** Canonical request form for impulse-response analysis. */
5489
5567
  interface AnalyzeImpulseResponseRequest extends SamplesRequest {
5490
5568
  nOctaveBands?: number;
5569
+ minDecayDb?: number;
5491
5570
  }
5492
5571
  /** Canonical request form for acoustic analysis. */
5493
5572
  interface DetectAcousticRequest extends AcousticOptions, SamplesRequest {
@@ -5603,7 +5682,7 @@ interface MusicAnalyzeRequest extends SamplesRequest, MusicAnalyzeOptions {
5603
5682
  declare function analyze(request: MusicAnalyzeRequest): AnalysisResult;
5604
5683
  declare function analyze(samples: Float32Array, sampleRate?: number, options?: GuardedOptions & MusicAnalyzeOptions): AnalysisResult;
5605
5684
  declare function analyzeImpulseResponse(request: AnalyzeImpulseResponseRequest): AcousticResult;
5606
- declare function analyzeImpulseResponse(samples: Float32Array, sampleRate?: number, nOctaveBands?: number): AcousticResult;
5685
+ declare function analyzeImpulseResponse(samples: Float32Array, sampleRate?: number, nOctaveBands?: number, minDecayDb?: number): AcousticResult;
5607
5686
  declare function detectAcoustic(request: DetectAcousticRequest): AcousticResult;
5608
5687
  declare function detectAcoustic(samples: Float32Array, sampleRate?: number, options?: AcousticOptions): AcousticResult;
5609
5688
  /**
@@ -5727,4 +5806,4 @@ declare function engineAbiVersion(): number;
5727
5806
  /** Voice-changer ABI version retained for cross-entry compatibility checks. */
5728
5807
  declare function voiceChangerAbiVersion(): number;
5729
5808
 
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 };
5809
+ 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 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 };
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");
1272
1328
  }
1273
- validateSpectrogramSamples("trim", samples, sampleRate, options);
1329
+ if (frameLengthOrOptions !== void 0 && typeof frameLengthOrOptions !== "number" && typeof frameLengthOrOptions !== "object") {
1330
+ throw new TypeError("trim: frameLength must be an integer or options object");
1331
+ }
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)) {
@@ -1869,6 +1943,36 @@ var SectionType = {
1869
1943
  Unknown: 7
1870
1944
  };
1871
1945
 
1946
+ // src/codes.ts
1947
+ function resolveOrdinalInRange(value, min, max, enumName) {
1948
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
1949
+ throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
1950
+ }
1951
+ return value;
1952
+ }
1953
+ function resolveEnumOrdinal(value, values, enumName) {
1954
+ if (typeof value === "number") {
1955
+ const ordinals = Object.values(values);
1956
+ const ordinal = resolveOrdinalInRange(
1957
+ value,
1958
+ Math.min(...ordinals),
1959
+ Math.max(...ordinals),
1960
+ enumName
1961
+ );
1962
+ if (!ordinals.includes(ordinal)) {
1963
+ throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
1964
+ }
1965
+ return ordinal;
1966
+ }
1967
+ if (typeof value === "string") {
1968
+ const ordinal = values[value];
1969
+ if (ordinal !== void 0) {
1970
+ return ordinal;
1971
+ }
1972
+ }
1973
+ throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
1974
+ }
1975
+
1872
1976
  // src/analysis_helpers.ts
1873
1977
  var PITCH_CLASS_NAMES = [
1874
1978
  "C",
@@ -1899,6 +2003,30 @@ function convertKeyCandidate(wasm) {
1899
2003
  correlation: wasm.correlation
1900
2004
  };
1901
2005
  }
2006
+ var KEY_MODE_VALUES = {
2007
+ major: Mode.Major,
2008
+ minor: Mode.Minor,
2009
+ dorian: Mode.Dorian,
2010
+ phrygian: Mode.Phrygian,
2011
+ lydian: Mode.Lydian,
2012
+ mixolydian: Mode.Mixolydian,
2013
+ locrian: Mode.Locrian
2014
+ };
2015
+ var KEY_PROFILE_VALUES = {
2016
+ ks: KeyProfile.KrumhanslSchmuckler,
2017
+ krumhansl: KeyProfile.KrumhanslSchmuckler,
2018
+ temperley: KeyProfile.Temperley,
2019
+ shaath: KeyProfile.Shaath,
2020
+ keyfinder: KeyProfile.Shaath,
2021
+ "faraldo-edmt": KeyProfile.FaraldoEDMT,
2022
+ edmt: KeyProfile.FaraldoEDMT,
2023
+ "faraldo-edma": KeyProfile.FaraldoEDMA,
2024
+ edma: KeyProfile.FaraldoEDMA,
2025
+ "faraldo-edmm": KeyProfile.FaraldoEDMM,
2026
+ edmm: KeyProfile.FaraldoEDMM,
2027
+ "bellman-budge": KeyProfile.BellmanBudge,
2028
+ bellman: KeyProfile.BellmanBudge
2029
+ };
1902
2030
  function keyModeValues(modes) {
1903
2031
  if (!modes) {
1904
2032
  return [];
@@ -1917,40 +2045,13 @@ function keyModeValues(modes) {
1917
2045
  Mode.Locrian
1918
2046
  ];
1919
2047
  }
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]);
2048
+ return modes.map((mode) => resolveEnumOrdinal(mode, KEY_MODE_VALUES, "key mode"));
1930
2049
  }
1931
2050
  function keyProfileValue(profile) {
1932
2051
  if (profile === void 0) {
1933
2052
  return -1;
1934
2053
  }
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];
2054
+ return resolveEnumOrdinal(profile, KEY_PROFILE_VALUES, "key profile");
1954
2055
  }
1955
2056
  function convertChordAnalysisResult(wasm) {
1956
2057
  return {
@@ -2156,18 +2257,27 @@ function analyze(samples, sampleRate = 22050, options = {}) {
2156
2257
  const result = requireModule8().analyze(request.samples, request.sampleRate ?? 22050, request);
2157
2258
  return convertAnalysisResult(result);
2158
2259
  }
2159
- function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6) {
2160
- const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands } : samples;
2260
+ function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6, minDecayDb) {
2261
+ const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands, minDecayDb } : samples;
2262
+ if (request.minDecayDb === null) {
2263
+ throw new TypeError("analyzeImpulseResponse: minDecayDb must be a finite number");
2264
+ }
2265
+ const resolvedMinDecayDb = request.minDecayDb === void 0 ? 30 : request.minDecayDb;
2266
+ assertFiniteScalar("analyzeImpulseResponse", resolvedMinDecayDb, "minDecayDb");
2267
+ if (resolvedMinDecayDb <= 0) {
2268
+ throw new RangeError("analyzeImpulseResponse: minDecayDb must be greater than zero");
2269
+ }
2161
2270
  validateAnalysisInput(
2162
2271
  "analyzeImpulseResponse",
2163
2272
  request.samples,
2164
2273
  request.sampleRate ?? 48e3,
2165
2274
  request
2166
2275
  );
2167
- const result = requireModule8().analyzeImpulseResponse(
2276
+ const result = requireModule8().analyzeImpulseResponseEx(
2168
2277
  request.samples,
2169
2278
  request.sampleRate ?? 48e3,
2170
- request.nOctaveBands ?? 6
2279
+ request.nOctaveBands ?? 6,
2280
+ resolvedMinDecayDb
2171
2281
  );
2172
2282
  return result;
2173
2283
  }