@libraz/libsonare 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -1
- package/dist/index.d.ts +1 -2842
- package/dist/index.js +3602 -1934
- package/dist/index.js.map +1 -1
- package/dist/sonare-rt-module.js +1 -1
- package/dist/sonare-rt.js +1 -1
- package/dist/sonare-rt.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +4816 -483
- package/dist/worklet.js +747 -440
- package/dist/worklet.js.map +1 -1
- package/package.json +2 -1
- package/src/analysis_helpers.ts +152 -0
- package/src/audio.ts +493 -0
- package/src/codes.ts +56 -0
- package/src/effects_mastering.ts +964 -0
- package/src/feature_core.ts +248 -0
- package/src/feature_music.ts +419 -0
- package/src/feature_pitch.ts +80 -0
- package/src/feature_resample.ts +21 -0
- package/src/feature_spectral.ts +330 -0
- package/src/feature_spectrogram.ts +454 -0
- package/src/features.ts +84 -0
- package/src/index.ts +341 -4963
- package/src/live_audio.ts +45 -0
- package/src/metering.ts +380 -0
- package/src/mixer.ts +523 -0
- package/src/module_state.ts +14 -0
- package/src/opfs_clip_pages.ts +188 -0
- package/src/project.ts +1614 -0
- package/src/public_types.ts +177 -2
- package/src/quick_analysis.ts +508 -0
- package/src/realtime_engine.ts +667 -0
- package/src/realtime_voice_changer.ts +275 -0
- package/src/scale.ts +42 -0
- package/src/sonare.js.d.ts +302 -4
- package/src/stream_analyzer.ts +275 -0
- package/src/stream_types.ts +26 -1
- package/src/streaming_mixing.ts +18 -0
- package/src/streaming_processors.ts +335 -0
- package/src/validation.ts +82 -0
- package/src/web_midi.ts +367 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/public_types.ts","../src/index.ts"],"sourcesContent":["/**\n * Pitch class enum (C=0, C#=1, ..., B=11)\n */\nexport const PitchClass = {\n C: 0,\n Cs: 1,\n D: 2,\n Ds: 3,\n E: 4,\n F: 5,\n Fs: 6,\n G: 7,\n Gs: 8,\n A: 9,\n As: 10,\n B: 11,\n} as const;\n\nexport type PitchClass = (typeof PitchClass)[keyof typeof PitchClass];\n\n/**\n * Musical mode\n */\nexport const Mode = {\n Major: 0,\n Minor: 1,\n Dorian: 2,\n Phrygian: 3,\n Lydian: 4,\n Mixolydian: 5,\n Locrian: 6,\n} as const;\n\nexport type Mode = (typeof Mode)[keyof typeof Mode];\n\nexport type TempogramMode = 'autocorrelation' | 'auto' | 'ac' | 'cosine' | 0 | 1;\n\nexport const KeyProfile = {\n KrumhanslSchmuckler: 0,\n Temperley: 1,\n Shaath: 2,\n FaraldoEDMT: 3,\n FaraldoEDMA: 4,\n FaraldoEDMM: 5,\n BellmanBudge: 6,\n} as const;\n\nexport type KeyProfile = (typeof KeyProfile)[keyof typeof KeyProfile];\n\nexport type KeyProfileName =\n | 'ks'\n | 'krumhansl'\n | 'temperley'\n | 'shaath'\n | 'keyfinder'\n | 'faraldo-edmt'\n | 'edmt'\n | 'faraldo-edma'\n | 'edma'\n | 'faraldo-edmm'\n | 'edmm'\n | 'bellman-budge'\n | 'bellman';\n\n/**\n * Chord quality\n */\nexport const ChordQuality = {\n Major: 0,\n Minor: 1,\n Diminished: 2,\n Augmented: 3,\n Dominant7: 4,\n Major7: 5,\n Minor7: 6,\n Sus2: 7,\n Sus4: 8,\n Unknown: 9,\n Add9: 10,\n MinorAdd9: 11,\n Dim7: 12,\n HalfDim7: 13,\n Major9: 14,\n Dominant9: 15,\n Sus2Add4: 16,\n} as const;\n\nexport type ChordQuality = (typeof ChordQuality)[keyof typeof ChordQuality];\n\nexport type MasteringPreset =\n | 'pop'\n | 'edm'\n | 'acoustic'\n | 'hipHop'\n | 'aiMusic'\n | 'speech'\n | 'streaming'\n | 'youtube'\n | 'broadcast'\n | 'podcast'\n | 'audiobook'\n | 'cinema'\n | 'jpop'\n | 'ambient'\n | 'lofi'\n | 'classical'\n | 'drumAndBass'\n | 'techno'\n | 'metal'\n | 'trap'\n | 'rnb'\n | 'jazz'\n | 'kpop'\n | 'trance'\n | 'gameOst';\n\nexport interface StreamingPlatform {\n name: string;\n targetLufs: number;\n ceilingDb: number;\n}\n\nexport type SoloProcessor =\n | 'dynamics.brickwallLimiter'\n | 'dynamics.compressor'\n | 'dynamics.deesser'\n | 'dynamics.expander'\n | 'dynamics.gate'\n | 'dynamics.limiter'\n | 'dynamics.parallelComp'\n | 'dynamics.sidechainRouter'\n | 'dynamics.duckingProcessor'\n | 'dynamics.transientShaper'\n | 'dynamics.upwardCompressor'\n | 'dynamics.upwardExpander'\n | 'dynamics.vocalRider'\n | 'eq.apiStyle'\n | 'eq.bandPass'\n | 'eq.cutFilter'\n | 'eq.dynamic'\n | 'eq.equalizer'\n | 'eq.graphic'\n | 'eq.linearPhase'\n | 'eq.midSide'\n | 'eq.minimumPhase'\n | 'eq.parametric'\n | 'eq.pultec'\n | 'eq.shelving'\n | 'eq.tilt'\n | 'final.bitDepth'\n | 'final.dither'\n | 'final.outputChain'\n | 'maximizer.adaptiveRelease'\n | 'maximizer.loudnessOptimize'\n | 'maximizer.maximizer'\n | 'maximizer.softKneeMax'\n | 'maximizer.truePeakLimiter'\n | 'multiband.compressor'\n | 'multiband.dynamicEq'\n | 'multiband.expander'\n | 'multiband.imager'\n | 'multiband.limiter'\n | 'multiband.saturation'\n | 'repair.declick'\n | 'repair.declip'\n | 'repair.decrackle'\n | 'repair.dehum'\n | 'repair.denoiseClassical'\n | 'repair.dereverbClassical'\n | 'repair.trimSilence'\n | 'saturation.bitcrusher'\n | 'saturation.exciter'\n | 'saturation.hardClipper'\n | 'saturation.multibandExciter'\n | 'saturation.softClipper'\n | 'saturation.tape'\n | 'saturation.transformer'\n | 'saturation.tube'\n | 'saturation.waveshaper'\n | 'spectral.airBand'\n | 'spectral.lowEndFocus'\n | 'spectral.presenceEnhancer'\n | 'spectral.spectralShaper'\n | 'stereo.autoPan'\n | 'stereo.haasEnhancer'\n | 'stereo.imager'\n | 'stereo.monoMaker'\n | 'stereo.phaseAlign'\n | 'stereo.stereoBalance';\n\nexport type PairProcessor =\n | 'match.applyMatchEq'\n | 'match.alignReferenceToSource'\n | 'match.abSwitch'\n | 'match.abCrossfade';\n\nexport type PairAnalysis =\n | 'match.referenceLoudness'\n | 'match.tonalBalance'\n | 'match.tonalBalanceLogBands'\n | 'match.matchEqCurve'\n | 'match.estimateReferenceDelaySamples';\n\nexport type StereoAnalysis = 'stereo.monoCompatCheck' | 'stereo.monoCompatCheckLogBands';\n\n/**\n * Section type\n */\nexport const SectionType = {\n Intro: 0,\n Verse: 1,\n PreChorus: 2,\n Chorus: 3,\n Bridge: 4,\n Instrumental: 5,\n Outro: 6,\n Unknown: 7,\n} as const;\n\nexport type SectionType = (typeof SectionType)[keyof typeof SectionType];\n\n/**\n * Detected musical key\n */\nexport interface Key {\n root: PitchClass;\n mode: Mode;\n confidence: number;\n name: string;\n shortName: string;\n}\n\nexport interface KeyDetectionOptions {\n nFft?: number;\n hopLength?: number;\n useHpss?: boolean;\n loudnessWeighted?: boolean;\n highPassHz?: number;\n modes?:\n | Mode[]\n | ('major' | 'minor' | 'dorian' | 'phrygian' | 'lydian' | 'mixolydian' | 'locrian')[]\n | 'major-minor'\n | 'all'\n | 'modal';\n profile?: KeyProfile | KeyProfileName;\n genreHint?: 'auto' | 'edm' | 'electronic' | 'dance' | 'pop' | 'classical' | 'jazz' | string;\n}\n\nexport interface KeyCandidate {\n key: Key;\n correlation: number;\n}\n\nexport interface ChordDetectionOptions {\n minDuration?: number;\n smoothingWindow?: number;\n threshold?: number;\n useTriadsOnly?: boolean;\n nFft?: number;\n hopLength?: number;\n useBeatSync?: boolean;\n useHmm?: boolean;\n hmmBeamWidth?: number;\n useKeyContext?: boolean;\n keyRoot?: PitchClass;\n keyMode?: Mode;\n detectInversions?: boolean;\n chromaMethod?: 'stft' | 'nnls';\n}\n\n/**\n * Detected beat\n */\nexport interface Beat {\n time: number;\n strength: number;\n}\n\n/**\n * Detected chord\n */\nexport interface Chord {\n root: PitchClass;\n bass: PitchClass;\n quality: ChordQuality;\n start: number;\n end: number;\n confidence: number;\n name: string;\n}\n\nexport interface ChordAnalysisResult {\n chords: Chord[];\n}\n\n/**\n * Detected section\n */\nexport interface Section {\n type: SectionType;\n start: number;\n end: number;\n energyLevel: number;\n confidence: number;\n name: string;\n}\n\n/**\n * A single melody contour point (mirrors the C `SonareMelodyPoint`).\n */\nexport interface MelodyPoint {\n /** Frame time in seconds. */\n time: number;\n /** Estimated fundamental frequency in Hz (0 when unvoiced). */\n frequency: number;\n /** Voicing confidence in `[0, 1]`. */\n confidence: number;\n}\n\n/**\n * Melody analysis result (mirrors the C `SonareMelodyResult`).\n */\nexport interface MelodyResult {\n points: MelodyPoint[];\n pitchRangeOctaves: number;\n pitchStability: number;\n meanFrequency: number;\n vibratoRate: number;\n}\n\n/**\n * Constant-Q / Variable-Q transform magnitude result (mirrors the C\n * `SonareCqtResult`).\n */\nexport interface CqtResult {\n /** Number of frequency bins. */\n nBins: number;\n /** Number of time frames. */\n nFrames: number;\n /** Hop length in samples. */\n hopLength: number;\n /** Sample rate in Hz. */\n sampleRate: number;\n /** Row-major `[nBins x nFrames]` magnitude matrix. */\n magnitude: Float32Array;\n /** Center frequency (Hz) of each of the `nBins` bins. */\n frequencies: Float32Array;\n}\n\n/**\n * Timbre characteristics\n */\nexport interface Timbre {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\n/**\n * Dynamics characteristics\n */\nexport interface Dynamics {\n dynamicRangeDb: number;\n loudnessRangeDb: number;\n crestFactor: number;\n isCompressed: boolean;\n}\n\n/**\n * Time signature\n */\nexport interface TimeSignature {\n numerator: number;\n denominator: number;\n confidence: number;\n}\n\n/**\n * Rhythm features\n */\nexport interface RhythmFeatures {\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n}\n\n/**\n * Complete analysis result\n */\nexport interface AnalysisResult {\n bpm: number;\n bpmConfidence: number;\n key: Key;\n timeSignature: TimeSignature;\n beatTimes: Float32Array;\n beats: Beat[];\n chords: Chord[];\n sections: Section[];\n timbre: Timbre;\n dynamics: Dynamics;\n rhythm: RhythmFeatures;\n form: string;\n}\n\n/**\n * Room acoustic parameters from an impulse response\n */\nexport interface AcousticResult {\n rt60: number;\n edt: number;\n c50: number;\n c80: number;\n d50: number;\n rt60Bands: Float32Array;\n edtBands: Float32Array;\n c50Bands: Float32Array;\n c80Bands: Float32Array;\n confidence: number;\n isBlind: boolean;\n}\n\n/** Shoebox geometry + placement shared by RIR synthesis and the room morph. */\nexport interface RoomGeometryOptions {\n lengthM?: number;\n widthM?: number;\n heightM?: number;\n absorption?: number;\n sourceX?: number;\n sourceY?: number;\n sourceZ?: number;\n listenerX?: number;\n listenerY?: number;\n listenerZ?: number;\n ismOrder?: number;\n seed?: number;\n maxSeconds?: number;\n}\n\nexport interface RirSynthOptions extends RoomGeometryOptions {\n sampleRate?: number;\n /** Use the Eyring statistical late-tail model (default true); false = Sabine. */\n preferEyring?: boolean;\n /** Early/late crossover in ms (0 = auto, ~sqrt(V) ms). */\n mixingTimeMs?: number;\n /** Equal-power crossfade width around the mixing time in ms (0 = default). */\n crossfadeMs?: number;\n}\n\nexport interface RirResult {\n rir: Float32Array;\n sampleRate: number;\n hasError: boolean;\n}\n\nexport interface RoomEstimateOptions {\n aspectHintLw?: number;\n aspectHintLh?: number;\n referenceAbsorption?: number;\n preferEyring?: boolean;\n nOctaveBands?: number;\n /** Analyzer routing: 0 = auto, 1 = blind, 2 = impulse-response. */\n mode?: number;\n /** Analyzer decay-fit span in dB (0 = library default). */\n minDecayDb?: number;\n /** Analyzer noise-floor margin in dB (0 = library default). */\n noiseFloorMarginDb?: number;\n}\n\nexport interface RoomEstimateResult {\n volume: number;\n length: number;\n width: number;\n height: number;\n drrDb: number;\n confidence: number;\n absorptionBands: Float32Array;\n rt60Bands: Float32Array;\n}\n\nexport interface RoomMorphOptions extends RoomGeometryOptions {\n wet?: number;\n sourceTailSuppression?: number;\n}\n\n/**\n * HPSS (Harmonic-Percussive Source Separation) result\n */\nexport interface HpssResult {\n harmonic: Float32Array;\n percussive: Float32Array;\n sampleRate: number;\n}\n\n/**\n * Mastering loudness/true-peak processing result\n */\nexport interface MasteringResult {\n samples: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n latencySamples?: number;\n}\n\nexport type MasteringProcessorParams = Record<string, number | boolean>;\n\nexport type PanMode = 'balance' | 'stereoPan' | 'stereo-pan' | 'dualPan' | 'dual-pan' | number;\n\nexport interface MixOptions {\n inputTrimDb?: number | number[];\n faderDb?: number | number[];\n pan?: number | number[];\n panMode?: PanMode | PanMode[];\n width?: number | number[];\n muted?: boolean | boolean[];\n}\n\nexport interface MixMeterSnapshot {\n peakDbL: number;\n peakDbR: number;\n rmsDbL: number;\n rmsDbR: number;\n correlation: number;\n monoCompatWidth: number;\n monoCompatPeak: number;\n monoCompatSideRms: number;\n likelyMonoCompatible: boolean;\n momentaryLufs: number;\n shortTermLufs: number;\n integratedLufs: number;\n gainReductionDb: number;\n truePeakDbL: number;\n truePeakDbR: number;\n maxTruePeakDb: number;\n seq: number;\n}\n\nexport interface MixResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n meters: MixMeterSnapshot[];\n}\n\n/** Mixed stereo master returned by {@link Mixer.processStereo}. */\nexport interface MixerProcessResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n}\n\n/**\n * Interpolation curve for scheduled automation events\n * (see {@link Mixer.scheduleInsertAutomation}).\n */\nexport type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';\n\n/**\n * Pan law applied when computing left/right gains from a pan position\n * (see {@link Mixer.setPanLaw}). Maps to the underlying integer code.\n */\nexport type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';\n\n/**\n * Meter tap point for reading a strip's meter snapshot\n * (see {@link Mixer.meterTap} and {@link Mixer.stripMeter}).\n */\nexport type MeterTap = 'preFader' | 'postFader';\n\n/** Pre/post-fader send timing (see {@link Mixer.addSend}). */\nexport type SendTiming = 'preFader' | 'postFader';\n\n/** A single goniometer (left/right) sample returned by {@link Mixer.readGoniometerLatest}. */\nexport interface GoniometerPoint {\n left: number;\n right: number;\n}\n\nexport interface MasteringChainConfig {\n repair?: {\n denoise?: boolean;\n nFft?: number;\n hopLength?: number;\n ddAlpha?: number;\n gainFloor?: number;\n declick?: {\n threshold?: number;\n neighborRatio?: number;\n maxClickSamples?: number;\n lpcOrder?: number;\n residualRatio?: number;\n };\n dereverb?: {\n threshold?: number;\n attenuation?: number;\n nFft?: number;\n hopLength?: number;\n t60Sec?: number;\n lateDelayMs?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n wpeEnabled?: boolean;\n wpeIterations?: number;\n wpeTaps?: number;\n wpeStrength?: number;\n };\n };\n eq?: {\n tiltDb?: number;\n pivotHz?: number;\n };\n dynamics?: {\n compressor?: {\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n kneeDb?: number;\n makeupGainDb?: number;\n autoMakeup?: boolean;\n };\n deesser?: {\n frequencyHz?: number;\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n rangeDb?: number;\n bandpassQ?: number;\n };\n transientShaper?: {\n attackGainDb?: number;\n sustainGainDb?: number;\n fastAttackMs?: number;\n fastReleaseMs?: number;\n slowAttackMs?: number;\n slowReleaseMs?: number;\n sensitivity?: number;\n maxGainDb?: number;\n gainSmoothingMs?: number;\n lookaheadMs?: number;\n };\n multibandComp?: {\n lowCutoffHz?: number;\n highCutoffHz?: number;\n lowThresholdDb?: number;\n lowRatio?: number;\n lowAttackMs?: number;\n lowReleaseMs?: number;\n midThresholdDb?: number;\n midRatio?: number;\n midAttackMs?: number;\n midReleaseMs?: number;\n highThresholdDb?: number;\n highRatio?: number;\n highAttackMs?: number;\n highReleaseMs?: number;\n };\n };\n saturation?: {\n tape?: {\n driveDb?: number;\n saturation?: number;\n hysteresis?: number;\n outputGainDb?: number;\n speedIps?: number;\n headBumpDb?: number;\n bias?: number;\n gapLoss?: number;\n };\n exciter?: {\n frequencyHz?: number;\n driveDb?: number;\n amount?: number;\n q?: number;\n evenOddMix?: number;\n };\n };\n spectral?: {\n airBand?: {\n amount?: number;\n shelfFrequencyHz?: number;\n dynamicThresholdDb?: number;\n dynamicRangeDb?: number;\n };\n };\n stereo?: {\n imager?: {\n width?: number;\n outputGainDb?: number;\n decorrelationAmount?: number;\n preserveEnergy?: boolean;\n };\n monoMaker?: {\n amount?: number;\n };\n };\n maximizer?: {\n truePeakLimiter?: {\n ceilingDb?: number;\n lookaheadMs?: number;\n releaseMs?: number;\n oversampleFactor?: number;\n applyGainAtInputRate?: boolean;\n };\n };\n loudness?: {\n targetLufs?: number;\n ceilingDb?: number;\n truePeakOversample?: number;\n };\n}\n\nexport interface MasteringChainResult extends MasteringResult {\n stages: string[];\n}\n\nexport interface MasteringStereoChainResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n stages: string[];\n latencySamples?: number;\n}\n\nexport interface MasteringStereoResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n latencySamples: number;\n}\n\n/**\n * STFT (Short-Time Fourier Transform) result\n */\nexport interface StftResult {\n nBins: number;\n nFrames: number;\n nFft: number;\n hopLength: number;\n sampleRate: number;\n magnitude: Float32Array;\n power: Float32Array;\n}\n\n/**\n * Mel spectrogram result\n */\nexport interface MelSpectrogramResult {\n nMels: number;\n nFrames: number;\n sampleRate: number;\n hopLength: number;\n power: Float32Array;\n db: Float32Array;\n}\n\n/**\n * MFCC result\n */\nexport interface MfccResult {\n nMfcc: number;\n nFrames: number;\n coefficients: Float32Array;\n}\n\n/**\n * STFT power spectrogram result (from inverse Mel reconstruction)\n */\nexport interface StftPowerResult {\n nBins: number;\n nFrames: number;\n power: Float32Array;\n}\n\n/**\n * Mel power spectrogram result (from inverse MFCC reconstruction)\n */\nexport interface MelPowerResult {\n nMels: number;\n nFrames: number;\n power: Float32Array;\n}\n\n/**\n * Chroma features result\n */\nexport interface ChromaResult {\n nChroma: number;\n nFrames: number;\n sampleRate: number;\n hopLength: number;\n features: Float32Array;\n meanEnergy: number[];\n}\n\n/**\n * Pitch detection result\n */\nexport interface PitchResult {\n f0: Float32Array;\n voicedProb: Float32Array;\n voicedFlag: boolean[];\n nFrames: number;\n medianF0: number;\n meanF0: number;\n}\n\n/**\n * Loudness measurement result (EBU R128 / ITU-R BS.1770)\n */\nexport interface LufsResult {\n integratedLufs: number;\n momentaryLufs: number;\n shortTermLufs: number;\n loudnessRange: number;\n}\n\n/**\n * Realtime equalizer spectrum snapshot.\n *\n * Mirrors the C++ `EqualizerSpectrumSnapshot`: `preLeft`/`preRight` and\n * `postLeft`/`postRight` are the pre- and post-EQ spectrum streams (trimmed to\n * their valid count). `bandGainDb` holds per-band applied gain (24 entries),\n * `profileDb` the smoothed magnitude profile (16 entries), `lastAutoGainDb`\n * the latest auto-gain compensation, and `seq` increments each time a new\n * snapshot is published.\n */\nexport interface EqSpectrumSnapshot {\n preLeft: Float32Array;\n preRight: Float32Array;\n postLeft: Float32Array;\n postRight: Float32Array;\n bandGainDb: Float32Array;\n profileDb: Float32Array;\n lastAutoGainDb: number;\n seq: number;\n}\n\n/**\n * Equalizer band type (string union mirroring `sonare::mastering::eq::EqBandType`).\n */\nexport type EqBandType =\n | 'Peak'\n | 'LowShelf'\n | 'HighShelf'\n | 'LowPass'\n | 'HighPass'\n | 'BandPass'\n | 'Notch'\n | 'TiltShelf'\n | 'FlatTilt';\n\n/** Biquad coefficient design mode. */\nexport type EqCoeffMode = 'Rbj' | 'Vicanek';\n\n/** Stereo placement for an EQ band. */\nexport type EqStereoPlacement = 'Stereo' | 'Left' | 'Right' | 'Mid' | 'Side';\n\n/** Per-band phase behaviour. */\nexport type EqBandPhase = 'Inherit' | 'ZeroLatency' | 'NaturalPhase' | 'LinearPhase';\n\n/**\n * Equalizer band configuration accepted by {@link StreamingEqualizer.setBand}.\n *\n * All fields are optional; omitted values fall back to the C++ band defaults\n * (Peak, 1000 Hz, 0 dB gain, Butterworth Q, disabled).\n */\nexport interface EqBand {\n type?: EqBandType;\n frequencyHz?: number;\n gainDb?: number;\n q?: number;\n enabled?: boolean;\n coeffMode?: EqCoeffMode;\n slopeDbOct?: number;\n placement?: EqStereoPlacement;\n phase?: EqBandPhase;\n soloed?: boolean;\n bypassed?: boolean;\n proportionalQ?: boolean;\n proportionalQStrength?: number;\n dynamic?: boolean;\n thresholdDb?: number;\n autoThreshold?: boolean;\n ratio?: number;\n rangeDb?: number;\n attackMs?: number;\n releaseMs?: number;\n lookaheadMs?: number;\n externalSidechain?: boolean;\n sidechainFreqHz?: number;\n sidechainQ?: number;\n}\n\n/** Construction options for {@link StreamingEqualizer}. */\nexport interface StreamingEqualizerConfig {\n sampleRate?: number;\n maxBlockSize?: number;\n}\n\n/** Configuration for {@link StreamingRetune}. */\nexport interface StreamingRetuneConfig {\n /** Pitch shift in semitones, clamped by the native processor to +/-24. */\n semitones?: number;\n /** Wet/dry mix, clamped by the native processor to 0..1. */\n mix?: number;\n /** Grain size in samples. Use 0/omit to derive it from the sample rate. */\n grainSize?: number;\n}\n\nexport type VoicePresetId =\n | 'neutral-monitor'\n | 'bright-idol'\n | 'soft-whisper'\n | 'deep-narrator'\n | 'robot-mascot'\n | 'dark-villain';\n\nexport interface RealtimeVoiceChangerPreset {\n schemaVersion: 1;\n id?: string;\n name?: string;\n description?: string;\n macros?: Record<string, number>;\n dsp?: Record<string, unknown>;\n}\n\nexport type RealtimeVoiceChangerConfigInput = VoicePresetId | RealtimeVoiceChangerPreset;\n\n/**\n * Flat (POD) realtime voice-changer configuration. Field names mirror the\n * C ABI `SonareRealtimeVoiceChangerConfig` / Python POD exactly (snake_case),\n * so a config can be round-tripped across bindings without renaming.\n */\nexport interface RealtimeVoiceChangerPodConfig {\n input_gain_db: number;\n output_gain_db: number;\n wet_mix: number;\n retune_semitones: number;\n retune_mix: number;\n retune_grain_size: number;\n formant_factor: number;\n formant_amount: number;\n formant_body: number;\n formant_brightness: number;\n formant_nasal: number;\n eq_highpass_hz: number;\n eq_body_db: number;\n eq_presence_db: number;\n eq_air_db: number;\n gate_threshold_db: number;\n gate_attack_ms: number;\n gate_release_ms: number;\n gate_range_db: number;\n compressor_threshold_db: number;\n compressor_ratio: number;\n compressor_attack_ms: number;\n compressor_release_ms: number;\n compressor_makeup_gain_db: number;\n deesser_frequency_hz: number;\n deesser_threshold_db: number;\n deesser_ratio: number;\n deesser_range_db: number;\n reverb_mix: number;\n reverb_time_ms: number;\n reverb_damping: number;\n reverb_seed: number;\n limiter_ceiling_db: number;\n limiter_release_ms: number;\n /** Non-zero enables the 4x-oversampled inter-sample-peak limiter (default enabled). */\n limiter_enable_isp_limiter: boolean;\n /** True-peak ceiling in dBTP applied by the ISP limiter (default -1.0). */\n limiter_isp_ceiling_dbtp: number;\n}\n\n/** Options for {@link StreamingEqualizer.match}. */\nexport interface EqMatchOptions {\n sampleRate?: number;\n maxBands?: number;\n}\n","/**\n * sonare - Audio Analysis Library\n *\n * @example\n * ```typescript\n * import { init, detectBpm, detectKey, analyze } from '@libraz/libsonare';\n *\n * await init();\n *\n * // Detect BPM from audio samples\n * const bpm = detectBpm(samples, sampleRate);\n *\n * // Detect musical key\n * const key = detectKey(samples, sampleRate);\n *\n * // Full analysis\n * const result = analyze(samples, sampleRate);\n * ```\n */\n\nimport type {\n AcousticResult,\n AnalysisResult,\n AutomationCurve,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChordQuality,\n ChromaResult,\n CqtResult,\n EqBand,\n EqMatchOptions,\n EqSpectrumSnapshot,\n GoniometerPoint,\n HpssResult,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n LufsResult,\n MasteringChainConfig,\n MasteringChainResult,\n MasteringPreset,\n MasteringProcessorParams,\n MasteringResult,\n MasteringStereoChainResult,\n MasteringStereoResult,\n MelodyResult,\n MelPowerResult,\n MelSpectrogramResult,\n MeterTap,\n MfccResult,\n MixerProcessResult,\n MixMeterSnapshot,\n MixOptions,\n MixResult,\n PairAnalysis,\n PairProcessor,\n PanLaw,\n PanMode,\n PitchResult,\n RealtimeVoiceChangerConfigInput,\n RealtimeVoiceChangerPodConfig,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomMorphOptions,\n Section,\n SectionType,\n SendTiming,\n SoloProcessor,\n StereoAnalysis,\n StftPowerResult,\n StftResult,\n StreamingEqualizerConfig,\n StreamingPlatform,\n StreamingRetuneConfig,\n TempogramMode,\n VoicePresetId,\n} from './public_types';\nimport { KeyProfile as KeyProfileValues, Mode, PitchClass } from './public_types';\nimport type {\n ProgressCallback,\n SonareModule,\n WasmAcousticResult,\n WasmAnalysisResult,\n WasmChordAnalysisResult,\n WasmCyclicTempogramResult,\n WasmDecomposeResult,\n WasmEngineAutomationPoint,\n WasmEngineBounceOptions,\n WasmEngineBounceResult,\n WasmEngineCaptureStatus,\n WasmEngineClip,\n WasmEngineFreezeOptions,\n WasmEngineFreezeResult,\n WasmEngineGraphSpec,\n WasmEngineMarker,\n WasmEngineMeterTelemetry,\n WasmEngineMetronomeConfig,\n WasmEngineParameterInfo,\n WasmEngineProcessWithMonitorResult,\n WasmEngineTelemetry,\n WasmEngineTransportState,\n WasmFourierTempogramResult,\n WasmFrameResult,\n WasmHpssWithResidualResult,\n WasmKeyCandidateResult,\n WasmLufsResult,\n WasmMatrix2dResult,\n WasmNnlsChromaResult,\n WasmRealtimeEngine,\n WasmStreamAnalyzer,\n WasmTempogramResult,\n WasmTrimResult,\n} from './sonare.js';\nimport type {\n AnalyzerStats,\n FrameBuffer,\n StreamConfig,\n StreamFramesI16,\n StreamFramesU8,\n} from './stream_types';\n\nexport type {\n AcousticResult,\n AnalysisResult,\n AutomationCurve,\n Beat,\n Chord,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChromaResult,\n CqtResult,\n Dynamics,\n EqBand,\n EqBandPhase,\n EqBandType,\n EqCoeffMode,\n EqMatchOptions,\n EqSpectrumSnapshot,\n EqStereoPlacement,\n GoniometerPoint,\n HpssResult,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n LufsResult,\n MasteringChainConfig,\n MasteringChainResult,\n MasteringPreset,\n MasteringProcessorParams,\n MasteringResult,\n MasteringStereoChainResult,\n MasteringStereoResult,\n MelodyPoint,\n MelodyResult,\n MelPowerResult,\n MelSpectrogramResult,\n MeterTap,\n MfccResult,\n MixerProcessResult,\n MixMeterSnapshot,\n MixOptions,\n MixResult,\n PairAnalysis,\n PairProcessor,\n PanLaw,\n PanMode,\n PitchResult,\n RealtimeVoiceChangerConfigInput,\n RealtimeVoiceChangerPodConfig,\n RhythmFeatures,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomGeometryOptions,\n RoomMorphOptions,\n Section,\n SendTiming,\n SoloProcessor,\n StereoAnalysis,\n StftPowerResult,\n StftResult,\n StreamingEqualizerConfig,\n StreamingPlatform,\n StreamingRetuneConfig,\n TempogramMode,\n Timbre,\n TimeSignature,\n VoicePresetId,\n} from './public_types';\nexport {\n ChordQuality,\n KeyProfile,\n Mode,\n PitchClass,\n SectionType,\n} from './public_types';\nexport type { ProgressCallback } from './sonare.js';\nexport type {\n AnalyzerStats,\n BarChord,\n ChordChange,\n FrameBuffer,\n PatternScore,\n ProgressiveEstimate,\n StreamConfig,\n StreamFramesI16,\n StreamFramesU8,\n} from './stream_types';\n\nexport type EngineClip = WasmEngineClip;\nexport type EngineParameterInfo = WasmEngineParameterInfo;\nexport type EngineAutomationPoint = WasmEngineAutomationPoint;\nexport type EngineMarker = WasmEngineMarker;\nexport type EngineMetronomeConfig = WasmEngineMetronomeConfig;\nexport type EngineGraphSpec = WasmEngineGraphSpec;\nexport type EngineCaptureStatus = WasmEngineCaptureStatus;\nexport type EngineBounceOptions = WasmEngineBounceOptions;\nexport type EngineBounceResult = WasmEngineBounceResult;\nexport type EngineFreezeOptions = WasmEngineFreezeOptions;\nexport type EngineFreezeResult = WasmEngineFreezeResult;\nexport type EngineTelemetry = WasmEngineTelemetry;\nexport type EngineMeterTelemetry = WasmEngineMeterTelemetry;\nexport type EngineTransportState = WasmEngineTransportState;\n\n/** Row-major 2-D matrix as a flat buffer plus its dimensions. */\nexport type Matrix2dResult = WasmMatrix2dResult;\n/** NMF factor matrices { w, h } from {@link decompose}. */\nexport type DecomposeResult = WasmDecomposeResult;\n/** Harmonic / percussive / residual signals from {@link hpssWithResidual}. */\nexport type HpssWithResidualResult = WasmHpssWithResidualResult;\n\nexport const EXPECTED_ENGINE_ABI_VERSION = 2;\n\nexport interface EngineCapabilities {\n engineAbiVersion: number;\n expectedEngineAbiVersion: number;\n abiCompatible: boolean;\n sharedArrayBuffer: boolean;\n atomics: boolean;\n audioWorklet: boolean;\n mode: 'sab' | 'postMessage';\n}\n\nexport interface MixerRealtimeBuffer {\n leftInputs: Float32Array[];\n rightInputs: Float32Array[];\n outLeft: Float32Array;\n outRight: Float32Array;\n process: (numSamples?: number) => void;\n}\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} mono\n * processing. The `input` / `output` `Float32Array`s are typed-memory views\n * onto the WASM heap — write samples into `input`, call `process()`, then\n * read from `output`. The views are owned by the {@link RealtimeVoiceChanger}\n * and remain valid until `delete()` is called on it.\n */\nexport interface RealtimeVoiceChangerMonoBuffer {\n input: Float32Array;\n output: Float32Array;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} interleaved\n * multi-channel processing. Layout is L0,R0,L1,R1,... for stereo. The views\n * are owned by the {@link RealtimeVoiceChanger}.\n */\nexport interface RealtimeVoiceChangerInterleavedBuffer {\n input: Float32Array;\n output: Float32Array;\n channels: number;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer for {@link RealtimeVoiceChanger} planar stereo\n * processing. Each entry in `channels` is a heap-backed `Float32Array` for one\n * channel (matching AudioWorklet's native layout). Process happens in place:\n * write samples into each channel view, call `process()`, then read back from\n * the same views.\n */\nexport interface RealtimeVoiceChangerPlanarBuffer {\n channels: Float32Array[];\n process: () => void;\n}\n\nfunction automationCurveCode(curve: AutomationCurve): number {\n switch (curve) {\n case 'linear':\n return 0;\n case 'exponential':\n return 1;\n case 'hold':\n return 2;\n case 's-curve':\n return 3;\n default:\n throw new Error(`Invalid automation curve: ${curve}`);\n }\n}\n\nfunction panLawCode(panLaw: PanLaw | number): number {\n if (typeof panLaw === 'number') {\n return panLaw;\n }\n switch (panLaw) {\n case 'const4.5dB':\n return 1;\n case 'const6dB':\n return 2;\n case 'linear0dB':\n return 3;\n default:\n return 0;\n }\n}\n\nfunction panModeCode(panMode: PanMode | number): number {\n if (typeof panMode === 'number') {\n return panMode;\n }\n switch (panMode) {\n case 'stereoPan':\n case 'stereo-pan':\n return 1;\n case 'dualPan':\n case 'dual-pan':\n return 2;\n default:\n return 0;\n }\n}\n\nfunction meterTapCode(tap: MeterTap | number): number {\n return tap === 'preFader' || tap === 0 ? 0 : 1;\n}\n\nfunction sendTimingCode(timing: SendTiming | number): number {\n return timing === 'preFader' || timing === 0 ? 0 : 1;\n}\n\n// ============================================================================\n// Module State\n// ============================================================================\n\nlet module: SonareModule | null = null;\nlet initPromise: Promise<void> | null = null;\n\n// ============================================================================\n// Input validation helpers (empty + NaN/Inf guards for sample buffers)\n// ============================================================================\n\n/**\n * Per-call validation options accepted by guarded wrappers. Empty-buffer\n * checks are always performed; pass `{ validate: false }` to opt out of the\n * O(n) NaN/Inf scan on hot paths.\n */\nexport interface ValidateOptions {\n validate?: boolean;\n}\n\nfunction assertNonEmptySamples(\n fnName: string,\n samples: ArrayLike<number>,\n argName = 'samples',\n): void {\n if (samples.length === 0) {\n throw new RangeError(`${fnName}: ${argName} must not be empty`);\n }\n}\n\nfunction assertFiniteSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n if (!validate) {\n return;\n }\n for (let i = 0; i < samples.length; i++) {\n const v = samples[i] as number;\n if (!Number.isFinite(v)) {\n throw new RangeError(`${fnName}: ${argName} contains NaN or Inf at index ${i}`);\n }\n }\n}\n\nfunction assertSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n assertNonEmptySamples(fnName, samples, argName);\n assertFiniteSamples(fnName, samples, validate, argName);\n}\n\nfunction assertFiniteScalar(fnName: string, value: number, argName: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${fnName}: ${argName} must be a finite number`);\n }\n}\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the WASM module.\n * Must be called before using any analysis functions.\n *\n * @param options - Optional module configuration\n * @returns Promise that resolves when initialization is complete\n */\nexport async function init(options?: {\n locateFile?: (path: string, prefix: string) => string;\n}): Promise<void> {\n if (module) {\n return;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n try {\n const createModule = (await import('./sonare.js')).default;\n module = await createModule(options);\n } catch (error) {\n initPromise = null;\n throw error;\n }\n })();\n\n return initPromise;\n}\n\n/**\n * Check if the module is initialized.\n */\nexport function isInitialized(): boolean {\n return module !== null;\n}\n\n/**\n * Get the library version.\n */\nexport function version(): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.version();\n}\n\nexport function engineAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.engineAbiVersion();\n}\n\nexport function voiceChangerAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceChangerAbiVersion();\n}\n\n// Canonical ordinal order of the built-in voice-character presets, matching the\n// C ABI SonareVoiceCharacterPreset enum and SONARE_REALTIME_VOICE_CHANGER_PRESET_IDS.\nconst VOICE_PRESET_ORDINALS: readonly VoicePresetId[] = [\n 'neutral-monitor',\n 'bright-idol',\n 'soft-whisper',\n 'deep-narrator',\n 'robot-mascot',\n 'dark-villain',\n];\n\nfunction resolveVoicePresetOrdinal(preset: VoicePresetId | number): number {\n if (typeof preset === 'number') {\n return preset;\n }\n const ordinal = VOICE_PRESET_ORDINALS.indexOf(preset);\n if (ordinal < 0) {\n throw new Error(`Unknown voice character preset: ${preset}`);\n }\n return ordinal;\n}\n\n/**\n * Map a voice-character preset ordinal (or canonical id) to its canonical id\n * string (e.g. `'bright-idol'`). Returns `null` for an out-of-range ordinal.\n */\nexport function voiceCharacterPresetId(preset: VoicePresetId | number): string | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));\n}\n\n/**\n * Return the canonical (normalized) flat POD config for a built-in voice\n * preset, skipping the JSON round-trip. Accepts a canonical preset id or its\n * integer ordinal. Returns `null` for an out-of-range ordinal.\n */\nexport function realtimeVoiceChangerPresetConfig(\n preset: VoicePresetId | number,\n): RealtimeVoiceChangerPodConfig | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.realtimeVoiceChangerPresetConfig(resolveVoicePresetOrdinal(preset));\n}\n\nexport function engineCapabilities(): EngineCapabilities {\n const abiVersion = engineAbiVersion();\n const sharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function';\n const atomics = typeof globalThis.Atomics === 'object';\n const audioWorklet =\n typeof AudioWorkletNode !== 'undefined' ||\n typeof (globalThis as typeof globalThis & { AudioWorkletProcessor?: unknown })\n .AudioWorkletProcessor !== 'undefined';\n return {\n engineAbiVersion: abiVersion,\n expectedEngineAbiVersion: EXPECTED_ENGINE_ABI_VERSION,\n abiCompatible: abiVersion === EXPECTED_ENGINE_ABI_VERSION,\n sharedArrayBuffer,\n atomics,\n audioWorklet,\n mode: sharedArrayBuffer && atomics ? 'sab' : 'postMessage',\n };\n}\n\nexport class RealtimeEngine {\n private native: WasmRealtimeEngine;\n\n constructor(\n sampleRate = 48000,\n maxBlockSize = 128,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ) {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n const capabilities = engineCapabilities();\n if (!capabilities.abiCompatible) {\n throw new Error(\n `Engine ABI mismatch: wasm=${capabilities.engineAbiVersion}, expected=${capabilities.expectedEngineAbiVersion}`,\n );\n }\n this.native = new module.RealtimeEngine(\n sampleRate,\n maxBlockSize,\n commandCapacity,\n telemetryCapacity,\n );\n }\n\n prepare(\n sampleRate: number,\n maxBlockSize: number,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ): void {\n this.native.prepare(sampleRate, maxBlockSize, commandCapacity, telemetryCapacity);\n }\n\n /** Queue a sample-accurate parameter change (engine kSetParam). */\n setParameter(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameter(paramId, value, renderFrame);\n }\n\n /** Queue a smoothed parameter change (engine kSetParamSmoothed). */\n setParameterSmoothed(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameterSmoothed(paramId, value, renderFrame);\n }\n\n /** Read back the current transport state snapshot. */\n getTransportState(): EngineTransportState {\n return this.native.getTransportState();\n }\n\n play(renderFrame = -1): void {\n this.native.play(renderFrame);\n }\n\n stop(renderFrame = -1): void {\n this.native.stop(renderFrame);\n }\n\n seekSample(timelineSample: number, renderFrame = -1): void {\n this.native.seekSample(timelineSample, renderFrame);\n }\n\n seekPpq(ppq: number, renderFrame = -1): void {\n this.native.seekPpq(ppq, renderFrame);\n }\n\n setTempo(bpm: number): void {\n this.native.setTempo(bpm);\n }\n\n setTimeSignature(numerator: number, denominator: number): void {\n this.native.setTimeSignature(numerator, denominator);\n }\n\n setLoop(startPpq: number, endPpq: number, enabled = true): void {\n this.native.setLoop(startPpq, endPpq, enabled);\n }\n\n addParameter(info: EngineParameterInfo): void {\n this.native.addParameter(info);\n }\n\n parameterCount(): number {\n return this.native.parameterCount();\n }\n\n parameterInfoByIndex(index: number): EngineParameterInfo {\n return this.native.parameterInfoByIndex(index);\n }\n\n parameterInfo(id: number): EngineParameterInfo {\n return this.native.parameterInfo(id);\n }\n\n setAutomationLane(paramId: number, points: EngineAutomationPoint[]): void {\n this.native.setAutomationLane(paramId, points);\n }\n\n automationLaneCount(): number {\n return this.native.automationLaneCount();\n }\n\n setMarkers(markers: EngineMarker[]): void {\n this.native.setMarkers(markers);\n }\n\n markerCount(): number {\n return this.native.markerCount();\n }\n\n markerByIndex(index: number): EngineMarker {\n return this.native.markerByIndex(index);\n }\n\n marker(id: number): EngineMarker {\n return this.native.marker(id);\n }\n\n seekMarker(markerId: number, renderFrame = -1): void {\n this.native.seekMarker(markerId, renderFrame);\n }\n\n setLoopFromMarkers(startMarkerId: number, endMarkerId: number): void {\n this.native.setLoopFromMarkers(startMarkerId, endMarkerId);\n }\n\n setMetronome(config: EngineMetronomeConfig): void {\n this.native.setMetronome(config);\n }\n\n metronome(): Required<EngineMetronomeConfig> {\n return this.native.metronome();\n }\n\n countInEndSample(startSample: number, bars: number): number {\n return Number(this.native.countInEndSample(startSample, bars));\n }\n\n setGraph(spec: EngineGraphSpec): void {\n this.native.setGraph(spec);\n }\n\n graphNodeCount(): number {\n return this.native.graphNodeCount();\n }\n\n graphConnectionCount(): number {\n return this.native.graphConnectionCount();\n }\n\n setClips(clips: EngineClip[]): void {\n this.native.setClips(clips);\n }\n\n clipCount(): number {\n return this.native.clipCount();\n }\n\n setCaptureBuffer(numChannels: number, capacityFrames: number): void {\n this.native.setCaptureBuffer(numChannels, capacityFrames);\n }\n\n armCapture(armed = true): void {\n this.native.armCapture(armed);\n }\n\n setCapturePunch(startSample: number, endSample: number, enabled = true): void {\n this.native.setCapturePunch(startSample, endSample, enabled);\n }\n\n resetCapture(): void {\n this.native.resetCapture();\n }\n\n captureStatus(): EngineCaptureStatus {\n return this.native.captureStatus();\n }\n\n capturedAudio(): Float32Array[] {\n return this.native.capturedAudio();\n }\n\n process(channels: Float32Array[]): Float32Array[] {\n return this.native.process(channels);\n }\n\n /**\n * Allocates persistent per-channel WASM-heap scratch for the zero-copy\n * `getChannelBuffer` / `processPrepared` realtime path. Call once (off the\n * audio thread) before driving `processPrepared` from an AudioWorklet so the\n * render callback never allocates on the C++/JS heap.\n */\n prepareChannels(numChannels: number, maxFrames: number): void {\n this.native.prepareChannels(numChannels, maxFrames);\n }\n\n /**\n * Returns a Float32Array view onto the persistent WASM-heap scratch for one\n * channel (valid for up to `numFrames`). Fill it, call `processPrepared`, then\n * read the same view back. Re-acquire after WASM memory growth.\n */\n getChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.native.getChannelBuffer(channel, numFrames);\n }\n\n /**\n * Runs the engine in place over the prepared per-channel scratch buffers.\n * Allocation-free: safe to call on the AudioWorklet render thread after\n * `prepareChannels`.\n */\n processPrepared(numFrames: number): void {\n this.native.processPrepared(numFrames);\n }\n\n processWithMonitor(channels: Float32Array[]): WasmEngineProcessWithMonitorResult {\n return this.native.processWithMonitor(channels);\n }\n\n renderOffline(channels: Float32Array[], blockSize = 128): Float32Array[] {\n return this.native.renderOffline(channels, blockSize);\n }\n\n bounceOffline(options: EngineBounceOptions): EngineBounceResult {\n return this.native.bounceOffline(options);\n }\n\n freezeOffline(options: EngineFreezeOptions): EngineFreezeResult {\n return this.native.freezeOffline(options);\n }\n\n drainTelemetry(maxRecords = 1024): EngineTelemetry[] {\n return this.native.drainTelemetry(maxRecords);\n }\n\n drainMeterTelemetry(maxRecords = 1024): EngineMeterTelemetry[] {\n return this.native.drainMeterTelemetry(maxRecords);\n }\n\n destroy(): void {\n this.native.delete();\n }\n}\n\n// ============================================================================\n// Quick API (High-level Analysis)\n// ============================================================================\n\n/**\n * Detect BPM from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected BPM\n */\nexport function detectBpm(samples: Float32Array, sampleRate = 22050): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.detectBpm(samples, sampleRate);\n}\n\n/**\n * Detect musical key from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected key\n */\nexport function detectKey(\n samples: Float32Array,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): Key {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n const result = module._detectKeyWithOptions(\n samples,\n sampleRate,\n options.nFft ?? 4096,\n options.hopLength ?? 512,\n options.useHpss ?? false,\n options.loudnessWeighted ?? false,\n options.highPassHz ?? 0,\n keyModeValues(options.modes),\n keyProfileValue(options.profile),\n options.genreHint ?? '',\n );\n return {\n root: result.root as PitchClass,\n mode: result.mode as Mode,\n confidence: result.confidence,\n name: result.name,\n shortName: result.shortName,\n };\n}\n\nfunction convertKeyCandidate(wasm: WasmKeyCandidateResult): KeyCandidate {\n return {\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n correlation: wasm.correlation,\n };\n}\n\nfunction keyModeValues(modes: KeyDetectionOptions['modes'] | undefined): number[] {\n if (!modes) {\n return [];\n }\n if (modes === 'major-minor') {\n return [Mode.Major, Mode.Minor];\n }\n if (modes === 'all' || modes === 'modal') {\n return [\n Mode.Major,\n Mode.Minor,\n Mode.Dorian,\n Mode.Phrygian,\n Mode.Lydian,\n Mode.Mixolydian,\n Mode.Locrian,\n ];\n }\n const names = {\n major: Mode.Major,\n minor: Mode.Minor,\n dorian: Mode.Dorian,\n phrygian: Mode.Phrygian,\n lydian: Mode.Lydian,\n mixolydian: Mode.Mixolydian,\n locrian: Mode.Locrian,\n } as const;\n return modes.map((mode) => (typeof mode === 'number' ? mode : names[mode]));\n}\n\nfunction keyProfileValue(profile: KeyDetectionOptions['profile'] | undefined): number {\n if (profile === undefined) {\n return -1;\n }\n if (typeof profile === 'number') {\n return profile;\n }\n const names: Record<KeyProfileName, number> = {\n ks: KeyProfileValues.KrumhanslSchmuckler,\n krumhansl: KeyProfileValues.KrumhanslSchmuckler,\n temperley: KeyProfileValues.Temperley,\n shaath: KeyProfileValues.Shaath,\n keyfinder: KeyProfileValues.Shaath,\n 'faraldo-edmt': KeyProfileValues.FaraldoEDMT,\n edmt: KeyProfileValues.FaraldoEDMT,\n 'faraldo-edma': KeyProfileValues.FaraldoEDMA,\n edma: KeyProfileValues.FaraldoEDMA,\n 'faraldo-edmm': KeyProfileValues.FaraldoEDMM,\n edmm: KeyProfileValues.FaraldoEDMM,\n 'bellman-budge': KeyProfileValues.BellmanBudge,\n bellman: KeyProfileValues.BellmanBudge,\n };\n return names[profile];\n}\n\nexport function detectKeyCandidates(\n samples: Float32Array,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): KeyCandidate[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module\n ._detectKeyCandidates(\n samples,\n sampleRate,\n options.nFft ?? 4096,\n options.hopLength ?? 512,\n options.useHpss ?? false,\n options.loudnessWeighted ?? false,\n options.highPassHz ?? 0,\n keyModeValues(options.modes),\n keyProfileValue(options.profile),\n options.genreHint ?? '',\n )\n .map(convertKeyCandidate);\n}\n\n/**\n * Detect onset times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of onset times in seconds\n */\nexport function detectOnsets(samples: Float32Array, sampleRate = 22050): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.detectOnsets(samples, sampleRate);\n}\n\n/**\n * Detect beat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of beat times in seconds\n */\nexport function detectBeats(samples: Float32Array, sampleRate = 22050): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.detectBeats(samples, sampleRate);\n}\n\n/**\n * Detect downbeat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of downbeat times in seconds\n */\nexport function detectDownbeats(samples: Float32Array, sampleRate = 22050): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.detectDownbeats(samples, sampleRate);\n}\n\nfunction convertChordAnalysisResult(wasm: WasmChordAnalysisResult): ChordAnalysisResult {\n return {\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n confidence: c.confidence,\n name: c.name,\n })),\n };\n}\n\n/**\n * Detect chords from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Optional chord detection settings\n * @returns Detected chord segments\n */\nexport function detectChords(\n samples: Float32Array,\n sampleRate = 22050,\n options: ChordDetectionOptions = {},\n): ChordAnalysisResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n const result = module.detectChords(\n samples,\n sampleRate,\n options.minDuration ?? 0.3,\n options.smoothingWindow ?? 2.0,\n options.threshold ?? 0.5,\n options.useTriadsOnly ?? false,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.useBeatSync ?? true,\n options.useHmm ?? false,\n options.hmmBeamWidth ?? 24,\n options.useKeyContext ?? false,\n options.keyRoot ?? PitchClass.C,\n options.keyMode ?? Mode.Major,\n options.detectInversions ?? false,\n chordChromaMethodValue(options.chromaMethod ?? 'stft'),\n );\n return convertChordAnalysisResult(result);\n}\n\nfunction chordChromaMethodValue(method: 'stft' | 'nnls'): number {\n if (method === 'stft') {\n return 0;\n }\n if (method === 'nnls') {\n return 1;\n }\n throw new Error(`Invalid chord chroma method: ${method}`);\n}\n\n// Helper to convert WASM result to typed result\nfunction convertAnalysisResult(wasm: WasmAnalysisResult): AnalysisResult {\n const beatTimes = new Float32Array(wasm.beats.length);\n for (let i = 0; i < wasm.beats.length; i++) {\n beatTimes[i] = wasm.beats[i].time;\n }\n return {\n bpm: wasm.bpm,\n bpmConfidence: wasm.bpmConfidence,\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n timeSignature: wasm.timeSignature,\n beatTimes,\n beats: wasm.beats,\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n confidence: c.confidence,\n name: c.name,\n })),\n sections: wasm.sections.map((s) => ({\n type: s.type as SectionType,\n start: s.start,\n end: s.end,\n energyLevel: s.energyLevel,\n confidence: s.confidence,\n name: s.name,\n })),\n timbre: wasm.timbre,\n dynamics: wasm.dynamics,\n rhythm: wasm.rhythm,\n form: wasm.form,\n };\n}\n\n/**\n * Perform complete music analysis.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Complete analysis result\n */\nexport function analyze(samples: Float32Array, sampleRate = 22050): AnalysisResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n const result = module.analyze(samples, sampleRate);\n return convertAnalysisResult(result);\n}\n\nexport function analyzeImpulseResponse(\n samples: Float32Array,\n sampleRate = 48000,\n nOctaveBands = 6,\n): AcousticResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n const result: WasmAcousticResult = module.analyzeImpulseResponse(\n samples,\n sampleRate,\n nOctaveBands,\n );\n return result;\n}\n\nexport function detectAcoustic(\n samples: Float32Array,\n sampleRate = 48000,\n nOctaveBands = 6,\n nThirdOctaveSubbands = 24,\n minDecayDb = 30.0,\n noiseFloorMarginDb = 10.0,\n): AcousticResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n const result: WasmAcousticResult = module.detectAcoustic(\n samples,\n sampleRate,\n nOctaveBands,\n nThirdOctaveSubbands,\n minDecayDb,\n noiseFloorMarginDb,\n );\n return result;\n}\n\n/**\n * Synthesize a room impulse response from shoebox geometry. `hasError` is true\n * when the source/listener falls outside the room (the RIR is then empty).\n */\nexport function synthesizeRir(options: RirSynthOptions = {}): RirResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (typeof module.synthesizeRir !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n return module.synthesizeRir(options);\n}\n\n/**\n * Estimate an equivalent room (volume/dimensions/absorption/DRR) from a\n * recording or impulse response.\n */\nexport function estimateRoom(\n samples: Float32Array,\n sampleRate = 48000,\n options: RoomEstimateOptions = {},\n): RoomEstimateResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (typeof module.estimateRoom !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n return module.estimateRoom(samples, sampleRate, options);\n}\n\n/**\n * Morph a recording's reverberation toward a target room (creative FX, not\n * dereverberation). Returns the morphed samples (input length plus the target\n * room's reverb tail).\n */\nexport function roomMorph(\n samples: Float32Array,\n sampleRate: number,\n options: RoomMorphOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (typeof module.roomMorph !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n return module.roomMorph(samples, sampleRate, options);\n}\n\n/**\n * Perform complete music analysis with progress reporting.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Complete analysis result\n */\nexport function analyzeWithProgress(\n samples: Float32Array,\n sampleRate = 22050,\n onProgress: ProgressCallback,\n): AnalysisResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n const result = module.analyzeWithProgress(samples, sampleRate, onProgress);\n return convertAnalysisResult(result);\n}\n\nexport interface BpmCandidate {\n bpm: number;\n confidence: number;\n}\n\nexport interface BpmAnalysisResult {\n bpm: number;\n confidence: number;\n candidates: BpmCandidate[];\n autocorrelation: Float32Array;\n tempogram: Float32Array;\n}\n\nexport interface RhythmAnalysisResult {\n timeSignature: { numerator: number; denominator: number; confidence: number };\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n tempoStability: number;\n bpm: number;\n beatIntervals: Float32Array;\n}\n\nexport interface DynamicsAnalysisResult {\n dynamicRangeDb: number;\n peakDb: number;\n rmsDb: number;\n crestFactor: number;\n loudnessRangeDb: number;\n isCompressed: boolean;\n /** Loudness curve timestamps (seconds), parallel to {@link loudnessRmsDb}. */\n loudnessTimes: Float32Array;\n /** Loudness curve RMS values (dB), parallel to {@link loudnessTimes}. */\n loudnessRmsDb: Float32Array;\n}\n\n/** Timbre metrics for one analysis window. Entries are ordered by time in `timbreOverTime`. */\nexport interface TimbreFrame {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\nexport interface TimbreAnalysisResult extends TimbreFrame {\n spectralCentroid: Float32Array;\n spectralFlatness: Float32Array;\n spectralRolloff: Float32Array;\n /** Time-varying timbre metrics, one entry per analysis window. */\n timbreOverTime: TimbreFrame[];\n}\n\n/**\n * Detailed BPM analysis (BPM, confidence, alternate candidates, autocorrelation,\n * tempogram). Matches the Node `analyzeBpm` / Python `analyze_bpm` surface.\n */\nexport function analyzeBpm(\n samples: Float32Array,\n sampleRate = 22050,\n bpmMin = 30.0,\n bpmMax = 300.0,\n startBpm = 120.0,\n nFft = 2048,\n hopLength = 512,\n maxCandidates = 5,\n): BpmAnalysisResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.analyzeBpm(\n samples,\n sampleRate,\n bpmMin,\n bpmMax,\n startBpm,\n nFft,\n hopLength,\n maxCandidates,\n );\n}\n\n/**\n * Detailed rhythm analysis (time signature, groove, syncopation, beat intervals).\n */\nexport function analyzeRhythm(\n samples: Float32Array,\n sampleRate = 22050,\n bpmMin = 60.0,\n bpmMax = 200.0,\n startBpm = 120.0,\n nFft = 2048,\n hopLength = 512,\n): RhythmAnalysisResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.analyzeRhythm(samples, sampleRate, bpmMin, bpmMax, startBpm, nFft, hopLength);\n}\n\n/**\n * Dynamics analysis (RMS, peak, crest factor, LRA, loudness curve).\n */\nexport function analyzeDynamics(\n samples: Float32Array,\n sampleRate = 22050,\n windowSec = 0.4,\n hopLength = 512,\n compressionThreshold = 6.0,\n): DynamicsAnalysisResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.analyzeDynamics(samples, sampleRate, windowSec, hopLength, compressionThreshold);\n}\n\n/**\n * Timbre analysis (brightness/warmth/density/roughness/complexity plus spectral\n * features and per-window timbre frames).\n */\nexport function analyzeTimbre(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nMfcc = 13,\n windowSec = 0.5,\n): TimbreAnalysisResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.analyzeTimbre(samples, sampleRate, nFft, hopLength, nMels, nMfcc, windowSec);\n}\n\n/**\n * Whether this WASM build was compiled with FFmpeg support. Mirrors Node /\n * Python `hasFfmpegSupport`. In the published WASM binding this currently\n * always returns `false` (FFmpeg is not bundled into the .wasm), but the API\n * exists so caller code can branch on capabilities portably.\n */\nexport function hasFfmpegSupport(): boolean {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.hasFfmpegSupport();\n}\n\n// ============================================================================\n// Effects\n// ============================================================================\n\n/**\n * Perform Harmonic-Percussive Source Separation (HPSS).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param kernelHarmonic - Horizontal median filter size for harmonic (default: 31)\n * @param kernelPercussive - Vertical median filter size for percussive (default: 31)\n * @returns Separated harmonic and percussive components\n */\nexport function hpss(\n samples: Float32Array,\n sampleRate = 22050,\n kernelHarmonic = 31,\n kernelPercussive = 31,\n): HpssResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.hpss(samples, sampleRate, kernelHarmonic, kernelPercussive);\n}\n\n/**\n * Extract harmonic component from audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @returns Harmonic component\n */\nexport function harmonic(\n samples: Float32Array,\n sampleRate: number,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('harmonic', samples, options.validate !== false);\n return module.harmonic(samples, sampleRate);\n}\n\n/**\n * Extract percussive component from audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @returns Percussive component\n */\nexport function percussive(\n samples: Float32Array,\n sampleRate: number,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('percussive', samples, options.validate !== false);\n return module.percussive(samples, sampleRate);\n}\n\n/**\n * Time-stretch audio without changing pitch.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param rate - Time stretch rate (0.5 = double duration, 2.0 = half duration)\n * @returns Time-stretched audio\n */\nexport function timeStretch(\n samples: Float32Array,\n sampleRate: number,\n rate: number,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('timeStretch', samples, options.validate !== false);\n return module.timeStretch(samples, sampleRate, rate);\n}\n\n/**\n * Pitch-shift audio without changing duration.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param semitones - Pitch shift in semitones (+12 = one octave up, -12 = one octave down)\n * @returns Pitch-shifted audio\n */\nexport function pitchShift(\n samples: Float32Array,\n sampleRate: number,\n semitones: number,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('pitchShift', samples, options.validate !== false);\n return module.pitchShift(samples, sampleRate, semitones);\n}\n\n/**\n * Pitch-correct audio from a current MIDI note to a target MIDI note.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param currentMidi - Detected/current MIDI note number\n * @param targetMidi - Desired MIDI note number\n * @returns Pitch-corrected audio\n */\nexport function pitchCorrectToMidi(\n samples: Float32Array,\n sampleRate = 22050,\n currentMidi = 69.0,\n targetMidi = 69.0,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('pitchCorrectToMidi', samples, options.validate !== false);\n return module.pitchCorrectToMidi(samples, sampleRate, currentMidi, targetMidi);\n}\n\n/**\n * Time-stretch a note region between two sample offsets without changing pitch.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param onsetSample - Note onset position in samples\n * @param offsetSample - Note offset position in samples\n * @param stretchRatio - Stretch ratio (0.5 = double duration, 2.0 = half duration)\n * @returns Audio with the note region stretched\n */\nexport function noteStretch(\n samples: Float32Array,\n sampleRate = 22050,\n onsetSample = 0,\n offsetSample = 0,\n stretchRatio = 1.0,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('noteStretch', samples, options.validate !== false);\n return module.noteStretch(samples, sampleRate, onsetSample, offsetSample, stretchRatio);\n}\n\n/**\n * Apply a voice change by shifting pitch and formants independently.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param pitchSemitones - Pitch shift in semitones\n * @param formantFactor - Formant scaling factor (1.0 = unchanged)\n * @returns Voice-changed audio\n */\nexport function voiceChange(\n samples: Float32Array,\n sampleRate = 22050,\n pitchSemitones = 0.0,\n formantFactor = 1.0,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('voiceChange', samples, options.validate !== false);\n return module.voiceChange(samples, sampleRate, pitchSemitones, formantFactor);\n}\n\n/** Options for the offline {@link voiceChangeRealtime} convenience wrapper. */\nexport interface VoiceChangeRealtimeOptions extends ValidateOptions {\n sampleRate?: number;\n /** Voice-changer preset id or full config object. */\n preset?: RealtimeVoiceChangerConfigInput;\n /** Channel count (1 = mono, 2 = interleaved stereo). */\n channels?: 1 | 2;\n /** Block size for the internal render loop (default 512). */\n blockSize?: number;\n}\n\n/**\n * Applies the realtime voice-changer chain to a whole buffer in one call.\n *\n * Constructs and prepares a {@link RealtimeVoiceChanger}, runs the block loop\n * for the caller, then disposes it — matching the Python `voice_change_realtime`\n * and Node `voiceChangeRealtime` convenience wrappers. For mono, `samples` is a\n * plain mono buffer; for stereo, `samples` is interleaved (L0,R0,L1,R1,...).\n *\n * @returns The processed buffer (same layout/length as the input).\n */\nexport function voiceChangeRealtime(\n samples: Float32Array,\n options: VoiceChangeRealtimeOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('voiceChangeRealtime', samples, options.validate !== false);\n const channels = options.channels ?? 1;\n if (channels !== 1 && channels !== 2) {\n throw new Error('voiceChangeRealtime: channels must be 1 or 2.');\n }\n // 48000 matches the Python voice_change_realtime and Node voiceChangeRealtime\n // convenience wrappers (and the RealtimeVoiceChanger default).\n const sampleRate = options.sampleRate ?? 48000;\n const blockSize = Math.max(1, Math.floor(options.blockSize ?? 512));\n const changer = new RealtimeVoiceChanger(options.preset ?? 'neutral-monitor');\n try {\n changer.prepare(sampleRate, blockSize, channels);\n const out = new Float32Array(samples.length);\n if (channels === 1) {\n for (let offset = 0; offset < samples.length; offset += blockSize) {\n const block = samples.subarray(offset, Math.min(offset + blockSize, samples.length));\n out.set(changer.processMono(block), offset);\n }\n } else {\n const frameStride = blockSize * 2;\n for (let offset = 0; offset < samples.length; offset += frameStride) {\n const block = samples.subarray(offset, Math.min(offset + frameStride, samples.length));\n out.set(changer.processInterleaved(block, 2), offset);\n }\n }\n return out;\n } finally {\n changer.delete();\n }\n}\n\n/**\n * Normalize audio to target peak level.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param targetDb - Target peak level in dB (default: 0 dB = full scale)\n * @returns Normalized audio\n */\nexport function normalize(\n samples: Float32Array,\n sampleRate: number,\n targetDb = 0.0,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('normalize', samples, options.validate !== false);\n return module.normalize(samples, sampleRate, targetDb);\n}\n\n/**\n * Apply mastering loudness normalization with a true-peak ceiling.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param targetLufs - Target integrated LUFS (default: -14)\n * @param ceilingDb - True/sample peak ceiling in dBFS (default: -1)\n * @param truePeakOversample - Oversampling factor used for peak estimation\n * @returns Processed audio and loudness metadata\n */\nexport function mastering(\n samples: Float32Array,\n sampleRate = 22050,\n targetLufs = -14.0,\n ceilingDb = -1.0,\n truePeakOversample = 4,\n): MasteringResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.mastering(samples, sampleRate, targetLufs, ceilingDb, truePeakOversample);\n}\n\nexport function masteringProcessorNames(): SoloProcessor[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringProcessorNames() as SoloProcessor[];\n}\n\nexport function masteringPairProcessorNames(): PairProcessor[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringPairProcessorNames() as PairProcessor[];\n}\n\nexport function masteringPairAnalysisNames(): PairAnalysis[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringPairAnalysisNames() as PairAnalysis[];\n}\n\nexport function masteringStereoAnalysisNames(): StereoAnalysis[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringStereoAnalysisNames() as StereoAnalysis[];\n}\n\nexport function masteringProcess(\n processorName: SoloProcessor,\n samples: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): MasteringResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringProcess(processorName, samples, sampleRate, params);\n}\n\nexport function masteringProcessStereo(\n processorName: SoloProcessor,\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): MasteringStereoResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return module.masteringProcessStereo(processorName, left, right, sampleRate, params);\n}\n\nexport function masteringPairProcess(\n processorName: PairProcessor,\n source: Float32Array,\n reference: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): MasteringResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringPairProcess(processorName, source, reference, sampleRate, params);\n}\n\nexport function masteringPairAnalyze(\n analysisName: PairAnalysis,\n source: Float32Array,\n reference: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringPairAnalyze(analysisName, source, reference, sampleRate, params);\n}\n\nexport function masteringStereoAnalyze(\n analysisName: StereoAnalysis,\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringStereoAnalyze(analysisName, left, right, sampleRate, params);\n}\n\nexport function masteringAssistantSuggest(\n samples: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringAssistantSuggest(samples, sampleRate, params);\n}\n\nexport function masteringAudioProfile(\n samples: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringAudioProfile(samples, sampleRate, params);\n}\n\nexport function masteringStreamingPreview(\n samples: Float32Array,\n sampleRate = 22050,\n platforms: StreamingPlatform[] = [],\n): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringStreamingPreview(samples, sampleRate, platforms);\n}\n\n// ============================================================================\n// Mastering repair (declick, denoise_classical, declip, decrackle, dehum,\n// dereverb_classical, trim_silence) — hand-written bindings.\n// ============================================================================\n\n/** Options for `masteringRepairDeclick`. */\nexport interface DeclickOptions {\n threshold?: number;\n neighborRatio?: number;\n maxClickSamples?: number;\n lpcOrder?: number;\n residualRatio?: number;\n}\n\n/** Algorithms accepted by `masteringRepairDenoiseClassical`. */\nexport type DenoiseClassicalMode = 'logMmse' | 'mmseStsa' | 'spectralSubtraction';\n\n/** Noise PSD estimators accepted by `masteringRepairDenoiseClassical`. */\nexport type DenoiseClassicalNoiseEstimator = 'quantile' | 'mcra' | 'imcra';\n\n/** Options for `masteringRepairDenoiseClassical`. */\nexport interface DenoiseClassicalOptions {\n mode?: DenoiseClassicalMode;\n noiseEstimator?: DenoiseClassicalNoiseEstimator;\n nFft?: number;\n hopLength?: number;\n ddAlpha?: number;\n gainFloor?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n noiseEstimationQuantile?: number;\n speechPresenceGain?: boolean;\n gainSmoothing?: boolean;\n}\n\n/** Offline LPC-based declicker. */\nexport function masteringRepairDeclick(\n samples: Float32Array,\n sampleRate: number,\n options: DeclickOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDeclick(samples, sampleRate, options);\n}\n\n/** Offline STFT-domain classical denoiser (LogMMSE / MMSE-STSA / SpectralSubtraction). */\nexport function masteringRepairDenoiseClassical(\n samples: Float32Array,\n sampleRate: number,\n options: DenoiseClassicalOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDenoiseClassical(samples, sampleRate, options);\n}\n\n/** Options for `masteringRepairDeclip`. */\nexport interface DeclipOptions {\n clipThreshold?: number;\n lpcOrder?: number;\n iterations?: number;\n lpcBlend?: number;\n}\n\n/** Algorithms accepted by `masteringRepairDecrackle`. */\nexport type DecrackleMode = 'median' | 'waveletShrinkage';\n\n/** Options for `masteringRepairDecrackle`. */\nexport interface DecrackleOptions {\n threshold?: number;\n mode?: DecrackleMode;\n levels?: number;\n}\n\n/** Options for `masteringRepairDehum`. */\nexport interface DehumOptions {\n fundamentalHz?: number;\n harmonics?: number;\n q?: number;\n adaptive?: boolean;\n searchRangeHz?: number;\n adaptation?: number;\n frameSize?: number;\n pllBandwidth?: number;\n}\n\n/** Options for `masteringRepairDereverbClassical`. */\nexport interface DereverbClassicalOptions {\n threshold?: number;\n attenuation?: number;\n nFft?: number;\n hopLength?: number;\n t60Sec?: number;\n lateDelayMs?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n wpeEnabled?: boolean;\n wpeIterations?: number;\n wpeTaps?: number;\n wpeStrength?: number;\n}\n\n/** Trimming modes accepted by `masteringRepairTrimSilence`. */\nexport type TrimSilenceMode = 'peak' | 'lufsGated';\n\n/** Options for `masteringRepairTrimSilence`. */\nexport interface TrimSilenceOptions {\n threshold?: number;\n paddingSamples?: number;\n mode?: TrimSilenceMode;\n gateLufs?: number;\n windowMs?: number;\n}\n\n/** Offline LPC-based declipper. */\nexport function masteringRepairDeclip(\n samples: Float32Array,\n sampleRate: number,\n options: DeclipOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDeclip(samples, sampleRate, options);\n}\n\n/** Offline crackle suppressor (median or wavelet-shrinkage). */\nexport function masteringRepairDecrackle(\n samples: Float32Array,\n sampleRate: number,\n options: DecrackleOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDecrackle(samples, sampleRate, options);\n}\n\n/** Offline mains-hum remover. */\nexport function masteringRepairDehum(\n samples: Float32Array,\n sampleRate: number,\n options: DehumOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDehum(samples, sampleRate, options);\n}\n\n/** Offline classical dereverberator (spectral subtraction + optional WPE). */\nexport function masteringRepairDereverbClassical(\n samples: Float32Array,\n sampleRate: number,\n options: DereverbClassicalOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDereverbClassical(samples, sampleRate, options);\n}\n\n/** Offline silence trimmer (peak threshold or LUFS-gated). */\nexport function masteringRepairTrimSilence(\n samples: Float32Array,\n sampleRate: number,\n options: TrimSilenceOptions = {},\n): Float32Array {\n return requireModule().masteringRepairTrimSilence(samples, sampleRate, options);\n}\n\n// ============================================================================\n// Mastering — offline dynamics processors (compressor / gate / transient_shaper)\n// ============================================================================\n\n/** Compressor sidechain detector mode. */\nexport type CompressorDetector = 'peak' | 'rms' | 'log_rms';\n\n/** Options for `masteringDynamicsCompressor`. */\nexport interface CompressorOptions extends ValidateOptions {\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n kneeDb?: number;\n makeupGainDb?: number;\n autoMakeup?: boolean;\n detector?: CompressorDetector | number;\n sidechainHpfEnabled?: boolean;\n sidechainHpfHz?: number;\n pdrTimeMs?: number;\n pdrReleaseScale?: number;\n}\n\n/** Options for `masteringDynamicsGate`. */\nexport interface GateOptions extends ValidateOptions {\n thresholdDb?: number;\n attackMs?: number;\n releaseMs?: number;\n rangeDb?: number;\n holdMs?: number;\n closeThresholdDb?: number;\n keyHpfHz?: number;\n}\n\n/** Options for `masteringDynamicsTransientShaper`. */\nexport interface TransientShaperOptions extends ValidateOptions {\n attackGainDb?: number;\n sustainGainDb?: number;\n fastAttackMs?: number;\n fastReleaseMs?: number;\n slowAttackMs?: number;\n slowReleaseMs?: number;\n sensitivity?: number;\n maxGainDb?: number;\n gainSmoothingMs?: number;\n lookaheadMs?: number;\n}\n\n/** Result envelope returned by offline mastering dynamics processors. */\nexport interface DynamicsResult {\n samples: Float32Array;\n latencySamples: number;\n}\n\nconst COMPRESSOR_DETECTOR_MAP: Record<CompressorDetector, number> = {\n peak: 0,\n rms: 1,\n log_rms: 2,\n};\n\n/** Offline feed-forward compressor (soft knee, optional auto-makeup / sidechain HPF). */\nexport function masteringDynamicsCompressor(\n samples: Float32Array,\n sampleRate: number,\n options: CompressorOptions = {},\n): DynamicsResult {\n assertSamples('masteringDynamicsCompressor', samples, options.validate !== false);\n const detector =\n typeof options.detector === 'string'\n ? COMPRESSOR_DETECTOR_MAP[options.detector]\n : options.detector;\n const opts: Record<string, unknown> = { ...options };\n if (detector !== undefined) {\n opts.detector = detector;\n }\n return requireModule().masteringDynamicsCompressor(samples, sampleRate, opts);\n}\n\n/** Offline noise gate (hysteresis, hold, optional key HPF). */\nexport function masteringDynamicsGate(\n samples: Float32Array,\n sampleRate: number,\n options: GateOptions = {},\n): DynamicsResult {\n assertSamples('masteringDynamicsGate', samples, options.validate !== false);\n return requireModule().masteringDynamicsGate(samples, sampleRate, options);\n}\n\n/** Offline transient shaper (envelope-difference attack/sustain control). */\nexport function masteringDynamicsTransientShaper(\n samples: Float32Array,\n sampleRate: number,\n options: TransientShaperOptions = {},\n): DynamicsResult {\n assertSamples('masteringDynamicsTransientShaper', samples, options.validate !== false);\n return requireModule().masteringDynamicsTransientShaper(samples, sampleRate, options);\n}\n\n/**\n * Apply a configurable mastering chain in WASM.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param config - Chain stage configuration\n * @returns Processed audio, loudness metadata, and applied stage names\n */\nexport function masteringChain(\n samples: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n): MasteringChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringChain(samples, sampleRate, config as Record<string, unknown>);\n}\n\n/**\n * Apply a configurable stereo mastering chain in WASM.\n *\n * @param left - Left channel samples\n * @param right - Right channel samples\n * @param sampleRate - Sample rate in Hz\n * @param config - Chain stage configuration\n * @returns Processed stereo audio, loudness metadata, and applied stage names\n */\nexport function masteringChainStereo(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n): MasteringStereoChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return module.masteringChainStereo(left, right, sampleRate, config as Record<string, unknown>);\n}\n\n/**\n * Apply a configurable mastering chain in WASM with progress reporting.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param config - Chain stage configuration\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Processed audio, loudness metadata, and applied stage names\n */\nexport function masteringChainWithProgress(\n samples: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n onProgress: ProgressCallback,\n): MasteringChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringChainWithProgress(\n samples,\n sampleRate,\n config as Record<string, unknown>,\n onProgress,\n );\n}\n\n/**\n * Apply a configurable stereo mastering chain in WASM with progress reporting.\n *\n * @param left - Left channel samples\n * @param right - Right channel samples\n * @param sampleRate - Sample rate in Hz\n * @param config - Chain stage configuration\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Processed stereo audio, loudness metadata, and applied stage names\n */\nexport function masteringChainStereoWithProgress(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n onProgress: ProgressCallback,\n): MasteringStereoChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return module.masteringChainStereoWithProgress(\n left,\n right,\n sampleRate,\n config as Record<string, unknown>,\n onProgress,\n );\n}\n\n/**\n * List built-in mastering preset identifiers.\n *\n * @returns Preset names in display order (e.g. \"pop\", \"edm\", \"aiMusic\")\n */\nexport function masteringPresetNames(): MasteringPreset[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masteringPresetNames() as MasteringPreset[];\n}\n\n/**\n * Apply a named mastering preset chain to mono audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param presetName - Preset identifier from {@link masteringPresetNames}\n * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.\n * @returns Processed audio, loudness metadata, and applied stage names\n */\nexport function masterAudio(\n samples: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset,\n overrides: Record<string, number | boolean> | null = null,\n): MasteringChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masterAudio(presetName, samples, sampleRate, overrides);\n}\n\n/**\n * Apply a named mastering preset chain to stereo audio.\n *\n * @param left - Left channel samples\n * @param right - Right channel samples\n * @param sampleRate - Sample rate in Hz\n * @param presetName - Preset identifier from {@link masteringPresetNames}\n * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.\n * @returns Processed stereo audio, loudness metadata, and applied stage names\n */\nexport function masterAudioStereo(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset,\n overrides: Record<string, number | boolean> | null = null,\n): MasteringStereoChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return module.masterAudioStereo(presetName, left, right, sampleRate, overrides);\n}\n\n/**\n * Mono `masterAudio` with per-stage progress reporting. `onProgress` is invoked\n * with `(progress, stage)` between each chain stage (progress is in [0,1]).\n */\nexport function masterAudioWithProgress(\n samples: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset,\n onProgress: ProgressCallback,\n overrides: Record<string, number | boolean> | null = null,\n): MasteringChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.masterAudioWithProgress(presetName, samples, sampleRate, overrides, onProgress);\n}\n\n/**\n * Stereo `masterAudio` with per-stage progress reporting.\n */\nexport function masterAudioStereoWithProgress(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset,\n onProgress: ProgressCallback,\n overrides: Record<string, number | boolean> | null = null,\n): MasteringStereoChainResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return module.masterAudioStereoWithProgress(\n presetName,\n left,\n right,\n sampleRate,\n overrides,\n onProgress,\n );\n}\n\nexport function mixingScenePresetNames(): string[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.mixingScenePresetNames();\n}\n\n/**\n * Get a built-in mixing scene preset serialized as JSON. This is the canonical\n * name shared with the Node and Python bindings; the returned JSON loads\n * directly into a {@link Mixer} via {@link Mixer.fromSceneJson}.\n *\n * @param presetName - Preset name (see {@link mixingScenePresetNames})\n * @returns Scene JSON string\n */\nexport function mixingScenePresetJson(presetName: string): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.mixingScenePresetJson(presetName);\n}\n\nexport function mixStereo(\n leftChannels: Float32Array[],\n rightChannels: Float32Array[],\n sampleRate = 48000,\n options: MixOptions = {},\n): MixResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n if (leftChannels.length === 0 || leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same non-zero length.');\n }\n return module.mixStereo(\n leftChannels,\n rightChannels,\n sampleRate,\n options as Record<string, unknown>,\n );\n}\n\n// ============================================================================\n// StreamingMasteringChain Class\n// ============================================================================\n\n/**\n * Block-by-block streaming variant of {@link masteringChain}.\n *\n * Maintains processor state across {@link processMono}/{@link processStereo}\n * calls. Only ProcessorBase-backed stages are supported. Configurations that\n * enable `repair.denoise` or `loudness` throw at construction.\n *\n * Call {@link delete} (or use a `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const chain = new StreamingMasteringChain({ eq: { tiltDb: 1.0 } });\n * try {\n * chain.prepare(44100, 512, 1);\n * const out = chain.processMono(blockSamples);\n * } finally {\n * chain.delete();\n * }\n * ```\n */\nexport class StreamingMasteringChain {\n private chain: import('./sonare.js').WasmStreamingMasteringChain;\n\n constructor(config: MasteringChainConfig) {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n this.chain = module.createStreamingMasteringChain(config as Record<string, unknown>);\n }\n\n /**\n * Initialize processors for the given sample rate and block layout.\n *\n * @param sampleRate - Sample rate in Hz\n * @param maxBlockSize - Maximum block size per process call\n * @param numChannels - 1 (mono) or 2 (stereo)\n */\n prepare(sampleRate: number, maxBlockSize: number, numChannels: number): void {\n this.chain.prepare(sampleRate, maxBlockSize, numChannels);\n }\n\n /**\n * Process one mono block, returning the processed samples (same length).\n */\n processMono(samples: Float32Array): Float32Array {\n return this.chain.processMono(samples);\n }\n\n /**\n * Process one stereo block, returning the processed channels.\n */\n processStereo(\n left: Float32Array,\n right: Float32Array,\n ): { left: Float32Array; right: Float32Array } {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return this.chain.processStereo(left, right);\n }\n\n /** Reset all processor state without rebuilding. */\n reset(): void {\n this.chain.reset();\n }\n\n /** Total reported latency in samples across all active processors. */\n latencySamples(): number {\n return this.chain.latencySamples();\n }\n\n /** Ordered stage names that will run (e.g. `\"eq.tilt\"`). */\n stageNames(): string[] {\n return this.chain.stageNames();\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.chain.delete();\n }\n}\n\n// ============================================================================\n// StreamingEqualizer Class\n// ============================================================================\n\n/**\n * Block-by-block streaming equalizer wrapping the unified C++\n * `EqualizerProcessor` (up to 24 bands, RBJ/Vicanek biquads, dynamic EQ,\n * linear-phase FIR, mid/side processing, and auto-gain).\n *\n * State is maintained across {@link processMono}/{@link processStereo} calls.\n * Call {@link delete} (or use `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const eq = new StreamingEqualizer({ sampleRate: 48000, maxBlockSize: 512 });\n * try {\n * eq.setBand(0, { type: 'HighShelf', frequencyHz: 8000, gainDb: 6, enabled: true });\n * const out = eq.processStereo(left, right);\n * const snapshot = eq.spectrum();\n * } finally {\n * eq.delete();\n * }\n * ```\n */\nexport class StreamingEqualizer {\n private eq: import('./sonare.js').WasmStreamingEqualizer;\n\n constructor(config: StreamingEqualizerConfig = {}) {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n this.eq = module.createEqualizer(config as Record<string, unknown>);\n }\n\n /**\n * Configure the band at `index` (0..23). Omitted fields use C++ defaults.\n */\n setBand(index: number, band: EqBand): void {\n this.eq.setBand(index, band as Record<string, unknown>);\n }\n\n /** Disable and reset every band. */\n clear(): void {\n this.eq.clear();\n }\n\n /**\n * Set the global phase mode: 1=ZeroLatency, 2=NaturalPhase, 3=LinearPhase.\n */\n setPhaseMode(mode: number): void {\n this.eq.setPhaseMode(mode);\n }\n\n /** Enable or disable output auto-gain compensation. */\n setAutoGain(enabled: boolean): void {\n this.eq.setAutoGain(enabled);\n }\n\n /** Set all-band EQ gain scale as a 0.0..2.0 multiplier. */\n setGainScale(scale: number): void {\n this.eq.setGainScale(scale);\n }\n\n /** Set post-EQ output gain in dB. */\n setOutputGainDb(gainDb: number): void {\n this.eq.setOutputGainDb(gainDb);\n }\n\n /** Set post-EQ stereo balance in -1.0..1.0; mono input ignores pan. */\n setOutputPan(pan: number): void {\n this.eq.setOutputPan(pan);\n }\n\n /**\n * Provide a mono external sidechain key for dynamic bands that opt into\n * `external_sidechain`. The samples are copied into an owned buffer.\n */\n setSidechainMono(samples: Float32Array): void {\n this.eq.setSidechainMono(samples);\n }\n\n /**\n * Provide a stereo external sidechain key. Both channels must match length.\n */\n setSidechainStereo(left: Float32Array, right: Float32Array): void {\n if (left.length !== right.length) {\n throw new Error('Sidechain channel lengths must match.');\n }\n this.eq.setSidechainStereo(left, right);\n }\n\n /** Release any borrowed external sidechain buffers. */\n clearSidechain(): void {\n this.eq.clearSidechain();\n }\n\n /** Auto-gain applied on the most recent block, in dB. */\n lastAutoGainDb(): number {\n return this.eq.lastAutoGainDb();\n }\n\n /** Reported processing latency in samples (non-zero for linear-phase bands). */\n latencySamples(): number {\n return this.eq.latencySamples();\n }\n\n /**\n * Process one mono block, returning the equalized samples (same length).\n */\n processMono(samples: Float32Array): Float32Array {\n return this.eq.processMono(samples);\n }\n\n /**\n * Process one stereo block, returning the equalized channels.\n */\n processStereo(\n left: Float32Array,\n right: Float32Array,\n ): { left: Float32Array; right: Float32Array } {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return this.eq.processStereo(left, right);\n }\n\n /**\n * Read the latest pre/post spectrum snapshot for metering. `seq` increments\n * each time a new snapshot is published.\n */\n spectrum(): EqSpectrumSnapshot {\n return this.eq.spectrum();\n }\n\n /**\n * Configure bands so the source spectrum matches the reference spectrum.\n *\n * @param source - Source audio (mono samples)\n * @param reference - Reference audio (mono samples)\n * @param options - `sampleRate` (default 48000) and `maxBands` (default 8)\n */\n match(source: Float32Array, reference: Float32Array, options: EqMatchOptions = {}): void {\n this.eq.match(source, reference, options as Record<string, unknown>);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.eq.delete();\n }\n}\n\n// ============================================================================\n// StreamingRetune Class\n// ============================================================================\n\n/**\n * Block-by-block mono voice retune / pitch shifter.\n *\n * State is maintained across {@link processMono} calls. Call {@link prepare}\n * before processing, and call {@link delete} (or use `try/finally`) to release\n * the underlying WASM object.\n */\nexport class StreamingRetune {\n private retune: import('./sonare.js').WasmStreamingRetune;\n\n constructor(config: StreamingRetuneConfig = {}) {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n this.retune = module.createStreamingRetune(config as Record<string, unknown>);\n }\n\n /**\n * Allocate and initialize native state for the given sample rate and maximum\n * process block size.\n */\n prepare(sampleRate: number, maxBlockSize: number): void {\n this.retune.prepare(sampleRate, maxBlockSize);\n }\n\n /** Reset delay, grain, and overlap-add state without changing config. */\n reset(): void {\n this.retune.reset();\n }\n\n /**\n * Update retune settings. Changing `grainSize` takes effect after the next\n * {@link prepare} call.\n */\n setConfig(config: StreamingRetuneConfig): void {\n this.retune.setConfig(config as Record<string, unknown>);\n }\n\n /** Current native config. */\n config(): Required<StreamingRetuneConfig> {\n return this.retune.config();\n }\n\n /** Resolved grain size in samples after {@link prepare}. */\n grainSize(): number {\n return this.retune.grainSize();\n }\n\n /** Process one mono block, returning the shifted samples (same length). */\n processMono(samples: Float32Array): Float32Array {\n return this.retune.processMono(samples);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.retune.delete();\n }\n}\n\n// ============================================================================\n// RealtimeVoiceChanger Class\n// ============================================================================\n\nexport class RealtimeVoiceChanger {\n private changer: import('./sonare.js').WasmRealtimeVoiceChanger;\n\n constructor(config: RealtimeVoiceChangerConfigInput = 'neutral-monitor') {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n this.changer = module.createRealtimeVoiceChanger(config as Record<string, unknown> | string);\n }\n\n prepare(sampleRate: number, maxBlockSize = 128, channels = 1): void {\n this.changer.prepare(sampleRate, maxBlockSize, channels);\n }\n\n reset(): void {\n this.changer.reset();\n }\n\n setConfig(config: RealtimeVoiceChangerConfigInput): void {\n this.changer.setConfig(config as Record<string, unknown> | string);\n }\n\n configJson(): string {\n return this.changer.configJson();\n }\n\n latencySamples(): number {\n return this.changer.latencySamples();\n }\n\n processMono(samples: Float32Array): Float32Array {\n return this.changer.processMono(samples);\n }\n\n processMonoInto(samples: Float32Array, output: Float32Array): void {\n this.changer.processMonoInto(samples, output);\n }\n\n processInterleaved(samples: Float32Array, channels: number): Float32Array {\n return this.changer.processInterleaved(samples, channels);\n }\n\n processInterleavedInto(samples: Float32Array, channels: number, output: Float32Array): void {\n this.changer.processInterleavedInto(samples, channels, output);\n }\n\n /**\n * Acquire a typed-memory view onto the WASM heap for mono input.\n *\n * Write your input samples into the returned `Float32Array` directly (e.g.\n * via `input.set(source)`); no copy crosses the JS↔C++ bridge until\n * {@link processPreparedMono} is called. The view is owned by this\n * RealtimeVoiceChanger and becomes invalid after {@link delete}; it may\n * also be invalidated if you later call this method with a larger\n * `numSamples` value (the underlying buffer may be reallocated).\n */\n getMonoInputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoInputBuffer(numSamples);\n }\n\n /** Mono output view counterpart to {@link getMonoInputBuffer}. */\n getMonoOutputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoOutputBuffer(numSamples);\n }\n\n /**\n * Process the previously-acquired mono input buffer in place. The output\n * appears in the buffer returned by {@link getMonoOutputBuffer}. No JS↔C++\n * sample-level crossings happen on this call — it just hands control to\n * the underlying DSP on already-on-heap data.\n */\n processPreparedMono(numSamples: number): void {\n this.changer.processPreparedMono(numSamples);\n }\n\n /** Interleaved input view (layout L0,R0,L1,R1,...). */\n getInterleavedInputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedInputBuffer(numFrames, numChannels);\n }\n\n /** Interleaved output view counterpart. */\n getInterleavedOutputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedOutputBuffer(numFrames, numChannels);\n }\n\n /**\n * Process the previously-acquired interleaved buffer in place. Output\n * appears in the buffer returned by {@link getInterleavedOutputBuffer}.\n */\n processPreparedInterleaved(numFrames: number, numChannels: number): void {\n this.changer.processPreparedInterleaved(numFrames, numChannels);\n }\n\n /**\n * Planar-channel input/output view (one Float32Array per channel). Matches\n * AudioWorklet's native layout; processing happens in place.\n */\n getPlanarChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.changer.getPlanarChannelBuffer(channel, numFrames);\n }\n\n /**\n * Process the previously-acquired planar channel buffers in place. Each\n * channel must have been obtained from {@link getPlanarChannelBuffer}\n * with the same `numFrames`. Output replaces input in the same buffers.\n */\n processPreparedPlanar(numFrames: number): void {\n this.changer.processPreparedPlanar(numFrames);\n }\n\n /**\n * Convenience factory for the mono zero-copy path: returns the input/output\n * heap views plus a `process()` thunk wired to the same `numSamples`. The\n * views are reused across calls and become invalid after {@link delete}.\n */\n createRealtimeMonoBuffer(numSamples: number): RealtimeVoiceChangerMonoBuffer {\n const input = this.getMonoInputBuffer(numSamples);\n const output = this.getMonoOutputBuffer(numSamples);\n return {\n input,\n output,\n process: () => this.processPreparedMono(numSamples),\n };\n }\n\n /** Same as {@link createRealtimeMonoBuffer} but for interleaved I/O. */\n createRealtimeInterleavedBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerInterleavedBuffer {\n const input = this.getInterleavedInputBuffer(numFrames, numChannels);\n const output = this.getInterleavedOutputBuffer(numFrames, numChannels);\n return {\n input,\n output,\n channels: numChannels,\n process: () => this.processPreparedInterleaved(numFrames, numChannels),\n };\n }\n\n /**\n * Convenience factory for the planar zero-copy path. Acquires one\n * heap-backed Float32Array per channel and returns a `process()` thunk\n * wired to the same `numFrames`. Buffers are reused across calls and\n * become invalid after {@link delete}.\n */\n createRealtimePlanarBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerPlanarBuffer {\n const channels: Float32Array[] = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channels.push(this.getPlanarChannelBuffer(ch, numFrames));\n }\n return {\n channels,\n process: () => this.processPreparedPlanar(numFrames),\n };\n }\n\n delete(): void {\n this.changer.delete();\n }\n}\n\nexport function realtimeVoiceChangerPresetNames(): VoicePresetId[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.realtimeVoiceChangerPresetNames() as VoicePresetId[];\n}\n\nexport function realtimeVoiceChangerPresetJson(name: VoicePresetId): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.realtimeVoiceChangerPresetJson(name);\n}\n\nexport function validateRealtimeVoiceChangerPresetJson(json: string): {\n ok: boolean;\n normalizedJson?: string;\n error?: string;\n} {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.validateRealtimeVoiceChangerPresetJson(json);\n}\n\n// ============================================================================\n// Mixer Class (scene-based persistent mixer)\n// ============================================================================\n\n/**\n * Persistent, scene-based stereo mixer.\n *\n * Build one from a scene JSON string (e.g. {@link mixingScenePresetJson} or a\n * hand-authored scene), then feed per-strip stereo blocks through\n * {@link processStereo} to get the routed stereo master. Strips, sends, buses,\n * and inserts are described entirely by the scene; the routing graph is\n * compiled lazily on the first {@link processStereo} call (or eagerly via\n * {@link compile}).\n *\n * Call {@link delete} (or use a `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const mixer = Mixer.fromSceneJson(mixingScenePresetJson('basicStereo'), 48000, 512);\n * try {\n * const out = mixer.processStereo([stripL], [stripR]);\n * } finally {\n * mixer.delete();\n * }\n * ```\n */\nexport class Mixer {\n private mixer: import('./sonare.js').WasmMixer;\n\n private constructor(mixer: import('./sonare.js').WasmMixer) {\n this.mixer = mixer;\n }\n\n /**\n * Build a mixer from a scene JSON string.\n *\n * @param json - Scene JSON (strips, buses, sends, connections, inserts)\n * @param sampleRate - Sample rate in Hz (default: 48000)\n * @param blockSize - Maximum block size per {@link processStereo} call (default: 512)\n */\n static fromSceneJson(json: string, sampleRate = 48000, blockSize = 512): Mixer {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return new Mixer(module.createMixerFromSceneJson(json, sampleRate, blockSize));\n }\n\n /** Rebuild and compile the routing graph from the current scene topology. */\n compile(): void {\n this.mixer.compile();\n }\n\n /**\n * Mix one block of per-strip stereo audio into the stereo master.\n *\n * @param leftChannels - `leftChannels[i]` is the left channel of strip `i`\n * @param rightChannels - `rightChannels[i]` is the right channel of strip `i`\n * @returns Mixed stereo master (`left`, `right`, `sampleRate`)\n */\n processStereo(leftChannels: Float32Array[], rightChannels: Float32Array[]): MixerProcessResult {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n return this.mixer.processStereo(leftChannels, rightChannels);\n }\n\n /**\n * Mix one block into caller-owned output arrays.\n *\n * This avoids allocating the result object and result `Float32Array`s. It is\n * intended for realtime bridges such as AudioWorklet; the input channel count\n * must match the scene strip count and all arrays must have the same length.\n */\n processStereoInto(\n leftChannels: Float32Array[],\n rightChannels: Float32Array[],\n outLeft: Float32Array,\n outRight: Float32Array,\n ): void {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n if (outLeft.length !== outRight.length) {\n throw new Error('outLeft and outRight must have the same length.');\n }\n this.mixer.processStereoInto(leftChannels, rightChannels, outLeft, outRight);\n }\n\n /**\n * Create reusable WASM-heap input/output views for realtime-style processing.\n *\n * Fill `leftInputs[i]` / `rightInputs[i]`, call `process()`, then read\n * `outLeft` / `outRight`. The views are owned by this mixer and become invalid\n * after {@link delete}.\n */\n createRealtimeBuffer(): MixerRealtimeBuffer {\n const stripCount = this.stripCount();\n const leftInputs: Float32Array[] = [];\n const rightInputs: Float32Array[] = [];\n for (let index = 0; index < stripCount; index++) {\n leftInputs.push(this.mixer.inputLeftView(index));\n rightInputs.push(this.mixer.inputRightView(index));\n }\n const outLeft = this.mixer.outputLeftView();\n const outRight = this.mixer.outputRightView();\n return {\n leftInputs,\n rightInputs,\n outLeft,\n outRight,\n process: (numSamples = outLeft.length) => this.mixer.processPreparedStereo(numSamples),\n };\n }\n\n /** Number of strips in the mixer (e.g. strips loaded from the scene). */\n stripCount(): number {\n return this.mixer.stripCount();\n }\n\n /**\n * Schedule sample-accurate insert-parameter automation on a strip's insert.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param insertIndex - Index into the strip's combined insert sequence\n * (`[pre-inserts... post-inserts...]`)\n * @param paramId - Processor-specific parameter id\n * @param samplePos - Absolute samples from the start of processing (the mixer\n * advances an internal position from 0 on the first {@link processStereo}\n * call; recompiling resets it to 0)\n * @param value - Target parameter value\n * @param curve - Interpolation curve (default: `'linear'`)\n * @throws If the strip index is out of range or the schedule call fails\n * (unknown curve, out-of-range insert index, or full event lane)\n */\n scheduleInsertAutomation(\n stripIndex: number,\n insertIndex: number,\n paramId: number,\n samplePos: number,\n value: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleInsertAutomation(\n stripIndex,\n insertIndex,\n paramId,\n samplePos,\n value,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Resolve a strip's index in `[0, stripCount())` from its scene id, or `null`\n * when no strip with that id exists (matches the Node binding's `number | null`).\n */\n stripById(id: string): number | null {\n const index = this.mixer.stripById(id);\n return index < 0 ? null : index;\n }\n\n /**\n * Add a bus to the mixer topology. `role` is one of `'master'`, `'aux'`, or\n * `'submix'` (defaults to `'aux'`). Marks the routing graph dirty; call\n * {@link compile} (or {@link processStereo}) to rebuild.\n */\n addBus(id: string, role = 'aux'): void {\n this.mixer.addBus(id, role);\n }\n\n /** Remove a bus by id. Marks the routing graph dirty. */\n removeBus(id: string): void {\n this.mixer.removeBus(id);\n }\n\n /** Number of buses in the mixer topology. */\n busCount(): number {\n return this.mixer.busCount();\n }\n\n /**\n * Add a VCA group with the given gain offset (dB). `members` is a list of\n * strip ids governed by the group (may be empty).\n */\n addVcaGroup(id: string, gainDb = 0.0, members: string[] = []): void {\n this.mixer.addVcaGroup(id, gainDb, members);\n }\n\n /** Remove a VCA group by id. */\n removeVcaGroup(id: string): void {\n this.mixer.removeVcaGroup(id);\n }\n\n /** Number of VCA groups in the mixer topology. */\n vcaGroupCount(): number {\n return this.mixer.vcaGroupCount();\n }\n\n /** Set the strip's input trim in dB. */\n setInputTrimDb(stripIndex: number, db: number): void {\n this.mixer.setInputTrimDb(stripIndex, db);\n }\n\n /** Set the strip's fader level in dB. */\n setFaderDb(stripIndex: number, db: number): void {\n this.mixer.setFaderDb(stripIndex, db);\n }\n\n /** Set the strip's pan position. */\n setPan(stripIndex: number, pan: number, panMode: PanMode | number = 0): void {\n this.mixer.setPan(stripIndex, pan, panModeCode(panMode));\n }\n\n /** Set the strip's stereo width. */\n setWidth(stripIndex: number, width: number): void {\n this.mixer.setWidth(stripIndex, width);\n }\n\n /** Set the strip's mute state. */\n setMuted(stripIndex: number, muted: boolean): void {\n this.mixer.setMuted(stripIndex, muted);\n }\n\n /**\n * Set a strip's solo state. Takes effect on the next process without a\n * graph recompile.\n */\n setSoloed(stripIndex: number, soloed: boolean): void {\n this.mixer.setSoloed(stripIndex, soloed);\n }\n\n /**\n * Mark a strip solo-safe so it is never implied-muted by another strip's\n * solo. Takes effect on the next process without a graph recompile.\n */\n setSoloSafe(stripIndex: number, soloSafe: boolean): void {\n this.mixer.setSoloSafe(stripIndex, soloSafe);\n }\n\n /** Invert the polarity of the left and/or right channel of a strip. */\n setPolarityInvert(stripIndex: number, invertLeft: boolean, invertRight: boolean): void {\n this.mixer.setPolarityInvert(stripIndex, invertLeft, invertRight);\n }\n\n /** Set the strip's pan law. */\n setPanLaw(stripIndex: number, panLaw: PanLaw | number): void {\n this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));\n }\n\n /**\n * Set a per-strip channel delay in samples. This changes the strip's reported\n * latency; recompile to re-run latency compensation.\n */\n setChannelDelaySamples(stripIndex: number, delaySamples: number): void {\n this.mixer.setChannelDelaySamples(stripIndex, delaySamples);\n }\n\n /** Set the strip's live VCA gain offset in dB (not persisted to the scene). */\n setVcaOffsetDb(stripIndex: number, offsetDb: number): void {\n this.mixer.setVcaOffsetDb(stripIndex, offsetDb);\n }\n\n /** Set independent left/right pan positions (dual-pan mode). */\n setDualPan(stripIndex: number, leftPan: number, rightPan: number): void {\n this.mixer.setDualPan(stripIndex, leftPan, rightPan);\n }\n\n /**\n * Add a send to a strip after construction.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param id - Send id\n * @param destinationBusId - Destination bus id\n * @param sendDb - Initial send level in dB\n * @param timing - `'preFader'` or `'postFader'` (default: `'postFader'`)\n * @returns The new send's index\n */\n addSend(\n stripIndex: number,\n id: string,\n destinationBusId: string,\n sendDb: number,\n timing: SendTiming | number = 'postFader',\n ): number {\n return this.mixer.addSend(stripIndex, id, destinationBusId, sendDb, sendTimingCode(timing));\n }\n\n /** Set the send level (in dB) for an existing send by index. */\n setSendDb(stripIndex: number, sendIndex: number, sendDb: number): void {\n this.mixer.setSendDb(stripIndex, sendIndex, sendDb);\n }\n\n /**\n * Read a strip's meter snapshot at the given tap point.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - `'preFader'` or `'postFader'` (default: `'postFader'`)\n */\n meterTap(stripIndex: number, tap: MeterTap = 'postFader'): MixMeterSnapshot {\n return this.mixer.meterTap(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Read a strip's meter snapshot. Alias of {@link meterTap}, provided for\n * cross-binding (Node/Python) parity.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - `'preFader'` or `'postFader'` (default: `'postFader'`)\n */\n stripMeter(stripIndex: number, tap: MeterTap = 'postFader'): MixMeterSnapshot {\n return this.mixer.stripMeter(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Schedule sample-accurate fader automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param faderDb - Target fader level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleFaderAutomation(\n stripIndex: number,\n samplePos: number,\n faderDb: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleFaderAutomation(stripIndex, samplePos, faderDb, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate pan automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param pan - Target pan position\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n schedulePanAutomation(\n stripIndex: number,\n samplePos: number,\n pan: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.schedulePanAutomation(stripIndex, samplePos, pan, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate width automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param width - Target stereo width\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleWidthAutomation(\n stripIndex: number,\n samplePos: number,\n width: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleWidthAutomation(stripIndex, samplePos, width, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate send-level automation on a strip's send.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param sendIndex - Send index in the strip's add order\n * @param samplePos - Absolute samples from the start of processing\n * @param db - Target send level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleSendAutomation(\n stripIndex: number,\n sendIndex: number,\n samplePos: number,\n db: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleSendAutomation(\n stripIndex,\n sendIndex,\n samplePos,\n db,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Read up to `maxPoints` of a strip's most recent goniometer samples\n * (oldest to newest).\n */\n readGoniometerLatest(stripIndex: number, maxPoints: number): GoniometerPoint[] {\n return this.mixer.readGoniometerLatest(stripIndex, maxPoints);\n }\n\n /** Serialize the current scene (strips, buses, sends, connections) to JSON. */\n toSceneJson(): string {\n return this.mixer.toSceneJson();\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.mixer.delete();\n }\n\n /** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */\n destroy(): void {\n this.delete();\n }\n}\n\n/**\n * Trim silence from beginning and end of audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param thresholdDb - Silence threshold in dB (default: -60 dB)\n * @returns Trimmed audio\n */\nexport function trim(samples: Float32Array, sampleRate: number, thresholdDb = -60.0): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.trim(samples, sampleRate, thresholdDb);\n}\n\n// ============================================================================\n// Features - Spectrogram\n// ============================================================================\n\n/**\n * Compute Short-Time Fourier Transform (STFT).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with magnitude and power spectrograms\n */\nexport function stft(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): StftResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.stft(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute STFT and return magnitude in decibels.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with dB values\n */\nexport function stftDb(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): { nBins: number; nFrames: number; db: Float32Array } {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.stftDb(samples, sampleRate, nFft, hopLength);\n}\n\n// ============================================================================\n// Features - Mel Spectrogram\n// ============================================================================\n\n/**\n * Compute Mel spectrogram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @returns Mel spectrogram result\n */\nexport function melSpectrogram(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n): MelSpectrogramResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.melSpectrogram(samples, sampleRate, nFft, hopLength, nMels);\n}\n\n/**\n * Compute MFCC (Mel-Frequency Cepstral Coefficients).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param nMfcc - Number of MFCC coefficients (default: 20)\n * @returns MFCC result\n */\nexport function mfcc(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nMfcc = 20,\n): MfccResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.mfcc(samples, sampleRate, nFft, hopLength, nMels, nMfcc);\n}\n\n// ============================================================================\n// Features - Inverse reconstruction\n// ============================================================================\n\n/**\n * Approximate inverse of a Mel filterbank: Mel power spectrogram -> STFT power\n * spectrogram. Mirrors `feature::mel_to_stft`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param fmin - Lower Mel band edge in Hz (default: 0)\n * @param fmax - Upper Mel band edge in Hz (default: sr/2 when 0)\n * @returns STFT power spectrogram result\n */\nexport function melToStft(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate = 22050,\n nFft = 2048,\n fmin = 0,\n fmax = 0,\n): StftPowerResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.melToStft(melPower, nMels, nFrames, sampleRate, nFft, fmin, fmax);\n}\n\n/**\n * Reconstruct audio from a Mel power spectrogram via Griffin-Lim. Mirrors\n * `feature::mel_to_audio`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function melToAudio(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.melToAudio(\n melPower,\n nMels,\n nFrames,\n sampleRate,\n nFft,\n hopLength,\n fmin,\n fmax,\n nIter,\n );\n}\n\n/**\n * Invert MFCC coefficients back to a Mel power spectrogram. Mirrors\n * `feature::mfcc_to_mel`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins to reconstruct (default: 128)\n * @returns Mel power spectrogram result\n */\nexport function mfccToMel(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels = 128,\n): MelPowerResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.mfccToMel(mfccCoefficients, nMfcc, nFrames, nMels);\n}\n\n/**\n * Reconstruct audio directly from MFCC coefficients via Griffin-Lim. Mirrors\n * `feature::mfcc_to_audio`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins (default: 128)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function mfccToAudio(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels = 128,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.mfccToAudio(\n mfccCoefficients,\n nMfcc,\n nFrames,\n nMels,\n sampleRate,\n nFft,\n hopLength,\n fmin,\n fmax,\n nIter,\n );\n}\n\n// ============================================================================\n// Features - Chroma\n// ============================================================================\n\n/**\n * Compute chromagram (pitch class distribution).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Chroma features result\n */\nexport function chroma(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): ChromaResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.chroma(samples, sampleRate, nFft, hopLength);\n}\n\n// ============================================================================\n// Features - Spectral\n// ============================================================================\n\n/**\n * Compute spectral centroid (center of mass of spectrum).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral centroid in Hz for each frame\n */\nexport function spectralCentroid(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.spectralCentroid(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute spectral contrast (librosa.feature.spectral_contrast).\n *\n * @returns Matrix2d of shape (nBands + 1) x nFrames.\n */\nexport function spectralContrast(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nBands = 6,\n fmin = 200.0,\n quantile = 0.02,\n): WasmMatrix2dResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.spectralContrast(samples, sampleRate, nFft, hopLength, nBands, fmin, quantile);\n}\n\n/**\n * Fit per-frame polynomial coefficients (librosa.feature.poly_features).\n *\n * @returns Matrix2d of shape (order + 1) x nFrames.\n */\nexport function polyFeatures(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n order = 1,\n): WasmMatrix2dResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.polyFeatures(samples, sampleRate, nFft, hopLength, order);\n}\n\n/**\n * Locate zero-crossing indices of a signal (librosa.zero_crossings).\n */\nexport function zeroCrossings(\n samples: Float32Array,\n threshold = 1e-10,\n refMagnitude = false,\n pad = true,\n zeroPos = true,\n): Int32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.zeroCrossings(samples, threshold, refMagnitude, pad, zeroPos);\n}\n\n/**\n * Estimate the global tuning offset from a set of frequencies\n * (librosa.pitch_tuning). Returns a deviation in fractions of a bin.\n */\nexport function pitchTuning(\n frequencies: Float32Array,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.pitchTuning(frequencies, resolution, binsPerOctave);\n}\n\n/**\n * Estimate the tuning offset of an audio signal (librosa.estimate_tuning).\n */\nexport function estimateTuning(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.estimateTuning(samples, sampleRate, nFft, hopLength, resolution, binsPerOctave);\n}\n\n/**\n * Non-negative matrix factorisation of a flattened [nFeatures x nFrames]\n * spectrogram (librosa.decompose.decompose). Returns the W and H factors.\n */\nexport function decompose(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n nComponents: number,\n nIter = 50,\n beta = 2.0,\n): WasmDecomposeResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.decompose(s, nFeatures, nFrames, nComponents, nIter, beta);\n}\n\n/**\n * Nearest-neighbour filtering of a flattened [nFeatures x nFrames] spectrogram\n * (librosa.decompose.nn_filter).\n */\nexport function nnFilter(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n aggregate = 'mean',\n k = 7,\n width = 1,\n): WasmMatrix2dResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.nnFilter(s, nFeatures, nFrames, aggregate, k, width);\n}\n\n/**\n * Reorder/concatenate a signal by interval slices (librosa.effects.remix).\n *\n * @param intervals - Flat (start, end) sample pairs (even length).\n */\nexport function remix(\n samples: Float32Array,\n intervals: Int32Array | ArrayLike<number>,\n sampleRate = 22050,\n alignZeros = false,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n // Sample indices must reach the native side as exact 32-bit integers. Passing\n // a Float32Array (or a number[] holding fractional/large values) would round\n // boundaries above 2^24 and misalign the slice. Coerce to an Int32Array,\n // truncating toward zero, so callers can hand us any numeric array safely.\n const intervalsI32 =\n intervals instanceof Int32Array ? intervals : Int32Array.from(intervals, (v) => Math.trunc(v));\n return module.remix(samples, intervalsI32, sampleRate, alignZeros);\n}\n\n/**\n * Phase-vocoder time-scale modification (rate > 1 faster, < 1 slower).\n */\nexport function phaseVocoder(\n samples: Float32Array,\n rate: number,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.phaseVocoder(samples, sampleRate, rate, nFft, hopLength);\n}\n\n/**\n * HPSS into harmonic / percussive / residual signals.\n */\nexport function hpssWithResidual(\n samples: Float32Array,\n sampleRate = 22050,\n kernelHarmonic = 31,\n kernelPercussive = 31,\n): WasmHpssWithResidualResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.hpssWithResidual(samples, sampleRate, kernelHarmonic, kernelPercussive);\n}\n\n/**\n * Channel-weighted multichannel integrated loudness + LRA (ITU-R BS.1770 /\n * EBU R128) from an interleaved buffer of `frames * channels` samples. The\n * per-channel frame count is derived from the buffer length and `channels`.\n */\nexport function lufsInterleaved(\n samples: Float32Array,\n channels: number,\n sampleRate = 22050,\n): WasmLufsResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.lufsInterleaved(samples, channels, sampleRate);\n}\n\n/**\n * Standards-compliant EBU R128 loudness range (LRA) in LU.\n */\nexport function ebur128LoudnessRange(samples: Float32Array, sampleRate = 22050): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.ebur128LoudnessRange(samples, sampleRate);\n}\n\n/**\n * Compute spectral bandwidth.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral bandwidth in Hz for each frame\n */\nexport function spectralBandwidth(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.spectralBandwidth(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute spectral rolloff frequency.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param rollPercent - Percentage threshold (default: 0.85)\n * @returns Rolloff frequency in Hz for each frame\n */\nexport function spectralRolloff(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n rollPercent = 0.85,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.spectralRolloff(samples, sampleRate, nFft, hopLength, rollPercent);\n}\n\n/**\n * Compute spectral flatness.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral flatness for each frame (0 = tonal, 1 = noise-like)\n */\nexport function spectralFlatness(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.spectralFlatness(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute zero crossing rate.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Zero crossing rate for each frame\n */\nexport function zeroCrossingRate(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.zeroCrossingRate(samples, sampleRate, frameLength, hopLength);\n}\n\n/**\n * Compute RMS energy.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns RMS energy for each frame\n */\nexport function rmsEnergy(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.rmsEnergy(samples, sampleRate, frameLength, hopLength);\n}\n\n// ============================================================================\n// Features - Pitch\n// ============================================================================\n\n/**\n * Detect pitch using YIN algorithm.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.3)\n * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)\n * @returns Pitch detection result\n */\nexport function pitchYin(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n): PitchResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.pitchYin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n\n/**\n * Detect pitch using pYIN algorithm (probabilistic YIN with HMM smoothing).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.3)\n * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)\n * @returns Pitch detection result\n */\nexport function pitchPyin(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n): PitchResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.pitchPyin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n\n// ============================================================================\n// Core - Unit Conversion\n// ============================================================================\n\n/**\n * Convert frequency in Hz to Mel scale.\n *\n * @param hz - Frequency in Hz\n * @returns Mel frequency\n */\nexport function hzToMel(hz: number): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.hzToMel(hz);\n}\n\n/**\n * Convert Mel scale to frequency in Hz.\n *\n * @param mel - Mel frequency\n * @returns Frequency in Hz\n */\nexport function melToHz(mel: number): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.melToHz(mel);\n}\n\n/**\n * Convert frequency in Hz to MIDI note number.\n *\n * @param hz - Frequency in Hz\n * @returns MIDI note number (A4 = 440 Hz = 69)\n */\nexport function hzToMidi(hz: number): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.hzToMidi(hz);\n}\n\n/**\n * Convert MIDI note number to frequency in Hz.\n *\n * @param midi - MIDI note number\n * @returns Frequency in Hz\n */\nexport function midiToHz(midi: number): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.midiToHz(midi);\n}\n\n/**\n * Convert frequency in Hz to note name.\n *\n * @param hz - Frequency in Hz\n * @returns Note name (e.g., \"A4\", \"C#5\")\n */\nexport function hzToNote(hz: number): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.hzToNote(hz);\n}\n\n/**\n * Convert note name to frequency in Hz.\n *\n * @param note - Note name (e.g., \"A4\", \"C#5\")\n * @returns Frequency in Hz\n */\nexport function noteToHz(note: string): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.noteToHz(note);\n}\n\n/**\n * Convert frame index to time in seconds.\n *\n * @param frames - Frame index\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Time in seconds\n */\nexport function framesToTime(frames: number, sr = 22050, hopLength = 512): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.framesToTime(frames, sr, hopLength);\n}\n\n/**\n * Convert time in seconds to frame index.\n *\n * @param time - Time in seconds\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Frame index\n */\nexport function timeToFrames(time: number, sr = 22050, hopLength = 512): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.timeToFrames(time, sr, hopLength);\n}\n\nexport function framesToSamples(frames: number, hopLength = 512, nFft = 0): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.framesToSamples(frames, hopLength, nFft);\n}\n\nexport function samplesToFrames(samples: number, hopLength = 512, nFft = 0): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.samplesToFrames(samples, hopLength, nFft);\n}\n\nexport function powerToDb(\n values: Float32Array,\n ref = 1.0,\n amin = 1e-10,\n topDb = 80.0,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.powerToDb(values, ref, amin, topDb);\n}\n\nexport function amplitudeToDb(\n values: Float32Array,\n ref = 1.0,\n amin = 1e-5,\n topDb = 80.0,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.amplitudeToDb(values, ref, amin, topDb);\n}\n\nexport function dbToPower(values: Float32Array, ref = 1.0): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.dbToPower(values, ref);\n}\n\nexport function dbToAmplitude(values: Float32Array, ref = 1.0): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.dbToAmplitude(values, ref);\n}\n\nexport function preemphasis(samples: Float32Array, coef = 0.97, zi?: number): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.preemphasis(samples, coef, zi ?? null);\n}\n\nexport function deemphasis(samples: Float32Array, coef = 0.97, zi?: number): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.deemphasis(samples, coef, zi ?? null);\n}\n\nexport function trimSilence(\n samples: Float32Array,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): WasmTrimResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.trimSilence(samples, topDb, frameLength, hopLength);\n}\n\nexport function splitSilence(\n samples: Float32Array,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): Int32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.splitSilence(samples, topDb, frameLength, hopLength);\n}\n\nexport function frameSignal(\n samples: Float32Array,\n frameLength: number,\n hopLength: number,\n): WasmFrameResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.frameSignal(samples, frameLength, hopLength);\n}\n\nexport function padCenter(values: Float32Array, targetSize: number, padValue = 0.0): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.padCenter(values, targetSize, padValue);\n}\n\nexport function fixLength(values: Float32Array, targetSize: number, padValue = 0.0): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.fixLength(values, targetSize, padValue);\n}\n\nexport function fixFrames(frames: Int32Array, xMin = 0, xMax = -1, pad = true): Int32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.fixFrames(frames, xMin, xMax, pad);\n}\n\nexport function peakPick(\n values: Float32Array,\n preMax: number,\n postMax: number,\n preAvg: number,\n postAvg: number,\n delta: number,\n wait: number,\n): Int32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.peakPick(values, preMax, postMax, preAvg, postAvg, delta, wait);\n}\n\nexport function vectorNormalize(values: Float32Array, normType = 0, threshold = 0.0): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.vectorNormalize(values, normType, threshold);\n}\n\nexport function pcen(\n values: Float32Array,\n nBins: number,\n nFrames: number,\n options: Record<string, number> = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.pcen(values, nBins, nFrames, options);\n}\n\nexport function tonnetz(chromagram: Float32Array, nChroma: number, nFrames: number): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.tonnetz(chromagram, nChroma, nFrames);\n}\n\nexport function tempogram(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n mode: TempogramMode = 'autocorrelation',\n): WasmTempogramResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.tempogram(onsetEnvelope, sampleRate, hopLength, winLength, mode);\n}\n\nexport function cyclicTempogram(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n bpmMin = 60.0,\n nBins = 60,\n): WasmCyclicTempogramResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.cyclicTempogram(onsetEnvelope, sampleRate, hopLength, winLength, bpmMin, nBins);\n}\n\nexport function plp(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n tempoMin = 30.0,\n tempoMax = 300.0,\n winLength = 384,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.plp(onsetEnvelope, sampleRate, hopLength, tempoMin, tempoMax, winLength);\n}\n\n/**\n * Compute NNLS (non-negative least squares) chromagram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns NNLS chroma result\n */\nexport function nnlsChroma(samples: Float32Array, sampleRate = 22050): WasmNnlsChromaResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.nnlsChroma(samples, sampleRate);\n}\n\n/**\n * Compute the Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function cqt(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n): CqtResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.cqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the Variable-Q Transform magnitude (gamma controls Q).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @param gamma - Bandwidth offset; 0 is equivalent to CQT (default: 0)\n * @returns VQT magnitude result (same shape as CQT)\n */\nexport function vqt(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n gamma = 0,\n): CqtResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.vqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave, gamma);\n}\n\n/**\n * Detect song-structure sections (intro/verse/chorus/...).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param minSectionSec - Minimum section duration in seconds (default: 4.0)\n * @returns Array of detected sections\n */\nexport function analyzeSections(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n minSectionSec = 4.0,\n): Section[] {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module\n .analyzeSections(samples, sampleRate, nFft, hopLength, minSectionSec)\n .map((s) => ({ ...s, type: s.type as SectionType }));\n}\n\n/**\n * Extract the melody contour from monophonic audio via YIN.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param fmin - Minimum frequency in Hz (default: 65.0)\n * @param fmax - Maximum frequency in Hz (default: 2093.0)\n * @param frameLength - Frame length in samples (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param threshold - YIN threshold; lower is stricter (default: 0.1)\n * @returns Melody contour with per-frame pitch points and summary stats\n */\nexport function analyzeMelody(\n samples: Float32Array,\n sampleRate = 22050,\n fmin = 65.0,\n fmax = 2093.0,\n frameLength = 2048,\n hopLength = 256,\n threshold = 0.1,\n): MelodyResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.analyzeMelody(samples, sampleRate, fmin, fmax, frameLength, hopLength, threshold);\n}\n\n/**\n * Compute the onset strength envelope.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @returns Onset envelope for each frame\n */\nexport function onsetEnvelope(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.onsetEnvelope(samples, sampleRate, nFft, hopLength, nMels);\n}\n\n/**\n * Compute the Fourier tempogram from an onset envelope.\n *\n * @param onsetEnvelope - Onset strength envelope (float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param winLength - Window length in frames (default: 384)\n * @returns Fourier tempogram result\n */\nexport function fourierTempogram(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n): WasmFourierTempogramResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.fourierTempogram(onsetEnvelope, sampleRate, hopLength, winLength);\n}\n\n/**\n * Compute tempogram ratio features.\n *\n * @param tempogramData - Tempogram data (float32)\n * @param winLength - Window length in frames (default: 384)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @returns Tempogram ratio features\n */\nexport function tempogramRatio(\n tempogramData: Float32Array,\n winLength = 384,\n sampleRate = 22050,\n hopLength = 512,\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.tempogramRatio(tempogramData, winLength, sampleRate, hopLength);\n}\n\n/**\n * Measure loudness (EBU R128 / ITU-R BS.1770).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Loudness measurement result\n */\nexport function lufs(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): LufsResult {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('lufs', samples, options.validate !== false);\n return module.lufs(samples, sampleRate);\n}\n\n/**\n * Compute the momentary loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Momentary LUFS values over time\n */\nexport function momentaryLufs(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('momentaryLufs', samples, options.validate !== false);\n return module.momentaryLufs(samples, sampleRate);\n}\n\n/**\n * Compute the short-term loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Short-term LUFS values over time\n */\nexport function shortTermLufs(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n assertSamples('shortTermLufs', samples, options.validate !== false);\n return module.shortTermLufs(samples, sampleRate);\n}\n\n// ============================================================================\n// Metering — basic / true-peak / clipping / dynamic range\n// ============================================================================\n\n/** One contiguous run of clipped samples reported by `meteringDetectClipping`. */\nexport interface ClippingRegion {\n startSample: number;\n endSample: number;\n length: number;\n peak: number;\n}\n\n/** Aggregated clipping report. */\nexport interface ClippingReport {\n clippedSamples: number;\n clippingRatio: number;\n maxClippedPeak: number;\n regions: ClippingRegion[];\n}\n\n/** Sliding-window dynamic range report. */\nexport interface DynamicRangeReport {\n dynamicRangeDb: number;\n lowPercentileDb: number;\n highPercentileDb: number;\n windowRmsDb: Float32Array;\n}\n\nfunction requireModule() {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module;\n}\n\nexport function meteringPeakDb(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringPeakDb', samples, options.validate !== false);\n return requireModule().meteringPeakDb(samples, sampleRate);\n}\n\nexport function meteringRmsDb(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringRmsDb', samples, options.validate !== false);\n return requireModule().meteringRmsDb(samples, sampleRate);\n}\n\nexport function meteringCrestFactorDb(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringCrestFactorDb', samples, options.validate !== false);\n return requireModule().meteringCrestFactorDb(samples, sampleRate);\n}\n\nexport function meteringDcOffset(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringDcOffset', samples, options.validate !== false);\n return requireModule().meteringDcOffset(samples, sampleRate);\n}\n\n/**\n * Inter-sample (true) peak in dBFS. `oversampleFactor` must be a power of two\n * in [1, 16]; pass 0 to use the library default (4).\n */\nexport function meteringTruePeakDb(\n samples: Float32Array,\n sampleRate = 22050,\n oversampleFactor = 4,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringTruePeakDb', samples, options.validate !== false);\n return requireModule().meteringTruePeakDb(samples, sampleRate, oversampleFactor);\n}\n\n/**\n * Detect contiguous runs of clipped samples.\n *\n * @param threshold Linear absolute threshold (default 0.999).\n * @param minRegionSamples Minimum run length to report (default 1).\n */\nexport function meteringDetectClipping(\n samples: Float32Array,\n sampleRate = 22050,\n threshold = 0.999,\n minRegionSamples = 1,\n options: ValidateOptions = {},\n): ClippingReport {\n assertSamples('meteringDetectClipping', samples, options.validate !== false);\n return requireModule().meteringDetectClipping(samples, sampleRate, threshold, minRegionSamples);\n}\n\n/**\n * Sliding-window dynamic range. Pass 0 for any parameter to use the library\n * default (window=3 s, hop=1 s, low=0.10, high=0.95).\n */\nexport function meteringDynamicRange(\n samples: Float32Array,\n sampleRate = 22050,\n windowSec = 0,\n hopSec = 0,\n lowPercentile = 0,\n highPercentile = 0,\n options: ValidateOptions = {},\n): DynamicRangeReport {\n assertSamples('meteringDynamicRange', samples, options.validate !== false);\n return requireModule().meteringDynamicRange(\n samples,\n sampleRate,\n windowSec,\n hopSec,\n lowPercentile,\n highPercentile,\n );\n}\n\n// ============================================================================\n// Metering — stereo / phase-scope / spectrum\n// ============================================================================\n\n/** Mid/side vectorscope point series for a (left, right) stereo pair. */\nexport interface VectorscopeReport {\n mid: Float32Array;\n side: Float32Array;\n}\n\n/** Phase-scope (Lissajous) point series plus summary stats. */\nexport interface PhaseScopeReport {\n mid: Float32Array;\n side: Float32Array;\n radius: Float32Array;\n angleRad: Float32Array;\n correlation: number;\n averageAbsAngleRad: number;\n maxRadius: number;\n}\n\n/** Options for `meteringSpectrum`. */\nexport interface SpectrumOptions {\n /** FFT size. Pass 0 / omit for the library default (2048). */\n nFft?: number;\n /** Apply fractional-octave smoothing to magnitude. */\n applyOctaveSmoothing?: boolean;\n /** Smoothing fraction (e.g. 3 = 1/3-octave). 0 / omit = library default (3). */\n octaveFraction?: number;\n /** Linear reference for the dB conversion. 0 / omit = 1.0. */\n dbRef?: number;\n /** Linear floor used to avoid log(0). 0 / omit = library default. */\n dbAmin?: number;\n}\n\n/** Single-frame magnitude / power / dB spectrum returned by `meteringSpectrum`. */\nexport interface SpectrumReport {\n frequencies: Float32Array;\n magnitude: Float32Array;\n power: Float32Array;\n db: Float32Array;\n nFft: number;\n sampleRate: number;\n}\n\n/** Pearson correlation in [-1, 1] between two equal-length channels. */\nexport function meteringStereoCorrelation(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const validate = options.validate !== false;\n assertSamples('meteringStereoCorrelation', left, validate, 'left');\n assertSamples('meteringStereoCorrelation', right, validate, 'right');\n return requireModule().meteringStereoCorrelation(left, right, sampleRate);\n}\n\n/** Side / mid energy ratio: 0 = pure mono, ~1 = wide stereo. */\nexport function meteringStereoWidth(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const validate = options.validate !== false;\n assertSamples('meteringStereoWidth', left, validate, 'left');\n assertSamples('meteringStereoWidth', right, validate, 'right');\n return requireModule().meteringStereoWidth(left, right, sampleRate);\n}\n\n/** Per-sample mid/side point series (one entry per input frame). */\nexport function meteringVectorscope(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): VectorscopeReport {\n const validate = options.validate !== false;\n assertSamples('meteringVectorscope', left, validate, 'left');\n assertSamples('meteringVectorscope', right, validate, 'right');\n return requireModule().meteringVectorscope(left, right, sampleRate);\n}\n\n/** Phase-scope point series plus summary stats. */\nexport function meteringPhaseScope(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): PhaseScopeReport {\n const validate = options.validate !== false;\n assertSamples('meteringPhaseScope', left, validate, 'left');\n assertSamples('meteringPhaseScope', right, validate, 'right');\n return requireModule().meteringPhaseScope(left, right, sampleRate);\n}\n\n/** Single-frame spectrum view (uses the first `nFft` samples of `samples`). */\nexport function meteringSpectrum(\n samples: Float32Array,\n sampleRate = 22050,\n options?: SpectrumOptions & ValidateOptions,\n): SpectrumReport {\n const validate = options?.validate !== false;\n assertSamples('meteringSpectrum', samples, validate);\n return requireModule().meteringSpectrum(samples, sampleRate, options ?? {});\n}\n\n// ============================================================================\n// Editing — 12-TET scale quantizer\n// ============================================================================\n\n/**\n * Snap a MIDI value to the nearest pitch class enabled by `modeMask`.\n *\n * `modeMask` is a 12-bit mask. For natural C major use `0b101010110101`.\n * `referenceMidi` defaults to A4 (69) when passed as 0.\n */\nexport function scaleQuantizeMidi(\n root: number,\n modeMask: number,\n midi: number,\n referenceMidi = 0,\n): number {\n assertFiniteScalar('scaleQuantizeMidi', midi, 'midi');\n assertFiniteScalar('scaleQuantizeMidi', referenceMidi, 'referenceMidi');\n return requireModule().scaleQuantizeMidi(root, modeMask, midi, referenceMidi);\n}\n\nexport function scaleCorrectionSemitones(\n root: number,\n modeMask: number,\n midi: number,\n referenceMidi = 0,\n): number {\n assertFiniteScalar('scaleCorrectionSemitones', midi, 'midi');\n assertFiniteScalar('scaleCorrectionSemitones', referenceMidi, 'referenceMidi');\n return requireModule().scaleCorrectionSemitones(root, modeMask, midi, referenceMidi);\n}\n\nexport function scalePitchClassEnabled(\n root: number,\n modeMask: number,\n pitchClass: number,\n): boolean {\n return requireModule().scalePitchClassEnabled(root, modeMask, pitchClass);\n}\n\n// ============================================================================\n// Core - Resample\n// ============================================================================\n\n/**\n * Resample audio to a different sample rate.\n *\n * @param samples - Audio samples (mono, float32)\n * @param srcSr - Source sample rate in Hz\n * @param targetSr - Target sample rate in Hz\n * @returns Resampled audio\n */\nexport function resample(samples: Float32Array, srcSr: number, targetSr: number): Float32Array {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.resample(samples, srcSr, targetSr);\n}\n\n// ============================================================================\n// Audio Class\n// ============================================================================\n\n/**\n * Wrapper around audio data that exposes all analysis and feature functions as instance methods.\n *\n * @example\n * ```typescript\n * import { init, Audio } from '@libraz/libsonare';\n *\n * await init();\n *\n * const audio = Audio.fromBuffer(samples, 44100);\n * console.log('BPM:', audio.detectBpm());\n * console.log('Key:', audio.detectKey().name);\n *\n * const mel = audio.melSpectrogram();\n * ```\n */\nexport class Audio {\n private _samples: Float32Array;\n private _sampleRate: number;\n\n private constructor(samples: Float32Array, sampleRate: number) {\n this._samples = samples;\n this._sampleRate = sampleRate;\n }\n\n /** Create an Audio instance from raw sample data. */\n static fromBuffer(samples: Float32Array, sampleRate: number): Audio {\n return new Audio(samples, sampleRate);\n }\n\n /** The raw audio samples. */\n get data(): Float32Array {\n return this._samples;\n }\n\n /** Number of samples. */\n get length(): number {\n return this._samples.length;\n }\n\n /** Sample rate in Hz. */\n get sampleRate(): number {\n return this._sampleRate;\n }\n\n /** Duration in seconds. */\n get duration(): number {\n return this._samples.length / this._sampleRate;\n }\n\n // -- Analysis --\n\n detectBpm(): number {\n return detectBpm(this._samples, this._sampleRate);\n }\n\n detectKey(options: KeyDetectionOptions = {}): Key {\n return detectKey(this._samples, this._sampleRate, options);\n }\n\n detectKeyCandidates(options: KeyDetectionOptions = {}): KeyCandidate[] {\n return detectKeyCandidates(this._samples, this._sampleRate, options);\n }\n\n detectOnsets(): Float32Array {\n return detectOnsets(this._samples, this._sampleRate);\n }\n\n detectBeats(): Float32Array {\n return detectBeats(this._samples, this._sampleRate);\n }\n\n detectDownbeats(): Float32Array {\n return detectDownbeats(this._samples, this._sampleRate);\n }\n\n detectChords(options: ChordDetectionOptions = {}): ChordAnalysisResult {\n return detectChords(this._samples, this._sampleRate, options);\n }\n\n analyze(): AnalysisResult {\n return analyze(this._samples, this._sampleRate);\n }\n\n analyzeWithProgress(onProgress: ProgressCallback): AnalysisResult {\n return analyzeWithProgress(this._samples, this._sampleRate, onProgress);\n }\n\n // -- Effects --\n\n hpss(kernelHarmonic = 31, kernelPercussive = 31): HpssResult {\n return hpss(this._samples, this._sampleRate, kernelHarmonic, kernelPercussive);\n }\n\n harmonic(): Float32Array {\n return harmonic(this._samples, this._sampleRate);\n }\n\n percussive(): Float32Array {\n return percussive(this._samples, this._sampleRate);\n }\n\n timeStretch(rate: number): Float32Array {\n return timeStretch(this._samples, this._sampleRate, rate);\n }\n\n pitchShift(semitones: number): Float32Array {\n return pitchShift(this._samples, this._sampleRate, semitones);\n }\n\n pitchCorrectToMidi(currentMidi = 69.0, targetMidi = 69.0): Float32Array {\n return pitchCorrectToMidi(this._samples, this._sampleRate, currentMidi, targetMidi);\n }\n\n noteStretch(onsetSample = 0, offsetSample = 0, stretchRatio = 1.0): Float32Array {\n return noteStretch(this._samples, this._sampleRate, onsetSample, offsetSample, stretchRatio);\n }\n\n voiceChange(pitchSemitones = 0.0, formantFactor = 1.0): Float32Array {\n return voiceChange(this._samples, this._sampleRate, pitchSemitones, formantFactor);\n }\n\n normalize(targetDb = 0.0): Float32Array {\n return normalize(this._samples, this._sampleRate, targetDb);\n }\n\n mastering(targetLufs = -14.0, ceilingDb = -1.0, truePeakOversample = 4): MasteringResult {\n return mastering(this._samples, this._sampleRate, targetLufs, ceilingDb, truePeakOversample);\n }\n\n masteringChain(config: MasteringChainConfig): MasteringChainResult {\n return masteringChain(this._samples, this._sampleRate, config);\n }\n\n masterAudio(\n presetName: MasteringPreset,\n overrides: Record<string, number | boolean> | null = null,\n ): MasteringChainResult {\n return masterAudio(this._samples, this._sampleRate, presetName, overrides);\n }\n\n masteringProcess(\n processorName: SoloProcessor,\n params: MasteringProcessorParams = {},\n ): MasteringResult {\n return masteringProcess(processorName, this._samples, this._sampleRate, params);\n }\n\n trim(thresholdDb = -60.0): Float32Array {\n return trim(this._samples, this._sampleRate, thresholdDb);\n }\n\n // -- Features --\n\n stft(nFft = 2048, hopLength = 512): StftResult {\n return stft(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n stftDb(nFft = 2048, hopLength = 512): { nBins: number; nFrames: number; db: Float32Array } {\n return stftDb(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n melSpectrogram(nFft = 2048, hopLength = 512, nMels = 128): MelSpectrogramResult {\n return melSpectrogram(this._samples, this._sampleRate, nFft, hopLength, nMels);\n }\n\n mfcc(nFft = 2048, hopLength = 512, nMels = 128, nMfcc = 20): MfccResult {\n return mfcc(this._samples, this._sampleRate, nFft, hopLength, nMels, nMfcc);\n }\n\n chroma(nFft = 2048, hopLength = 512): ChromaResult {\n return chroma(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n nnlsChroma(): WasmNnlsChromaResult {\n return nnlsChroma(this._samples, this._sampleRate);\n }\n\n onsetEnvelope(nFft = 2048, hopLength = 512, nMels = 128): Float32Array {\n return onsetEnvelope(this._samples, this._sampleRate, nFft, hopLength, nMels);\n }\n\n lufs(): LufsResult {\n return lufs(this._samples, this._sampleRate);\n }\n\n momentaryLufs(): Float32Array {\n return momentaryLufs(this._samples, this._sampleRate);\n }\n\n shortTermLufs(): Float32Array {\n return shortTermLufs(this._samples, this._sampleRate);\n }\n\n spectralCentroid(nFft = 2048, hopLength = 512): Float32Array {\n return spectralCentroid(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n spectralBandwidth(nFft = 2048, hopLength = 512): Float32Array {\n return spectralBandwidth(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n spectralRolloff(nFft = 2048, hopLength = 512, rollPercent = 0.85): Float32Array {\n return spectralRolloff(this._samples, this._sampleRate, nFft, hopLength, rollPercent);\n }\n\n spectralFlatness(nFft = 2048, hopLength = 512): Float32Array {\n return spectralFlatness(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n zeroCrossingRate(frameLength = 2048, hopLength = 512): Float32Array {\n return zeroCrossingRate(this._samples, this._sampleRate, frameLength, hopLength);\n }\n\n rmsEnergy(frameLength = 2048, hopLength = 512): Float32Array {\n return rmsEnergy(this._samples, this._sampleRate, frameLength, hopLength);\n }\n\n pitchYin(\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n ): PitchResult {\n return pitchYin(\n this._samples,\n this._sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n }\n\n pitchPyin(\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n ): PitchResult {\n return pitchPyin(\n this._samples,\n this._sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n }\n\n resample(targetSr: number): Float32Array {\n return resample(this._samples, this._sampleRate, targetSr);\n }\n}\n\n// ============================================================================\n// StreamAnalyzer Class\n// ============================================================================\n\n/**\n * Real-time streaming audio analyzer.\n *\n * @example\n * ```typescript\n * import { init, StreamAnalyzer } from '@libraz/libsonare';\n *\n * await init();\n *\n * const analyzer = new StreamAnalyzer({ sampleRate: 44100 });\n *\n * // In audio processing callback\n * analyzer.process(samples);\n *\n * // Get current analysis state\n * const stats = analyzer.stats();\n * console.log('BPM:', stats.estimate.bpm);\n * console.log('Key:', stats.estimate.key);\n * console.log('Chord progression:', stats.estimate.chordProgression);\n * ```\n */\nexport class StreamAnalyzer {\n private analyzer: WasmStreamAnalyzer;\n\n /**\n * Create a new StreamAnalyzer.\n *\n * @param config - Configuration options\n */\n constructor(config: StreamConfig) {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n this.analyzer = new module.StreamAnalyzer(\n config.sampleRate ?? 44100,\n config.nFft ?? 2048,\n config.hopLength ?? 512,\n config.nMels ?? 128,\n config.fmin ?? 0,\n config.fmax ?? 0,\n config.tuningRefHz ?? 440,\n config.computeMagnitude ?? true,\n config.computeMel ?? true,\n config.computeChroma ?? true,\n config.computeOnset ?? true,\n config.computeSpectral ?? true,\n config.emitEveryNFrames ?? 1,\n config.magnitudeDownsample ?? 1,\n config.keyUpdateIntervalSec ?? 5,\n config.bpmUpdateIntervalSec ?? 10,\n config.window ?? 0,\n config.outputFormat ?? 0,\n );\n }\n\n /**\n * Process audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n */\n process(samples: Float32Array): void {\n this.analyzer.process(samples);\n }\n\n /**\n * Process audio samples with explicit sample offset.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleOffset - Cumulative sample count at start of this chunk\n */\n processWithOffset(samples: Float32Array, sampleOffset: number): void {\n this.analyzer.processWithOffset(samples, sampleOffset);\n }\n\n /**\n * Get the number of frames available to read.\n */\n availableFrames(): number {\n return this.analyzer.availableFrames();\n }\n\n /**\n * Read processed frames as Structure of Arrays.\n *\n * @param maxFrames - Maximum number of frames to read\n * @returns Frame buffer with analysis results\n */\n readFrames(maxFrames: number): FrameBuffer {\n return this.analyzer.readFramesSoa(maxFrames);\n }\n\n readFramesU8(maxFrames: number): StreamFramesU8 {\n return this.analyzer.readFramesU8(maxFrames) as StreamFramesU8;\n }\n\n readFramesI16(maxFrames: number): StreamFramesI16 {\n return this.analyzer.readFramesI16(maxFrames) as StreamFramesI16;\n }\n\n /**\n * Reset the analyzer state.\n *\n * @param baseSampleOffset - Starting sample offset (default 0)\n */\n reset(baseSampleOffset = 0): void {\n this.analyzer.reset(baseSampleOffset);\n }\n\n /**\n * Get current statistics and progressive estimates.\n *\n * @returns Analyzer statistics including BPM, key, and chord progression\n */\n stats(): AnalyzerStats {\n const s = this.analyzer.stats();\n return {\n totalFrames: s.totalFrames,\n totalSamples: s.totalSamples,\n durationSeconds: s.durationSeconds,\n estimate: {\n bpm: s.estimate.bpm,\n bpmConfidence: s.estimate.bpmConfidence,\n bpmCandidateCount: s.estimate.bpmCandidateCount,\n key: s.estimate.key as PitchClass,\n keyMinor: s.estimate.keyMinor,\n keyConfidence: s.estimate.keyConfidence,\n chordRoot: s.estimate.chordRoot as PitchClass,\n chordQuality: s.estimate.chordQuality as ChordQuality,\n chordConfidence: s.estimate.chordConfidence,\n chordStartTime: s.estimate.chordStartTime,\n chordProgression: s.estimate.chordProgression.map((c) => ({\n root: c.root as PitchClass,\n quality: c.quality as ChordQuality,\n startTime: c.startTime,\n confidence: c.confidence,\n })),\n barChordProgression: s.estimate.barChordProgression.map((c) => ({\n barIndex: c.barIndex,\n root: c.root as PitchClass,\n quality: c.quality as ChordQuality,\n startTime: c.startTime,\n confidence: c.confidence,\n })),\n currentBar: s.estimate.currentBar,\n barDuration: s.estimate.barDuration,\n votedPattern: (s.estimate.votedPattern || []).map((c) => ({\n barIndex: c.barIndex,\n root: c.root as PitchClass,\n quality: c.quality as ChordQuality,\n startTime: c.startTime,\n confidence: c.confidence,\n })),\n patternLength: s.estimate.patternLength,\n detectedPatternName: s.estimate.detectedPatternName || '',\n detectedPatternScore: s.estimate.detectedPatternScore || 0,\n allPatternScores: (s.estimate.allPatternScores || []).map((p) => ({\n name: p.name,\n score: p.score,\n })),\n accumulatedSeconds: s.estimate.accumulatedSeconds,\n usedFrames: s.estimate.usedFrames,\n updated: s.estimate.updated,\n },\n };\n }\n\n /**\n * Get total frames processed.\n */\n frameCount(): number {\n return this.analyzer.frameCount();\n }\n\n /**\n * Get current time position in seconds.\n */\n currentTime(): number {\n return this.analyzer.currentTime();\n }\n\n /**\n * Get the sample rate.\n */\n sampleRate(): number {\n return this.analyzer.sampleRate();\n }\n\n /**\n * Set the expected total duration for pattern lock timing.\n *\n * @param durationSeconds - Total duration in seconds\n */\n setExpectedDuration(durationSeconds: number): void {\n this.analyzer.setExpectedDuration(durationSeconds);\n }\n\n /**\n * Set normalization gain for loud/compressed audio.\n *\n * @param gain - Gain factor to apply (e.g., 0.5 for -6dB reduction)\n */\n setNormalizationGain(gain: number): void {\n this.analyzer.setNormalizationGain(gain);\n }\n\n /**\n * Set tuning reference frequency for non-standard tuning.\n *\n * @param refHz - Reference frequency for A4 (default 440 Hz)\n * @example\n * // If audio is 1 semitone sharp (A4 = 466.16 Hz)\n * analyzer.setTuningRefHz(466.16);\n * // If audio is 1 semitone flat (A4 = 415.30 Hz)\n * analyzer.setTuningRefHz(415.30);\n */\n setTuningRefHz(refHz: number): void {\n this.analyzer.setTuningRefHz(refHz);\n }\n\n /**\n * Release resources. Call when done using the analyzer.\n */\n dispose(): void {\n this.analyzer.delete();\n }\n}\n\n// ============================================================================\n// Re-exports\n// ============================================================================\n\nexport { PitchClass as Pitch } from './public_types';\n"],"mappings":"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","names":["onsetEnvelope"]}
|
|
1
|
+
{"version":3,"sources":["../src/module_state.ts","../src/codes.ts","../src/mixer.ts","../src/realtime_voice_changer.ts","../src/streaming_processors.ts","../src/validation.ts","../src/effects_mastering.ts","../src/feature_core.ts","../src/feature_music.ts","../src/feature_pitch.ts","../src/feature_resample.ts","../src/feature_spectral.ts","../src/feature_spectrogram.ts","../src/public_types.ts","../src/analysis_helpers.ts","../src/quick_analysis.ts","../src/audio.ts","../src/live_audio.ts","../src/metering.ts","../src/opfs_clip_pages.ts","../src/project.ts","../src/realtime_engine.ts","../src/scale.ts","../src/stream_analyzer.ts","../src/web_midi.ts","../src/index.ts"],"sourcesContent":["import type { SonareModule } from './sonare.js';\n\nlet wasmModule: SonareModule | null = null;\n\nexport function setSonareModule(module: SonareModule): void {\n wasmModule = module;\n}\n\nexport function getSonareModule(): SonareModule {\n if (!wasmModule) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return wasmModule;\n}\n","import type { AutomationCurve, MeterTap, PanLaw, PanMode, SendTiming } from './public_types';\n\nexport function automationCurveCode(curve: AutomationCurve): number {\n switch (curve) {\n case 'linear':\n return 0;\n case 'exponential':\n return 1;\n case 'hold':\n return 2;\n case 's-curve':\n return 3;\n default:\n throw new Error(`Invalid automation curve: ${curve}`);\n }\n}\n\nexport function panLawCode(panLaw: PanLaw | number): number {\n if (typeof panLaw === 'number') {\n return panLaw;\n }\n switch (panLaw) {\n case 'const4.5dB':\n return 1;\n case 'const6dB':\n return 2;\n case 'linear0dB':\n return 3;\n default:\n return 0;\n }\n}\n\nexport function panModeCode(panMode: PanMode | number): number {\n if (typeof panMode === 'number') {\n return panMode;\n }\n switch (panMode) {\n case 'stereoPan':\n case 'stereo-pan':\n return 1;\n case 'dualPan':\n case 'dual-pan':\n return 2;\n default:\n return 0;\n }\n}\n\nexport function meterTapCode(tap: MeterTap | number): number {\n return tap === 'preFader' || tap === 0 ? 0 : 1;\n}\n\nexport function sendTimingCode(timing: SendTiming | number): number {\n return timing === 'preFader' || timing === 0 ? 0 : 1;\n}\n","import {\n automationCurveCode,\n meterTapCode,\n panLawCode,\n panModeCode,\n sendTimingCode,\n} from './codes';\nimport { getSonareModule } from './module_state';\nimport type {\n AutomationCurve,\n GoniometerPoint,\n MeterTap,\n MixerProcessResult,\n MixMeterSnapshot,\n PanLaw,\n PanMode,\n SendTiming,\n} from './public_types';\n\nexport interface MixerRealtimeBuffer {\n leftInputs: Float32Array[];\n rightInputs: Float32Array[];\n outLeft: Float32Array;\n outRight: Float32Array;\n process: (numSamples?: number) => void;\n}\n\n// ============================================================================\n// Mixer Class (scene-based persistent mixer)\n// ============================================================================\n\n/**\n * Persistent, scene-based stereo mixer.\n *\n * Build one from a scene JSON string (e.g. {@link mixingScenePresetJson} or a\n * hand-authored scene), then feed per-strip stereo blocks through\n * {@link processStereo} to get the routed stereo master. Strips, sends, buses,\n * and inserts are described entirely by the scene; the routing graph is\n * compiled lazily on the first {@link processStereo} call (or eagerly via\n * {@link compile}).\n *\n * Call {@link delete} (or use a `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const mixer = Mixer.fromSceneJson(mixingScenePresetJson('basicStereo'), 48000, 512);\n * try {\n * const out = mixer.processStereo([stripL], [stripR]);\n * } finally {\n * mixer.delete();\n * }\n * ```\n */\nexport class Mixer {\n private mixer: import('./sonare.js').WasmMixer;\n\n private constructor(mixer: import('./sonare.js').WasmMixer) {\n this.mixer = mixer;\n }\n\n /**\n * Build a mixer from a scene JSON string.\n *\n * @param json - Scene JSON (strips, buses, sends, connections, inserts)\n * @param sampleRate - Sample rate in Hz (default: 48000)\n * @param blockSize - Maximum block size per {@link processStereo} call (default: 512)\n */\n static fromSceneJson(json: string, sampleRate = 48000, blockSize = 512): Mixer {\n const module = getSonareModule();\n return new Mixer(module.createMixerFromSceneJson(json, sampleRate, blockSize));\n }\n\n /** Rebuild and compile the routing graph from the current scene topology. */\n compile(): void {\n this.mixer.compile();\n }\n\n /**\n * Mix one block of per-strip stereo audio into the stereo master.\n *\n * @param leftChannels - `leftChannels[i]` is the left channel of strip `i`\n * @param rightChannels - `rightChannels[i]` is the right channel of strip `i`\n * @returns Mixed stereo master (`left`, `right`, `sampleRate`)\n */\n processStereo(leftChannels: Float32Array[], rightChannels: Float32Array[]): MixerProcessResult {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n return this.mixer.processStereo(leftChannels, rightChannels);\n }\n\n /**\n * Mix one block into caller-owned output arrays.\n *\n * This avoids allocating the result object and result `Float32Array`s. It is\n * intended for realtime bridges such as AudioWorklet; the input channel count\n * must match the scene strip count and all arrays must have the same length.\n */\n processStereoInto(\n leftChannels: Float32Array[],\n rightChannels: Float32Array[],\n outLeft: Float32Array,\n outRight: Float32Array,\n ): void {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n if (outLeft.length !== outRight.length) {\n throw new Error('outLeft and outRight must have the same length.');\n }\n this.mixer.processStereoInto(leftChannels, rightChannels, outLeft, outRight);\n }\n\n /**\n * Create reusable WASM-heap input/output views for realtime-style processing.\n *\n * Fill `leftInputs[i]` / `rightInputs[i]`, call `process()`, then read\n * `outLeft` / `outRight`. The views are owned by this mixer and become invalid\n * after {@link delete}.\n */\n createRealtimeBuffer(): MixerRealtimeBuffer {\n const stripCount = this.stripCount();\n let leftInputs: Float32Array[] = [];\n let rightInputs: Float32Array[] = [];\n let outLeft = this.mixer.outputLeftView();\n let outRight = this.mixer.outputRightView();\n const acquire = (): void => {\n leftInputs = [];\n rightInputs = [];\n for (let index = 0; index < stripCount; index++) {\n leftInputs.push(this.mixer.inputLeftView(index));\n rightInputs.push(this.mixer.inputRightView(index));\n }\n outLeft = this.mixer.outputLeftView();\n outRight = this.mixer.outputRightView();\n };\n acquire();\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before use, mirroring the worklet RT path.\n const reacquireIfDetached = (): void => {\n if (outLeft.byteLength === 0 || (leftInputs[0]?.byteLength ?? 1) === 0) {\n acquire();\n }\n };\n return {\n get leftInputs(): Float32Array[] {\n reacquireIfDetached();\n return leftInputs;\n },\n get rightInputs(): Float32Array[] {\n reacquireIfDetached();\n return rightInputs;\n },\n get outLeft(): Float32Array {\n reacquireIfDetached();\n return outLeft;\n },\n get outRight(): Float32Array {\n reacquireIfDetached();\n return outRight;\n },\n process: (numSamples = outLeft.length) => {\n reacquireIfDetached();\n this.mixer.processPreparedStereo(numSamples);\n },\n };\n }\n\n /** Number of strips in the mixer (e.g. strips loaded from the scene). */\n stripCount(): number {\n return this.mixer.stripCount();\n }\n\n /**\n * Schedule sample-accurate insert-parameter automation on a strip's insert.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param insertIndex - Index into the strip's combined insert sequence\n * (`[pre-inserts... post-inserts...]`)\n * @param paramId - Processor-specific parameter id\n * @param samplePos - Absolute samples from the start of processing (the mixer\n * advances an internal position from 0 on the first {@link processStereo}\n * call; recompiling resets it to 0)\n * @param value - Target parameter value\n * @param curve - Interpolation curve (default: `'linear'`)\n * @throws If the strip index is out of range or the schedule call fails\n * (unknown curve, out-of-range insert index, or full event lane)\n */\n scheduleInsertAutomation(\n stripIndex: number,\n insertIndex: number,\n paramId: number,\n samplePos: number,\n value: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleInsertAutomation(\n stripIndex,\n insertIndex,\n paramId,\n samplePos,\n value,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Resolve a strip's index in `[0, stripCount())` from its scene id, or `null`\n * when no strip with that id exists (matches the Node binding's `number | null`).\n */\n stripById(id: string): number | null {\n const index = this.mixer.stripById(id);\n return index < 0 ? null : index;\n }\n\n /**\n * Add a bus to the mixer topology. `role` is one of `'master'`, `'aux'`, or\n * `'submix'` (defaults to `'aux'`). Marks the routing graph dirty; call\n * {@link compile} (or {@link processStereo}) to rebuild.\n */\n addBus(id: string, role = 'aux'): void {\n this.mixer.addBus(id, role);\n }\n\n /** Remove a bus by id. Marks the routing graph dirty. */\n removeBus(id: string): void {\n this.mixer.removeBus(id);\n }\n\n /** Number of buses in the mixer topology. */\n busCount(): number {\n return this.mixer.busCount();\n }\n\n /**\n * Add a VCA group with the given gain offset (dB). `members` is a list of\n * strip ids governed by the group (may be empty).\n */\n addVcaGroup(id: string, gainDb = 0.0, members: string[] = []): void {\n this.mixer.addVcaGroup(id, gainDb, members);\n }\n\n /** Set an existing VCA group's gain in dB. */\n setVcaGroupGainDb(id: string, gainDb: number): void {\n this.mixer.setVcaGroupGainDb(id, gainDb);\n }\n\n /** Remove a VCA group by id. */\n removeVcaGroup(id: string): void {\n this.mixer.removeVcaGroup(id);\n }\n\n /** Number of VCA groups in the mixer topology. */\n vcaGroupCount(): number {\n return this.mixer.vcaGroupCount();\n }\n\n /** Set the strip's input trim in dB. */\n setInputTrimDb(stripIndex: number, db: number): void {\n this.mixer.setInputTrimDb(stripIndex, db);\n }\n\n /** Set the strip's fader level in dB. */\n setFaderDb(stripIndex: number, db: number): void {\n this.mixer.setFaderDb(stripIndex, db);\n }\n\n /**\n * Set the strip's pan position.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param pan - Pan position in `[-1, 1]`\n * @param panMode - Optional pan mode. When omitted the strip's current pan\n * mode is kept (passes `SONARE_PAN_MODE_KEEP`), so a plain pan nudge does\n * not reset a scene-defined `'stereoPan'` / `'dualPan'` mode back to\n * balance. Pass `'balance'` (or `0`) explicitly to force balance mode.\n */\n setPan(stripIndex: number, pan: number, panMode?: PanMode | number): void {\n // SONARE_PAN_MODE_KEEP (-1) = keep the strip's current pan mode.\n const mode = panMode === undefined ? -1 : panModeCode(panMode);\n this.mixer.setPan(stripIndex, pan, mode);\n }\n\n /** Set the strip's stereo width. */\n setWidth(stripIndex: number, width: number): void {\n this.mixer.setWidth(stripIndex, width);\n }\n\n /** Set the strip's mute state. */\n setMuted(stripIndex: number, muted: boolean): void {\n this.mixer.setMuted(stripIndex, muted);\n }\n\n /**\n * Set a strip's solo state. Takes effect on the next process without a\n * graph recompile.\n */\n setSoloed(stripIndex: number, soloed: boolean): void {\n this.mixer.setSoloed(stripIndex, soloed);\n }\n\n /**\n * Mark a strip solo-safe so it is never implied-muted by another strip's\n * solo. Takes effect on the next process without a graph recompile.\n */\n setSoloSafe(stripIndex: number, soloSafe: boolean): void {\n this.mixer.setSoloSafe(stripIndex, soloSafe);\n }\n\n /** Invert the polarity of the left and/or right channel of a strip. */\n setPolarityInvert(stripIndex: number, invertLeft: boolean, invertRight: boolean): void {\n this.mixer.setPolarityInvert(stripIndex, invertLeft, invertRight);\n }\n\n /** Set the strip's pan law. */\n setPanLaw(stripIndex: number, panLaw: PanLaw | number): void {\n this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));\n }\n\n /**\n * Set a per-strip channel delay in samples. This changes the strip's reported\n * latency; recompile to re-run latency compensation.\n */\n setChannelDelaySamples(stripIndex: number, delaySamples: number): void {\n this.mixer.setChannelDelaySamples(stripIndex, delaySamples);\n }\n\n /** Set the strip's live VCA gain offset in dB (not persisted to the scene). */\n setVcaOffsetDb(stripIndex: number, offsetDb: number): void {\n this.mixer.setVcaOffsetDb(stripIndex, offsetDb);\n }\n\n /** Set independent left/right pan positions (dual-pan mode). */\n setDualPan(stripIndex: number, leftPan: number, rightPan: number): void {\n this.mixer.setDualPan(stripIndex, leftPan, rightPan);\n }\n\n /**\n * Add a send to a strip after construction.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param id - Send id\n * @param destinationBusId - Destination bus id\n * @param sendDb - Initial send level in dB\n * @param timing - `'preFader'` or `'postFader'` (default: `'postFader'`)\n * @returns The new send's index\n */\n addSend(\n stripIndex: number,\n id: string,\n destinationBusId: string,\n sendDb = 0.0,\n timing: SendTiming | number = 'postFader',\n ): number {\n return this.mixer.addSend(stripIndex, id, destinationBusId, sendDb, sendTimingCode(timing));\n }\n\n /** Set the send level (in dB) for an existing send by index. */\n setSendDb(stripIndex: number, sendIndex: number, sendDb: number): void {\n this.mixer.setSendDb(stripIndex, sendIndex, sendDb);\n }\n\n /**\n * Remove an existing send from a strip by index.\n *\n * Sends are addressed in add order. After removal, sends with a higher index\n * than `sendIndex` shift down by one. Recompile (or process) before reading\n * results so the routing graph rebuilds.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param sendIndex - Send index in add order\n */\n removeSend(stripIndex: number, sendIndex: number): void {\n this.mixer.removeSend(stripIndex, sendIndex);\n }\n\n /**\n * Read a strip's meter snapshot at the given tap point.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - `'preFader'` or `'postFader'` (default: `'postFader'`)\n */\n meterTap(stripIndex: number, tap: MeterTap = 'postFader'): MixMeterSnapshot {\n return this.mixer.meterTap(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Read a strip's meter snapshot.\n *\n * With no `tap` argument this reads the strip's own (post-fader) meter,\n * matching the Node/Python tap-less `stripMeter` contract. Pass an optional\n * `tap` (`'preFader'` / `'postFader'`) to read the tap-selectable snapshot\n * instead — the same backing call as {@link meterTap}.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - Optional tap point (`'preFader'` / `'postFader'`); when omitted\n * the tap-less post-fader strip meter is read.\n */\n stripMeter(stripIndex: number, tap?: MeterTap | number): MixMeterSnapshot {\n if (tap === undefined) {\n return this.mixer.stripMeter(stripIndex);\n }\n return this.mixer.meterTap(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Schedule sample-accurate fader automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param faderDb - Target fader level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleFaderAutomation(\n stripIndex: number,\n samplePos: number,\n faderDb: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleFaderAutomation(stripIndex, samplePos, faderDb, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate pan automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param pan - Target pan position\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n schedulePanAutomation(\n stripIndex: number,\n samplePos: number,\n pan: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.schedulePanAutomation(stripIndex, samplePos, pan, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate width automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param width - Target stereo width\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleWidthAutomation(\n stripIndex: number,\n samplePos: number,\n width: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleWidthAutomation(stripIndex, samplePos, width, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate send-level automation on a strip's send.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param sendIndex - Send index in the strip's add order\n * @param samplePos - Absolute samples from the start of processing\n * @param db - Target send level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleSendAutomation(\n stripIndex: number,\n sendIndex: number,\n samplePos: number,\n db: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleSendAutomation(\n stripIndex,\n sendIndex,\n samplePos,\n db,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Read up to `maxPoints` of a strip's most recent goniometer samples\n * (oldest to newest).\n */\n readGoniometerLatest(stripIndex: number, maxPoints: number): GoniometerPoint[] {\n return this.mixer.readGoniometerLatest(stripIndex, maxPoints);\n }\n\n /** Serialize the current scene (strips, buses, sends, connections) to JSON. */\n toSceneJson(): string {\n return this.mixer.toSceneJson();\n }\n\n /**\n * Maximum processor tail length (samples) in the compiled mixer graph. Lazily\n * compiles the routing graph if the topology is dirty.\n */\n tailSamples(): number {\n return this.mixer.tailSamples();\n }\n\n /**\n * Drain delayed / tail audio by processing a zero-input block of `numSamples`\n * frames after the host stops feeding strip inputs. Returns the mixed stereo\n * master (`left`, `right`, `sampleRate`).\n */\n drainTailStereo(numSamples: number): MixerProcessResult {\n return this.mixer.drainTailStereo(numSamples);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.mixer.delete();\n }\n\n /** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */\n destroy(): void {\n this.delete();\n }\n}\n","import { getSonareModule } from './module_state';\nimport type { RealtimeVoiceChangerConfigInput, VoicePresetId } from './public_types';\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} mono\n * processing. The `input` / `output` `Float32Array`s are typed-memory views\n * onto the WASM heap — write samples into `input`, call `process()`, then\n * read from `output`. The views are owned by the {@link RealtimeVoiceChanger}\n * and remain valid until `delete()` is called on it.\n */\nexport interface RealtimeVoiceChangerMonoBuffer {\n input: Float32Array;\n output: Float32Array;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} interleaved\n * multi-channel processing. Layout is L0,R0,L1,R1,... for stereo. The views\n * are owned by the {@link RealtimeVoiceChanger}.\n */\nexport interface RealtimeVoiceChangerInterleavedBuffer {\n input: Float32Array;\n output: Float32Array;\n channels: number;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer for {@link RealtimeVoiceChanger} planar stereo\n * processing. Each entry in `channels` is a heap-backed `Float32Array` for one\n * channel (matching AudioWorklet's native layout). Process happens in place:\n * write samples into each channel view, call `process()`, then read back from\n * the same views.\n */\nexport interface RealtimeVoiceChangerPlanarBuffer {\n channels: Float32Array[];\n process: () => void;\n}\n\n// ============================================================================\n// RealtimeVoiceChanger Class\n// ============================================================================\n\nexport class RealtimeVoiceChanger {\n private changer: import('./sonare.js').WasmRealtimeVoiceChanger;\n\n constructor(config: RealtimeVoiceChangerConfigInput = 'neutral-monitor') {\n const module = getSonareModule();\n this.changer = module.createRealtimeVoiceChanger(config as Record<string, unknown> | string);\n }\n\n prepare(sampleRate: number, maxBlockSize = 128, channels = 1): void {\n this.changer.prepare(sampleRate, maxBlockSize, channels);\n }\n\n reset(): void {\n this.changer.reset();\n }\n\n setConfig(config: RealtimeVoiceChangerConfigInput): void {\n this.changer.setConfig(config as Record<string, unknown> | string);\n }\n\n configJson(): string {\n return this.changer.configJson();\n }\n\n latencySamples(): number {\n return this.changer.latencySamples();\n }\n\n processMono(samples: Float32Array): Float32Array {\n return this.changer.processMono(samples);\n }\n\n processMonoInto(samples: Float32Array, output: Float32Array): void {\n this.changer.processMonoInto(samples, output);\n }\n\n processInterleaved(samples: Float32Array, channels: number): Float32Array {\n return this.changer.processInterleaved(samples, channels);\n }\n\n processInterleavedInto(samples: Float32Array, channels: number, output: Float32Array): void {\n this.changer.processInterleavedInto(samples, channels, output);\n }\n\n /**\n * Acquire a typed-memory view onto the WASM heap for mono input.\n *\n * Write your input samples into the returned `Float32Array` directly (e.g.\n * via `input.set(source)`); no copy crosses the JS↔C++ bridge until\n * {@link processPreparedMono} is called. The view is owned by this\n * RealtimeVoiceChanger and becomes invalid after {@link delete}; it may\n * also be invalidated if you later call this method with a larger\n * `numSamples` value (the underlying buffer may be reallocated).\n */\n getMonoInputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoInputBuffer(numSamples);\n }\n\n /** Mono output view counterpart to {@link getMonoInputBuffer}. */\n getMonoOutputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoOutputBuffer(numSamples);\n }\n\n /**\n * Process the previously-acquired mono input buffer in place. The output\n * appears in the buffer returned by {@link getMonoOutputBuffer}. No JS↔C++\n * sample-level crossings happen on this call — it just hands control to\n * the underlying DSP on already-on-heap data.\n */\n processPreparedMono(numSamples: number): void {\n this.changer.processPreparedMono(numSamples);\n }\n\n /** Interleaved input view (layout L0,R0,L1,R1,...). */\n getInterleavedInputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedInputBuffer(numFrames, numChannels);\n }\n\n /** Interleaved output view counterpart. */\n getInterleavedOutputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedOutputBuffer(numFrames, numChannels);\n }\n\n /**\n * Process the previously-acquired interleaved buffer in place. Output\n * appears in the buffer returned by {@link getInterleavedOutputBuffer}.\n */\n processPreparedInterleaved(numFrames: number, numChannels: number): void {\n this.changer.processPreparedInterleaved(numFrames, numChannels);\n }\n\n /**\n * Planar-channel input/output view (one Float32Array per channel). Matches\n * AudioWorklet's native layout; processing happens in place.\n */\n getPlanarChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.changer.getPlanarChannelBuffer(channel, numFrames);\n }\n\n /**\n * Process the previously-acquired planar channel buffers in place. Each\n * channel must have been obtained from {@link getPlanarChannelBuffer}\n * with the same `numFrames`. Output replaces input in the same buffers.\n */\n processPreparedPlanar(numFrames: number): void {\n this.changer.processPreparedPlanar(numFrames);\n }\n\n /**\n * Convenience factory for the mono zero-copy path: returns the input/output\n * heap views plus a `process()` thunk wired to the same `numSamples`. The\n * views are reused across calls and become invalid after {@link delete}.\n */\n createRealtimeMonoBuffer(numSamples: number): RealtimeVoiceChangerMonoBuffer {\n let input = this.getMonoInputBuffer(numSamples);\n let output = this.getMonoOutputBuffer(numSamples);\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before use, mirroring the worklet RT path. In the\n // common no-growth case this is a cheap branch with no allocation.\n const reacquireIfDetached = (): void => {\n if (input.byteLength === 0 || output.byteLength === 0) {\n input = this.getMonoInputBuffer(numSamples);\n output = this.getMonoOutputBuffer(numSamples);\n }\n };\n return {\n get input(): Float32Array {\n reacquireIfDetached();\n return input;\n },\n get output(): Float32Array {\n reacquireIfDetached();\n return output;\n },\n process: () => {\n reacquireIfDetached();\n this.processPreparedMono(numSamples);\n },\n };\n }\n\n /** Same as {@link createRealtimeMonoBuffer} but for interleaved I/O. */\n createRealtimeInterleavedBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerInterleavedBuffer {\n let input = this.getInterleavedInputBuffer(numFrames, numChannels);\n let output = this.getInterleavedOutputBuffer(numFrames, numChannels);\n // Re-acquire detached views after WASM memory growth (see\n // createRealtimeMonoBuffer for rationale).\n const reacquireIfDetached = (): void => {\n if (input.byteLength === 0 || output.byteLength === 0) {\n input = this.getInterleavedInputBuffer(numFrames, numChannels);\n output = this.getInterleavedOutputBuffer(numFrames, numChannels);\n }\n };\n return {\n get input(): Float32Array {\n reacquireIfDetached();\n return input;\n },\n get output(): Float32Array {\n reacquireIfDetached();\n return output;\n },\n channels: numChannels,\n process: () => {\n reacquireIfDetached();\n this.processPreparedInterleaved(numFrames, numChannels);\n },\n };\n }\n\n /**\n * Convenience factory for the planar zero-copy path. Acquires one\n * heap-backed Float32Array per channel and returns a `process()` thunk\n * wired to the same `numFrames`. Buffers are reused across calls and\n * become invalid after {@link delete}.\n */\n createRealtimePlanarBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerPlanarBuffer {\n let channels: Float32Array[] = [];\n const acquire = (): void => {\n channels = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channels.push(this.getPlanarChannelBuffer(ch, numFrames));\n }\n };\n acquire();\n // Re-acquire detached views after WASM memory growth (see\n // createRealtimeMonoBuffer for rationale).\n const reacquireIfDetached = (): void => {\n if ((channels[0]?.byteLength ?? 0) === 0) {\n acquire();\n }\n };\n return {\n get channels(): Float32Array[] {\n reacquireIfDetached();\n return channels;\n },\n process: () => {\n reacquireIfDetached();\n this.processPreparedPlanar(numFrames);\n },\n };\n }\n\n delete(): void {\n this.changer.delete();\n }\n}\n\nexport function realtimeVoiceChangerPresetNames(): VoicePresetId[] {\n return getSonareModule().realtimeVoiceChangerPresetNames() as VoicePresetId[];\n}\n\nexport function realtimeVoiceChangerPresetJson(name: VoicePresetId): string {\n return getSonareModule().realtimeVoiceChangerPresetJson(name);\n}\n\nexport function validateRealtimeVoiceChangerPresetJson(json: string): {\n ok: boolean;\n normalizedJson?: string;\n error?: string;\n} {\n return getSonareModule().validateRealtimeVoiceChangerPresetJson(json);\n}\n","import { getSonareModule } from './module_state';\nimport type {\n EqBand,\n EqMatchOptions,\n EqSpectrumSnapshot,\n StreamingEqualizerConfig,\n StreamingMasteringChainConfig,\n StreamingRetuneConfig,\n} from './public_types';\n\ntype EqPhaseMode =\n | 'zero'\n | 'zero-latency'\n | 'zero_latency'\n | 'natural'\n | 'natural-phase'\n | 'natural_phase'\n | 'linear'\n | 'linear-phase'\n | 'linear_phase'\n | number;\n\nconst EQ_PHASE_MODES: Record<string, number> = {\n zero: 1,\n 'zero-latency': 1,\n zero_latency: 1,\n natural: 2,\n 'natural-phase': 2,\n natural_phase: 2,\n linear: 3,\n 'linear-phase': 3,\n linear_phase: 3,\n};\n\n// ============================================================================\n// StreamingMasteringChain Class\n// ============================================================================\n\n/**\n * Block-by-block streaming variant of {@link masteringChain}.\n *\n * Maintains processor state across {@link processMono}/{@link processStereo}\n * calls. Only ProcessorBase-backed stages are supported. Configurations that\n * enable `repair.denoise` throw at construction. An enabled `loudness` stage\n * also throws unless {@link StreamingMasteringChainConfig.loudnessStaticGainDb}\n * supplies a precomputed normalization gain.\n *\n * Call {@link delete} (or use a `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const chain = new StreamingMasteringChain({ eq: { tiltDb: 1.0 } });\n * try {\n * chain.prepare(44100, 512, 1);\n * const out = chain.processMono(blockSamples);\n * } finally {\n * chain.delete();\n * }\n * ```\n */\nexport class StreamingMasteringChain {\n private chain: import('./sonare.js').WasmStreamingMasteringChain;\n\n constructor(config: StreamingMasteringChainConfig) {\n const module = getSonareModule();\n this.chain = module.createStreamingMasteringChain(config as Record<string, unknown>);\n }\n\n /**\n * Initialize processors for the given sample rate and block layout.\n *\n * @param sampleRate - Sample rate in Hz\n * @param maxBlockSize - Maximum block size per process call\n * @param numChannels - 1 (mono) or 2 (stereo)\n */\n prepare(sampleRate: number, maxBlockSize: number, numChannels: number): void {\n this.chain.prepare(sampleRate, maxBlockSize, numChannels);\n }\n\n /**\n * Process one mono block, returning the processed samples (same length).\n */\n processMono(samples: Float32Array): Float32Array {\n return this.chain.processMono(samples);\n }\n\n /**\n * Process one stereo block, returning the processed channels.\n */\n processStereo(\n left: Float32Array,\n right: Float32Array,\n ): { left: Float32Array; right: Float32Array } {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return this.chain.processStereo(left, right);\n }\n\n /** Reset all processor state without rebuilding. */\n reset(): void {\n this.chain.reset();\n }\n\n /** Total reported latency in samples across all active processors. */\n latencySamples(): number {\n return this.chain.latencySamples();\n }\n\n /** Ordered stage names that will run (e.g. `\"eq.tilt\"`). */\n stageNames(): string[] {\n return this.chain.stageNames();\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.chain.delete();\n }\n}\n\n// ============================================================================\n// StreamingEqualizer Class\n// ============================================================================\n\n/**\n * Block-by-block streaming equalizer wrapping the unified C++\n * `EqualizerProcessor` (up to 24 bands, RBJ/Vicanek biquads, dynamic EQ,\n * linear-phase FIR, mid/side processing, and auto-gain).\n *\n * State is maintained across {@link processMono}/{@link processStereo} calls.\n * Call {@link delete} (or use `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const eq = new StreamingEqualizer({ sampleRate: 48000, maxBlockSize: 512 });\n * try {\n * eq.setBand(0, { type: 'HighShelf', frequencyHz: 8000, gainDb: 6, enabled: true });\n * const out = eq.processStereo(left, right);\n * const snapshot = eq.spectrum();\n * } finally {\n * eq.delete();\n * }\n * ```\n */\nexport class StreamingEqualizer {\n private eq: import('./sonare.js').WasmStreamingEqualizer;\n\n constructor(config: StreamingEqualizerConfig = {}) {\n const module = getSonareModule();\n this.eq = module.createEqualizer(config as Record<string, unknown>);\n }\n\n /**\n * Configure the band at `index` (0..23). Omitted fields use C++ defaults.\n */\n setBand(index: number, band: EqBand): void {\n this.eq.setBand(index, band as Record<string, unknown>);\n }\n\n /** Disable and reset every band. */\n clear(): void {\n this.eq.clear();\n }\n\n /**\n * Set the global phase mode: `'zero'` | `'natural'` | `'linear'` or 1/2/3.\n */\n setPhaseMode(mode: EqPhaseMode): void {\n const value = typeof mode === 'number' ? mode : EQ_PHASE_MODES[mode.toLowerCase()];\n if (value === undefined) {\n throw new Error(`unknown EQ phase mode: ${mode}`);\n }\n this.eq.setPhaseMode(value);\n }\n\n /** Enable or disable output auto-gain compensation. */\n setAutoGain(enabled: boolean): void {\n this.eq.setAutoGain(enabled);\n }\n\n /** Set all-band EQ gain scale as a 0.0..2.0 multiplier. */\n setGainScale(scale: number): void {\n this.eq.setGainScale(scale);\n }\n\n /** Set post-EQ output gain in dB. */\n setOutputGainDb(gainDb: number): void {\n this.eq.setOutputGainDb(gainDb);\n }\n\n /** Set post-EQ stereo balance in -1.0..1.0; mono input ignores pan. */\n setOutputPan(pan: number): void {\n this.eq.setOutputPan(pan);\n }\n\n /**\n * Provide a mono external sidechain key for dynamic bands that opt into\n * `external_sidechain`. The samples are copied into an owned buffer.\n */\n setSidechainMono(samples: Float32Array): void {\n this.eq.setSidechainMono(samples);\n }\n\n /**\n * Provide a stereo external sidechain key. Both channels must match length.\n */\n setSidechainStereo(left: Float32Array, right: Float32Array): void {\n if (left.length !== right.length) {\n throw new Error('Sidechain channel lengths must match.');\n }\n this.eq.setSidechainStereo(left, right);\n }\n\n /** Release any borrowed external sidechain buffers. */\n clearSidechain(): void {\n this.eq.clearSidechain();\n }\n\n /** Auto-gain applied on the most recent block, in dB. */\n lastAutoGainDb(): number {\n return this.eq.lastAutoGainDb();\n }\n\n /** Reported processing latency in samples (non-zero for linear-phase bands). */\n latencySamples(): number {\n return this.eq.latencySamples();\n }\n\n /**\n * Process one mono block, returning the equalized samples (same length).\n */\n processMono(samples: Float32Array): Float32Array {\n return this.eq.processMono(samples);\n }\n\n /**\n * Process one stereo block, returning the equalized channels.\n */\n processStereo(\n left: Float32Array,\n right: Float32Array,\n ): { left: Float32Array; right: Float32Array } {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return this.eq.processStereo(left, right);\n }\n\n /**\n * Read the latest pre/post spectrum snapshot for metering. `seq` increments\n * each time a new snapshot is published.\n */\n spectrum(): EqSpectrumSnapshot {\n return this.eq.spectrum();\n }\n\n /**\n * Configure bands so the source spectrum matches the reference spectrum.\n *\n * @param source - Source audio (mono samples)\n * @param reference - Reference audio (mono samples)\n * @param options - `sampleRate` (default 48000) and `maxBands` (default 8)\n */\n match(source: Float32Array, reference: Float32Array, options: EqMatchOptions = {}): void {\n this.eq.match(source, reference, options as Record<string, unknown>);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.eq.delete();\n }\n}\n\n// ============================================================================\n// StreamingRetune Class\n// ============================================================================\n\n/**\n * Block-by-block mono voice retune / pitch shifter.\n *\n * State is maintained across {@link processMono} calls. Call {@link prepare}\n * before processing, and call {@link delete} (or use `try/finally`) to release\n * the underlying WASM object.\n */\nexport class StreamingRetune {\n private retune: import('./sonare.js').WasmStreamingRetune;\n\n constructor(config: StreamingRetuneConfig = {}) {\n const module = getSonareModule();\n this.retune = module.createStreamingRetune(config as Record<string, unknown>);\n }\n\n /**\n * Allocate and initialize native state for the given sample rate and maximum\n * process block size.\n */\n prepare(sampleRate: number, maxBlockSize: number): void {\n this.retune.prepare(sampleRate, maxBlockSize);\n }\n\n /** Reset delay, grain, and overlap-add state without changing config. */\n reset(): void {\n this.retune.reset();\n }\n\n /**\n * Update retune settings. Changing `grainSize` takes effect after the next\n * {@link prepare} call.\n */\n setConfig(config: StreamingRetuneConfig): void {\n this.retune.setConfig(config as Record<string, unknown>);\n }\n\n /** Current native config. */\n config(): Required<StreamingRetuneConfig> {\n return this.retune.config();\n }\n\n /** Resolved grain size in samples after {@link prepare}. */\n grainSize(): number {\n return this.retune.grainSize();\n }\n\n /** Process one mono block, returning the shifted samples (same length). */\n processMono(samples: Float32Array): Float32Array {\n return this.retune.processMono(samples);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.retune.delete();\n }\n}\n","/**\n * Per-call validation options accepted by guarded wrappers. Empty-buffer\n * checks are always performed; pass `{ validate: false }` to opt out of the\n * O(n) NaN/Inf scan on hot paths.\n */\nexport interface ValidateOptions {\n validate?: boolean;\n}\n\nfunction assertNonEmptySamples(\n fnName: string,\n samples: ArrayLike<number>,\n argName = 'samples',\n): void {\n if (samples.length === 0) {\n throw new RangeError(`${fnName}: ${argName} must not be empty`);\n }\n}\n\nfunction assertFiniteSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n if (!validate) {\n return;\n }\n for (let i = 0; i < samples.length; i++) {\n const v = samples[i] as number;\n if (!Number.isFinite(v)) {\n throw new RangeError(`${fnName}: ${argName} contains NaN or Inf at index ${i}`);\n }\n }\n}\n\nexport function assertSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n assertNonEmptySamples(fnName, samples, argName);\n assertFiniteSamples(fnName, samples, validate, argName);\n}\n\nexport function assertFiniteScalar(fnName: string, value: number, argName: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${fnName}: ${argName} must be a finite number`);\n }\n}\n\nexport function assertSampleRate(fnName: string, sampleRate: number): void {\n if (!Number.isInteger(sampleRate) || sampleRate < 8000 || sampleRate > 384000) {\n throw new RangeError(`${fnName}: sampleRate out of supported range [8000, 384000]`);\n }\n}\n\nexport function assertNonNegativeInteger(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new RangeError(`${fnName}: ${argName} must be a non-negative integer`);\n }\n}\n\nexport function assertPositiveInteger(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new RangeError(`${fnName}: ${argName} must be a positive integer`);\n }\n}\n\nexport function assertInterleavedSamples(\n fnName: string,\n samples: ArrayLike<number>,\n channels: number,\n validate: boolean,\n): void {\n assertSamples(fnName, samples, validate);\n assertPositiveInteger(fnName, channels, 'channels');\n if (samples.length % channels !== 0) {\n throw new RangeError(`${fnName}: samples length must be a multiple of channels`);\n }\n}\n","import { getSonareModule } from './module_state';\nimport type {\n HpssResult,\n MasteringChainConfig,\n MasteringChainResult,\n MasteringOptions,\n MasteringPreset,\n MasteringProcessorParams,\n MasteringResult,\n MasteringStereoChainResult,\n MasteringStereoResult,\n MixOptions,\n MixResult,\n NoteStretchOptions,\n PairAnalysis,\n PairProcessor,\n RealtimeVoiceChangerConfigInput,\n SoloProcessor,\n StereoAnalysis,\n StreamingPlatform,\n} from './public_types';\nimport type { ProgressCallback } from './sonare.js';\nimport { RealtimeVoiceChanger } from './streaming_mixing';\nimport type { ValidateOptions } from './validation';\nimport { assertSamples } from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Effects\n// ============================================================================\n\n/**\n * Perform Harmonic-Percussive Source Separation (HPSS).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param kernelHarmonic - Horizontal median filter size for harmonic (default: 31)\n * @param kernelPercussive - Vertical median filter size for percussive (default: 31)\n * @returns Separated harmonic and percussive components\n */\nexport function hpss(\n samples: Float32Array,\n sampleRate = 22050,\n kernelHarmonic = 31,\n kernelPercussive = 31,\n): HpssResult {\n return requireModule().hpss(samples, sampleRate, kernelHarmonic, kernelPercussive);\n}\n\n/**\n * Extract harmonic component from audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @returns Harmonic component\n */\nexport function harmonic(\n samples: Float32Array,\n sampleRate: number,\n options: ValidateOptions = {},\n): Float32Array {\n assertSamples('harmonic', samples, options.validate !== false);\n return requireModule().harmonic(samples, sampleRate);\n}\n\n/**\n * Extract percussive component from audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @returns Percussive component\n */\nexport function percussive(\n samples: Float32Array,\n sampleRate: number,\n options: ValidateOptions = {},\n): Float32Array {\n assertSamples('percussive', samples, options.validate !== false);\n return requireModule().percussive(samples, sampleRate);\n}\n\n/**\n * Time-stretch audio without changing pitch.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param rate - Time stretch rate (0.5 = double duration, 2.0 = half duration)\n * @returns Time-stretched audio\n */\nexport function timeStretch(\n samples: Float32Array,\n sampleRate: number,\n rate: number,\n options: ValidateOptions = {},\n): Float32Array {\n assertSamples('timeStretch', samples, options.validate !== false);\n return requireModule().timeStretch(samples, sampleRate, rate);\n}\n\n/**\n * Pitch-shift audio without changing duration.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param semitones - Pitch shift in semitones (+12 = one octave up, -12 = one octave down)\n * @returns Pitch-shifted audio\n */\nexport function pitchShift(\n samples: Float32Array,\n sampleRate: number,\n semitones: number,\n options: ValidateOptions = {},\n): Float32Array {\n assertSamples('pitchShift', samples, options.validate !== false);\n return requireModule().pitchShift(samples, sampleRate, semitones);\n}\n\n/**\n * Pitch-correct audio from a current MIDI note to a target MIDI note.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param currentMidi - Detected/current MIDI note number\n * @param targetMidi - Desired MIDI note number\n * @returns Pitch-corrected audio\n */\nexport function pitchCorrectToMidi(\n samples: Float32Array,\n sampleRate = 22050,\n currentMidi = 69.0,\n targetMidi = 69.0,\n options: ValidateOptions = {},\n): Float32Array {\n assertSamples('pitchCorrectToMidi', samples, options.validate !== false);\n return requireModule().pitchCorrectToMidi(samples, sampleRate, currentMidi, targetMidi);\n}\n\n/**\n * Contour-following (\"time-varying\") pitch correction toward a MIDI target.\n *\n * Unlike {@link pitchCorrectToMidi} (a single constant transpose), this follows\n * the caller-supplied per-frame `f0Hz` contour and retunes every voiced frame\n * toward `targetMidi`, so vibrato/drift in the source is tracked rather than\n * flattened. `voiced` (non-zero = voiced) and `voicedProb` ([0,1]) are optional;\n * omitting them treats every frame as voiced.\n *\n * @param samples - Audio samples (mono, float32)\n * @param f0Hz - Per-frame measured F0 in Hz (one entry per analysis frame)\n * @param targetMidi - Desired MIDI note number\n * @param sampleRate - Sample rate in Hz\n * @param hopLength - F0 hop in samples (frame i covers sample i*hopLength)\n * @param voiced - Optional per-frame voiced flags (non-zero = voiced)\n * @param voicedProb - Optional per-frame voicing probability in [0, 1]\n * @returns Pitch-corrected audio\n */\nexport function pitchCorrectToMidiTimevarying(\n samples: Float32Array,\n f0Hz: Float32Array,\n targetMidi: number,\n sampleRate = 22050,\n hopLength = 512,\n voiced?: Int32Array,\n voicedProb?: Float32Array,\n options: ValidateOptions = {},\n): Float32Array {\n assertSamples('pitchCorrectToMidiTimevarying', samples, options.validate !== false);\n if (voiced && voiced.length !== f0Hz.length) {\n throw new RangeError('pitchCorrectToMidiTimevarying: voiced length must match f0Hz length');\n }\n if (voicedProb && voicedProb.length !== f0Hz.length) {\n throw new RangeError('pitchCorrectToMidiTimevarying: voicedProb length must match f0Hz length');\n }\n // The embind layer reads the companion arrays as Float32Array (voiced uses\n // 0.0/1.0); convert here so a single native conversion path suffices.\n const voicedF32 = voiced ? Float32Array.from(voiced) : undefined;\n return requireModule().pitchCorrectToMidiTimevarying(\n samples,\n sampleRate,\n f0Hz,\n targetMidi,\n hopLength,\n voicedF32,\n voicedProb,\n );\n}\n\n/**\n * Time-stretch a note region between two sample offsets without changing pitch.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param onsetSample - Note onset position in samples\n * @param offsetSample - Note offset position in samples\n * @param stretchRatio - Stretch ratio (0.5 = double duration, 2.0 = half duration)\n * @returns Audio with the note region stretched\n */\nexport function noteStretch(\n samples: Float32Array,\n sampleRate = 22050,\n options: NoteStretchOptions & ValidateOptions = {},\n): Float32Array {\n assertSamples('noteStretch', samples, options.validate !== false);\n return requireModule().noteStretch(\n samples,\n sampleRate,\n options.onsetSample ?? 0,\n options.offsetSample ?? 0,\n options.stretchRatio ?? 1.0,\n );\n}\n\n/** Options for {@link voiceChange}. All fields are optional. */\nexport interface VoiceChangeOptions extends ValidateOptions {\n /** Pitch shift in semitones (negative = down). Default 0. */\n pitchSemitones?: number;\n /** Formant scale factor (>1 brightens, <1 darkens). Default 1. */\n formantFactor?: number;\n}\n\n/**\n * Apply a voice change by shifting pitch and formants independently.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param options - Pitch/formant settings ({@link VoiceChangeOptions})\n * @returns Voice-changed audio\n */\nexport function voiceChange(\n samples: Float32Array,\n sampleRate = 22050,\n options: VoiceChangeOptions = {},\n): Float32Array {\n assertSamples('voiceChange', samples, options.validate !== false);\n return requireModule().voiceChange(\n samples,\n sampleRate,\n options.pitchSemitones ?? 0.0,\n options.formantFactor ?? 1.0,\n );\n}\n\n/** Options for the offline {@link voiceChangeRealtime} convenience wrapper. */\nexport interface VoiceChangeRealtimeOptions extends ValidateOptions {\n sampleRate?: number;\n /** Voice-changer preset id or full config object. */\n preset?: RealtimeVoiceChangerConfigInput;\n /** Channel count (1 = mono, 2 = interleaved stereo). */\n channels?: 1 | 2;\n /** Block size for the internal render loop (default 512). */\n blockSize?: number;\n}\n\nfunction latencyCompensatedVoiceChange(\n changer: RealtimeVoiceChanger,\n samples: Float32Array,\n channels: 1 | 2,\n blockFrames: number,\n): Float32Array {\n const latencyFrames = Math.max(0, changer.latencySamples());\n if (channels === 1) {\n const total = samples.length + latencyFrames;\n const input = new Float32Array(total);\n input.set(samples);\n const processed = new Float32Array(total);\n for (let offset = 0; offset < total; offset += blockFrames) {\n const block = input.subarray(offset, Math.min(offset + blockFrames, total));\n processed.set(changer.processMono(block), offset);\n }\n return processed.slice(latencyFrames, latencyFrames + samples.length);\n }\n\n const frames = samples.length / 2;\n const totalFrames = frames + latencyFrames;\n const input = new Float32Array(totalFrames * 2);\n input.set(samples);\n const processed = new Float32Array(totalFrames * 2);\n const frameStride = blockFrames * 2;\n for (let offset = 0; offset < input.length; offset += frameStride) {\n const block = input.subarray(offset, Math.min(offset + frameStride, input.length));\n processed.set(changer.processInterleaved(block, 2), offset);\n }\n const start = latencyFrames * 2;\n return processed.slice(start, start + samples.length);\n}\n\n/**\n * Applies the realtime voice-changer chain to a whole buffer in one call.\n *\n * Constructs and prepares a {@link RealtimeVoiceChanger}, runs the block loop\n * for the caller, then disposes it — matching the Python `voice_change_realtime`\n * and Node `voiceChangeRealtime` convenience wrappers. For mono, `samples` is a\n * plain mono buffer; for stereo, `samples` is interleaved (L0,R0,L1,R1,...).\n *\n * @returns The processed buffer (same layout/length as the input).\n */\nexport function voiceChangeRealtime(\n samples: Float32Array,\n options: VoiceChangeRealtimeOptions = {},\n): Float32Array {\n assertSamples('voiceChangeRealtime', samples, options.validate !== false);\n const channels = options.channels ?? 1;\n if (channels !== 1 && channels !== 2) {\n throw new Error('voiceChangeRealtime: channels must be 1 or 2.');\n }\n if (channels === 2 && samples.length % 2 !== 0) {\n throw new Error('voiceChangeRealtime: stereo input length must be a multiple of 2.');\n }\n // 48000 matches the Python voice_change_realtime and Node voiceChangeRealtime\n // convenience wrappers (and the RealtimeVoiceChanger default).\n const sampleRate = options.sampleRate ?? 48000;\n const blockSize = Math.max(1, Math.floor(options.blockSize ?? 512));\n const changer = new RealtimeVoiceChanger(options.preset ?? 'neutral-monitor');\n try {\n changer.prepare(sampleRate, blockSize, channels);\n return latencyCompensatedVoiceChange(changer, samples, channels, blockSize);\n } finally {\n changer.delete();\n }\n}\n\n/**\n * Normalize audio to target peak level.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param targetDb - Target peak level in dB (default: 0 dB = full scale)\n * @returns Normalized audio\n */\nexport function normalize(\n samples: Float32Array,\n sampleRate: number,\n targetDb = 0.0,\n options: ValidateOptions = {},\n): Float32Array {\n assertSamples('normalize', samples, options.validate !== false);\n return requireModule().normalize(samples, sampleRate, targetDb);\n}\n\n/**\n * Apply mastering loudness normalization with a true-peak ceiling.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Loudness/ceiling settings ({@link MasteringOptions})\n * @returns Processed audio and loudness metadata\n */\nexport function mastering(\n samples: Float32Array,\n sampleRate = 22050,\n options: MasteringOptions = {},\n): MasteringResult {\n return requireModule().mastering(\n samples,\n sampleRate,\n options.targetLufs ?? -14.0,\n options.ceilingDb ?? -1.0,\n options.truePeakOversample ?? 4,\n );\n}\n\nexport function masteringProcessorNames(): SoloProcessor[] {\n return requireModule().masteringProcessorNames() as SoloProcessor[];\n}\n\n/**\n * Names of the insert processors the mastering chain can instantiate by name\n * (`mastering::api::insert_factory_names`). Mirrors the C-ABI\n * `sonare_mastering_insert_names` (which joins this list) as a `string[]`.\n */\nexport function masteringInsertNames(): string[] {\n return (\n requireModule() as unknown as { masteringInsertNames: () => string[] }\n ).masteringInsertNames();\n}\n\nexport function masteringPairProcessorNames(): PairProcessor[] {\n return requireModule().masteringPairProcessorNames() as PairProcessor[];\n}\n\nexport function masteringPairAnalysisNames(): PairAnalysis[] {\n return requireModule().masteringPairAnalysisNames() as PairAnalysis[];\n}\n\nexport function masteringStereoAnalysisNames(): StereoAnalysis[] {\n return requireModule().masteringStereoAnalysisNames() as StereoAnalysis[];\n}\n\nexport function masteringProcess(\n processorName: SoloProcessor,\n samples: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): MasteringResult {\n return requireModule().masteringProcess(processorName, samples, sampleRate, params);\n}\n\nexport function masteringProcessStereo(\n processorName: SoloProcessor,\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): MasteringStereoResult {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return requireModule().masteringProcessStereo(processorName, left, right, sampleRate, params);\n}\n\n/**\n * Apply a two-input `match.*` processor. `source` and `reference` may have\n * independent lengths — the match primitives consume each buffer at its own\n * length.\n */\nexport function masteringPairProcess(\n processorName: PairProcessor,\n source: Float32Array,\n reference: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): MasteringResult {\n return requireModule().masteringPairProcess(processorName, source, reference, sampleRate, params);\n}\n\n/**\n * Analyze a `source` against a `reference` with a two-input analysis. The two\n * buffers may have independent lengths.\n */\nexport function masteringPairAnalyze(\n analysisName: PairAnalysis,\n source: Float32Array,\n reference: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n return requireModule().masteringPairAnalyze(analysisName, source, reference, sampleRate, params);\n}\n\nexport function masteringStereoAnalyze(\n analysisName: StereoAnalysis,\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n return requireModule().masteringStereoAnalyze(analysisName, left, right, sampleRate, params);\n}\n\nexport function masteringAssistantSuggest(\n samples: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n return requireModule().masteringAssistantSuggest(samples, sampleRate, params);\n}\n\nexport function masteringAudioProfile(\n samples: Float32Array,\n sampleRate = 22050,\n params: MasteringProcessorParams = {},\n): string {\n return requireModule().masteringAudioProfile(samples, sampleRate, params);\n}\n\nexport function masteringStreamingPreview(\n samples: Float32Array,\n sampleRate = 22050,\n platforms: StreamingPlatform[] = [],\n): string {\n return requireModule().masteringStreamingPreview(samples, sampleRate, platforms);\n}\n\n// ============================================================================\n// Mastering repair (declick, denoise_classical, declip, decrackle, dehum,\n// dereverb_classical, trim_silence) — hand-written bindings.\n// ============================================================================\n\n/** Options for `masteringRepairDeclick`. */\nexport interface DeclickOptions {\n threshold?: number;\n neighborRatio?: number;\n maxClickSamples?: number;\n lpcOrder?: number;\n residualRatio?: number;\n}\n\n/** Algorithms accepted by `masteringRepairDenoiseClassical`. */\nexport type DenoiseClassicalMode = 'logMmse' | 'mmseStsa' | 'spectralSubtraction';\n\n/** Noise PSD estimators accepted by `masteringRepairDenoiseClassical`. */\nexport type DenoiseClassicalNoiseEstimator = 'quantile' | 'mcra' | 'imcra';\n\n/** Options for `masteringRepairDenoiseClassical`. */\nexport interface DenoiseClassicalOptions {\n mode?: DenoiseClassicalMode;\n noiseEstimator?: DenoiseClassicalNoiseEstimator;\n nFft?: number;\n hopLength?: number;\n ddAlpha?: number;\n gainFloor?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n noiseEstimationQuantile?: number;\n speechPresenceGain?: boolean;\n gainSmoothing?: boolean;\n}\n\n/** Offline LPC-based declicker. */\nexport function masteringRepairDeclick(\n samples: Float32Array,\n sampleRate: number,\n options: DeclickOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDeclick(samples, sampleRate, options);\n}\n\n/** Offline STFT-domain classical denoiser (LogMMSE / MMSE-STSA / SpectralSubtraction). */\nexport function masteringRepairDenoiseClassical(\n samples: Float32Array,\n sampleRate: number,\n options: DenoiseClassicalOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDenoiseClassical(samples, sampleRate, options);\n}\n\n/** Options for `masteringRepairDeclip`. */\nexport interface DeclipOptions {\n clipThreshold?: number;\n lpcOrder?: number;\n iterations?: number;\n lpcBlend?: number;\n}\n\n/** Algorithms accepted by `masteringRepairDecrackle`. */\nexport type DecrackleMode = 'median' | 'waveletShrinkage';\n\n/** Options for `masteringRepairDecrackle`. */\nexport interface DecrackleOptions {\n threshold?: number;\n mode?: DecrackleMode;\n levels?: number;\n}\n\n/** Options for `masteringRepairDehum`. */\nexport interface DehumOptions {\n fundamentalHz?: number;\n harmonics?: number;\n q?: number;\n adaptive?: boolean;\n searchRangeHz?: number;\n adaptation?: number;\n frameSize?: number;\n pllBandwidth?: number;\n}\n\n/** Options for `masteringRepairDereverbClassical`. */\nexport interface DereverbClassicalOptions {\n threshold?: number;\n attenuation?: number;\n nFft?: number;\n hopLength?: number;\n t60Sec?: number;\n lateDelayMs?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n wpeEnabled?: boolean;\n wpeIterations?: number;\n wpeTaps?: number;\n wpeStrength?: number;\n}\n\n/** Trimming modes accepted by `masteringRepairTrimSilence`. */\nexport type TrimSilenceMode = 'peak' | 'lufsGated';\n\n/** Options for `masteringRepairTrimSilence`. */\nexport interface TrimSilenceOptions {\n threshold?: number;\n paddingSamples?: number;\n mode?: TrimSilenceMode;\n gateLufs?: number;\n windowMs?: number;\n}\n\n/** Offline LPC-based declipper. */\nexport function masteringRepairDeclip(\n samples: Float32Array,\n sampleRate: number,\n options: DeclipOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDeclip(samples, sampleRate, options);\n}\n\n/** Offline crackle suppressor (median or wavelet-shrinkage). */\nexport function masteringRepairDecrackle(\n samples: Float32Array,\n sampleRate: number,\n options: DecrackleOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDecrackle(samples, sampleRate, options);\n}\n\n/** Offline mains-hum remover. */\nexport function masteringRepairDehum(\n samples: Float32Array,\n sampleRate: number,\n options: DehumOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDehum(samples, sampleRate, options);\n}\n\n/** Offline classical dereverberator (spectral subtraction + optional WPE). */\nexport function masteringRepairDereverbClassical(\n samples: Float32Array,\n sampleRate: number,\n options: DereverbClassicalOptions = {},\n): Float32Array {\n return requireModule().masteringRepairDereverbClassical(samples, sampleRate, options);\n}\n\n/** Offline silence trimmer (peak threshold or LUFS-gated). */\nexport function masteringRepairTrimSilence(\n samples: Float32Array,\n sampleRate: number,\n options: TrimSilenceOptions = {},\n): Float32Array {\n return requireModule().masteringRepairTrimSilence(samples, sampleRate, options);\n}\n\n// ============================================================================\n// Mastering — offline dynamics processors (compressor / gate / transient_shaper)\n// ============================================================================\n\n/** Compressor sidechain detector mode. */\nexport type CompressorDetector = 'peak' | 'rms' | 'log_rms';\n\n/** Options for `masteringDynamicsCompressor`. */\nexport interface CompressorOptions extends ValidateOptions {\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n kneeDb?: number;\n makeupGainDb?: number;\n autoMakeup?: boolean;\n detector?: CompressorDetector | number;\n sidechainHpfEnabled?: boolean;\n sidechainHpfHz?: number;\n pdrTimeMs?: number;\n pdrReleaseScale?: number;\n}\n\n/** Options for `masteringDynamicsGate`. */\nexport interface GateOptions extends ValidateOptions {\n thresholdDb?: number;\n attackMs?: number;\n releaseMs?: number;\n rangeDb?: number;\n holdMs?: number;\n closeThresholdDb?: number;\n keyHpfHz?: number;\n}\n\n/** Options for `masteringDynamicsTransientShaper`. */\nexport interface TransientShaperOptions extends ValidateOptions {\n attackGainDb?: number;\n sustainGainDb?: number;\n fastAttackMs?: number;\n fastReleaseMs?: number;\n slowAttackMs?: number;\n slowReleaseMs?: number;\n sensitivity?: number;\n maxGainDb?: number;\n gainSmoothingMs?: number;\n lookaheadMs?: number;\n}\n\n/** Result envelope returned by offline mastering dynamics processors. */\nexport interface DynamicsResult {\n samples: Float32Array;\n latencySamples: number;\n}\n\nconst COMPRESSOR_DETECTOR_MAP: Record<CompressorDetector, number> = {\n peak: 0,\n rms: 1,\n log_rms: 2,\n};\n\n/** Offline feed-forward compressor (soft knee, optional auto-makeup / sidechain HPF). */\nexport function masteringDynamicsCompressor(\n samples: Float32Array,\n sampleRate: number,\n options: CompressorOptions = {},\n): DynamicsResult {\n assertSamples('masteringDynamicsCompressor', samples, options.validate !== false);\n const detector =\n typeof options.detector === 'string'\n ? COMPRESSOR_DETECTOR_MAP[options.detector]\n : options.detector;\n const opts: Record<string, unknown> = { ...options };\n if (detector !== undefined) {\n opts.detector = detector;\n }\n return requireModule().masteringDynamicsCompressor(samples, sampleRate, opts);\n}\n\n/** Offline noise gate (hysteresis, hold, optional key HPF). */\nexport function masteringDynamicsGate(\n samples: Float32Array,\n sampleRate: number,\n options: GateOptions = {},\n): DynamicsResult {\n assertSamples('masteringDynamicsGate', samples, options.validate !== false);\n return requireModule().masteringDynamicsGate(samples, sampleRate, options);\n}\n\n/** Offline transient shaper (envelope-difference attack/sustain control). */\nexport function masteringDynamicsTransientShaper(\n samples: Float32Array,\n sampleRate: number,\n options: TransientShaperOptions = {},\n): DynamicsResult {\n assertSamples('masteringDynamicsTransientShaper', samples, options.validate !== false);\n return requireModule().masteringDynamicsTransientShaper(samples, sampleRate, options);\n}\n\n/**\n * Apply a configurable mastering chain in WASM.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param config - Chain stage configuration\n * @returns Processed audio, loudness metadata, and applied stage names\n */\nexport function masteringChain(\n samples: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n): MasteringChainResult {\n return requireModule().masteringChain(samples, sampleRate, config as Record<string, unknown>);\n}\n\n/**\n * Apply a configurable stereo mastering chain in WASM.\n *\n * @param left - Left channel samples\n * @param right - Right channel samples\n * @param sampleRate - Sample rate in Hz\n * @param config - Chain stage configuration\n * @returns Processed stereo audio, loudness metadata, and applied stage names\n */\nexport function masteringChainStereo(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n): MasteringStereoChainResult {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return requireModule().masteringChainStereo(\n left,\n right,\n sampleRate,\n config as Record<string, unknown>,\n );\n}\n\n/**\n * Apply a configurable mastering chain in WASM with progress reporting.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param config - Chain stage configuration\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Processed audio, loudness metadata, and applied stage names\n */\nexport function masteringChainWithProgress(\n samples: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n onProgress: ProgressCallback,\n): MasteringChainResult {\n return requireModule().masteringChainWithProgress(\n samples,\n sampleRate,\n config as Record<string, unknown>,\n onProgress,\n );\n}\n\n/**\n * Apply a configurable stereo mastering chain in WASM with progress reporting.\n *\n * @param left - Left channel samples\n * @param right - Right channel samples\n * @param sampleRate - Sample rate in Hz\n * @param config - Chain stage configuration\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Processed stereo audio, loudness metadata, and applied stage names\n */\nexport function masteringChainStereoWithProgress(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n config: MasteringChainConfig,\n onProgress: ProgressCallback,\n): MasteringStereoChainResult {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return requireModule().masteringChainStereoWithProgress(\n left,\n right,\n sampleRate,\n config as Record<string, unknown>,\n onProgress,\n );\n}\n\n/**\n * List built-in mastering preset identifiers.\n *\n * @returns Preset names in display order (e.g. \"pop\", \"edm\", \"aiMusic\")\n */\nexport function masteringPresetNames(): MasteringPreset[] {\n return requireModule().masteringPresetNames() as MasteringPreset[];\n}\n\n/**\n * Apply a named mastering preset chain to mono audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param presetName - Preset identifier from {@link masteringPresetNames}\n * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.\n * @returns Processed audio, loudness metadata, and applied stage names\n */\nexport function masterAudio(\n samples: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset = 'pop',\n overrides: Record<string, number | boolean> = {},\n): MasteringChainResult {\n return requireModule().masterAudio(presetName, samples, sampleRate, overrides);\n}\n\n/**\n * Apply a named mastering preset chain to stereo audio.\n *\n * @param left - Left channel samples\n * @param right - Right channel samples\n * @param sampleRate - Sample rate in Hz\n * @param presetName - Preset identifier from {@link masteringPresetNames}\n * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.\n * @returns Processed stereo audio, loudness metadata, and applied stage names\n */\nexport function masterAudioStereo(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset = 'pop',\n overrides: Record<string, number | boolean> = {},\n): MasteringStereoChainResult {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return requireModule().masterAudioStereo(presetName, left, right, sampleRate, overrides);\n}\n\n/**\n * Mono `masterAudio` with per-stage progress reporting. `onProgress` is invoked\n * with `(progress, stage)` between each chain stage (progress is in [0,1]).\n */\nexport function masterAudioWithProgress(\n samples: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset,\n onProgress: ProgressCallback,\n overrides: Record<string, number | boolean> | null = null,\n): MasteringChainResult {\n return requireModule().masterAudioWithProgress(\n presetName,\n samples,\n sampleRate,\n overrides,\n onProgress,\n );\n}\n\n/**\n * Stereo `masterAudio` with per-stage progress reporting.\n */\nexport function masterAudioStereoWithProgress(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n presetName: MasteringPreset,\n onProgress: ProgressCallback,\n overrides: Record<string, number | boolean> | null = null,\n): MasteringStereoChainResult {\n if (left.length !== right.length) {\n throw new Error('Stereo channel lengths must match.');\n }\n return requireModule().masterAudioStereoWithProgress(\n presetName,\n left,\n right,\n sampleRate,\n overrides,\n onProgress,\n );\n}\n\nexport function mixingScenePresetNames(): string[] {\n return requireModule().mixingScenePresetNames();\n}\n\n/**\n * Get a built-in mixing scene preset serialized as JSON. This is the canonical\n * name shared with the Node and Python bindings; the returned JSON loads\n * directly into a {@link Mixer} via {@link Mixer.fromSceneJson}.\n *\n * @param presetName - Preset name (see {@link mixingScenePresetNames})\n * @returns Scene JSON string\n */\nexport function mixingScenePresetJson(presetName: string): string {\n return requireModule().mixingScenePresetJson(presetName);\n}\n\n/**\n * One-shot stereo mix of multiple strips through the routing graph + master bus.\n *\n * Each returned per-strip meter reflects only this single one-shot block. The\n * integrating-meter fields (`momentaryLufs`, `shortTermLufs`, `integratedLufs`\n * and the true-peak fields) require sustained streaming to populate; on a short\n * one-shot mix they read the -120 dB floor sentinel. Drive a streaming\n * {@link Mixer} block-by-block if you need meaningful loudness/true-peak\n * readings.\n *\n * @param leftChannels - Per-strip left input buffers (all the same length)\n * @param rightChannels - Per-strip right input buffers (all the same length)\n * @param sampleRate - Sample rate in Hz\n * @param options - Per-strip mix options (trim, fader, pan, width, mute)\n */\nexport function mixStereo(\n leftChannels: Float32Array[],\n rightChannels: Float32Array[],\n sampleRate = 48000,\n options: MixOptions = {},\n): MixResult {\n if (leftChannels.length === 0 || leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same non-zero length.');\n }\n return requireModule().mixStereo(\n leftChannels,\n rightChannels,\n sampleRate,\n options as Record<string, unknown>,\n );\n}\n","import { getSonareModule } from './module_state';\nimport type { TempogramMode } from './public_types';\nimport type {\n WasmCyclicTempogramResult,\n WasmFrameResult,\n WasmTempogramResult,\n WasmTrimResult,\n} from './sonare.js';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Core - Unit Conversion\n// ============================================================================\n\n/**\n * Convert frequency in Hz to Mel scale.\n *\n * @param hz - Frequency in Hz\n * @returns Mel frequency\n */\nexport function hzToMel(hz: number): number {\n return requireModule().hzToMel(hz);\n}\n\n/**\n * Convert Mel scale to frequency in Hz.\n *\n * @param mel - Mel frequency\n * @returns Frequency in Hz\n */\nexport function melToHz(mel: number): number {\n return requireModule().melToHz(mel);\n}\n\n/**\n * Convert frequency in Hz to MIDI note number.\n *\n * @param hz - Frequency in Hz\n * @returns MIDI note number (A4 = 440 Hz = 69)\n */\nexport function hzToMidi(hz: number): number {\n return requireModule().hzToMidi(hz);\n}\n\n/**\n * Convert MIDI note number to frequency in Hz.\n *\n * @param midi - MIDI note number\n * @returns Frequency in Hz\n */\nexport function midiToHz(midi: number): number {\n return requireModule().midiToHz(midi);\n}\n\n/**\n * Convert frequency in Hz to note name.\n *\n * @param hz - Frequency in Hz\n * @returns Note name (e.g., \"A4\", \"C#5\")\n */\nexport function hzToNote(hz: number): string {\n return requireModule().hzToNote(hz);\n}\n\n/**\n * Convert note name to frequency in Hz.\n *\n * @param note - Note name (e.g., \"A4\", \"C#5\")\n * @returns Frequency in Hz\n */\nexport function noteToHz(note: string): number {\n return requireModule().noteToHz(note);\n}\n\n/**\n * Convert frame index to time in seconds.\n *\n * @param frames - Frame index\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Time in seconds\n */\nexport function framesToTime(frames: number, sr = 22050, hopLength = 512): number {\n return requireModule().framesToTime(frames, sr, hopLength);\n}\n\n/**\n * Convert time in seconds to frame index.\n *\n * @param time - Time in seconds\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Frame index\n */\nexport function timeToFrames(time: number, sr = 22050, hopLength = 512): number {\n return requireModule().timeToFrames(time, sr, hopLength);\n}\n\nexport function framesToSamples(frames: number, hopLength = 512, nFft = 0): number {\n return requireModule().framesToSamples(frames, hopLength, nFft);\n}\n\nexport function samplesToFrames(samples: number, hopLength = 512, nFft = 0): number {\n return requireModule().samplesToFrames(samples, hopLength, nFft);\n}\n\nexport function powerToDb(\n values: Float32Array,\n ref = 1.0,\n amin = 1e-10,\n topDb = 80.0,\n): Float32Array {\n return requireModule().powerToDb(values, ref, amin, topDb);\n}\n\nexport function amplitudeToDb(\n values: Float32Array,\n ref = 1.0,\n amin = 1e-5,\n topDb = 80.0,\n): Float32Array {\n return requireModule().amplitudeToDb(values, ref, amin, topDb);\n}\n\nexport function dbToPower(values: Float32Array, ref = 1.0): Float32Array {\n return requireModule().dbToPower(values, ref);\n}\n\nexport function dbToAmplitude(values: Float32Array, ref = 1.0): Float32Array {\n return requireModule().dbToAmplitude(values, ref);\n}\n\nexport function preemphasis(samples: Float32Array, coef = 0.97, zi?: number): Float32Array {\n return requireModule().preemphasis(samples, coef, zi ?? null);\n}\n\nexport function deemphasis(samples: Float32Array, coef = 0.97, zi?: number): Float32Array {\n return requireModule().deemphasis(samples, coef, zi ?? null);\n}\n\nexport function trimSilence(\n samples: Float32Array,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): WasmTrimResult {\n return requireModule().trimSilence(samples, topDb, frameLength, hopLength);\n}\n\nexport function splitSilence(\n samples: Float32Array,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): Int32Array {\n return requireModule().splitSilence(samples, topDb, frameLength, hopLength);\n}\n\nexport function frameSignal(\n samples: Float32Array,\n frameLength: number,\n hopLength: number,\n): WasmFrameResult {\n return requireModule().frameSignal(samples, frameLength, hopLength);\n}\n\nexport function padCenter(values: Float32Array, targetSize: number, padValue = 0.0): Float32Array {\n return requireModule().padCenter(values, targetSize, padValue);\n}\n\nexport function fixLength(values: Float32Array, targetSize: number, padValue = 0.0): Float32Array {\n return requireModule().fixLength(values, targetSize, padValue);\n}\n\nexport function fixFrames(frames: Int32Array, xMin = 0, xMax = -1, pad = true): Int32Array {\n return requireModule().fixFrames(frames, xMin, xMax, pad);\n}\n\nexport function peakPick(\n values: Float32Array,\n preMax: number,\n postMax: number,\n preAvg: number,\n postAvg: number,\n delta: number,\n wait: number,\n): Int32Array {\n return requireModule().peakPick(values, preMax, postMax, preAvg, postAvg, delta, wait);\n}\n\nexport function vectorNormalize(values: Float32Array, normType = 0, threshold = 0.0): Float32Array {\n return requireModule().vectorNormalize(values, normType, threshold);\n}\n\nexport function pcen(\n values: Float32Array,\n nBins: number,\n nFrames: number,\n options: Record<string, number> = {},\n): Float32Array {\n return requireModule().pcen(values, nBins, nFrames, options);\n}\n\nexport function tonnetz(chromagram: Float32Array, nChroma: number, nFrames: number): Float32Array {\n return requireModule().tonnetz(chromagram, nChroma, nFrames);\n}\n\nexport function tempogram(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n mode: TempogramMode = 'autocorrelation',\n): WasmTempogramResult {\n return requireModule().tempogram(onsetEnvelope, sampleRate, hopLength, winLength, mode);\n}\n\nexport function cyclicTempogram(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n bpmMin = 60.0,\n nBins = 60,\n): WasmCyclicTempogramResult {\n return requireModule().cyclicTempogram(\n onsetEnvelope,\n sampleRate,\n hopLength,\n winLength,\n bpmMin,\n nBins,\n );\n}\n\nexport function plp(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n tempoMin = 30.0,\n tempoMax = 300.0,\n winLength = 384,\n): Float32Array {\n return requireModule().plp(onsetEnvelope, sampleRate, hopLength, tempoMin, tempoMax, winLength);\n}\n","import { getSonareModule } from './module_state';\nimport type {\n AnalyzeSectionsOptions,\n CqtResult,\n LufsResult,\n MelodyResult,\n OnsetStrengthMultiResult,\n Section,\n SectionType,\n} from './public_types';\nimport type { WasmFourierTempogramResult, WasmNnlsChromaResult } from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport {\n assertFiniteScalar,\n assertPositiveInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\ntype AnalyzeSectionsGuardedOptions = AnalyzeSectionsOptions & ValidateOptions;\ntype MelodyGuardedOptions = MelodyOptions & ValidateOptions;\n\nfunction validateMusicSamples(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\nfunction validatePositiveIntegers(fnName: string, values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n assertPositiveInteger(fnName, value, name);\n }\n}\n\nfunction validateFrequencyBounds(fnName: string, fmin: number, fmax?: number): void {\n assertFiniteScalar(fnName, fmin, 'fmin');\n if (fmin < 0) {\n throw new RangeError(`${fnName}: fmin must be non-negative`);\n }\n if (fmax !== undefined) {\n assertFiniteScalar(fnName, fmax, 'fmax');\n if (fmax <= fmin) {\n throw new RangeError(`${fnName}: fmax must be greater than fmin`);\n }\n }\n}\n\n/**\n * Compute NNLS (non-negative least squares) chromagram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns NNLS chroma result\n */\nexport function nnlsChroma(\n samples: Float32Array,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): WasmNnlsChromaResult {\n validateMusicSamples('nnlsChroma', samples, sampleRate, options);\n return requireModule().nnlsChroma(samples, sampleRate);\n}\n\n/**\n * Compute the Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function cqt(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n validateMusicSamples('cqt', samples, sampleRate, options);\n validatePositiveIntegers('cqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('cqt', fmin);\n return requireModule().cqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the pseudo Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function pseudoCqt(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n validateMusicSamples('pseudoCqt', samples, sampleRate, options);\n validatePositiveIntegers('pseudoCqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('pseudoCqt', fmin);\n return requireModule().pseudoCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the hybrid Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function hybridCqt(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n validateMusicSamples('hybridCqt', samples, sampleRate, options);\n validatePositiveIntegers('hybridCqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('hybridCqt', fmin);\n return requireModule().hybridCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the Variable-Q Transform magnitude (gamma controls Q).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @param gamma - Bandwidth offset; 0 is equivalent to CQT (default: 0)\n * @returns VQT magnitude result (same shape as CQT)\n */\nexport function vqt(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n gamma = 0,\n options: GuardedOptions = {},\n): CqtResult {\n validateMusicSamples('vqt', samples, sampleRate, options);\n validatePositiveIntegers('vqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('vqt', fmin);\n assertFiniteScalar('vqt', gamma, 'gamma');\n if (gamma < 0) {\n throw new RangeError('vqt: gamma must be non-negative');\n }\n return requireModule().vqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave, gamma);\n}\n\n/**\n * Detect song-structure sections (intro/verse/chorus/...).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param minSectionSec - Minimum section duration in seconds (default: 4.0)\n * @returns Array of detected sections\n */\nexport function analyzeSections(\n samples: Float32Array,\n sampleRate = 22050,\n options: AnalyzeSectionsGuardedOptions = {},\n): Section[] {\n validateMusicSamples('analyzeSections', samples, sampleRate, options);\n validatePositiveIntegers('analyzeSections', {\n nFft: options.nFft ?? 2048,\n hopLength: options.hopLength ?? 512,\n });\n assertFiniteScalar('analyzeSections', options.minSectionSec ?? 4.0, 'minSectionSec');\n if ((options.minSectionSec ?? 4.0) <= 0) {\n throw new RangeError('analyzeSections: minSectionSec must be positive');\n }\n return requireModule()\n .analyzeSections(\n samples,\n sampleRate,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.minSectionSec ?? 4.0,\n )\n .map((s) => ({ ...s, type: s.type as SectionType }));\n}\n\n/** Options for {@link analyzeMelody}. All fields are optional. */\nexport interface MelodyOptions {\n /** Lowest f0 (Hz) the tracker will consider. Default 65 (≈ C2). */\n fmin?: number;\n /** Highest f0 (Hz) the tracker will consider. Default 2093 (≈ C7). */\n fmax?: number;\n /** Analysis frame length in samples. Default 2048. */\n frameLength?: number;\n /** Hop length between frames in samples. Default 256. */\n hopLength?: number;\n /** Voicing confidence threshold in [0,1]; frames below are unvoiced. Default 0.1. */\n threshold?: number;\n /**\n * Use the pYIN tracker (Viterbi-smoothed) instead of plain per-frame YIN.\n * Produces a less octave-jumpy contour. Defaults to `false`.\n */\n usePyin?: boolean;\n /**\n * When {@link usePyin} is `true`, reflect-pad by `frameLength / 2` so frame\n * `i` is centered at `i * hopLength` (matches `librosa.pyin(center=True)`).\n * Ignored by the plain-YIN path. Defaults to `true`.\n */\n center?: boolean;\n}\n\n/**\n * Extract the melody contour from monophonic audio via YIN (or pYIN).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Tracker + tuning options ({@link MelodyOptions})\n * @returns Melody contour with per-frame pitch points and summary stats\n */\nexport function analyzeMelody(\n samples: Float32Array,\n sampleRate = 22050,\n options: MelodyGuardedOptions = {},\n): MelodyResult {\n validateMusicSamples('analyzeMelody', samples, sampleRate, options);\n const fmin = options.fmin ?? 65.0;\n const fmax = options.fmax ?? 2093.0;\n validateFrequencyBounds('analyzeMelody', fmin, fmax);\n validatePositiveIntegers('analyzeMelody', {\n frameLength: options.frameLength ?? 2048,\n hopLength: options.hopLength ?? 256,\n });\n assertFiniteScalar('analyzeMelody', options.threshold ?? 0.1, 'threshold');\n return requireModule().analyzeMelody(\n samples,\n sampleRate,\n options.fmin ?? 65.0,\n options.fmax ?? 2093.0,\n options.frameLength ?? 2048,\n options.hopLength ?? 256,\n options.threshold ?? 0.1,\n options.usePyin ?? false,\n options.center ?? true,\n );\n}\n\n/**\n * Compute the onset strength envelope.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @returns Onset envelope for each frame\n */\nexport function onsetEnvelope(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n options: GuardedOptions = {},\n): Float32Array {\n validateMusicSamples('onsetEnvelope', samples, sampleRate, options);\n validatePositiveIntegers('onsetEnvelope', { nFft, hopLength, nMels });\n return requireModule().onsetEnvelope(samples, sampleRate, nFft, hopLength, nMels);\n}\n\n/**\n * Compute multi-band onset strength envelopes.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param nBands - Number of onset bands (default: 3)\n * @returns Multi-band onset matrix\n */\nexport function onsetStrengthMulti(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nBands = 3,\n options: GuardedOptions = {},\n): OnsetStrengthMultiResult {\n validateMusicSamples('onsetStrengthMulti', samples, sampleRate, options);\n validatePositiveIntegers('onsetStrengthMulti', { nFft, hopLength, nMels, nBands });\n return requireModule().onsetStrengthMulti(samples, sampleRate, nFft, hopLength, nMels, nBands);\n}\n\n/**\n * Compute the Fourier tempogram from an onset envelope.\n *\n * @param onsetEnvelope - Onset strength envelope (float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param winLength - Window length in frames (default: 384)\n * @returns Fourier tempogram result\n */\nexport function fourierTempogram(\n onsetEnvelope: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n options: GuardedOptions = {},\n): WasmFourierTempogramResult {\n assertSampleRate('fourierTempogram', sampleRate);\n assertSamples('fourierTempogram', onsetEnvelope, options.validate !== false, 'onsetEnvelope');\n validatePositiveIntegers('fourierTempogram', { hopLength, winLength });\n return requireModule().fourierTempogram(onsetEnvelope, sampleRate, hopLength, winLength);\n}\n\n/**\n * Compute tempogram ratio features.\n *\n * @param tempogramData - Tempogram data (float32)\n * @param winLength - Window length in frames (default: 384)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @returns Tempogram ratio features\n */\nexport function tempogramRatio(\n tempogramData: Float32Array,\n winLength = 384,\n sampleRate = 22050,\n hopLength = 512,\n options: GuardedOptions = {},\n): Float32Array {\n assertSampleRate('tempogramRatio', sampleRate);\n assertSamples('tempogramRatio', tempogramData, options.validate !== false, 'tempogramData');\n validatePositiveIntegers('tempogramRatio', { winLength, hopLength });\n return requireModule().tempogramRatio(tempogramData, winLength, sampleRate, hopLength);\n}\n\n/**\n * Measure loudness (EBU R128 / ITU-R BS.1770).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Loudness measurement result\n */\nexport function lufs(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): LufsResult {\n assertSampleRate('lufs', sampleRate);\n assertSamples('lufs', samples, options.validate !== false);\n return requireModule().lufs(samples, sampleRate);\n}\n\n/**\n * Compute the momentary loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Momentary LUFS values over time\n */\nexport function momentaryLufs(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n assertSampleRate('momentaryLufs', sampleRate);\n assertSamples('momentaryLufs', samples, options.validate !== false);\n return requireModule().momentaryLufs(samples, sampleRate);\n}\n\n/**\n * Compute the short-term loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Short-term LUFS values over time\n */\nexport function shortTermLufs(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n assertSampleRate('shortTermLufs', sampleRate);\n assertSamples('shortTermLufs', samples, options.validate !== false);\n return requireModule().shortTermLufs(samples, sampleRate);\n}\n","import { getSonareModule } from './module_state';\nimport type { PitchResult } from './public_types';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Features - Pitch\n// ============================================================================\n\n/**\n * Detect pitch using YIN algorithm.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.3)\n * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)\n * @returns Pitch detection result\n */\nexport function pitchYin(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n): PitchResult {\n return requireModule().pitchYin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n\n/**\n * Detect pitch using pYIN algorithm (probabilistic YIN with HMM smoothing).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.3)\n * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)\n * @returns Pitch detection result\n */\nexport function pitchPyin(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n): PitchResult {\n return requireModule().pitchPyin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n","import { getSonareModule } from './module_state';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Core - Resample\n// ============================================================================\n\n/**\n * Resample audio to a different sample rate.\n *\n * @param samples - Audio samples (mono, float32)\n * @param srcSr - Source sample rate in Hz\n * @param targetSr - Target sample rate in Hz\n * @returns Resampled audio\n */\nexport function resample(samples: Float32Array, srcSr: number, targetSr: number): Float32Array {\n return requireModule().resample(samples, srcSr, targetSr);\n}\n","import { getSonareModule } from './module_state';\nimport type {\n WasmDecomposeResult,\n WasmHpssWithResidualResult,\n WasmLufsResult,\n WasmMatrix2dResult,\n} from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport { assertInterleavedSamples, assertSampleRate } from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Features - Spectral\n// ============================================================================\n\n/**\n * Compute spectral centroid (center of mass of spectrum).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral centroid in Hz for each frame\n */\nexport function spectralCentroid(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n return requireModule().spectralCentroid(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute spectral contrast (librosa.feature.spectral_contrast).\n *\n * @returns Matrix2d of shape (nBands + 1) x nFrames.\n */\nexport function spectralContrast(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nBands = 6,\n fmin = 200.0,\n quantile = 0.02,\n): WasmMatrix2dResult {\n return requireModule().spectralContrast(\n samples,\n sampleRate,\n nFft,\n hopLength,\n nBands,\n fmin,\n quantile,\n );\n}\n\n/**\n * Fit per-frame polynomial coefficients (librosa.feature.poly_features).\n *\n * @returns Matrix2d of shape (order + 1) x nFrames.\n */\nexport function polyFeatures(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n order = 1,\n): WasmMatrix2dResult {\n return requireModule().polyFeatures(samples, sampleRate, nFft, hopLength, order);\n}\n\n/**\n * Locate zero-crossing indices of a signal (librosa.zero_crossings).\n */\nexport function zeroCrossings(\n samples: Float32Array,\n threshold = 1e-10,\n refMagnitude = false,\n pad = true,\n zeroPos = true,\n): Int32Array {\n return requireModule().zeroCrossings(samples, threshold, refMagnitude, pad, zeroPos);\n}\n\n/**\n * Estimate the global tuning offset from a set of frequencies\n * (librosa.pitch_tuning). Returns a deviation in fractions of a bin.\n */\nexport function pitchTuning(\n frequencies: Float32Array,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n return requireModule().pitchTuning(frequencies, resolution, binsPerOctave);\n}\n\n/**\n * Estimate the tuning offset of an audio signal (librosa.estimate_tuning).\n */\nexport function estimateTuning(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n return requireModule().estimateTuning(\n samples,\n sampleRate,\n nFft,\n hopLength,\n resolution,\n binsPerOctave,\n );\n}\n\n/**\n * Non-negative matrix factorisation of a flattened [nFeatures x nFrames]\n * spectrogram (librosa.decompose.decompose). Returns the W and H factors.\n */\nexport function decompose(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n nComponents: number,\n nIter = 50,\n beta = 2.0,\n): WasmDecomposeResult {\n return requireModule().decompose(s, nFeatures, nFrames, nComponents, nIter, beta);\n}\n\n/**\n * Non-negative matrix factorisation with a selectable initialiser\n * (librosa.decompose.decompose, `init`). Identical to {@link decompose} but\n * exposes the initialisation strategy: `'random'` (default, deterministic seed)\n * or `'nndsvd'` (SVD-based warm start, which tends to converge in fewer\n * iterations). Returns the W and H factors.\n */\nexport function decomposeWithInit(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n nComponents: number,\n nIter = 50,\n beta = 2.0,\n init: 'random' | 'nndsvd' = 'random',\n): WasmDecomposeResult {\n return requireModule().decomposeWithInit(s, nFeatures, nFrames, nComponents, nIter, beta, init);\n}\n\n/**\n * Nearest-neighbour filtering of a flattened [nFeatures x nFrames] spectrogram\n * (librosa.decompose.nn_filter).\n */\nexport function nnFilter(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n aggregate = 'mean',\n k = 7,\n width = 1,\n): WasmMatrix2dResult {\n return requireModule().nnFilter(s, nFeatures, nFrames, aggregate, k, width);\n}\n\n/**\n * Reorder/concatenate a signal by interval slices (librosa.effects.remix).\n *\n * @param intervals - Flat (start, end) sample pairs (even length).\n */\nexport function remix(\n samples: Float32Array,\n intervals: Int32Array | ArrayLike<number>,\n sampleRate = 22050,\n alignZeros = false,\n): Float32Array {\n // Sample indices must reach the native side as exact 32-bit integers. Passing\n // a Float32Array (or a number[] holding fractional/large values) would round\n // boundaries above 2^24 and misalign the slice. Coerce to an Int32Array,\n // truncating toward zero, so callers can hand us any numeric array safely.\n const intervalsI32 =\n intervals instanceof Int32Array ? intervals : Int32Array.from(intervals, (v) => Math.trunc(v));\n return requireModule().remix(samples, intervalsI32, sampleRate, alignZeros);\n}\n\n/**\n * Phase-vocoder time-scale modification (rate > 1 faster, < 1 slower).\n */\nexport function phaseVocoder(\n samples: Float32Array,\n rate: number,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n return requireModule().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);\n}\n\n/**\n * HPSS into harmonic / percussive / residual signals.\n */\nexport function hpssWithResidual(\n samples: Float32Array,\n sampleRate = 22050,\n kernelHarmonic = 31,\n kernelPercussive = 31,\n): WasmHpssWithResidualResult {\n return requireModule().hpssWithResidual(samples, sampleRate, kernelHarmonic, kernelPercussive);\n}\n\n/**\n * Channel-weighted multichannel integrated loudness + LRA (ITU-R BS.1770 /\n * EBU R128) from an interleaved buffer of `frames * channels` samples. The\n * per-channel frame count is derived from the buffer length and `channels`.\n */\nexport function lufsInterleaved(\n samples: Float32Array,\n channels: number,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): WasmLufsResult {\n assertSampleRate('lufsInterleaved', sampleRate);\n assertInterleavedSamples('lufsInterleaved', samples, channels, options.validate !== false);\n return requireModule().lufsInterleaved(samples, channels, sampleRate);\n}\n\n/**\n * Standards-compliant EBU R128 loudness range (LRA) in LU.\n */\nexport function ebur128LoudnessRange(samples: Float32Array, sampleRate = 22050): number {\n return requireModule().ebur128LoudnessRange(samples, sampleRate);\n}\n\n/**\n * Compute spectral bandwidth.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral bandwidth in Hz for each frame\n */\nexport function spectralBandwidth(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n return requireModule().spectralBandwidth(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute spectral rolloff frequency.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param rollPercent - Percentage threshold (default: 0.85)\n * @returns Rolloff frequency in Hz for each frame\n */\nexport function spectralRolloff(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n rollPercent = 0.85,\n): Float32Array {\n return requireModule().spectralRolloff(samples, sampleRate, nFft, hopLength, rollPercent);\n}\n\n/**\n * Compute spectral flatness.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral flatness for each frame (0 = tonal, 1 = noise-like)\n */\nexport function spectralFlatness(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n return requireModule().spectralFlatness(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute zero crossing rate.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Zero crossing rate for each frame\n */\nexport function zeroCrossingRate(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n return requireModule().zeroCrossingRate(samples, sampleRate, frameLength, hopLength);\n}\n\n/**\n * Compute RMS energy.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns RMS energy for each frame\n */\nexport function rmsEnergy(\n samples: Float32Array,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n return requireModule().rmsEnergy(samples, sampleRate, frameLength, hopLength);\n}\n","import { getSonareModule } from './module_state';\nimport type {\n ChromaResult,\n MelPowerResult,\n MelSpectrogramResult,\n MfccResult,\n StftPowerResult,\n StftResult,\n} from './public_types';\nimport type { ValidateOptions } from './validation';\nimport {\n assertFiniteScalar,\n assertPositiveInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\n\nfunction validateSpectrogramSamples(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\nfunction validatePositiveIntegers(fnName: string, values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n assertPositiveInteger(fnName, value, name);\n }\n}\n\nfunction validateMelFrequencyRange(\n fnName: string,\n fmin: number,\n fmax: number,\n sampleRate: number,\n): void {\n assertFiniteScalar(fnName, fmin, 'fmin');\n assertFiniteScalar(fnName, fmax, 'fmax');\n if (fmin < 0) {\n throw new RangeError(`${fnName}: fmin must be non-negative`);\n }\n if (fmax < 0) {\n throw new RangeError(`${fnName}: fmax must be non-negative`);\n }\n const effectiveFmax = fmax === 0 ? sampleRate / 2 : fmax;\n if (effectiveFmax <= fmin) {\n throw new RangeError(`${fnName}: fmax must be greater than fmin`);\n }\n}\n\nfunction validateMatrix(\n fnName: string,\n data: Float32Array,\n rows: number,\n frames: number,\n dataName: string,\n rowName: string,\n options: GuardedOptions = {},\n): void {\n validatePositiveIntegers(fnName, { [rowName]: rows, nFrames: frames });\n assertSamples(fnName, data, options.validate !== false, dataName);\n const expectedLength = rows * frames;\n if (!Number.isSafeInteger(expectedLength) || data.length !== expectedLength) {\n throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);\n }\n}\n\n/**\n * Trim silence from beginning and end of audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param thresholdDb - Silence threshold in dB (default: -60 dB)\n * @returns Trimmed audio\n */\nexport function trim(\n samples: Float32Array,\n sampleRate: number,\n thresholdDb = -60.0,\n options: GuardedOptions = {},\n): Float32Array {\n validateSpectrogramSamples('trim', samples, sampleRate, options);\n assertFiniteScalar('trim', thresholdDb, 'thresholdDb');\n return requireModule().trim(samples, sampleRate, thresholdDb);\n}\n\n// ============================================================================\n// Features - Spectrogram\n// ============================================================================\n\n/**\n * Compute Short-Time Fourier Transform (STFT).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with magnitude and power spectrograms\n */\nexport function stft(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): StftResult {\n validateSpectrogramSamples('stft', samples, sampleRate, options);\n validatePositiveIntegers('stft', { nFft, hopLength });\n return requireModule().stft(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute STFT and return magnitude in decibels.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with dB values\n */\nexport function stftDb(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): { nBins: number; nFrames: number; db: Float32Array } {\n validateSpectrogramSamples('stftDb', samples, sampleRate, options);\n validatePositiveIntegers('stftDb', { nFft, hopLength });\n return requireModule().stftDb(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute Chroma Energy Normalized Statistics.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function chromaCens(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n options: GuardedOptions = {},\n): ChromaResult {\n validateSpectrogramSamples('chromaCens', samples, sampleRate, options);\n validatePositiveIntegers('chromaCens', { hopLength, nChroma });\n return requireModule().chromaCens(samples, sampleRate, hopLength, nChroma);\n}\n\n/**\n * Compute low-frequency bass chroma.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function bassChroma(\n samples: Float32Array,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n options: GuardedOptions = {},\n): ChromaResult {\n validateSpectrogramSamples('bassChroma', samples, sampleRate, options);\n validatePositiveIntegers('bassChroma', { hopLength, nChroma });\n return requireModule().bassChroma(samples, sampleRate, hopLength, nChroma);\n}\n\n// ============================================================================\n// Features - Mel Spectrogram\n// ============================================================================\n\n/**\n * Compute Mel spectrogram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default).\n * Set with `fmax` to round-trip with `melToStft` / `melToAudio`.\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Mel spectrogram result\n */\nexport function melSpectrogram(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n fmin = 0,\n fmax = 0,\n htk = false,\n options: GuardedOptions = {},\n): MelSpectrogramResult {\n validateSpectrogramSamples('melSpectrogram', samples, sampleRate, options);\n validatePositiveIntegers('melSpectrogram', { nFft, hopLength, nMels });\n validateMelFrequencyRange('melSpectrogram', fmin, fmax, sampleRate);\n return requireModule().melSpectrogram(\n samples,\n sampleRate,\n nFft,\n hopLength,\n nMels,\n fmin,\n fmax,\n htk,\n );\n}\n\n/**\n * Compute MFCC (Mel-Frequency Cepstral Coefficients).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param nMfcc - Number of MFCC coefficients (default: 20)\n * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns MFCC result\n */\nexport function mfcc(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nMfcc = 20,\n fmin = 0,\n fmax = 0,\n htk = false,\n options: GuardedOptions = {},\n): MfccResult {\n validateSpectrogramSamples('mfcc', samples, sampleRate, options);\n validatePositiveIntegers('mfcc', { nFft, hopLength, nMels, nMfcc });\n validateMelFrequencyRange('mfcc', fmin, fmax, sampleRate);\n return requireModule().mfcc(samples, sampleRate, nFft, hopLength, nMels, nMfcc, fmin, fmax, htk);\n}\n\n// ============================================================================\n// Features - Inverse reconstruction\n// ============================================================================\n\n/**\n * Approximate inverse of a Mel filterbank: Mel power spectrogram -> STFT power\n * spectrogram. Mirrors `feature::mel_to_stft`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param fmin - Lower Mel band edge in Hz (default: 0)\n * @param fmax - Upper Mel band edge in Hz (default: sr/2 when 0)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns STFT power spectrogram result\n */\nexport function melToStft(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate = 22050,\n nFft = 2048,\n fmin = 0,\n fmax = 0,\n htk = false,\n options: GuardedOptions = {},\n): StftPowerResult {\n assertSampleRate('melToStft', sampleRate);\n validateMatrix('melToStft', melPower, nMels, nFrames, 'melPower', 'nMels', options);\n validatePositiveIntegers('melToStft', { nFft });\n validateMelFrequencyRange('melToStft', fmin, fmax, sampleRate);\n return requireModule().melToStft(melPower, nMels, nFrames, sampleRate, nFft, fmin, fmax, htk);\n}\n\n/**\n * Reconstruct audio from a Mel power spectrogram via Griffin-Lim. Mirrors\n * `feature::mel_to_audio`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function melToAudio(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n htk = false,\n options: GuardedOptions = {},\n): Float32Array {\n assertSampleRate('melToAudio', sampleRate);\n validateMatrix('melToAudio', melPower, nMels, nFrames, 'melPower', 'nMels', options);\n validatePositiveIntegers('melToAudio', { nFft, hopLength, nIter });\n validateMelFrequencyRange('melToAudio', fmin, fmax, sampleRate);\n return requireModule().melToAudio(\n melPower,\n nMels,\n nFrames,\n sampleRate,\n nFft,\n hopLength,\n fmin,\n fmax,\n nIter,\n htk,\n );\n}\n\n/**\n * Invert MFCC coefficients back to a Mel power spectrogram. Mirrors\n * `feature::mfcc_to_mel`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins to reconstruct (default: 128)\n * @returns Mel power spectrogram result\n */\nexport function mfccToMel(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels = 128,\n options: GuardedOptions = {},\n): MelPowerResult {\n validateMatrix(\n 'mfccToMel',\n mfccCoefficients,\n nMfcc,\n nFrames,\n 'mfccCoefficients',\n 'nMfcc',\n options,\n );\n validatePositiveIntegers('mfccToMel', { nMels });\n return requireModule().mfccToMel(mfccCoefficients, nMfcc, nFrames, nMels);\n}\n\n/**\n * Reconstruct audio directly from MFCC coefficients via Griffin-Lim. Mirrors\n * `feature::mfcc_to_audio`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins (default: 128)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function mfccToAudio(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels = 128,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n htk = false,\n options: GuardedOptions = {},\n): Float32Array {\n assertSampleRate('mfccToAudio', sampleRate);\n validateMatrix(\n 'mfccToAudio',\n mfccCoefficients,\n nMfcc,\n nFrames,\n 'mfccCoefficients',\n 'nMfcc',\n options,\n );\n validatePositiveIntegers('mfccToAudio', { nMels, nFft, hopLength, nIter });\n validateMelFrequencyRange('mfccToAudio', fmin, fmax, sampleRate);\n return requireModule().mfccToAudio(\n mfccCoefficients,\n nMfcc,\n nFrames,\n nMels,\n sampleRate,\n nFft,\n hopLength,\n fmin,\n fmax,\n nIter,\n htk,\n );\n}\n\n// ============================================================================\n// Features - Chroma\n// ============================================================================\n\n/**\n * Compute chromagram (pitch class distribution).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Chroma features result\n */\nexport function chroma(\n samples: Float32Array,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): ChromaResult {\n validateSpectrogramSamples('chroma', samples, sampleRate, options);\n validatePositiveIntegers('chroma', { nFft, hopLength });\n return requireModule().chroma(samples, sampleRate, nFft, hopLength);\n}\n","import type { ValidateOptions } from './validation';\n\n/**\n * Pitch class enum (C=0, C#=1, ..., B=11)\n */\nexport const PitchClass = {\n C: 0,\n Cs: 1,\n D: 2,\n Ds: 3,\n E: 4,\n F: 5,\n Fs: 6,\n G: 7,\n Gs: 8,\n A: 9,\n As: 10,\n B: 11,\n} as const;\n\nexport type PitchClass = (typeof PitchClass)[keyof typeof PitchClass];\n\n/**\n * Musical mode\n */\nexport const Mode = {\n Major: 0,\n Minor: 1,\n Dorian: 2,\n Phrygian: 3,\n Lydian: 4,\n Mixolydian: 5,\n Locrian: 6,\n} as const;\n\nexport type Mode = (typeof Mode)[keyof typeof Mode];\n\nexport type TempogramMode = 'autocorrelation' | 'auto' | 'ac' | 'cosine' | 0 | 1;\n\nexport const KeyProfile = {\n KrumhanslSchmuckler: 0,\n Temperley: 1,\n Shaath: 2,\n FaraldoEDMT: 3,\n FaraldoEDMA: 4,\n FaraldoEDMM: 5,\n BellmanBudge: 6,\n} as const;\n\nexport type KeyProfile = (typeof KeyProfile)[keyof typeof KeyProfile];\n\nexport type KeyProfileName =\n | 'ks'\n | 'krumhansl'\n | 'temperley'\n | 'shaath'\n | 'keyfinder'\n | 'faraldo-edmt'\n | 'edmt'\n | 'faraldo-edma'\n | 'edma'\n | 'faraldo-edmm'\n | 'edmm'\n | 'bellman-budge'\n | 'bellman';\n\n/**\n * Chord quality\n */\nexport const ChordQuality = {\n Major: 0,\n Minor: 1,\n Diminished: 2,\n Augmented: 3,\n Dominant7: 4,\n Major7: 5,\n Minor7: 6,\n Sus2: 7,\n Sus4: 8,\n Unknown: 9,\n Add9: 10,\n MinorAdd9: 11,\n Dim7: 12,\n HalfDim7: 13,\n Major9: 14,\n Dominant9: 15,\n Sus2Add4: 16,\n} as const;\n\nexport type ChordQuality = (typeof ChordQuality)[keyof typeof ChordQuality];\n\nexport type MasteringPreset =\n | 'pop'\n | 'edm'\n | 'acoustic'\n | 'hipHop'\n | 'aiMusic'\n | 'speech'\n | 'streaming'\n | 'youtube'\n | 'broadcast'\n | 'podcast'\n | 'audiobook'\n | 'cinema'\n | 'jpop'\n | 'ambient'\n | 'lofi'\n | 'classical'\n | 'drumAndBass'\n | 'techno'\n | 'metal'\n | 'trap'\n | 'rnb'\n | 'jazz'\n | 'kpop'\n | 'trance'\n | 'gameOst';\n\nexport interface StreamingPlatform {\n name: string;\n targetLufs: number;\n ceilingDb: number;\n}\n\nexport type SoloProcessor =\n | 'dynamics.brickwallLimiter'\n | 'dynamics.compressor'\n | 'dynamics.deesser'\n | 'dynamics.expander'\n | 'dynamics.gate'\n | 'dynamics.limiter'\n | 'dynamics.parallelComp'\n | 'dynamics.sidechainRouter'\n | 'dynamics.duckingProcessor'\n | 'dynamics.transientShaper'\n | 'dynamics.upwardCompressor'\n | 'dynamics.upwardExpander'\n | 'dynamics.vocalRider'\n | 'eq.apiStyle'\n | 'eq.bandPass'\n | 'eq.cutFilter'\n | 'eq.dynamic'\n | 'eq.equalizer'\n | 'eq.graphic'\n | 'eq.linearPhase'\n | 'eq.midSide'\n | 'eq.minimumPhase'\n | 'eq.parametric'\n | 'eq.pultec'\n | 'eq.shelving'\n | 'eq.tilt'\n | 'final.bitDepth'\n | 'final.dither'\n | 'final.outputChain'\n | 'maximizer.adaptiveRelease'\n | 'maximizer.loudnessOptimize'\n | 'maximizer.maximizer'\n | 'maximizer.softKneeMax'\n | 'maximizer.truePeakLimiter'\n | 'multiband.compressor'\n | 'multiband.dynamicEq'\n | 'multiband.expander'\n | 'multiband.imager'\n | 'multiband.limiter'\n | 'multiband.saturation'\n | 'repair.declick'\n | 'repair.declip'\n | 'repair.decrackle'\n | 'repair.dehum'\n | 'repair.denoiseClassical'\n | 'repair.dereverbClassical'\n | 'repair.trimSilence'\n | 'saturation.bitcrusher'\n | 'saturation.exciter'\n | 'saturation.hardClipper'\n | 'saturation.multibandExciter'\n | 'saturation.ampSim'\n | 'saturation.softClipper'\n | 'saturation.tape'\n | 'saturation.transformer'\n | 'saturation.tube'\n | 'saturation.waveshaper'\n | 'spectral.airBand'\n | 'spectral.lowEndFocus'\n | 'spectral.presenceEnhancer'\n | 'spectral.spectralShaper'\n | 'stereo.autoPan'\n | 'stereo.haasEnhancer'\n | 'stereo.imager'\n | 'stereo.monoMaker'\n | 'stereo.phaseAlign'\n | 'stereo.stereoBalance';\n\nexport type PairProcessor =\n | 'match.applyMatchEq'\n | 'match.alignReferenceToSource'\n | 'match.abSwitch'\n | 'match.abCrossfade';\n\nexport type PairAnalysis =\n | 'match.referenceLoudness'\n | 'match.tonalBalance'\n | 'match.tonalBalanceLogBands'\n | 'match.matchEqCurve'\n | 'match.estimateReferenceDelaySamples';\n\nexport type StereoAnalysis = 'stereo.monoCompatCheck' | 'stereo.monoCompatCheckLogBands';\n\n/**\n * Section type\n */\nexport const SectionType = {\n Intro: 0,\n Verse: 1,\n PreChorus: 2,\n Chorus: 3,\n Bridge: 4,\n Instrumental: 5,\n Outro: 6,\n Unknown: 7,\n} as const;\n\nexport type SectionType = (typeof SectionType)[keyof typeof SectionType];\n\n/**\n * Detected musical key\n */\nexport interface Key {\n root: PitchClass;\n mode: Mode;\n confidence: number;\n name: string;\n shortName: string;\n}\n\nexport interface KeyDetectionOptions extends ValidateOptions {\n nFft?: number;\n hopLength?: number;\n useHpss?: boolean;\n loudnessWeighted?: boolean;\n highPassHz?: number;\n modes?:\n | Mode[]\n | ('major' | 'minor' | 'dorian' | 'phrygian' | 'lydian' | 'mixolydian' | 'locrian')[]\n | 'major-minor'\n | 'all'\n | 'modal';\n profile?: KeyProfile | KeyProfileName;\n genreHint?: 'auto' | 'edm' | 'electronic' | 'dance' | 'pop' | 'classical' | 'jazz' | string;\n}\n\nexport interface KeyCandidate {\n key: Key;\n correlation: number;\n}\n\nexport interface ChordDetectionOptions extends ValidateOptions {\n minDuration?: number;\n smoothingWindow?: number;\n threshold?: number;\n useTriadsOnly?: boolean;\n nFft?: number;\n hopLength?: number;\n useBeatSync?: boolean;\n useHmm?: boolean;\n hmmBeamWidth?: number;\n useKeyContext?: boolean;\n keyRoot?: PitchClass;\n keyMode?: Mode;\n detectInversions?: boolean;\n chromaMethod?: 'stft' | 'nnls';\n}\n\n/** Options for `detectAcoustic`. All fields are optional. */\nexport interface AcousticOptions extends ValidateOptions {\n /** Number of octave bands. Default 6. */\n nOctaveBands?: number;\n /** Number of 1/3-octave sub-bands. Default 24. */\n nThirdOctaveSubbands?: number;\n /** Minimum decay range (dB) for a valid RT60 fit. Default 30. */\n minDecayDb?: number;\n /** Margin (dB) above the noise floor for the decay fit. Default 10. */\n noiseFloorMarginDb?: number;\n}\n\n/** Options for `analyzeBpm`. All fields are optional. */\nexport interface AnalyzeBpmOptions extends ValidateOptions {\n /** Lowest BPM to consider. Default 30. */\n bpmMin?: number;\n /** Highest BPM to consider. Default 300. */\n bpmMax?: number;\n /** Tempo prior the tracker is biased toward. Default 120. */\n startBpm?: number;\n /** FFT size for the onset envelope. Default 2048. */\n nFft?: number;\n /** Hop length for the onset envelope. Default 512. */\n hopLength?: number;\n /** Number of tempo candidates to return. Default 5. */\n maxCandidates?: number;\n}\n\n/** Options for `analyzeRhythm`. All fields are optional. */\nexport interface AnalyzeRhythmOptions extends ValidateOptions {\n /** Lowest BPM to consider. Default 60. */\n bpmMin?: number;\n /** Highest BPM to consider. Default 200. */\n bpmMax?: number;\n /** Tempo prior the tracker is biased toward. Default 120. */\n startBpm?: number;\n /** FFT size for the onset envelope. Default 2048. */\n nFft?: number;\n /** Hop length for the onset envelope. Default 512. */\n hopLength?: number;\n}\n\n/** Options for `analyzeDynamics`. All fields are optional. */\nexport interface AnalyzeDynamicsOptions extends ValidateOptions {\n /** Loudness-curve window length in seconds. Default 0.4. */\n windowSec?: number;\n /** Hop length for the loudness curve. Default 512. */\n hopLength?: number;\n /** Crest-factor (dB) below which the signal is flagged as compressed. Default 6. */\n compressionThreshold?: number;\n}\n\n/** Options for `analyzeTimbre`. All fields are optional. */\nexport interface AnalyzeTimbreOptions extends ValidateOptions {\n /** FFT size. Default 2048. */\n nFft?: number;\n /** Hop length. Default 512. */\n hopLength?: number;\n /** Number of Mel bands. Default 128. */\n nMels?: number;\n /** Number of MFCCs. Default 13. */\n nMfcc?: number;\n /** Per-window analysis length in seconds. Default 0.5. */\n windowSec?: number;\n}\n\n/** Options for `analyzeSections`. All fields are optional. */\nexport interface AnalyzeSectionsOptions {\n /** FFT size. Default 2048. */\n nFft?: number;\n /** Hop length. Default 512. */\n hopLength?: number;\n /** Minimum section duration in seconds. Default 4. */\n minSectionSec?: number;\n}\n\n/** Options for `mastering`. All fields are optional. */\nexport interface MasteringOptions {\n /** Target integrated LUFS. Default -14. */\n targetLufs?: number;\n /** True/sample peak ceiling in dBFS. Default -1. */\n ceilingDb?: number;\n /** Oversampling factor used for peak estimation. Default 4. */\n truePeakOversample?: number;\n}\n\n/** Options for `noteStretch`. All fields are optional. */\nexport interface NoteStretchOptions {\n /** Note onset position in samples (selects the region). Default 0. */\n onsetSample?: number;\n /** Note offset position in samples (selects the region). Default 0. */\n offsetSample?: number;\n /** Stretch ratio (0.5 = double duration, 2.0 = half duration). Default 1. */\n stretchRatio?: number;\n}\n\n/**\n * Detected beat\n */\nexport interface Beat {\n time: number;\n strength: number;\n}\n\n/**\n * Detected chord\n */\nexport interface Chord {\n root: PitchClass;\n bass: PitchClass;\n quality: ChordQuality;\n start: number;\n end: number;\n confidence: number;\n name: string;\n}\n\nexport interface ChordAnalysisResult {\n chords: Chord[];\n}\n\n/**\n * Detected section\n */\nexport interface Section {\n type: SectionType;\n start: number;\n end: number;\n energyLevel: number;\n confidence: number;\n name: string;\n}\n\n/**\n * A single melody contour point (mirrors the C `SonareMelodyPoint`).\n */\nexport interface MelodyPoint {\n /** Frame time in seconds. */\n time: number;\n /** Estimated fundamental frequency in Hz (0 when unvoiced). */\n frequency: number;\n /** Voicing confidence in `[0, 1]`. */\n confidence: number;\n}\n\n/**\n * Melody analysis result (mirrors the C `SonareMelodyResult`).\n */\nexport interface MelodyResult {\n points: MelodyPoint[];\n pitchRangeOctaves: number;\n pitchStability: number;\n meanFrequency: number;\n vibratoRate: number;\n}\n\n/**\n * Constant-Q / Variable-Q transform magnitude result (mirrors the C\n * `SonareCqtResult`).\n */\nexport interface CqtResult {\n /** Number of frequency bins. */\n nBins: number;\n /** Number of time frames. */\n nFrames: number;\n /** Hop length in samples. */\n hopLength: number;\n /** Sample rate in Hz. */\n sampleRate: number;\n /** Row-major `[nBins x nFrames]` magnitude matrix. */\n magnitude: Float32Array;\n /** Center frequency (Hz) of each of the `nBins` bins. */\n frequencies: Float32Array;\n}\n\n/**\n * Multi-band onset strength matrix result.\n */\nexport interface OnsetStrengthMultiResult {\n nBands: number;\n nFrames: number;\n data: Float32Array;\n}\n\n/**\n * Timbre characteristics\n */\nexport interface Timbre {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\n/**\n * Dynamics characteristics\n */\nexport interface Dynamics {\n dynamicRangeDb: number;\n peakDb: number;\n rmsDb: number;\n loudnessRangeDb: number;\n crestFactor: number;\n isCompressed: boolean;\n}\n\n/**\n * Time signature\n */\nexport interface TimeSignature {\n numerator: number;\n denominator: number;\n confidence: number;\n}\n\n/**\n * Rhythm features\n */\nexport interface RhythmFeatures {\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n tempoStability: number;\n timeSignature: TimeSignature;\n}\n\n/**\n * Melody contour from the unified analysis (pitch trajectory + summary stats).\n */\nexport interface MelodyContour {\n pitchRangeOctaves: number;\n pitchStability: number;\n meanFrequency: number;\n vibratoRate: number;\n pitches: MelodyPoint[];\n}\n\n/**\n * Complete analysis result\n */\nexport interface AnalysisResult {\n bpm: number;\n bpmConfidence: number;\n key: Key;\n timeSignature: TimeSignature;\n beatTimes: Float32Array;\n beats: Beat[];\n chords: Chord[];\n sections: Section[];\n timbre: Timbre;\n dynamics: Dynamics;\n rhythm: RhythmFeatures;\n melody: MelodyContour;\n form: string;\n}\n\n/**\n * Room acoustic parameters from an impulse response\n */\nexport interface AcousticResult {\n rt60: number;\n edt: number;\n c50: number;\n c80: number;\n d50: number;\n rt60Bands: Float32Array;\n edtBands: Float32Array;\n c50Bands: Float32Array;\n c80Bands: Float32Array;\n confidence: number;\n isBlind: boolean;\n}\n\n/** Shoebox geometry + placement shared by RIR synthesis and the room morph. */\nexport interface RoomGeometryOptions {\n lengthM?: number;\n widthM?: number;\n heightM?: number;\n /** Uniform wall absorption, clamped to [0, 0.999] (the back-compat scalar). */\n absorption?: number;\n /**\n * Optional per-octave-band wall absorption (125/250/500/1k/2k/4k.. Hz). When\n * provided it overrides `absorption` unless `materialPreset` is set.\n */\n bandAbsorption?: Float32Array | number[];\n /** Optional per-band wall scattering; missing bands default to 0. */\n bandScattering?: Float32Array | number[];\n /**\n * Named wall-material preset (0 none; 1 concrete, 2 wood, 3 curtain,\n * 4 carpet, 5 glass). A non-zero preset wins over `bandAbsorption`/`absorption`.\n */\n materialPreset?: number;\n sourceX?: number;\n sourceY?: number;\n sourceZ?: number;\n listenerX?: number;\n listenerY?: number;\n listenerZ?: number;\n ismOrder?: number;\n seed?: number;\n maxSeconds?: number;\n}\n\nexport interface RirSynthOptions extends RoomGeometryOptions {\n sampleRate?: number;\n /** Use the Eyring statistical late-tail model (default true); false = Sabine. */\n preferEyring?: boolean;\n /** Early/late crossover in ms (0 = auto, ~sqrt(V) ms). */\n mixingTimeMs?: number;\n /** Equal-power crossfade width around the mixing time in ms (0 = default). */\n crossfadeMs?: number;\n}\n\nexport interface RirResult {\n rir: Float32Array;\n sampleRate: number;\n hasError: boolean;\n}\n\nexport interface RoomEstimateOptions {\n aspectHintLw?: number;\n aspectHintLh?: number;\n referenceAbsorption?: number;\n preferEyring?: boolean;\n nOctaveBands?: number;\n /** Analyzer routing: 0 = auto, 1 = blind, 2 = impulse-response. */\n mode?: number;\n /** Analyzer decay-fit span in dB (0 = library default). */\n minDecayDb?: number;\n /** Analyzer noise-floor margin in dB (0 = library default). */\n noiseFloorMarginDb?: number;\n}\n\nexport interface RoomEstimateResult {\n volume: number;\n length: number;\n width: number;\n height: number;\n drrDb: number;\n confidence: number;\n absorptionBands: Float32Array;\n rt60Bands: Float32Array;\n}\n\nexport interface RoomMorphOptions extends RoomGeometryOptions {\n wet?: number;\n sourceTailSuppression?: number;\n /**\n * Use the Eyring statistical late-tail model for the target room (default\n * true); false = Sabine. Matches {@link RirSynthOptions.preferEyring}.\n */\n preferEyring?: boolean;\n /** Early/late crossover in ms (0 = auto, ~sqrt(V) ms). */\n mixingTimeMs?: number;\n /** Equal-power crossfade width around the mixing time in ms (0 = default). */\n crossfadeMs?: number;\n}\n\n/**\n * HPSS (Harmonic-Percussive Source Separation) result\n */\nexport interface HpssResult {\n harmonic: Float32Array;\n percussive: Float32Array;\n sampleRate: number;\n}\n\n/**\n * Mastering loudness/true-peak processing result\n */\nexport interface MasteringResult {\n samples: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n latencySamples?: number;\n}\n\nexport type MasteringProcessorParams = Record<string, number | boolean>;\n\nexport type PanMode = 'balance' | 'stereoPan' | 'stereo-pan' | 'dualPan' | 'dual-pan' | number;\n\nexport interface MixOptions {\n inputTrimDb?: number | number[];\n faderDb?: number | number[];\n pan?: number | number[];\n panMode?: PanMode | PanMode[];\n width?: number | number[];\n muted?: boolean | boolean[];\n}\n\nexport interface MixMeterSnapshot {\n peakDbL: number;\n peakDbR: number;\n rmsDbL: number;\n rmsDbR: number;\n correlation: number;\n monoCompatWidth: number;\n monoCompatPeak: number;\n monoCompatSideRms: number;\n likelyMonoCompatible: boolean;\n momentaryLufs: number;\n shortTermLufs: number;\n integratedLufs: number;\n gainReductionDb: number;\n truePeakDbL: number;\n truePeakDbR: number;\n maxTruePeakDb: number;\n seq: number;\n}\n\nexport interface MixResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n meters: MixMeterSnapshot[];\n}\n\n/** Mixed stereo master returned by {@link Mixer.processStereo}. */\nexport interface MixerProcessResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n}\n\n/**\n * Interpolation curve for scheduled automation events\n * (see {@link Mixer.scheduleInsertAutomation}).\n */\nexport type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';\n\n/**\n * Pan law applied when computing left/right gains from a pan position\n * (see {@link Mixer.setPanLaw}). Maps to the underlying integer code.\n */\nexport type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';\n\n/**\n * Meter tap point for reading a strip's meter snapshot\n * (see {@link Mixer.meterTap} and {@link Mixer.stripMeter}).\n */\nexport type MeterTap = 'preFader' | 'postFader';\n\n/** Pre/post-fader send timing (see {@link Mixer.addSend}). */\nexport type SendTiming = 'preFader' | 'postFader';\n\n/** A single goniometer (left/right) sample returned by {@link Mixer.readGoniometerLatest}. */\nexport interface GoniometerPoint {\n left: number;\n right: number;\n}\n\nexport interface MasteringChainConfig {\n repair?: {\n denoise?: boolean;\n nFft?: number;\n hopLength?: number;\n ddAlpha?: number;\n gainFloor?: number;\n declick?: {\n threshold?: number;\n neighborRatio?: number;\n maxClickSamples?: number;\n lpcOrder?: number;\n residualRatio?: number;\n };\n dereverb?: {\n threshold?: number;\n attenuation?: number;\n nFft?: number;\n hopLength?: number;\n t60Sec?: number;\n lateDelayMs?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n wpeEnabled?: boolean;\n wpeIterations?: number;\n wpeTaps?: number;\n wpeStrength?: number;\n };\n };\n eq?: {\n tiltDb?: number;\n pivotHz?: number;\n };\n dynamics?: {\n compressor?: {\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n kneeDb?: number;\n makeupGainDb?: number;\n autoMakeup?: boolean;\n };\n deesser?: {\n frequencyHz?: number;\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n rangeDb?: number;\n bandpassQ?: number;\n };\n transientShaper?: {\n attackGainDb?: number;\n sustainGainDb?: number;\n fastAttackMs?: number;\n fastReleaseMs?: number;\n slowAttackMs?: number;\n slowReleaseMs?: number;\n sensitivity?: number;\n maxGainDb?: number;\n gainSmoothingMs?: number;\n lookaheadMs?: number;\n };\n multibandComp?: {\n lowCutoffHz?: number;\n highCutoffHz?: number;\n lowThresholdDb?: number;\n lowRatio?: number;\n lowAttackMs?: number;\n lowReleaseMs?: number;\n midThresholdDb?: number;\n midRatio?: number;\n midAttackMs?: number;\n midReleaseMs?: number;\n highThresholdDb?: number;\n highRatio?: number;\n highAttackMs?: number;\n highReleaseMs?: number;\n };\n };\n saturation?: {\n tape?: {\n driveDb?: number;\n saturation?: number;\n hysteresis?: number;\n outputGainDb?: number;\n speedIps?: number;\n headBumpDb?: number;\n bias?: number;\n gapLoss?: number;\n };\n exciter?: {\n frequencyHz?: number;\n driveDb?: number;\n amount?: number;\n q?: number;\n evenOddMix?: number;\n };\n };\n spectral?: {\n airBand?: {\n amount?: number;\n shelfFrequencyHz?: number;\n dynamicThresholdDb?: number;\n dynamicRangeDb?: number;\n };\n };\n stereo?: {\n imager?: {\n width?: number;\n outputGainDb?: number;\n decorrelationAmount?: number;\n preserveEnergy?: boolean;\n };\n monoMaker?: {\n amount?: number;\n };\n };\n maximizer?: {\n truePeakLimiter?: {\n ceilingDb?: number;\n lookaheadMs?: number;\n releaseMs?: number;\n oversampleFactor?: number;\n applyGainAtInputRate?: boolean;\n };\n };\n loudness?: {\n targetLufs?: number;\n ceilingDb?: number;\n truePeakOversample?: number;\n };\n}\n\n/**\n * Configuration for the block-by-block {@link StreamingMasteringChain}.\n *\n * Extends {@link MasteringChainConfig} with optional precomputed loudness\n * parameters. The streaming chain cannot measure whole-signal integrated LUFS,\n * so an enabled `loudness` stage normally throws at construction. To let a\n * preset's streaming preview match its offline render, the caller may\n * precompute the loudness normalization gain offline (e.g.\n * `targetLufs - measuredIntegratedLufs`) and supply it here.\n */\nexport interface StreamingMasteringChainConfig extends MasteringChainConfig {\n /**\n * Precomputed static loudness gain in dB. When omitted (the default), an\n * enabled `loudness` stage still throws. When provided and `loudness.enabled`\n * is set, the chain applies this fixed gain per block before the loudness\n * stage's true-peak limiter instead of throwing.\n */\n loudnessStaticGainDb?: number;\n\n /**\n * Offline-measured true-peak (dBFS) of the source the static gain was\n * computed for. When provided, the static gain is clamped to\n * `loudness.ceilingDb - loudnessStaticGainPeakDb` so the streaming preview\n * does not drive the loudness limiter harder than the offline chain. When\n * omitted (the default) the static gain is applied verbatim.\n */\n loudnessStaticGainPeakDb?: number;\n}\n\nexport interface MasteringChainResult extends MasteringResult {\n stages: string[];\n}\n\nexport interface MasteringStereoChainResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n stages: string[];\n latencySamples?: number;\n}\n\nexport interface MasteringStereoResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n latencySamples: number;\n}\n\n/**\n * STFT (Short-Time Fourier Transform) result\n */\nexport interface StftResult {\n nBins: number;\n nFrames: number;\n nFft: number;\n hopLength: number;\n sampleRate: number;\n magnitude: Float32Array;\n power: Float32Array;\n}\n\n/**\n * Mel spectrogram result\n */\nexport interface MelSpectrogramResult {\n nMels: number;\n nFrames: number;\n sampleRate: number;\n hopLength: number;\n power: Float32Array;\n db: Float32Array;\n}\n\n/**\n * MFCC result\n */\nexport interface MfccResult {\n nMfcc: number;\n nFrames: number;\n coefficients: Float32Array;\n}\n\n/**\n * STFT power spectrogram result (from inverse Mel reconstruction)\n */\nexport interface StftPowerResult {\n nBins: number;\n nFrames: number;\n power: Float32Array;\n}\n\n/**\n * Mel power spectrogram result (from inverse MFCC reconstruction)\n */\nexport interface MelPowerResult {\n nMels: number;\n nFrames: number;\n power: Float32Array;\n}\n\n/**\n * Chroma features result\n */\nexport interface ChromaResult {\n nChroma: number;\n nFrames: number;\n sampleRate: number;\n hopLength: number;\n features: Float32Array;\n meanEnergy: number[];\n}\n\n/**\n * Pitch detection result\n */\nexport interface PitchResult {\n f0: Float32Array;\n voicedProb: Float32Array;\n voicedFlag: boolean[];\n nFrames: number;\n medianF0: number;\n meanF0: number;\n}\n\n/**\n * Loudness measurement result (EBU R128 / ITU-R BS.1770)\n */\nexport interface LufsResult {\n integratedLufs: number;\n momentaryLufs: number;\n shortTermLufs: number;\n loudnessRange: number;\n}\n\n/**\n * Realtime equalizer spectrum snapshot.\n *\n * Mirrors the C++ `EqualizerSpectrumSnapshot`: `preLeft`/`preRight` and\n * `postLeft`/`postRight` are the pre- and post-EQ spectrum streams (trimmed to\n * their valid count). `bandGainDb` holds per-band applied gain (24 entries),\n * `profileDb` the smoothed magnitude profile (16 entries), `lastAutoGainDb`\n * the latest auto-gain compensation, and `seq` increments each time a new\n * snapshot is published.\n */\nexport interface EqSpectrumSnapshot {\n preLeft: Float32Array;\n preRight: Float32Array;\n postLeft: Float32Array;\n postRight: Float32Array;\n bandGainDb: Float32Array;\n profileDb: Float32Array;\n lastAutoGainDb: number;\n seq: number;\n}\n\n/**\n * Equalizer band type (string union mirroring `sonare::mastering::eq::EqBandType`).\n */\nexport type EqBandType =\n | 'Peak'\n | 'LowShelf'\n | 'HighShelf'\n | 'LowPass'\n | 'HighPass'\n | 'BandPass'\n | 'Notch'\n | 'TiltShelf'\n | 'FlatTilt';\n\n/** Biquad coefficient design mode. */\nexport type EqCoeffMode = 'Rbj' | 'Vicanek';\n\n/** Stereo placement for an EQ band. */\nexport type EqStereoPlacement = 'Stereo' | 'Left' | 'Right' | 'Mid' | 'Side';\n\n/** Per-band phase behaviour. */\nexport type EqBandPhase = 'Inherit' | 'ZeroLatency' | 'NaturalPhase' | 'LinearPhase';\n\n/**\n * Equalizer band configuration accepted by {@link StreamingEqualizer.setBand}.\n *\n * All fields are optional; omitted values fall back to the C++ band defaults\n * (Peak, 1000 Hz, 0 dB gain, Butterworth Q, disabled).\n */\nexport interface EqBand {\n type?: EqBandType;\n frequencyHz?: number;\n gainDb?: number;\n q?: number;\n enabled?: boolean;\n coeffMode?: EqCoeffMode;\n slopeDbOct?: number;\n placement?: EqStereoPlacement;\n phase?: EqBandPhase;\n soloed?: boolean;\n bypassed?: boolean;\n proportionalQ?: boolean;\n proportionalQStrength?: number;\n dynamic?: boolean;\n thresholdDb?: number;\n autoThreshold?: boolean;\n ratio?: number;\n rangeDb?: number;\n attackMs?: number;\n releaseMs?: number;\n lookaheadMs?: number;\n externalSidechain?: boolean;\n sidechainFreqHz?: number;\n sidechainQ?: number;\n}\n\n/** Construction options for {@link StreamingEqualizer}. */\nexport interface StreamingEqualizerConfig {\n sampleRate?: number;\n maxBlockSize?: number;\n}\n\n/** Configuration for {@link StreamingRetune}. */\nexport interface StreamingRetuneConfig {\n /** Pitch shift in semitones, clamped by the native processor to +/-24. */\n semitones?: number;\n /** Wet/dry mix, clamped by the native processor to 0..1. */\n mix?: number;\n /** Grain size in samples. Use 0/omit to derive it from the sample rate. */\n grainSize?: number;\n}\n\nexport type VoicePresetId =\n | 'neutral-monitor'\n | 'bright-idol'\n | 'soft-whisper'\n | 'deep-narrator'\n | 'robot-mascot'\n | 'dark-villain';\n\nexport interface RealtimeVoiceChangerPreset {\n schemaVersion: 1;\n id?: string;\n name?: string;\n description?: string;\n macros?: Record<string, number>;\n dsp?: Record<string, unknown>;\n}\n\nexport type RealtimeVoiceChangerConfigInput = VoicePresetId | RealtimeVoiceChangerPreset;\n\n/**\n * Flat (POD) realtime voice-changer configuration. Field names mirror the\n * C ABI `SonareRealtimeVoiceChangerConfig` / Python POD exactly (snake_case),\n * so a config can be round-tripped across bindings without renaming.\n */\nexport interface RealtimeVoiceChangerPodConfig {\n input_gain_db: number;\n output_gain_db: number;\n wet_mix: number;\n retune_semitones: number;\n retune_mix: number;\n retune_grain_size: number;\n formant_factor: number;\n formant_amount: number;\n formant_body: number;\n formant_brightness: number;\n formant_nasal: number;\n eq_highpass_hz: number;\n eq_body_db: number;\n eq_presence_db: number;\n eq_air_db: number;\n gate_threshold_db: number;\n gate_attack_ms: number;\n gate_release_ms: number;\n gate_range_db: number;\n compressor_threshold_db: number;\n compressor_ratio: number;\n compressor_attack_ms: number;\n compressor_release_ms: number;\n compressor_makeup_gain_db: number;\n deesser_frequency_hz: number;\n deesser_threshold_db: number;\n deesser_ratio: number;\n deesser_range_db: number;\n reverb_mix: number;\n reverb_time_ms: number;\n reverb_damping: number;\n reverb_seed: number;\n limiter_ceiling_db: number;\n limiter_release_ms: number;\n /** Non-zero enables the 4x-oversampled inter-sample-peak limiter (default enabled). */\n limiter_enable_isp_limiter: boolean;\n /** True-peak ceiling in dBTP applied by the ISP limiter (default -1.0). */\n limiter_isp_ceiling_dbtp: number;\n}\n\n/** Options for {@link StreamingEqualizer.match}. */\nexport interface EqMatchOptions {\n sampleRate?: number;\n maxBands?: number;\n}\n","import type {\n AnalysisResult,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChordQuality,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n PitchClass,\n SectionType,\n} from './public_types';\nimport { KeyProfile as KeyProfileValues, Mode } from './public_types';\nimport type {\n WasmAnalysisResult,\n WasmChordAnalysisResult,\n WasmKeyCandidateResult,\n} from './sonare.js';\n\nexport function convertKeyCandidate(wasm: WasmKeyCandidateResult): KeyCandidate {\n return {\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n correlation: wasm.correlation,\n };\n}\n\nexport function keyModeValues(modes: KeyDetectionOptions['modes'] | undefined): number[] {\n if (!modes) {\n return [];\n }\n if (modes === 'major-minor') {\n return [Mode.Major, Mode.Minor];\n }\n if (modes === 'all' || modes === 'modal') {\n return [\n Mode.Major,\n Mode.Minor,\n Mode.Dorian,\n Mode.Phrygian,\n Mode.Lydian,\n Mode.Mixolydian,\n Mode.Locrian,\n ];\n }\n const names = {\n major: Mode.Major,\n minor: Mode.Minor,\n dorian: Mode.Dorian,\n phrygian: Mode.Phrygian,\n lydian: Mode.Lydian,\n mixolydian: Mode.Mixolydian,\n locrian: Mode.Locrian,\n } as const;\n return modes.map((mode) => (typeof mode === 'number' ? mode : names[mode]));\n}\n\nexport function keyProfileValue(profile: KeyDetectionOptions['profile'] | undefined): number {\n if (profile === undefined) {\n return -1;\n }\n if (typeof profile === 'number') {\n return profile;\n }\n const names: Record<KeyProfileName, number> = {\n ks: KeyProfileValues.KrumhanslSchmuckler,\n krumhansl: KeyProfileValues.KrumhanslSchmuckler,\n temperley: KeyProfileValues.Temperley,\n shaath: KeyProfileValues.Shaath,\n keyfinder: KeyProfileValues.Shaath,\n 'faraldo-edmt': KeyProfileValues.FaraldoEDMT,\n edmt: KeyProfileValues.FaraldoEDMT,\n 'faraldo-edma': KeyProfileValues.FaraldoEDMA,\n edma: KeyProfileValues.FaraldoEDMA,\n 'faraldo-edmm': KeyProfileValues.FaraldoEDMM,\n edmm: KeyProfileValues.FaraldoEDMM,\n 'bellman-budge': KeyProfileValues.BellmanBudge,\n bellman: KeyProfileValues.BellmanBudge,\n };\n return names[profile];\n}\n\nexport function convertChordAnalysisResult(wasm: WasmChordAnalysisResult): ChordAnalysisResult {\n return {\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n confidence: c.confidence,\n name: c.name,\n })),\n };\n}\n\nexport function chordChromaMethodValue(method: ChordDetectionOptions['chromaMethod']): number {\n if (method === 'stft') {\n return 0;\n }\n if (method === 'nnls') {\n return 1;\n }\n throw new Error(`Invalid chord chroma method: ${method}`);\n}\n\nexport function convertAnalysisResult(wasm: WasmAnalysisResult): AnalysisResult {\n const beatTimes = new Float32Array(wasm.beats.length);\n for (let i = 0; i < wasm.beats.length; i++) {\n beatTimes[i] = wasm.beats[i].time;\n }\n return {\n bpm: wasm.bpm,\n bpmConfidence: wasm.bpmConfidence,\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n timeSignature: wasm.timeSignature,\n beatTimes,\n beats: wasm.beats,\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n confidence: c.confidence,\n name: c.name,\n })),\n sections: wasm.sections.map((s) => ({\n type: s.type as SectionType,\n start: s.start,\n end: s.end,\n energyLevel: s.energyLevel,\n confidence: s.confidence,\n name: s.name,\n })),\n timbre: wasm.timbre,\n dynamics: wasm.dynamics,\n rhythm: wasm.rhythm,\n melody: wasm.melody,\n form: wasm.form,\n };\n}\n","import {\n chordChromaMethodValue,\n convertAnalysisResult,\n convertChordAnalysisResult,\n convertKeyCandidate,\n keyModeValues,\n keyProfileValue,\n} from './analysis_helpers';\nimport { getSonareModule } from './module_state';\nimport type {\n AcousticOptions,\n AcousticResult,\n AnalysisResult,\n AnalyzeBpmOptions,\n AnalyzeDynamicsOptions,\n AnalyzeRhythmOptions,\n AnalyzeTimbreOptions,\n ChordAnalysisResult,\n ChordDetectionOptions,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomMorphOptions,\n} from './public_types';\nimport { Mode, PitchClass } from './public_types';\nimport type { ProgressCallback, WasmAcousticResult } from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport { assertNonNegativeInteger, assertSampleRate, assertSamples } from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\n\nfunction validateAnalysisInput(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\n// ============================================================================\n// Quick API (High-level Analysis)\n// ============================================================================\n\n/**\n * Detect BPM from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected BPM\n */\nexport function detectBpm(\n samples: Float32Array,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): number {\n validateAnalysisInput('detectBpm', samples, sampleRate, options);\n return requireModule().detectBpm(samples, sampleRate);\n}\n\n/**\n * Detect musical key from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected key\n */\nexport function detectKey(\n samples: Float32Array,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): Key {\n validateAnalysisInput('detectKey', samples, sampleRate, options);\n const result = requireModule()._detectKeyWithOptions(\n samples,\n sampleRate,\n options.nFft ?? 4096,\n options.hopLength ?? 512,\n options.useHpss ?? false,\n options.loudnessWeighted ?? false,\n options.highPassHz ?? 0,\n keyModeValues(options.modes),\n keyProfileValue(options.profile),\n options.genreHint ?? '',\n );\n return {\n root: result.root as PitchClass,\n mode: result.mode as Mode,\n confidence: result.confidence,\n name: result.name,\n shortName: result.shortName,\n };\n}\n\nexport function detectKeyCandidates(\n samples: Float32Array,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): KeyCandidate[] {\n validateAnalysisInput('detectKeyCandidates', samples, sampleRate, options);\n return requireModule()\n ._detectKeyCandidates(\n samples,\n sampleRate,\n options.nFft ?? 4096,\n options.hopLength ?? 512,\n options.useHpss ?? false,\n options.loudnessWeighted ?? false,\n options.highPassHz ?? 0,\n keyModeValues(options.modes),\n keyProfileValue(options.profile),\n options.genreHint ?? '',\n )\n .map(convertKeyCandidate);\n}\n\n/**\n * Detect onset times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of onset times in seconds\n */\nexport function detectOnsets(\n samples: Float32Array,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): Float32Array {\n validateAnalysisInput('detectOnsets', samples, sampleRate, options);\n return requireModule().detectOnsets(samples, sampleRate);\n}\n\n/**\n * Detect beat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of beat times in seconds\n */\nexport function detectBeats(\n samples: Float32Array,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): Float32Array {\n validateAnalysisInput('detectBeats', samples, sampleRate, options);\n return requireModule().detectBeats(samples, sampleRate);\n}\n\n/**\n * Detect downbeat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of downbeat times in seconds\n */\nexport function detectDownbeats(\n samples: Float32Array,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): Float32Array {\n validateAnalysisInput('detectDownbeats', samples, sampleRate, options);\n return requireModule().detectDownbeats(samples, sampleRate);\n}\n\n/**\n * Detect chords from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Optional chord detection settings\n * @returns Detected chord segments\n */\nexport function detectChords(\n samples: Float32Array,\n sampleRate = 22050,\n options: ChordDetectionOptions = {},\n): ChordAnalysisResult {\n validateAnalysisInput('detectChords', samples, sampleRate, options);\n const result = requireModule().detectChords(\n samples,\n sampleRate,\n options.minDuration ?? 0.3,\n options.smoothingWindow ?? 2.0,\n options.threshold ?? 0.5,\n options.useTriadsOnly ?? false,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.useBeatSync ?? true,\n options.useHmm ?? false,\n options.hmmBeamWidth ?? 24,\n options.useKeyContext ?? false,\n options.keyRoot ?? PitchClass.C,\n options.keyMode ?? Mode.Major,\n options.detectInversions ?? false,\n chordChromaMethodValue(options.chromaMethod ?? 'stft'),\n );\n return convertChordAnalysisResult(result);\n}\n\n/**\n * Functional (Roman-numeral) harmonic analysis of the detected chord\n * progression, relative to the given key. Mirrors the C-ABI\n * `sonare_chord_functional_analysis` and the Node/Python `chordFunctionalAnalysis`.\n *\n * @returns One Roman-numeral label (e.g. \"I\", \"IV\", \"V\", \"vi\") per detected chord\n */\nexport function chordFunctionalAnalysis(\n samples: Float32Array,\n keyRoot: PitchClass,\n keyMode: Mode,\n sampleRate = 22050,\n options: ChordDetectionOptions = {},\n): string[] {\n validateAnalysisInput('chordFunctionalAnalysis', samples, sampleRate, options);\n return requireModule().chordFunctionalAnalysis(\n samples,\n keyRoot,\n keyMode,\n sampleRate,\n options.minDuration ?? 0.3,\n options.smoothingWindow ?? 2.0,\n options.threshold ?? 0.5,\n options.useTriadsOnly ?? false,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.useBeatSync ?? true,\n options.useHmm ?? false,\n options.hmmBeamWidth ?? 24,\n options.useKeyContext ?? false,\n options.detectInversions ?? false,\n chordChromaMethodValue(options.chromaMethod ?? 'stft'),\n );\n}\n\n/**\n * Perform complete music analysis.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Complete analysis result\n *\n * @remarks\n * This call is synchronous and blocks until analysis completes. Unlike the\n * Node binding (which offers `analyzeAsync` on a libuv worker thread), the\n * WASM build runs on a single thread, so there is no non-blocking variant —\n * the DSP pipeline always runs to completion on the calling thread. To keep\n * the UI responsive for long inputs, drive this from a Web Worker and use\n * {@link analyzeWithProgress} to report progress.\n */\nexport function analyze(\n samples: Float32Array,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): AnalysisResult {\n validateAnalysisInput('analyze', samples, sampleRate, options);\n const result = requireModule().analyze(samples, sampleRate);\n return convertAnalysisResult(result);\n}\n\nexport function analyzeImpulseResponse(\n samples: Float32Array,\n sampleRate = 48000,\n nOctaveBands = 6,\n): AcousticResult {\n validateAnalysisInput('analyzeImpulseResponse', samples, sampleRate);\n const result: WasmAcousticResult = requireModule().analyzeImpulseResponse(\n samples,\n sampleRate,\n nOctaveBands,\n );\n return result;\n}\n\nexport function detectAcoustic(\n samples: Float32Array,\n sampleRate = 48000,\n options: AcousticOptions = {},\n): AcousticResult {\n validateAnalysisInput('detectAcoustic', samples, sampleRate);\n const result: WasmAcousticResult = requireModule().detectAcoustic(\n samples,\n sampleRate,\n options.nOctaveBands ?? 6,\n options.nThirdOctaveSubbands ?? 24,\n options.minDecayDb ?? 30.0,\n options.noiseFloorMarginDb ?? 10.0,\n );\n return result;\n}\n\n/**\n * Synthesize a room impulse response from shoebox geometry. `hasError` is true\n * when the source/listener falls outside the room (the RIR is then empty).\n */\nexport function synthesizeRir(options: RirSynthOptions = {}): RirResult {\n const module = requireModule();\n if (typeof module.synthesizeRir !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n return module.synthesizeRir(options);\n}\n\n/**\n * Estimate an equivalent room (volume/dimensions/absorption/DRR) from a\n * recording or impulse response.\n */\nexport function estimateRoom(\n samples: Float32Array,\n sampleRate = 48000,\n options: RoomEstimateOptions = {},\n): RoomEstimateResult {\n const module = requireModule();\n if (typeof module.estimateRoom !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n validateAnalysisInput('estimateRoom', samples, sampleRate);\n return module.estimateRoom(samples, sampleRate, options);\n}\n\n/**\n * Morph a recording's reverberation toward a target room (creative FX, not\n * dereverberation). Returns the morphed samples (input length plus the target\n * room's reverb tail).\n */\nexport function roomMorph(\n samples: Float32Array,\n sampleRate: number,\n options: RoomMorphOptions = {},\n): Float32Array {\n const module = requireModule();\n if (typeof module.roomMorph !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n validateAnalysisInput('roomMorph', samples, sampleRate);\n return module.roomMorph(samples, sampleRate, options);\n}\n\n/**\n * Perform complete music analysis with progress reporting.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Complete analysis result\n */\nexport function analyzeWithProgress(\n samples: Float32Array,\n sampleRate = 22050,\n onProgress: ProgressCallback,\n): AnalysisResult {\n validateAnalysisInput('analyzeWithProgress', samples, sampleRate);\n const result = requireModule().analyzeWithProgress(samples, sampleRate, onProgress);\n return convertAnalysisResult(result);\n}\n\nexport interface BpmCandidate {\n bpm: number;\n confidence: number;\n}\n\nexport interface BpmAnalysisResult {\n bpm: number;\n confidence: number;\n candidates: BpmCandidate[];\n autocorrelation: Float32Array;\n tempogram: Float32Array;\n}\n\nexport interface RhythmAnalysisResult {\n timeSignature: { numerator: number; denominator: number; confidence: number };\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n tempoStability: number;\n bpm: number;\n beatIntervals: Float32Array;\n}\n\nexport interface DynamicsAnalysisResult {\n dynamicRangeDb: number;\n peakDb: number;\n rmsDb: number;\n crestFactor: number;\n loudnessRangeDb: number;\n isCompressed: boolean;\n /** Loudness curve timestamps (seconds), parallel to {@link loudnessRmsDb}. */\n loudnessTimes: Float32Array;\n /** Loudness curve RMS values (dB), parallel to {@link loudnessTimes}. */\n loudnessRmsDb: Float32Array;\n}\n\n/** Timbre metrics for one analysis window. Entries are ordered by time in `timbreOverTime`. */\nexport interface TimbreFrame {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\nexport interface TimbreAnalysisResult extends TimbreFrame {\n spectralCentroid: Float32Array;\n spectralFlatness: Float32Array;\n spectralRolloff: Float32Array;\n /** Time-varying timbre metrics, one entry per analysis window. */\n timbreOverTime: TimbreFrame[];\n}\n\n/**\n * Detailed BPM analysis (BPM, confidence, alternate candidates, autocorrelation,\n * tempogram). Matches the Node `analyzeBpm` / Python `analyze_bpm` surface.\n */\nexport function analyzeBpm(\n samples: Float32Array,\n sampleRate = 22050,\n options: AnalyzeBpmOptions = {},\n): BpmAnalysisResult {\n validateAnalysisInput('analyzeBpm', samples, sampleRate, options);\n assertNonNegativeInteger('analyzeBpm', options.maxCandidates ?? 5, 'maxCandidates');\n return requireModule().analyzeBpm(\n samples,\n sampleRate,\n options.bpmMin ?? 30.0,\n options.bpmMax ?? 300.0,\n options.startBpm ?? 120.0,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.maxCandidates ?? 5,\n );\n}\n\n/**\n * Detailed rhythm analysis (time signature, groove, syncopation, beat intervals).\n */\nexport function analyzeRhythm(\n samples: Float32Array,\n sampleRate = 22050,\n options: AnalyzeRhythmOptions = {},\n): RhythmAnalysisResult {\n validateAnalysisInput('analyzeRhythm', samples, sampleRate, options);\n return requireModule().analyzeRhythm(\n samples,\n sampleRate,\n options.bpmMin ?? 60.0,\n options.bpmMax ?? 200.0,\n options.startBpm ?? 120.0,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n );\n}\n\n/**\n * Dynamics analysis (RMS, peak, crest factor, LRA, loudness curve).\n */\nexport function analyzeDynamics(\n samples: Float32Array,\n sampleRate = 22050,\n options: AnalyzeDynamicsOptions = {},\n): DynamicsAnalysisResult {\n validateAnalysisInput('analyzeDynamics', samples, sampleRate, options);\n return requireModule().analyzeDynamics(\n samples,\n sampleRate,\n options.windowSec ?? 0.4,\n options.hopLength ?? 512,\n options.compressionThreshold ?? 6.0,\n );\n}\n\n/**\n * Timbre analysis (brightness/warmth/density/roughness/complexity plus spectral\n * features and per-window timbre frames).\n */\nexport function analyzeTimbre(\n samples: Float32Array,\n sampleRate = 22050,\n options: AnalyzeTimbreOptions = {},\n): TimbreAnalysisResult {\n validateAnalysisInput('analyzeTimbre', samples, sampleRate, options);\n return requireModule().analyzeTimbre(\n samples,\n sampleRate,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.nMels ?? 128,\n options.nMfcc ?? 13,\n options.windowSec ?? 0.5,\n );\n}\n\n/**\n * Whether this WASM build was compiled with FFmpeg support. Mirrors Node /\n * Python `hasFfmpegSupport`. In the published WASM binding this currently\n * always returns `false` (FFmpeg is not bundled into the .wasm), but the API\n * exists so caller code can branch on capabilities portably.\n */\nexport function hasFfmpegSupport(): boolean {\n return requireModule().hasFfmpegSupport();\n}\n","import type { VoiceChangeOptions } from './effects_mastering';\nimport {\n harmonic,\n hpss,\n masterAudio,\n mastering,\n masteringChain,\n masteringProcess,\n normalize,\n noteStretch,\n percussive,\n pitchCorrectToMidi,\n pitchShift,\n timeStretch,\n voiceChange,\n} from './effects_mastering';\nimport {\n chroma,\n lufs,\n melSpectrogram,\n mfcc,\n momentaryLufs,\n nnlsChroma,\n onsetEnvelope,\n pitchPyin,\n pitchYin,\n resample,\n rmsEnergy,\n shortTermLufs,\n spectralBandwidth,\n spectralCentroid,\n spectralFlatness,\n spectralRolloff,\n stft,\n stftDb,\n trim,\n zeroCrossingRate,\n} from './features';\nimport { getSonareModule } from './module_state';\nimport type {\n AnalysisResult,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChromaResult,\n HpssResult,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n LufsResult,\n MasteringChainConfig,\n MasteringChainResult,\n MasteringOptions,\n MasteringPreset,\n MasteringProcessorParams,\n MasteringResult,\n MelSpectrogramResult,\n MfccResult,\n Mode,\n NoteStretchOptions,\n PitchClass,\n PitchResult,\n SoloProcessor,\n StftResult,\n} from './public_types';\nimport {\n analyze,\n analyzeWithProgress,\n chordFunctionalAnalysis,\n detectBeats,\n detectBpm,\n detectChords,\n detectDownbeats,\n detectKey,\n detectKeyCandidates,\n detectOnsets,\n} from './quick_analysis';\nimport type { ProgressCallback, WasmNnlsChromaResult } from './sonare.js';\n\n// ============================================================================\n// Audio Class\n// ============================================================================\n\ntype BrowserDecodeContext = Pick<BaseAudioContext, 'decodeAudioData' | 'sampleRate'>;\n\nexport interface BrowserAudioDecodeOptions {\n /**\n * AudioContext/OfflineAudioContext used for browser codec fallback. Its\n * `sampleRate` becomes the returned Audio sample rate.\n */\n audioContext?: BrowserDecodeContext;\n /**\n * Factory used when `audioContext` is omitted. `targetSampleRate` is passed\n * through so browsers that honor AudioContextOptions decode directly at that\n * rate.\n */\n createAudioContext?: (options?: AudioContextOptions) => BrowserDecodeContext;\n /**\n * Requested fallback decode rate when this helper creates the context. If the\n * browser ignores it or a context is supplied, no extra resampling is applied.\n */\n targetSampleRate?: number;\n}\n\nfunction encodedBytesToArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\nfunction getBrowserAudioContextFactory():\n | ((options?: AudioContextOptions) => BrowserDecodeContext)\n | undefined {\n const root = globalThis as typeof globalThis & {\n AudioContext?: new (options?: AudioContextOptions) => BaseAudioContext;\n webkitAudioContext?: new (options?: AudioContextOptions) => BaseAudioContext;\n };\n const Ctor = root.AudioContext ?? root.webkitAudioContext;\n return Ctor ? (options?: AudioContextOptions) => new Ctor(options) : undefined;\n}\n\nfunction audioBufferToMono(buffer: AudioBuffer): Float32Array {\n const samples = new Float32Array(buffer.length);\n if (buffer.numberOfChannels <= 0) {\n return samples;\n }\n if (buffer.numberOfChannels === 1) {\n samples.set(buffer.getChannelData(0));\n return samples;\n }\n for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n const data = buffer.getChannelData(channel);\n for (let i = 0; i < buffer.length; i++) {\n samples[i] += data[i] / buffer.numberOfChannels;\n }\n }\n return samples;\n}\n\nasync function closeCreatedContext(context: BrowserDecodeContext): Promise<void> {\n const maybeClosable = context as BrowserDecodeContext & { close?: () => Promise<void> };\n if (maybeClosable.close) {\n await maybeClosable.close();\n }\n}\n\n/**\n * Wrapper around audio data that exposes all analysis and feature functions as instance methods.\n *\n * @example\n * ```typescript\n * import { init, Audio } from '@libraz/libsonare';\n *\n * await init();\n *\n * const audio = Audio.fromBuffer(samples, 44100);\n * console.log('BPM:', audio.detectBpm());\n * console.log('Key:', audio.detectKey().name);\n *\n * const mel = audio.melSpectrogram();\n * ```\n */\nexport class Audio {\n private _samples: Float32Array;\n private _sampleRate: number;\n\n private constructor(samples: Float32Array, sampleRate: number) {\n this._samples = samples;\n this._sampleRate = sampleRate;\n }\n\n /**\n * Create an Audio instance from raw sample data.\n *\n * @param samples - Mono float samples.\n * @param sampleRate - Sample rate in Hz (default `48000`, matching the\n * Node/Python surfaces).\n */\n static fromBuffer(samples: Float32Array, sampleRate = 48000): Audio {\n return new Audio(samples, sampleRate);\n }\n\n /**\n * Create an Audio instance by decoding audio bytes in memory.\n *\n * @param bytes - Encoded audio bytes such as WAV or MP3.\n */\n static fromMemory(bytes: Uint8Array): Audio {\n const decoded = getSonareModule().audioFromMemory(bytes);\n return new Audio(decoded.samples, decoded.sampleRate);\n }\n\n /**\n * Decode audio bytes with the native WASM decoder first, then fall back to the\n * browser codec stack (`AudioContext.decodeAudioData`) for formats such as\n * AAC, OGG, and FLAC when available. Browser-decoded multi-channel audio is\n * mixed down to mono to match the `Audio` wrapper contract.\n */\n static async fromMemoryWithBrowserFallback(\n bytes: Uint8Array,\n options: BrowserAudioDecodeOptions = {},\n ): Promise<Audio> {\n try {\n return Audio.fromMemory(bytes);\n } catch (nativeError) {\n let createdContext = false;\n const contextFactory = options.createAudioContext ?? getBrowserAudioContextFactory();\n const context =\n options.audioContext ??\n contextFactory?.(\n options.targetSampleRate ? { sampleRate: options.targetSampleRate } : undefined,\n );\n\n if (!context) {\n throw new Error(\n `Audio.fromMemory failed and browser decodeAudioData is unavailable: ${\n nativeError instanceof Error ? nativeError.message : String(nativeError)\n }`,\n );\n }\n\n createdContext = !options.audioContext;\n try {\n const decoded = await context.decodeAudioData(encodedBytesToArrayBuffer(bytes));\n return new Audio(audioBufferToMono(decoded), decoded.sampleRate || context.sampleRate);\n } catch (fallbackError) {\n throw new Error(\n `Audio.fromMemory failed and browser decodeAudioData fallback failed: ${\n fallbackError instanceof Error ? fallbackError.message : String(fallbackError)\n }`,\n );\n } finally {\n if (createdContext) {\n await closeCreatedContext(context);\n }\n }\n }\n }\n\n /** The raw audio samples. */\n get data(): Float32Array {\n return this._samples;\n }\n\n /** Number of samples. */\n get length(): number {\n return this._samples.length;\n }\n\n /** Sample rate in Hz. */\n get sampleRate(): number {\n return this._sampleRate;\n }\n\n /** Duration in seconds. */\n get duration(): number {\n return this._samples.length / this._sampleRate;\n }\n\n // -- Analysis --\n\n detectBpm(): number {\n return detectBpm(this._samples, this._sampleRate);\n }\n\n detectKey(options: KeyDetectionOptions = {}): Key {\n return detectKey(this._samples, this._sampleRate, options);\n }\n\n detectKeyCandidates(options: KeyDetectionOptions = {}): KeyCandidate[] {\n return detectKeyCandidates(this._samples, this._sampleRate, options);\n }\n\n detectOnsets(): Float32Array {\n return detectOnsets(this._samples, this._sampleRate);\n }\n\n detectBeats(): Float32Array {\n return detectBeats(this._samples, this._sampleRate);\n }\n\n detectDownbeats(): Float32Array {\n return detectDownbeats(this._samples, this._sampleRate);\n }\n\n detectChords(options: ChordDetectionOptions = {}): ChordAnalysisResult {\n return detectChords(this._samples, this._sampleRate, options);\n }\n\n chordFunctionalAnalysis(\n keyRoot: PitchClass,\n keyMode: Mode,\n options: ChordDetectionOptions = {},\n ): string[] {\n return chordFunctionalAnalysis(this._samples, keyRoot, keyMode, this._sampleRate, options);\n }\n\n analyze(): AnalysisResult {\n return analyze(this._samples, this._sampleRate);\n }\n\n analyzeWithProgress(onProgress: ProgressCallback): AnalysisResult {\n return analyzeWithProgress(this._samples, this._sampleRate, onProgress);\n }\n\n // -- Effects --\n\n hpss(kernelHarmonic = 31, kernelPercussive = 31): HpssResult {\n return hpss(this._samples, this._sampleRate, kernelHarmonic, kernelPercussive);\n }\n\n harmonic(): Float32Array {\n return harmonic(this._samples, this._sampleRate);\n }\n\n percussive(): Float32Array {\n return percussive(this._samples, this._sampleRate);\n }\n\n timeStretch(rate: number): Float32Array {\n return timeStretch(this._samples, this._sampleRate, rate);\n }\n\n pitchShift(semitones: number): Float32Array {\n return pitchShift(this._samples, this._sampleRate, semitones);\n }\n\n pitchCorrectToMidi(currentMidi = 69.0, targetMidi = 69.0): Float32Array {\n return pitchCorrectToMidi(this._samples, this._sampleRate, currentMidi, targetMidi);\n }\n\n noteStretch(options: NoteStretchOptions = {}): Float32Array {\n return noteStretch(this._samples, this._sampleRate, options);\n }\n\n voiceChange(options: VoiceChangeOptions = {}): Float32Array {\n return voiceChange(this._samples, this._sampleRate, options);\n }\n\n normalize(targetDb = 0.0): Float32Array {\n return normalize(this._samples, this._sampleRate, targetDb);\n }\n\n mastering(options: MasteringOptions = {}): MasteringResult {\n return mastering(this._samples, this._sampleRate, options);\n }\n\n masteringChain(config: MasteringChainConfig): MasteringChainResult {\n return masteringChain(this._samples, this._sampleRate, config);\n }\n\n masterAudio(\n presetName: MasteringPreset = 'pop',\n overrides: Record<string, number | boolean> | null = null,\n ): MasteringChainResult {\n return masterAudio(this._samples, this._sampleRate, presetName, overrides ?? {});\n }\n\n masteringProcess(\n processorName: SoloProcessor,\n params: MasteringProcessorParams = {},\n ): MasteringResult {\n return masteringProcess(processorName, this._samples, this._sampleRate, params);\n }\n\n trim(thresholdDb = -60.0): Float32Array {\n return trim(this._samples, this._sampleRate, thresholdDb);\n }\n\n // -- Features --\n\n stft(nFft = 2048, hopLength = 512): StftResult {\n return stft(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n stftDb(nFft = 2048, hopLength = 512): { nBins: number; nFrames: number; db: Float32Array } {\n return stftDb(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n melSpectrogram(\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n fmin = 0,\n fmax = 0,\n htk = false,\n ): MelSpectrogramResult {\n return melSpectrogram(this._samples, this._sampleRate, nFft, hopLength, nMels, fmin, fmax, htk);\n }\n\n mfcc(\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nMfcc = 20,\n fmin = 0,\n fmax = 0,\n htk = false,\n ): MfccResult {\n return mfcc(this._samples, this._sampleRate, nFft, hopLength, nMels, nMfcc, fmin, fmax, htk);\n }\n\n chroma(nFft = 2048, hopLength = 512): ChromaResult {\n return chroma(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n nnlsChroma(): WasmNnlsChromaResult {\n return nnlsChroma(this._samples, this._sampleRate);\n }\n\n onsetEnvelope(nFft = 2048, hopLength = 512, nMels = 128): Float32Array {\n return onsetEnvelope(this._samples, this._sampleRate, nFft, hopLength, nMels);\n }\n\n lufs(): LufsResult {\n return lufs(this._samples, this._sampleRate);\n }\n\n momentaryLufs(): Float32Array {\n return momentaryLufs(this._samples, this._sampleRate);\n }\n\n shortTermLufs(): Float32Array {\n return shortTermLufs(this._samples, this._sampleRate);\n }\n\n spectralCentroid(nFft = 2048, hopLength = 512): Float32Array {\n return spectralCentroid(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n spectralBandwidth(nFft = 2048, hopLength = 512): Float32Array {\n return spectralBandwidth(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n spectralRolloff(nFft = 2048, hopLength = 512, rollPercent = 0.85): Float32Array {\n return spectralRolloff(this._samples, this._sampleRate, nFft, hopLength, rollPercent);\n }\n\n spectralFlatness(nFft = 2048, hopLength = 512): Float32Array {\n return spectralFlatness(this._samples, this._sampleRate, nFft, hopLength);\n }\n\n zeroCrossingRate(frameLength = 2048, hopLength = 512): Float32Array {\n return zeroCrossingRate(this._samples, this._sampleRate, frameLength, hopLength);\n }\n\n rmsEnergy(frameLength = 2048, hopLength = 512): Float32Array {\n return rmsEnergy(this._samples, this._sampleRate, frameLength, hopLength);\n }\n\n pitchYin(\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n ): PitchResult {\n return pitchYin(\n this._samples,\n this._sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n }\n\n pitchPyin(\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.3,\n fillNa = false,\n ): PitchResult {\n return pitchPyin(\n this._samples,\n this._sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n }\n\n resample(targetSr: number): Float32Array {\n return resample(this._samples, this._sampleRate, targetSr);\n }\n}\n","import type { SonareRealtimeEngineNode } from './worklet';\n\nexport interface BindMicrophoneInputOptions extends MediaStreamConstraints {\n stream?: MediaStream;\n stopTracksOnClose?: boolean;\n}\n\nexport interface MicrophoneInputBinding {\n stream: MediaStream;\n source: MediaStreamAudioSourceNode;\n close(): void;\n}\n\nexport async function bindMicrophoneInput(\n context: AudioContext,\n engine: SonareRealtimeEngineNode | AudioWorkletNode,\n options: BindMicrophoneInputOptions = {},\n): Promise<MicrophoneInputBinding> {\n const stream =\n options.stream ??\n (await navigator.mediaDevices.getUserMedia({\n audio: options.audio ?? true,\n video: false,\n }));\n const source = context.createMediaStreamSource(stream);\n const node = 'node' in engine ? engine.node : engine;\n source.connect(node);\n let closed = false;\n return {\n stream,\n source,\n close() {\n if (closed) {\n return;\n }\n closed = true;\n source.disconnect();\n if (options.stopTracksOnClose !== false) {\n for (const track of stream.getAudioTracks()) {\n track.stop();\n }\n }\n },\n };\n}\n","import { getSonareModule } from './module_state';\nimport type { ValidateOptions } from './validation';\nimport { assertSamples } from './validation';\n\n// ============================================================================\n// Metering — basic / true-peak / clipping / dynamic range\n// ============================================================================\n\n/** One contiguous run of clipped samples reported by `meteringDetectClipping`. */\nexport interface ClippingRegion {\n startSample: number;\n endSample: number;\n length: number;\n peak: number;\n}\n\n/** Aggregated clipping report. */\nexport interface ClippingReport {\n clippedSamples: number;\n clippingRatio: number;\n maxClippedPeak: number;\n regions: ClippingRegion[];\n}\n\n/** Sliding-window dynamic range report. */\nexport interface DynamicRangeReport {\n dynamicRangeDb: number;\n lowPercentileDb: number;\n highPercentileDb: number;\n windowRmsDb: Float32Array;\n}\n\n/** Options for {@link meteringDetectClipping}. All fields are optional. */\nexport interface MeteringDetectClippingOptions extends ValidateOptions {\n /** Linear absolute threshold. Default 0.999. */\n threshold?: number;\n /** Minimum run length to report. Default 1. */\n minRegionSamples?: number;\n}\n\n/** Options for {@link meteringDynamicRange}. All fields are optional. */\nexport interface MeteringDynamicRangeOptions extends ValidateOptions {\n /** Window length in seconds (0 = library default, 3 s). Default 0. */\n windowSec?: number;\n /** Hop length in seconds (0 = library default, 1 s). Default 0. */\n hopSec?: number;\n /** Low percentile in [0,1] (negative = library default, 0.10). Default -1. */\n lowPercentile?: number;\n /** High percentile in [0,1] (negative = library default, 0.95). Default -1. */\n highPercentile?: number;\n}\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nexport function meteringPeakDb(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringPeakDb', samples, options.validate !== false);\n return requireModule().meteringPeakDb(samples, sampleRate);\n}\n\nexport function meteringRmsDb(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringRmsDb', samples, options.validate !== false);\n return requireModule().meteringRmsDb(samples, sampleRate);\n}\n\nexport function meteringCrestFactorDb(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringCrestFactorDb', samples, options.validate !== false);\n return requireModule().meteringCrestFactorDb(samples, sampleRate);\n}\n\nexport function meteringDcOffset(\n samples: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringDcOffset', samples, options.validate !== false);\n return requireModule().meteringDcOffset(samples, sampleRate);\n}\n\n/**\n * Inter-sample (true) peak in dBFS. `oversampleFactor` must be a power of two\n * in [1, 16]; pass 0 to use the library default (4).\n */\nexport function meteringTruePeakDb(\n samples: Float32Array,\n sampleRate = 22050,\n oversampleFactor = 4,\n options: ValidateOptions = {},\n): number {\n assertSamples('meteringTruePeakDb', samples, options.validate !== false);\n const factor = oversampleFactor === 0 ? 4 : oversampleFactor;\n if (factor < 1 || factor > 16 || (factor & (factor - 1)) !== 0) {\n throw new RangeError(\n 'meteringTruePeakDb: oversampleFactor must be 0 or a power of two from 1 to 16',\n );\n }\n return requireModule().meteringTruePeakDb(samples, sampleRate, oversampleFactor);\n}\n\n/**\n * Detect contiguous runs of clipped samples.\n *\n * @param threshold Linear absolute threshold (default 0.999).\n * @param minRegionSamples Minimum run length to report (default 1).\n */\nexport function meteringDetectClipping(\n samples: Float32Array,\n sampleRate = 22050,\n options: MeteringDetectClippingOptions = {},\n): ClippingReport {\n assertSamples('meteringDetectClipping', samples, options.validate !== false);\n return requireModule().meteringDetectClipping(\n samples,\n sampleRate,\n options.threshold ?? 0.999,\n options.minRegionSamples ?? 1,\n );\n}\n\n/**\n * Sliding-window dynamic range. Pass 0 for window/hop to use the library\n * default (window=3 s, hop=1 s). The percentiles use a NEGATIVE sentinel for\n * \"use the library default\" (low=0.10, high=0.95) because 0 is a literal 0th\n * percentile; omitted percentiles therefore default to -1.\n */\nexport function meteringDynamicRange(\n samples: Float32Array,\n sampleRate = 22050,\n options: MeteringDynamicRangeOptions = {},\n): DynamicRangeReport {\n assertSamples('meteringDynamicRange', samples, options.validate !== false);\n return requireModule().meteringDynamicRange(\n samples,\n sampleRate,\n options.windowSec ?? 0,\n options.hopSec ?? 0,\n options.lowPercentile ?? -1,\n options.highPercentile ?? -1,\n );\n}\n\n// ============================================================================\n// Metering — stereo / phase-scope / spectrum\n// ============================================================================\n\n/** Mid/side vectorscope point series for a (left, right) stereo pair. */\nexport interface VectorscopeReport {\n mid: Float32Array;\n side: Float32Array;\n}\n\n/** Phase-scope (Lissajous) point series plus summary stats. */\nexport interface PhaseScopeReport {\n mid: Float32Array;\n side: Float32Array;\n radius: Float32Array;\n angleRad: Float32Array;\n correlation: number;\n averageAbsAngleRad: number;\n maxRadius: number;\n}\n\n/** Options for `meteringSpectrum`. */\nexport interface SpectrumOptions {\n /** FFT size. Pass 0 / omit for the library default (2048). */\n nFft?: number;\n /** Apply fractional-octave smoothing to magnitude. */\n applyOctaveSmoothing?: boolean;\n /** Smoothing fraction (e.g. 3 = 1/3-octave). 0 / omit = library default (3). */\n octaveFraction?: number;\n /** Linear reference for the dB conversion. 0 / omit = 1.0. */\n dbRef?: number;\n /** Linear floor used to avoid log(0). 0 / omit = library default. */\n dbAmin?: number;\n}\n\n/** Single-frame magnitude / power / dB spectrum returned by `meteringSpectrum`. */\nexport interface SpectrumReport {\n frequencies: Float32Array;\n magnitude: Float32Array;\n power: Float32Array;\n db: Float32Array;\n nFft: number;\n sampleRate: number;\n}\n\n/** Options for {@link waveformPeaks}. All fields are optional. */\nexport interface WaveformPeaksOptions extends ValidateOptions {\n /** Bucket width in frames. Default 512. */\n samplesPerBucket?: number;\n}\n\n/** Options for {@link waveformPeakPyramid}. All fields are optional. */\nexport interface WaveformPeakPyramidOptions extends ValidateOptions {\n /** Bucket widths in frames, one per zoom level. Default [512, 1024, 2048, 4096]. */\n samplesPerBucketLevels?: number[];\n}\n\n/** Per-channel min/max waveform buckets. Arrays are channel-major. */\nexport interface WaveformPeaksReport {\n min: Float32Array;\n max: Float32Array;\n channels: number;\n bucketCount: number;\n samplesPerBucket: number;\n}\n\n/** Pearson correlation in [-1, 1] between two equal-length channels. */\nexport function meteringStereoCorrelation(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const validate = options.validate !== false;\n assertSamples('meteringStereoCorrelation', left, validate, 'left');\n assertSamples('meteringStereoCorrelation', right, validate, 'right');\n return requireModule().meteringStereoCorrelation(left, right, sampleRate);\n}\n\n/**\n * Side / mid energy ratio, clamped to `[0, 2]`: 0 = pure mono, ~1 = wide\n * stereo, 2 = fully decorrelated / out-of-phase.\n */\nexport function meteringStereoWidth(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const validate = options.validate !== false;\n assertSamples('meteringStereoWidth', left, validate, 'left');\n assertSamples('meteringStereoWidth', right, validate, 'right');\n return requireModule().meteringStereoWidth(left, right, sampleRate);\n}\n\n/** Per-sample mid/side point series (one entry per input frame). */\nexport function meteringVectorscope(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): VectorscopeReport {\n const validate = options.validate !== false;\n assertSamples('meteringVectorscope', left, validate, 'left');\n assertSamples('meteringVectorscope', right, validate, 'right');\n return requireModule().meteringVectorscope(left, right, sampleRate);\n}\n\n/**\n * Display-sized mid/side vectorscope. Like {@link meteringVectorscope} but the\n * point series is deterministically decimated to at most `maxPoints` points\n * (`0`, or a value `>= length`, yields one point per input sample). Mirrors the\n * Node/Python decimated vectorscope.\n */\nexport function meteringVectorscopeDecimated(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n maxPoints = 0,\n options: ValidateOptions = {},\n): VectorscopeReport {\n const validate = options.validate !== false;\n assertSamples('meteringVectorscopeDecimated', left, validate, 'left');\n assertSamples('meteringVectorscopeDecimated', right, validate, 'right');\n return requireModule().meteringVectorscopeDecimated(left, right, sampleRate, maxPoints);\n}\n\n/** Phase-scope point series plus summary stats. */\nexport function meteringPhaseScope(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): PhaseScopeReport {\n const validate = options.validate !== false;\n assertSamples('meteringPhaseScope', left, validate, 'left');\n assertSamples('meteringPhaseScope', right, validate, 'right');\n return requireModule().meteringPhaseScope(left, right, sampleRate);\n}\n\n/**\n * Display-sized phase scope. Like {@link meteringPhaseScope} but the point\n * series is deterministically decimated to at most `maxPoints` points (`0`, or\n * a value `>= length`, yields one point per input sample). The summary stats are\n * always computed over the full-resolution signal. Mirrors the Node/Python\n * decimated phase scope.\n */\nexport function meteringPhaseScopeDecimated(\n left: Float32Array,\n right: Float32Array,\n sampleRate = 22050,\n maxPoints = 0,\n options: ValidateOptions = {},\n): PhaseScopeReport {\n const validate = options.validate !== false;\n assertSamples('meteringPhaseScopeDecimated', left, validate, 'left');\n assertSamples('meteringPhaseScopeDecimated', right, validate, 'right');\n return requireModule().meteringPhaseScopeDecimated(left, right, sampleRate, maxPoints);\n}\n\n/**\n * Welch-averaged magnitude / power / dB spectrum over the WHOLE signal (split\n * into Hann-windowed, 50%-overlapping `nFft`-length frames whose power spectra\n * are averaged). For a true single-frame snapshot, use\n * {@link meteringSpectrumFrame}.\n */\nexport function meteringSpectrum(\n samples: Float32Array,\n sampleRate = 22050,\n options?: SpectrumOptions & ValidateOptions,\n): SpectrumReport {\n const validate = options?.validate !== false;\n assertSamples('meteringSpectrum', samples, validate);\n return requireModule().meteringSpectrum(samples, sampleRate, options ?? {});\n}\n\n/**\n * True single-frame magnitude / power / dB spectrum (one Hann-windowed\n * `nFft`-length FFT), for spectrum-analyzer \"moment\" snapshots that must not be\n * time-averaged like {@link meteringSpectrum}. The analysis frame spans\n * `[frameOffset, frameOffset + nFft)`; samples past the end are zero-padded.\n */\nexport function meteringSpectrumFrame(\n samples: Float32Array,\n sampleRate = 22050,\n frameOffset = 0,\n options?: SpectrumOptions & ValidateOptions,\n): SpectrumReport {\n const validate = options?.validate !== false;\n assertSamples('meteringSpectrumFrame', samples, validate);\n return requireModule().meteringSpectrumFrame(samples, sampleRate, frameOffset, options ?? {});\n}\n\n/** Compute per-channel min/max waveform buckets from interleaved audio. */\nexport function waveformPeaks(\n samples: Float32Array,\n channels: number,\n options: WaveformPeaksOptions = {},\n): WaveformPeaksReport {\n assertSamples('waveformPeaks', samples, options.validate !== false);\n if (channels <= 0 || samples.length % channels !== 0) {\n throw new RangeError('waveformPeaks: samples length must be a multiple of channels');\n }\n const samplesPerBucket = options.samplesPerBucket ?? 512;\n if (samplesPerBucket <= 0) {\n throw new RangeError('waveformPeaks: samplesPerBucket must be > 0');\n }\n return requireModule().waveformPeaks(samples, channels, samplesPerBucket);\n}\n\n/** Compute waveform peak buckets for several zoom levels. */\nexport function waveformPeakPyramid(\n samples: Float32Array,\n channels: number,\n options: WaveformPeakPyramidOptions = {},\n): WaveformPeaksReport[] {\n assertSamples('waveformPeakPyramid', samples, options.validate !== false);\n if (channels <= 0 || samples.length % channels !== 0) {\n throw new RangeError('waveformPeakPyramid: samples length must be a multiple of channels');\n }\n const levels = options.samplesPerBucketLevels ?? [512, 1024, 2048, 4096];\n if (levels.length === 0 || levels.some((level) => level <= 0)) {\n throw new RangeError('waveformPeakPyramid: samplesPerBucketLevels must be non-empty and > 0');\n }\n return requireModule().waveformPeakPyramid(samples, channels, levels);\n}\n","import type { ClipPageProvider, ClipPageRequest, RealtimeEngine } from './realtime_engine';\n\nexport interface OpfsClipPageProviderOptions {\n path: string;\n numChannels: number;\n numSamples: number;\n pageFrames: number;\n dataOffsetBytes?: number;\n worker?: Worker;\n terminateWorkerOnClose?: boolean;\n}\n\nexport interface OpfsClipPageProviderBinding {\n provider: ClipPageProvider;\n supplyPage(pageIndex: number): Promise<boolean>;\n supplyRequest(request: ClipPageRequest): Promise<boolean>;\n close(): void;\n}\n\ninterface PageResponse {\n type: 'sonare:clip-page';\n requestId: number;\n pageIndex: number;\n ok: boolean;\n frames?: number;\n channels?: Float32Array[];\n channelBuffers?: ArrayBufferLike[];\n error?: string;\n}\n\nexport const opfsClipPageWorkerSource = `\nself.onmessage = async (event) => {\n const message = event.data;\n if (!message || message.type !== 'sonare:read-clip-page') return;\n const { requestId, path, pageIndex, numChannels, numSamples, pageFrames, dataOffsetBytes = 0 } = message;\n try {\n if (pageIndex < 0) {\n self.postMessage({ type: 'sonare:clip-page', requestId, pageIndex, ok: false });\n return;\n }\n const startFrame = pageIndex * pageFrames;\n if (startFrame >= numSamples) {\n self.postMessage({ type: 'sonare:clip-page', requestId, pageIndex, ok: false });\n return;\n }\n const root = await self.navigator.storage.getDirectory();\n let dir = root;\n const parts = String(path).split('/').filter(Boolean);\n for (let i = 0; i < parts.length - 1; ++i) {\n dir = await dir.getDirectoryHandle(parts[i]);\n }\n const fileHandle = await dir.getFileHandle(parts[parts.length - 1]);\n const access = await fileHandle.createSyncAccessHandle();\n try {\n const frames = Math.min(pageFrames, numSamples - startFrame);\n const frameBytes = numChannels * 4;\n const bytes = new Uint8Array(frames * frameBytes);\n const bytesRead = access.read(bytes, { at: dataOffsetBytes + startFrame * frameBytes });\n const framesRead = Math.floor(bytesRead / frameBytes);\n if (framesRead <= 0) {\n self.postMessage({ type: 'sonare:clip-page', requestId, pageIndex, ok: false });\n return;\n }\n const view = new DataView(bytes.buffer, 0, framesRead * frameBytes);\n const channelBuffers = Array.from({ length: numChannels }, () => new ArrayBuffer(framesRead * 4));\n for (let ch = 0; ch < numChannels; ++ch) {\n const channel = new Float32Array(channelBuffers[ch]);\n for (let frame = 0; frame < framesRead; ++frame) {\n channel[frame] = view.getFloat32((frame * numChannels + ch) * 4, true);\n }\n }\n self.postMessage(\n { type: 'sonare:clip-page', requestId, pageIndex, ok: true, frames: framesRead, channelBuffers },\n channelBuffers,\n );\n } finally {\n access.close();\n }\n } catch (error) {\n self.postMessage({\n type: 'sonare:clip-page',\n requestId,\n pageIndex,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n};\n`;\n\nexport function createOpfsClipPageWorker(): Worker {\n const blob = new Blob([opfsClipPageWorkerSource], { type: 'text/javascript' });\n return new Worker(URL.createObjectURL(blob));\n}\n\nexport function createOpfsClipPageProvider(\n engine: RealtimeEngine,\n options: OpfsClipPageProviderOptions,\n): OpfsClipPageProviderBinding {\n if (options.numChannels <= 0 || options.numSamples <= 0 || options.pageFrames <= 0) {\n throw new Error('numChannels, numSamples, and pageFrames must be positive');\n }\n const provider = engine.createClipPageProvider(\n options.numChannels,\n options.numSamples,\n options.pageFrames,\n );\n const worker = options.worker ?? createOpfsClipPageWorker();\n const ownsWorker = options.worker === undefined || options.terminateWorkerOnClose === true;\n let nextRequestId = 1;\n let closed = false;\n const pending = new Map<\n number,\n { resolve: (value: boolean) => void; reject: (reason: unknown) => void }\n >();\n\n const onMessage = (event: MessageEvent<PageResponse>) => {\n const response = event.data;\n if (response?.type !== 'sonare:clip-page') {\n return;\n }\n const entry = pending.get(response.requestId);\n if (!entry) {\n return;\n }\n pending.delete(response.requestId);\n if (!response.ok) {\n entry.resolve(false);\n return;\n }\n const channels =\n response.channels ??\n response.channelBuffers?.map(\n (buffer) => new Float32Array(buffer, 0, response.frames ?? buffer.byteLength / 4),\n );\n if (!channels || channels.length === 0) {\n entry.resolve(false);\n return;\n }\n provider.supply(response.pageIndex, channels);\n entry.resolve(true);\n };\n worker.addEventListener('message', onMessage as EventListener);\n\n const supplyPage = (pageIndex: number): Promise<boolean> => {\n if (closed) {\n return Promise.reject(new Error('OpfsClipPageProvider is closed'));\n }\n const requestId = nextRequestId++;\n const promise = new Promise<boolean>((resolve, reject) => {\n pending.set(requestId, { resolve, reject });\n });\n worker.postMessage({\n type: 'sonare:read-clip-page',\n requestId,\n path: options.path,\n pageIndex,\n numChannels: options.numChannels,\n numSamples: options.numSamples,\n pageFrames: options.pageFrames,\n dataOffsetBytes: options.dataOffsetBytes ?? 0,\n });\n return promise;\n };\n\n return {\n provider,\n supplyPage,\n supplyRequest(request: ClipPageRequest) {\n return supplyPage(Math.floor(request.sample / options.pageFrames));\n },\n close() {\n if (closed) {\n return;\n }\n closed = true;\n worker.removeEventListener('message', onMessage as EventListener);\n for (const entry of pending.values()) {\n entry.reject(new Error('OpfsClipPageProvider is closed'));\n }\n pending.clear();\n provider.destroy();\n if (ownsWorker) {\n worker.terminate();\n }\n },\n };\n}\n","import { getSonareModule } from './module_state';\n\n// ============================================================================\n// Headless DAW Project\n// ============================================================================\n\n/**\n * Expected project ABI version. Mirrors `SONARE_PROJECT_ABI_VERSION` in\n * `src/sonare_c_project.h`; checked against {@link projectAbiVersion} to detect\n * a WASM build whose flat project POD layout has drifted from this wrapper.\n */\nexport const EXPECTED_PROJECT_ABI_VERSION = 1;\n\n/** Render options for {@link Project.bounce}. All fields are optional. */\nexport interface ProjectBounceOptions {\n /** Render length in frames at the output sample rate. */\n totalFrames?: number;\n /** Render block size; <= 0 uses the engine default (128). */\n blockSize?: number;\n /** Output channel count; <= 0 uses the default (2). */\n numChannels?: number;\n /** Output sample rate; <= 0 uses the project sample rate. */\n sampleRate?: number;\n /** Host-instrument PDC (latency) fed to the compiler. */\n instrumentLatencySamples?: number;\n}\n\n/** Oscillator waveform for the built-in synth. */\nexport type BuiltinSynthWaveform =\n | 'sine'\n | 'saw'\n | 'sawtooth'\n | 'square'\n | 'triangle'\n | 0\n | 1\n | 2\n | 3;\n\n/**\n * Built-in synth patch + MIDI routing for\n * {@link Project.bounceWithBuiltinInstrument}. Every field is optional; a\n * non-positive (or omitted) numeric field falls back to the C-ABI default\n * (gain 0.2, attack 5ms, decay 60ms, sustain 0.7, release 120ms, 16 voices),\n * so `{}` is a usable default sine patch.\n */\nexport interface BuiltinSynthBinding {\n /** MIDI destination id this patch answers to (default 0; see {@link Project.setTrackMidiDestination}). */\n destinationId?: number;\n /** Oscillator waveform (default `'sine'`). */\n waveform?: BuiltinSynthWaveform;\n /** Master output gain, linear (0 => 0.2). */\n gain?: number;\n /** ADSR attack in ms (0 => 5). */\n attackMs?: number;\n /** ADSR decay in ms (0 => 60). */\n decayMs?: number;\n /** ADSR sustain level [0,1] (0 => 0.7). */\n sustain?: number;\n /** ADSR release in ms (0 => 120). */\n releaseMs?: number;\n /** Max simultaneous voices (0 => 16, clamped to [1, 64]). */\n polyphony?: number;\n}\n\n/**\n * Cross-binding alias of {@link BuiltinSynthBinding}. The same built-in-synth\n * patch concept is named `BuiltinSynthConfig` in the Python binding; this alias\n * lets portable code use that shared name on the WASM surface too.\n */\nexport type BuiltinSynthConfig = BuiltinSynthBinding;\n\n/**\n * SoundFont (SF2) player patch + MIDI routing for\n * {@link Project.bounceWithSf2Instrument}. Every field is optional; a\n * non-positive (or omitted) numeric field falls back to the C-ABI default\n * (gain 0.5, 48 voices), so `{}` is a usable default patch.\n */\nexport interface Sf2InstrumentConfig {\n /** MIDI destination id this player answers to (default 0; see {@link Project.setTrackMidiDestination}). */\n destinationId?: number;\n /** Master output gain, linear (0 => 0.5). */\n gain?: number;\n /** Max simultaneous voices (0 => 48, clamped to [1, 64]). */\n polyphony?: number;\n}\n\n/** Source backend a resolved MIDI program renders through. */\nexport type SourceBackend = 'sf2' | 'synth';\n\n/**\n * One {@link Project.soundFontManifest} entry: a (channel, bank, program)\n * combination the arrangement plays, with the backend it resolves to.\n */\nexport interface Sf2ProgramStatus {\n /** MIDI channel (0-15). */\n channel: number;\n /** Effective SF2 bank (drum channels report 128). */\n bank: number;\n /** Program number (0-127). */\n program: number;\n /** `'sf2'` when the loaded SoundFont covers the program, else `'synth'`. */\n backend: SourceBackend;\n /** Resolved SF2 preset name (GS fallback included); empty for `'synth'`. */\n presetName: string;\n}\n\nexport const SYNTH_ENGINE_MODES = [\n 'default',\n 'subtractive',\n 'fm',\n 'karplus-strong',\n 'modal',\n 'additive',\n 'percussion',\n 'piano',\n] as const;\nexport const SYNTH_OSC_WAVEFORMS = [\n 'default',\n 'sine',\n 'saw',\n 'square',\n 'triangle',\n 'noise',\n] as const;\nexport const SYNTH_FILTER_MODELS = [\n 'default',\n 'svf',\n 'moog-ladder',\n 'diode-ladder',\n 'sallen-key',\n] as const;\nexport const SYNTH_FILTER_OUTPUTS = ['default', 'lowpass', 'bandpass', 'highpass'] as const;\nexport const SYNTH_BODY_TYPES = ['default', 'none', 'guitar', 'violin', 'wood-tube'] as const;\nexport const SYNTH_MOD_SOURCES = [\n 'none',\n 'amp-env',\n 'filter-env',\n 'lfo1',\n 'lfo2',\n 'velocity',\n 'key-track',\n 'mod-wheel',\n 'random',\n] as const;\nexport const SYNTH_MOD_DESTINATIONS = [\n 'none',\n 'pitch-cents',\n 'cutoff-cents',\n 'amp-gain',\n 'pan-units',\n] as const;\n\nexport interface SynthEnumTables {\n engineModes: string[];\n waveforms: string[];\n filterModels: string[];\n filterOutputs: string[];\n bodyTypes: string[];\n modSources: string[];\n modDestinations: string[];\n}\n\n/** NativeSynth engine selector ({@link SynthPatch}; `'default'` keeps the base patch's). */\nexport type SynthEngineMode = (typeof SYNTH_ENGINE_MODES)[number];\n\n/** NativeSynth oscillator waveform (`'default'` keeps the base patch's). */\nexport type SynthOscWaveform = (typeof SYNTH_OSC_WAVEFORMS)[number];\n\n/** NativeSynth filter model — the character core (`'default'` keeps the base patch's). */\nexport type SynthFilterModel = (typeof SYNTH_FILTER_MODELS)[number];\n\n/** NativeSynth filter output (SVF only; `'default'` keeps the base patch's). */\nexport type SynthFilterOutput = (typeof SYNTH_FILTER_OUTPUTS)[number];\n\n/** NativeSynth body/formant resonance voicing (`'default'` keeps the base patch's). */\nexport type SynthBodyType = (typeof SYNTH_BODY_TYPES)[number];\n\n/** {@link SynthPatch} mod-matrix source. */\nexport type SynthModSource = (typeof SYNTH_MOD_SOURCES)[number];\n\n/** {@link SynthPatch} mod-matrix destination. */\nexport type SynthModDestination = (typeof SYNTH_MOD_DESTINATIONS)[number];\n\n/** One {@link SynthPatch} mod-matrix routing (name or C ordinal per field). */\nexport interface SynthModRouting {\n source: SynthModSource | number;\n destination: SynthModDestination | number;\n /** Destination units at full source deflection. */\n depth: number;\n}\n\n/**\n * Versioned NativeSynth patch for {@link Project.bounceWithSynthInstrument}\n * and {@link RealtimeEngine.setSynthInstrument}.\n *\n * The patch starts from a BASE — the named `preset` (see\n * {@link synthPresetNames}; a `\"va:\"` routing prefix is accepted) or, when\n * `preset` is omitted, the default subtractive patch. Every numeric field then\n * uses \"0 / omit => keep the base value\" (non-zero values override, clamped to\n * their audible ranges) and the enum fields reserve `'default'` as keep. The\n * frozen C ABI has no per-field presence bits, so explicit zero numeric\n * overrides (for example `ampSustain: 0`) cannot be represented; they keep the\n * base value. A non-empty `modRoutings` REPLACES the base mod matrix.\n *\n * Mode-specific deep parameters (FM operator stacks, modal mode tables,\n * drawbar registrations, kit pieces, piano strings) travel inside the named\n * presets; the patch exposes the wrapper sections every engine shares.\n */\nexport interface SynthPatch {\n /**\n * Optional binding convenience for JS realtime/offline helpers. It is not\n * part of the NativeSynth patch itself; Python uses explicit\n * `(destination_id, patch)` bindings instead. Defaults to `0`.\n */\n destinationId?: number;\n /** Base preset name (see {@link synthPresetNames}); omit for the init patch. */\n preset?: string;\n engineMode?: SynthEngineMode | number;\n waveform?: SynthOscWaveform | number;\n /** Detuned-stack width [1, 7]. */\n unison?: number;\n detuneCents?: number;\n /** Per-voice slow pitch drift depth (cents). */\n driftCents?: number;\n /** Pre-filter drive [0, 1]. */\n drive?: number;\n filterModel?: SynthFilterModel | number;\n filterOutput?: SynthFilterOutput | number;\n cutoffHz?: number;\n resonanceQ?: number;\n /** Cutoff keyboard tracking [0, 1]. */\n keyTrack?: number;\n envToCutoffCents?: number;\n velToCutoffCents?: number;\n ampAttackMs?: number;\n ampDecayMs?: number;\n /** 0 / omit keeps the base value; explicit zero sustain is not representable. */\n ampSustain?: number;\n ampReleaseMs?: number;\n filterAttackMs?: number;\n filterDecayMs?: number;\n /** 0 / omit keeps the base value; explicit zero sustain is not representable. */\n filterSustain?: number;\n filterReleaseMs?: number;\n lfoRateHz?: number;\n lfoToPitchCents?: number;\n lfo2RateHz?: number;\n glideMs?: number;\n body?: SynthBodyType | number;\n /** Body resonance mix [0, 1]. */\n bodyMix?: number;\n /** Seeded per-voice pan scatter [0, 1]. */\n stereoSpread?: number;\n /** Mod matrix (at most 8 routings; REPLACES the base matrix when non-empty). */\n modRoutings?: SynthModRouting[];\n /** Master output gain (linear). */\n gain?: number;\n /** Max simultaneous voices [1, 64]. */\n polyphony?: number;\n /** Gain-neutral bus saturation [0, 1]. */\n busDrive?: number;\n}\n\n/** Clip fade-curve for {@link Project.setClipFade}. */\nexport type ProjectFadeCurve =\n | 'linear'\n | 'equal-power'\n | 'equal_power'\n | 'equalPower'\n | 'exponential'\n | 'logarithmic'\n | 0\n | 1\n | 2\n | 3;\n\n/** One clip fade region for {@link Project.setClipFade}. */\nexport interface ProjectClipFade {\n /** Fade length in PPQ (>= 0; 0 = no fade). */\n lengthPpq?: number;\n /** Fade curve (default `'linear'`). */\n curve?: ProjectFadeCurve;\n}\n\n/** One alternate take for {@link Project.setClipTakes}. */\nexport interface ProjectClipTake {\n id: number;\n sourceId?: number;\n sourceOffsetPpq?: number;\n name?: string;\n}\n\n/** One comp segment for {@link Project.setClipCompSegments}. */\nexport interface ProjectClipCompSegment {\n startPpq: number;\n endPpq: number;\n takeId?: number;\n}\n\n/** Descriptor for {@link Project.addLoopRecordingTakes}. */\nexport interface ProjectLoopRecordingDesc {\n trackId: number;\n startPpq?: number;\n loopLengthPpq: number;\n audio: Float32Array;\n audioChannels?: number;\n audioSampleRate?: number;\n}\n\n/** Result returned by {@link Project.addLoopRecordingTakes}. */\nexport interface ProjectLoopRecordingResult {\n clipId: number;\n takeCount: number;\n}\n\n/** Clip loop mode for {@link Project.setClipLoop}. */\nexport type ProjectLoopMode = 'off' | 'loop' | 0 | 1;\nexport type ProjectWarpMode = 'off' | 'repitch' | 'tempo-sync' | 0 | 1 | 2;\n\n/** Automation breakpoint interpolation for {@link ProjectAutomationPoint}. */\nexport type ProjectAutomationCurve = 'linear' | 'exponential' | 'hold' | 'scurve' | 0 | 1 | 2 | 3;\n\n/** One automation breakpoint accepted by the automation-lane edit ops. */\nexport interface ProjectAutomationPoint {\n /** Breakpoint position in PPQ. */\n ppq: number;\n /** Breakpoint value. */\n value: number;\n /** Curve to the next breakpoint (default `'linear'`). */\n curve?: ProjectAutomationCurve;\n}\n\n/** Automation-lane descriptor for {@link Project.addAutomationLane}. */\nexport interface ProjectAutomationLaneDesc {\n /** Host-defined id of the parameter the lane drives. */\n targetParamId: number;\n /** Breakpoints (stored verbatim). */\n points: ReadonlyArray<ProjectAutomationPoint>;\n}\n\n/** One tempo segment for {@link Project.setTempoSegments}. */\nexport interface ProjectTempoSegment {\n /** Segment start in PPQ. */\n startPpq: number;\n /** Tempo in beats per minute at the segment start. */\n bpm: number;\n /** Derived segment start in samples. Accepted for compatibility, ignored on input. */\n startSample?: number;\n /** Optional ramp end tempo in BPM (0 = constant tempo over the segment). */\n endBpm?: number;\n}\n\n/** One time-signature segment for {@link Project.setTimeSignatures}. */\nexport interface ProjectTimeSignatureSegment {\n /** Segment start in PPQ. */\n startPpq: number;\n /** Beats per bar (time-signature numerator). */\n numerator: number;\n /** Beat unit (time-signature denominator, e.g. 4 or 8). */\n denominator: number;\n}\n\n/** Key segment for {@link Project.annotateKeys}. */\nexport interface ProjectKeySegment {\n startPpq: number;\n endPpq: number;\n /** Tonic pitch class 0..11 (C=0) or 255 for unknown. */\n tonicPc?: number;\n /** KeyMode ordinal (0 unknown, 1 major, 2 minor, 3 dorian, ...). */\n mode?: number;\n}\n\n/** Chord symbol for {@link Project.annotateChords}. */\nexport interface ProjectChordSymbol {\n startPpq: number;\n endPpq: number;\n /** Root pitch class 0..11 (C=0) or 255 for unknown. */\n rootPc?: number;\n /** ChordQuality ordinal (0 unknown, 1 major, 2 minor, ...). */\n quality?: number;\n /** Extension semitone offsets (up to 8). */\n extensions?: ReadonlyArray<number>;\n /** Slash-bass pitch class 0..11 or 255 for none. */\n slashBassPc?: number;\n /** Optional roman-numeral label. */\n romanNumeral?: string;\n /** True at a modulation boundary. */\n modulationBoundary?: boolean;\n}\n\n/** Assist sidecar snapshot returned by {@link Project.getAssistSidecar}. */\nexport interface ProjectAssistSidecar {\n moduleId: string;\n schemaVersion: number;\n targetTrackId: number;\n regionStartPpq: number;\n regionEndPpq: number;\n payload: Uint8Array;\n}\n\n/** Track kind for {@link Project.addTrack}. */\nexport type ProjectTrackKind = 'audio' | 'midi' | 'aux' | 0 | 1 | 2;\n\n/** Descriptor for {@link Project.addTrack}. */\nexport interface ProjectTrackDesc {\n kind?: ProjectTrackKind;\n name?: string;\n}\n\nexport interface ProjectWarpAnchor {\n warpSample: number;\n sourceSample: number;\n}\n\nexport interface ProjectWarpMapDesc {\n id: number;\n name?: string;\n anchors: ProjectWarpAnchor[];\n}\n\n/** Descriptor for {@link Project.addClip}. */\nexport interface ProjectClipDesc {\n trackId: number;\n isMidi?: boolean;\n startPpq?: number;\n lengthPpq: number;\n sourceOffsetPpq?: number;\n gain?: number;\n audio?: Float32Array;\n audioChannels?: number;\n audioSampleRate?: number;\n sourceUri?: string;\n}\n\n/** Result returned by {@link Project.addMidiClip}. */\nexport interface ProjectMidiClipResult {\n trackId: number;\n clipId: number;\n}\n\n/** Flat MIDI event accepted by {@link Project.setMidiEvents}. */\nexport interface ProjectMidiEvent {\n ppq: number;\n data0: number;\n data1?: number;\n}\n\n/** Options for {@link Project.midiRouteEvents}. `null`/omitted filter fields mean any/no remap. */\nexport interface ProjectMidiRouteConfig {\n filterGroup?: number | null;\n filterChannel?: number | null;\n remapChannel?: number | null;\n thru?: boolean;\n}\n\n/** Result of {@link Project.midiRouteEvents}. */\nexport interface ProjectMidiRouteResult {\n events: ProjectMidiEvent[];\n overflowed: boolean;\n overflowCount: number;\n}\n\nexport type ProjectMidiCcBindingKind = 0 | 1 | 2 | 3;\n\n/** Options for {@link Project.midiCcLearn}. All fields are optional. */\nexport interface MidiCcLearnOptions {\n /** Lower end of the mapped parameter range. Default `0`. */\n minValue?: number;\n /** Upper end of the mapped parameter range. Default `1`. */\n maxValue?: number;\n /** Minimum normalized CC movement required to learn a binding. Default `0`. */\n minMovement?: number;\n}\n\n/** MIDI CC <-> automation binding descriptor used by CC learn/conversion helpers. */\nexport interface ProjectMidiCcBinding {\n ccNumber: number;\n /** MIDI channel 0..15, or 255 for any channel. */\n channel: number;\n /** 0 = 7-bit CC, 1 = 14-bit CC, 2 = RPN, 3 = NRPN. */\n kind: ProjectMidiCcBindingKind;\n ccLsbNumber?: number;\n selectorMsb?: number;\n selectorLsb?: number;\n paramId: number;\n minValue: number;\n maxValue: number;\n}\n\n/** Result of {@link Project.validateMidiNotes}. */\nexport interface ProjectNotePairValidation {\n /** True when every note-on has a matching note-off (and vice versa). */\n ok: boolean;\n /** Count of note-ons that never received a matching note-off. */\n unmatchedNoteOns: number;\n /** Count of note-offs with no preceding matching note-on. */\n unmatchedNoteOffs: number;\n}\n\n/** One compile diagnostic (mirrors SonareProjectDiagnostic). */\nexport interface ProjectDiagnostic {\n code: number;\n /** 0 = error, 1 = warning. */\n severity: number;\n /** Affected clip / track / source id (0 = n/a). */\n targetId: number;\n /** Human-readable message for this diagnostic. */\n message: string;\n}\n\n/** Diagnostics summary returned by {@link Project.compile}. */\nexport interface ProjectCompileResult {\n /** Number of diagnostics surfaced by the compile. Kept for backward compatibility. */\n diagnosticCount: number;\n /** True when compilation produced a renderable timeline (no error diagnostics). */\n hasTimeline: boolean;\n /** Newline-joined human-readable detail of every diagnostic. */\n messages: string;\n diagnostics: ProjectDiagnostic[];\n}\n\nexport interface ProjectDeserializeResult {\n project: Project;\n diagnostics: string;\n}\n\n// Embind handle for the C++ `ProjectWasm` class. The generated `SonareModule`\n// type only gains `Project` / `projectAbiVersion` after a WASM rebuild, so the\n// module is cast through this shape here.\ninterface WasmProject {\n toJson: () => string;\n setSampleRate: (sampleRate: number) => void;\n addTrack: (desc: { kind?: number | string; name?: string }) => number;\n addClip: (desc: ProjectClipDesc) => number;\n addLoopRecordingTakes: (desc: ProjectLoopRecordingDesc) => ProjectLoopRecordingResult;\n addMidiClip: (startPpq: number, lengthPpq: number) => ProjectMidiClipResult;\n splitClip: (clipId: number, splitPpq: number) => number;\n trimClip: (clipId: number, newStartPpq: number, newLengthPpq: number) => void;\n moveClip: (clipId: number, newStartPpq: number, newTrackId: number) => void;\n setTrackKind: (trackId: number, kind: number) => void;\n setClipWarpRef: (clipId: number, warpRefId: number) => void;\n setClipWarpMode: (clipId: number, mode: number) => void;\n setWarpMap: (map: ProjectWarpMapDesc) => void;\n removeWarpMap: (warpRefId: number) => void;\n setTrackMidiDestination: (trackId: number, destinationId: number) => void;\n undo: () => void;\n redo: () => void;\n setMidiEvents: (\n clipId: number,\n events: ReadonlyArray<ProjectMidiEvent | readonly [number, number, number]>,\n ) => void;\n importSmf: (data: Uint8Array) => number;\n exportSmf: () => Uint8Array;\n importClipFile: (data: Uint8Array) => number;\n exportClipFile: () => Uint8Array;\n setProgram: (clipId: number, program: number, bank: number) => void;\n setProgramOnChannel: (\n clipId: number,\n group: number,\n channel: number,\n program: number,\n bank: number,\n ) => void;\n bakeMidiFx: (clipId: number, configJson: string) => void;\n setMidiFx: (clipId: number, configJson: string) => void;\n validateMidiNotes: (clipId: number) => ProjectNotePairValidation;\n autoTempo: (audio: Float32Array, sampleRate: number) => number;\n snapToGrid: (ppq: number, strength: number) => number;\n compile: () => ProjectCompileResult;\n bounce: (options: ProjectBounceOptions) => Float32Array;\n bounceWithBuiltinInstrument: (\n bindings: BuiltinSynthBinding | ReadonlyArray<BuiltinSynthBinding> | undefined,\n options: ProjectBounceOptions,\n ) => Float32Array;\n bounceWithSynthInstrument: (\n bindings: SynthPatch | string | ReadonlyArray<SynthPatch | string> | undefined,\n options: ProjectBounceOptions,\n ) => Float32Array;\n loadSoundFont: (data: Uint8Array) => void;\n clearSoundFont: () => void;\n soundFontPresetCount: () => number;\n soundFontManifest: () => Sf2ProgramStatus[];\n bounceWithSf2Instrument: (\n bindings: Sf2InstrumentConfig | ReadonlyArray<Sf2InstrumentConfig> | undefined,\n options: ProjectBounceOptions,\n ) => Float32Array;\n removeClip: (clipId: number) => void;\n setClipGain: (clipId: number, gain: number) => void;\n setClipFade: (clipId: number, fadeIn: ProjectClipFade, fadeOut: ProjectClipFade) => void;\n setClipTakes: (\n clipId: number,\n takes: ReadonlyArray<ProjectClipTake>,\n activeTakeId: number,\n ) => void;\n setClipCompSegments: (clipId: number, segments: ReadonlyArray<ProjectClipCompSegment>) => void;\n setClipLoop: (clipId: number, loopMode: number, loopLengthPpq: number) => void;\n setClipSource: (clipId: number, sourceId: number) => void;\n duplicateClip: (clipId: number, newStartPpq: number) => number;\n removeTrack: (trackId: number) => void;\n renameTrack: (trackId: number, name: string) => void;\n setTrackRoute: (trackId: number, channelStripRef: string, outputTarget: string) => void;\n addAutomationLane: (\n trackId: number,\n desc: { targetParamId: number; points: ReadonlyArray<ProjectAutomationPoint> },\n ) => number;\n editAutomationLane: (\n trackId: number,\n laneIndex: number,\n desc: { targetParamId: number; points: ReadonlyArray<ProjectAutomationPoint> },\n ) => void;\n removeAutomationLane: (trackId: number, laneIndex: number) => void;\n annotateKeys: (keys: ReadonlyArray<ProjectKeySegment>) => void;\n annotateChords: (chords: ReadonlyArray<ProjectChordSymbol>) => void;\n setAssistSidecar: (\n moduleId: string,\n schemaVersion: number,\n targetTrackId: number,\n regionStartPpq: number,\n regionEndPpq: number,\n payload: Uint8Array,\n ) => void;\n assistSidecarCount: () => number;\n getAssistSidecar: (index: number) => ProjectAssistSidecar;\n setOverlapPolicy: (policy: number) => void;\n getOverlapPolicy: () => number;\n getSampleRate: () => number;\n setMixerSceneJson: (sceneJson: string) => void;\n setMarker: (markerId: number, ppq: number, name: string) => number;\n trackCount: () => number;\n sourceCount: () => number;\n tempoSegmentCount: () => number;\n timeSignatureCount: () => number;\n setTempoSegments: (segments: ReadonlyArray<ProjectTempoSegment>) => void;\n setTimeSignatures: (segments: ReadonlyArray<ProjectTimeSignatureSegment>) => void;\n lastBounceCompileResult: () => ProjectCompileResult;\n delete: () => void;\n}\n\ninterface ProjectModule {\n Project: {\n new (): WasmProject;\n fromJson: (json: string) => WasmProject;\n fromJsonWithDiagnostics: (json: string) => { project: WasmProject; diagnostics: string };\n };\n projectAbiVersion: () => number;\n synthPresetNames: () => string[];\n synthPresetPatch: (name: string) => SynthPatch;\n _synthEnumTables: () => SynthEnumTables;\n _synthPatchRoundTrip: (patch: SynthPatch) => SynthPatch;\n midiGmInstrumentName: (program: number) => string | null;\n midiGmProgramForName: (name: string) => number;\n midiGmFamilyName: (family: number) => string | null;\n midiGmFamilyFirstProgram: (family: number) => number;\n midiGm2InstrumentName: (bankLsb: number, program: number) => string | null;\n midiGmDrumName: (note: number) => string | null;\n midiGmDrumNoteForName: (name: string) => number;\n midiGm2DrumSetName: (bankLsb: number) => string | null;\n midiGm2DrumName: (bankLsb: number, note: number) => string | null;\n midiCcName: (controller: number) => string | null;\n midiCcIndexForName: (name: string) => number;\n midiPerNoteControllerName: (index: number) => string | null;\n midiBankProgram: (\n ppq: number,\n group: number,\n channel: number,\n bankMsb: number,\n bankLsb: number,\n program: number,\n ) => ProjectMidiEvent[];\n midiRouteEvents: (\n events: ReadonlyArray<ProjectMidiEvent>,\n config: ProjectMidiRouteConfig,\n ) => ProjectMidiRouteResult;\n midiCcLearn: (\n events: ReadonlyArray<ProjectMidiEvent>,\n paramId: number,\n minValue: number,\n maxValue: number,\n minMovement: number,\n ) => ProjectMidiCcBinding | null;\n midiCcToBreakpoint: (\n bindings: ReadonlyArray<ProjectMidiCcBinding>,\n event: ProjectMidiEvent,\n ) => ProjectAutomationPoint | null;\n midiParamToCc: (\n bindings: ReadonlyArray<ProjectMidiCcBinding>,\n paramId: number,\n unitValue: number,\n group: number,\n ppq: number,\n ) => ProjectMidiEvent | null;\n}\n\nfunction projectModule(): ProjectModule {\n const candidate = getSonareModule() as unknown as Partial<ProjectModule>;\n if (typeof candidate.projectAbiVersion !== 'function' || candidate.Project === undefined) {\n throw new Error('libsonare was built without arrangement (headless DAW) support');\n }\n return candidate as ProjectModule;\n}\n\nfunction assertProjectU7(fnName: string, value: number, argName: string): number {\n if (!Number.isInteger(value) || value < 0 || value > 127) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 127]`);\n }\n return value;\n}\n\nfunction assertProjectNibble(fnName: string, value: number, argName: string): number {\n if (!Number.isInteger(value) || value < 0 || value > 15) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 15]`);\n }\n return value;\n}\n\nfunction projectMidi1Event(\n fnName: string,\n ppq: number,\n group: number,\n status: number,\n channel: number,\n data1: number,\n data2 = 0,\n): ProjectMidiEvent {\n if (!Number.isFinite(ppq) || ppq < 0) {\n throw new RangeError(`${fnName}: ppq must be a non-negative finite number`);\n }\n const g = assertProjectNibble(fnName, group, 'group');\n const ch = assertProjectNibble(fnName, channel, 'channel');\n const d1 = assertProjectU7(fnName, data1, 'data1');\n const d2 = assertProjectU7(fnName, data2, 'data2');\n // UMP MIDI-1.0 channel-voice word (message type 0x2). Canonical layout is\n // sonare::midi::make_midi1_* (C-ABI sonare_midi_*, which Python delegates to);\n // this hand-written copy is locked against those words by the golden vectors\n // in project.test.ts (mirrored in the Node suite) so it cannot silently drift.\n const word = ((0x2 << 28) | (g << 24) | (status << 20) | (ch << 16) | (d1 << 8) | d2) >>> 0;\n return { ppq, data0: word, data1: 0 };\n}\n\nfunction assertProjectU32(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value < 0 || value > 0xffffffff) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 4294967295]`);\n }\n}\n\nfunction assertProjectMidiEvents(\n fnName: string,\n events: ReadonlyArray<ProjectMidiEvent | readonly [number, number, number]>,\n): void {\n if (!Array.isArray(events)) {\n throw new TypeError(`${fnName}: events must be an array`);\n }\n events.forEach((event, index) => {\n const prefix = `events[${index}]`;\n if (Array.isArray(event)) {\n if (event.length < 3) {\n throw new TypeError(`${fnName}: ${prefix} must contain [ppq, data0, data1]`);\n }\n if (!Number.isFinite(event[0]) || event[0] < 0) {\n throw new RangeError(`${fnName}: ${prefix}.ppq must be a non-negative finite number`);\n }\n assertProjectU32(fnName, event[1], `${prefix}.data0`);\n assertProjectU32(fnName, event[2], `${prefix}.data1`);\n return;\n }\n if (event === null || typeof event !== 'object') {\n throw new TypeError(`${fnName}: ${prefix} must be a MIDI event object or tuple`);\n }\n if (!Number.isFinite(event.ppq) || event.ppq < 0) {\n throw new RangeError(`${fnName}: ${prefix}.ppq must be a non-negative finite number`);\n }\n assertProjectU32(fnName, event.data0, `${prefix}.data0`);\n if (event.data1 !== undefined) {\n assertProjectU32(fnName, event.data1, `${prefix}.data1`);\n }\n });\n}\n\n/**\n * Runtime ABI version of the flat project POD layout exposed by this WASM\n * build. Equals {@link EXPECTED_PROJECT_ABI_VERSION} when the arrangement\n * subsystem is compiled in. Mirrors the C-ABI `sonare_project_abi_version`.\n */\nexport function projectAbiVersion(): number {\n return projectModule().projectAbiVersion();\n}\n\n/**\n * NativeSynth preset catalog names (`'sine'`, `'saw-lead'`, `'e-piano'`,\n * `'drum-kit'`, ...). Use these to discover valid {@link SynthPatch} preset\n * names instead of hardcoding magic strings.\n */\nexport function synthPresetNames(): string[] {\n return projectModule().synthPresetNames();\n}\n\n/**\n * Fetch a named catalog preset as a {@link SynthPatch} (the preset name plus\n * the wrapper-section values), so hosts can inspect a preset and tweak fields\n * before binding it. A `\"va:\"` routing prefix is accepted; unknown names\n * throw.\n */\nexport function synthPresetPatch(name: string): SynthPatch {\n return projectModule().synthPresetPatch(name);\n}\n\nexport function synthEnumTables(): SynthEnumTables {\n return projectModule()._synthEnumTables();\n}\n\nexport function synthPatchRoundTripForTest(patch: SynthPatch): SynthPatch {\n return projectModule()._synthPatchRoundTrip(patch);\n}\n\n/**\n * Headless DAW project (control-thread-only arrangement model).\n *\n * Wraps the embind `Project` class over the C-ABI keystone\n * `sonare_c_project.{h,cpp}`. Construct an empty project with `new Project()`,\n * or deserialize one with {@link Project.fromJson}; serialize back with\n * {@link toJson}; compile to a renderable timeline with {@link compile}; render\n * offline to interleaved float audio with {@link bounce}. The edit and MIDI\n * methods mirror the Node/Python project bindings.\n *\n * Call {@link delete} (or use a `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const project = new Project();\n * try {\n * project.setSampleRate(48000);\n * const json = project.toJson();\n * const restored = Project.fromJson(json);\n * restored.delete();\n * } finally {\n * project.delete();\n * }\n * ```\n */\nexport class Project {\n private native: WasmProject;\n\n constructor() {\n this.native = new (projectModule().Project)();\n }\n\n /** Pack a MIDI 1.0 note-on event accepted by {@link setMidiEvents}. */\n static midiNoteOn(\n ppq: number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n ): ProjectMidiEvent {\n return projectMidi1Event('Project.midiNoteOn', ppq, group, 0x9, channel, note, velocity);\n }\n\n /** Pack a MIDI 1.0 note-off event accepted by {@link setMidiEvents}. */\n static midiNoteOff(\n ppq: number,\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n ): ProjectMidiEvent {\n return projectMidi1Event('Project.midiNoteOff', ppq, group, 0x8, channel, note, velocity);\n }\n\n /** Pack a MIDI 1.0 control-change event. */\n static midiCc(\n ppq: number,\n group: number,\n channel: number,\n controller: number,\n value: number,\n ): ProjectMidiEvent {\n return projectMidi1Event('Project.midiCc', ppq, group, 0xb, channel, controller, value);\n }\n\n /** Pack a MIDI 1.0 poly-pressure event. */\n static midiPolyPressure(\n ppq: number,\n group: number,\n channel: number,\n note: number,\n pressure: number,\n ): ProjectMidiEvent {\n return projectMidi1Event('Project.midiPolyPressure', ppq, group, 0xa, channel, note, pressure);\n }\n\n /** Pack a MIDI 1.0 program-change event. */\n static midiProgram(\n ppq: number,\n group: number,\n channel: number,\n program: number,\n ): ProjectMidiEvent {\n return projectMidi1Event('Project.midiProgram', ppq, group, 0xc, channel, program, 0);\n }\n\n /** Return the General MIDI instrument name for `program`, or `null` when out of range. */\n static gmInstrumentName(program: number): string | null {\n return projectModule().midiGmInstrumentName(program);\n }\n\n /** Return the General MIDI program number for a canonical instrument name, or `-1`. */\n static gmProgramForName(name: string): number {\n return projectModule().midiGmProgramForName(name);\n }\n\n /** Return the General MIDI family name for `family`, or `null` when out of range. */\n static gmFamilyName(family: number): string | null {\n return projectModule().midiGmFamilyName(family);\n }\n\n /** Return the first General MIDI program number in `family`, or `-1`. */\n static gmFamilyFirstProgram(family: number): number {\n return projectModule().midiGmFamilyFirstProgram(family);\n }\n\n /** Return the GM2 bank/program instrument variation name, or `null` when unavailable. */\n static gm2InstrumentName(bankLsb: number, program: number): string | null {\n return projectModule().midiGm2InstrumentName(bankLsb, program);\n }\n\n /** Return the General MIDI drum name for `note`, or `null` when out of range. */\n static gmDrumName(note: number): string | null {\n return projectModule().midiGmDrumName(note);\n }\n\n /** Return the General MIDI drum note for a canonical drum name, or `-1`. */\n static gmDrumNoteForName(name: string): number {\n return projectModule().midiGmDrumNoteForName(name);\n }\n\n /** Return the GM2 drum-set name for `bankLsb`, or `null` when unavailable. */\n static gm2DrumSetName(bankLsb: number): string | null {\n return projectModule().midiGm2DrumSetName(bankLsb);\n }\n\n /** Return the GM2 drum name for `bankLsb`/`note`, or `null` when unavailable. */\n static gm2DrumName(bankLsb: number, note: number): string | null {\n return projectModule().midiGm2DrumName(bankLsb, note);\n }\n\n /** Return the MIDI CC name for `controller`, or `null` when out of range. */\n static midiCcName(controller: number): string | null {\n return projectModule().midiCcName(controller);\n }\n\n /** Return the MIDI CC number for a canonical controller name, or `-1`. */\n static midiCcIndexForName(name: string): number {\n return projectModule().midiCcIndexForName(name);\n }\n\n /** Return the MIDI 2.0 per-note controller name for `index`, or `null`. */\n static perNoteControllerName(index: number): string | null {\n return projectModule().midiPerNoteControllerName(index);\n }\n\n /** Expand bank-select + program-change into MIDI events accepted by {@link setMidiEvents}. */\n static midiBankProgram(\n ppq: number,\n group: number,\n channel: number,\n bankMsb: number,\n bankLsb: number,\n program: number,\n ): ProjectMidiEvent[] {\n return projectModule().midiBankProgram(ppq, group, channel, bankMsb, bankLsb, program);\n }\n\n /** Route MIDI events through the native MidiRouter filter/remap/thru logic. */\n static midiRouteEvents(\n events: ReadonlyArray<ProjectMidiEvent>,\n config: ProjectMidiRouteConfig = {},\n ): ProjectMidiRouteResult {\n return projectModule().midiRouteEvents(events, config);\n }\n\n /** Run native MIDI learn over an event stream; returns `null` when nothing is learned. */\n static midiCcLearn(\n events: ReadonlyArray<ProjectMidiEvent>,\n paramId: number,\n options: MidiCcLearnOptions = {},\n ): ProjectMidiCcBinding | null {\n return projectModule().midiCcLearn(\n events,\n paramId,\n options.minValue ?? 0,\n options.maxValue ?? 1,\n options.minMovement ?? 0,\n );\n }\n\n /** Convert one CC event to an automation breakpoint using native CcMap. */\n static midiCcToBreakpoint(\n bindings: ReadonlyArray<ProjectMidiCcBinding>,\n event: ProjectMidiEvent,\n ): ProjectAutomationPoint | null {\n return projectModule().midiCcToBreakpoint(bindings, event);\n }\n\n /** Convert one automation value back to a CC UMP event using native CcMap. */\n static midiParamToCc(\n bindings: ReadonlyArray<ProjectMidiCcBinding>,\n paramId: number,\n unitValue: number,\n group: number,\n ppq = 0,\n ): ProjectMidiEvent | null {\n return projectModule().midiParamToCc(bindings, paramId, unitValue, group, ppq);\n }\n\n /** Pack a MIDI 1.0 channel-pressure event. */\n static midiChannelPressure(\n ppq: number,\n group: number,\n channel: number,\n pressure: number,\n ): ProjectMidiEvent {\n return projectMidi1Event('Project.midiChannelPressure', ppq, group, 0xd, channel, pressure, 0);\n }\n\n /** Pack a MIDI 1.0 pitch-bend event (`bend` is unsigned 14-bit, center = 8192). */\n static midiPitchBend(\n ppq: number,\n group: number,\n channel: number,\n bend: number,\n ): ProjectMidiEvent {\n if (!Number.isInteger(bend) || bend < 0 || bend > 0x3fff) {\n throw new RangeError('Project.midiPitchBend: bend must be an integer in [0, 16383]');\n }\n return projectMidi1Event(\n 'Project.midiPitchBend',\n ppq,\n group,\n 0xe,\n channel,\n bend & 0x7f,\n bend >> 7,\n );\n }\n\n /**\n * Deserialize project JSON into a new {@link Project}. Throws if the JSON is\n * malformed, surfacing the joined diagnostic messages.\n */\n static fromJson(json: string): Project {\n const project = new Project();\n // Replace the freshly-created empty handle with the deserialized one. If\n // fromJson throws (malformed JSON) the empty handle is released first so no\n // WASM object leaks.\n const restored = (() => {\n try {\n return projectModule().Project.fromJson(json);\n } catch (error) {\n project.native.delete();\n throw error;\n }\n })();\n project.native.delete();\n project.native = restored;\n return project;\n }\n\n /**\n * Deserialize project JSON and return native warning diagnostics emitted on\n * successful loads, such as dangling source references preserved for repair.\n */\n static fromJsonWithDiagnostics(json: string): ProjectDeserializeResult {\n const project = new Project();\n const restored = (() => {\n try {\n return projectModule().Project.fromJsonWithDiagnostics(json);\n } catch (error) {\n project.native.delete();\n throw error;\n }\n })();\n project.native.delete();\n project.native = restored.project;\n return { project, diagnostics: restored.diagnostics };\n }\n\n /** Serialize the project (+ MIDI content) to deterministic JSON. */\n toJson(): string {\n return this.native.toJson();\n }\n\n /** Set the project sample rate in Hz. Must be > 0. */\n setSampleRate(sampleRate: number): void {\n this.native.setSampleRate(sampleRate);\n }\n\n /** Add a track and return its allocated stable id. */\n addTrack(desc: ProjectTrackDesc = {}): number {\n return this.native.addTrack({ ...desc, kind: projectTrackKindValue(desc.kind) });\n }\n\n /** Add an audio or MIDI clip and return its allocated clip id. */\n addClip(desc: ProjectClipDesc): number {\n return this.native.addClip(desc);\n }\n\n /** Split captured loop-recording audio into takes and add one clip. */\n addLoopRecordingTakes(desc: ProjectLoopRecordingDesc): ProjectLoopRecordingResult {\n return this.native.addLoopRecordingTakes(desc);\n }\n\n /** Create a MIDI track + clip; returns `{ trackId, clipId }`. */\n addMidiClip(startPpq: number, lengthPpq: number): ProjectMidiClipResult {\n return this.native.addMidiClip(startPpq, lengthPpq);\n }\n\n /** Split a clip at `splitPpq` and return the new clip id. */\n splitClip(clipId: number, splitPpq: number): number {\n return this.native.splitClip(clipId, splitPpq);\n }\n\n /** Trim a clip's start / length in PPQ. */\n trimClip(clipId: number, newStartPpq: number, newLengthPpq: number): void {\n this.native.trimClip(clipId, newStartPpq, newLengthPpq);\n }\n\n /** Move a clip to `newStartPpq` and optionally another track. */\n moveClip(clipId: number, newStartPpq: number, newTrackId = 0): void {\n this.native.moveClip(clipId, newStartPpq, newTrackId);\n }\n\n /** Change a track kind via an undoable edit. */\n setTrackKind(trackId: number, kind: ProjectTrackKind): void {\n this.native.setTrackKind(trackId, projectTrackKindValue(kind));\n }\n\n /** Set a clip's warp reference id (0 clears it). */\n setClipWarpRef(clipId: number, warpRefId: number): void {\n this.native.setClipWarpRef(clipId, warpRefId);\n }\n\n /** Set a clip's warp playback mode. */\n setClipWarpMode(clipId: number, mode: ProjectWarpMode): void {\n this.native.setClipWarpMode(clipId, projectWarpModeValue(mode));\n }\n\n /** Add or replace a first-class warp map referenced by clip warp ids. */\n setWarpMap(map: ProjectWarpMapDesc): void {\n this.native.setWarpMap(map);\n }\n\n /** Remove a first-class warp map by id. */\n removeWarpMap(warpRefId: number): void {\n this.native.removeWarpMap(warpRefId);\n }\n\n /**\n * Route a track's MIDI to host-instrument `destinationId` (0 = default). The\n * compiler stamps every MIDI clip on the track with this id so the engine\n * dispatches its events to the instrument registered for that destination.\n * Routes through an undoable edit command.\n */\n setTrackMidiDestination(trackId: number, destinationId: number): void {\n this.native.setTrackMidiDestination(trackId, destinationId);\n }\n\n /** Undo the most recent edit. */\n undo(): void {\n this.native.undo();\n }\n\n /** Redo the most recently undone edit. */\n redo(): void {\n this.native.redo();\n }\n\n /** Replace a MIDI clip's entire event list. */\n setMidiEvents(\n clipId: number,\n events: ReadonlyArray<ProjectMidiEvent | readonly [number, number, number]>,\n ): void {\n assertProjectMidiEvents('Project.setMidiEvents', events);\n this.native.setMidiEvents(clipId, events);\n }\n\n /** Import an in-memory SMF buffer; returns the first added clip id. */\n importSmf(data: Uint8Array): number {\n return this.native.importSmf(data);\n }\n\n /** Export the project's tempo map + MIDI clips to an SMF byte buffer. */\n exportSmf(): Uint8Array {\n return this.native.exportSmf();\n }\n\n /**\n * Import a MIDI 2.0 Clip File (`SMF2CLIP`); returns the first added clip id.\n * Unlike {@link importSmf}, MIDI 2.0 channel-voice messages (16-bit velocity,\n * 32-bit CC, per-note / registered controllers, bank-valid Program Change)\n * survive without loss.\n */\n importClipFile(data: Uint8Array): number {\n return this.native.importClipFile(data);\n }\n\n /**\n * Export the project's tempo map + MIDI clips to a MIDI 2.0 Clip File\n * (`SMF2CLIP`) byte buffer. MIDI 2.0-only events are written without loss —\n * prefer this over {@link exportSmf} when MIDI 2.0 fidelity matters.\n */\n exportClipFile(): Uint8Array {\n return this.native.exportClipFile();\n }\n\n /**\n * Set a MIDI clip's channel-0 program / bank at source PPQ 0. `bank` defaults\n * to `-1` (no Bank Select emitted), matching `setProgramOnChannel` and the\n * Node/Python surfaces; pass `>= 0` to emit a Bank Select.\n */\n setProgram(clipId: number, program: number, bank = -1): void {\n this.native.setProgram(clipId, program, bank);\n }\n\n /** Set a MIDI clip's program / bank for one UMP group and channel. */\n setProgramOnChannel(\n clipId: number,\n group: number,\n channel: number,\n program: number,\n bank = -1,\n ): void {\n this.native.setProgramOnChannel(clipId, group, channel, program, bank);\n }\n\n /** Destructively bake a MIDI-FX chain into a clip's stored MIDI events. */\n bakeMidiFx(clipId: number, configJson: string): void {\n this.native.bakeMidiFx(clipId, configJson);\n }\n\n /** Backward alias for {@link bakeMidiFx}. */\n setMidiFx(clipId: number, configJson: string): void {\n this.bakeMidiFx(clipId, configJson);\n }\n\n /**\n * Pre-flight check for hanging / unmatched notes in a MIDI clip: reports\n * whether every note-on has a matching note-off (FIFO per channel+note).\n * Useful before bouncing to catch a stuck note. Throws if `clipId` is unknown\n * or not a MIDI clip.\n */\n validateMidiNotes(clipId: number): ProjectNotePairValidation {\n return this.native.validateMidiNotes(clipId);\n }\n\n /** Detect tempo from a mono buffer and install it; returns the primary BPM. */\n autoTempo(audio: Float32Array, sampleRate: number): number {\n return this.native.autoTempo(audio, sampleRate);\n }\n\n /** Snap a PPQ coordinate to the nearest beat of the project grid. */\n snapToGrid(ppq: number, strength = 1.0): number {\n return this.native.snapToGrid(ppq, strength);\n }\n\n /** Compile the project into a renderable timeline, surfacing diagnostics. */\n compile(): ProjectCompileResult {\n return this.native.compile();\n }\n\n /**\n * Compile + render the project offline to interleaved float audio. MIDI\n * tracks render silently here (no instrument is bound) — use\n * {@link bounceWithBuiltinInstrument} to make MIDI audible.\n *\n * When `totalFrames` is omitted (or `<= 0`) the render length is auto-derived\n * from the arrangement, so a project with content renders without computing a\n * frame count; an empty project yields an empty buffer.\n *\n * @example\n * ```typescript\n * const audio = project.bounce({ numChannels: 2 });\n * ```\n */\n bounce(options: ProjectBounceOptions = {}): Float32Array {\n return this.native.bounce(options);\n }\n\n /**\n * Compile + render the project offline, routing MIDI tracks through the\n * built-in oscillator synth so a MIDI-only arrangement bounces to audible\n * audio. Pass a {@link BuiltinSynthBinding} (or an array of them) to choose\n * the patch and MIDI destination; omit it (or pass `{}`) for one\n * default-destination sine patch. An explicitly empty array `[]` (or\n * `undefined` / `null`) produces zero bindings, so MIDI tracks render silently.\n *\n * Like {@link bounce}, omitting `totalFrames` auto-derives the render length\n * from the arrangement plus the synth's release tail.\n *\n * @example\n * ```typescript\n * // MIDI-only project -> non-silent stereo audio.\n * const audio = project.bounceWithBuiltinInstrument(\n * { waveform: 'saw' },\n * { numChannels: 2 },\n * );\n * ```\n */\n bounceWithBuiltinInstrument(\n instrument: BuiltinSynthBinding | ReadonlyArray<BuiltinSynthBinding> = {},\n options: ProjectBounceOptions = {},\n ): Float32Array {\n return this.native.bounceWithBuiltinInstrument(instrument, options);\n }\n\n /**\n * Compile + render the project offline, routing MIDI tracks through the\n * patch-driven NativeSynth — the full synthesizer (subtractive / FM /\n * Karplus-Strong / modal / additive / percussion / extended-waveguide-piano\n * engines plus the realism layer). Pass a {@link SynthPatch}, a preset-name\n * string (`'saw-lead'` / `'va:saw-lead'`; see {@link synthPresetNames}), or\n * an array of either; each object entry may carry a `destinationId` binding\n * convenience (default 0), which is not part of the NativeSynth patch itself.\n * An explicitly empty array (or `undefined` / `null`) produces zero bindings.\n * Unknown preset names throw. Deterministic for a fixed project + options +\n * patch.\n */\n bounceWithSynthInstrument(\n instrument: SynthPatch | string | ReadonlyArray<SynthPatch | string> = {},\n options: ProjectBounceOptions = {},\n ): Float32Array {\n return this.native.bounceWithSynthInstrument(instrument, options);\n }\n\n /**\n * Load (parse) SoundFont 2 bytes into the project: presets / instruments /\n * sample headers plus the sample PCM decoded to a float pool. The host\n * fetches the `.sf2` and passes the raw bytes; they are copied into linear\n * memory for the call and not referenced afterwards. Replaces any previously\n * loaded SoundFont; throws on malformed input (the previous SoundFont is\n * kept).\n */\n loadSoundFont(data: Uint8Array): void {\n this.native.loadSoundFont(data);\n }\n\n /** Release the project's loaded SoundFont (no-op when none is loaded). */\n clearSoundFont(): void {\n this.native.clearSoundFont();\n }\n\n /** Number of presets in the loaded SoundFont (0 when none is loaded). */\n soundFontPresetCount(): number {\n return this.native.soundFontPresetCount();\n }\n\n /**\n * Enumerate every (channel, bank, program) combination the arrangement plays\n * a note through, in first-use order, reporting whether each resolves in the\n * loaded SoundFont (`'sf2'`, GS variation/drum fallbacks included) or would\n * fall back to the built-in synth (`'synth'`). Without a loaded SoundFont\n * every entry is a synth fallback.\n */\n soundFontManifest(): Sf2ProgramStatus[] {\n return this.native.soundFontManifest();\n }\n\n /**\n * Like {@link bounceWithBuiltinInstrument}, but each bound destination\n * renders through a GS-compatible SoundFont player fed by the project's\n * loaded SoundFont ({@link loadSoundFont}): 16 MIDI channels per player,\n * channel 10 drums via bank 128, GS NRPN part edits and GS/GM SysEx resets\n * honored. Programs the SoundFont does not cover — including bouncing with\n * no SoundFont loaded at all — play through the built-in synthesizer GM\n * fallback bank (the data-free floor; see {@link soundFontManifest} for the\n * per-program backend). An explicitly empty array `[]` (or `undefined` /\n * `null`) produces zero bindings, so MIDI tracks render silently.\n */\n bounceWithSf2Instrument(\n instrument: Sf2InstrumentConfig | ReadonlyArray<Sf2InstrumentConfig> = {},\n options: ProjectBounceOptions = {},\n ): Float32Array {\n return this.native.bounceWithSf2Instrument(instrument, options);\n }\n\n /** Remove a clip (undoable). */\n removeClip(clipId: number): void {\n this.native.removeClip(clipId);\n }\n\n /** Set a clip's linear playback gain (>= 0; undoable). */\n setClipGain(clipId: number, gain: number): void {\n this.native.setClipGain(clipId, gain);\n }\n\n /** Set a clip's fade-in / fade-out regions (undoable). */\n setClipFade(clipId: number, fadeIn: ProjectClipFade = {}, fadeOut: ProjectClipFade = {}): void {\n this.native.setClipFade(clipId, fadeIn, fadeOut);\n }\n\n /** Replace a clip's take list and active take id (undoable). */\n setClipTakes(clipId: number, takes: ReadonlyArray<ProjectClipTake>, activeTakeId = 0): void {\n this.native.setClipTakes(clipId, takes, activeTakeId);\n }\n\n /** Replace a clip's comp segments (undoable). */\n setClipCompSegments(clipId: number, segments: ReadonlyArray<ProjectClipCompSegment>): void {\n this.native.setClipCompSegments(clipId, segments);\n }\n\n /** Set a clip's loop mode + loop length in PPQ (undoable). */\n setClipLoop(clipId: number, loopMode: ProjectLoopMode, loopLengthPpq = 0): void {\n this.native.setClipLoop(clipId, projectLoopModeValue(loopMode), loopLengthPpq);\n }\n\n /** Rebind a clip to a different (already-registered) source (undoable). */\n setClipSource(clipId: number, sourceId: number): void {\n this.native.setClipSource(clipId, sourceId);\n }\n\n /** Duplicate a clip at `newStartPpq` (same track); returns the new clip id. */\n duplicateClip(clipId: number, newStartPpq: number): number {\n return this.native.duplicateClip(clipId, newStartPpq);\n }\n\n /** Remove a track and its clips (undoable). */\n removeTrack(trackId: number): void {\n this.native.removeTrack(trackId);\n }\n\n /** Rename a track (undoable). */\n renameTrack(trackId: number, name: string): void {\n this.native.renameTrack(trackId, name);\n }\n\n /** Set a track's mixer-strip binding + output target (undoable; omit / '' clears). */\n setTrackRoute(trackId: number, channelStripRef?: string, outputTarget?: string): void {\n this.native.setTrackRoute(trackId, channelStripRef ?? '', outputTarget ?? '');\n }\n\n /** Append an automation lane to a track; returns the lane index (undoable). */\n addAutomationLane(trackId: number, desc: ProjectAutomationLaneDesc): number {\n return this.native.addAutomationLane(trackId, {\n targetParamId: desc.targetParamId,\n points: desc.points,\n });\n }\n\n /** Replace an existing automation lane in place (undoable). */\n editAutomationLane(trackId: number, laneIndex: number, desc: ProjectAutomationLaneDesc): void {\n this.native.editAutomationLane(trackId, laneIndex, {\n targetParamId: desc.targetParamId,\n points: desc.points,\n });\n }\n\n /** Remove an automation lane from a track (undoable). */\n removeAutomationLane(trackId: number, laneIndex: number): void {\n this.native.removeAutomationLane(trackId, laneIndex);\n }\n\n /** Replace the project's key annotation stream (undoable). */\n annotateKeys(keys: ReadonlyArray<ProjectKeySegment>): void {\n this.native.annotateKeys(keys);\n }\n\n /** Replace the project's chord-symbol annotation stream (undoable). */\n annotateChords(chords: ReadonlyArray<ProjectChordSymbol>): void {\n this.native.annotateChords(chords);\n }\n\n /** Add or update an opaque assist sidecar by module id + target scope (undoable). */\n setAssistSidecar(\n moduleId: string,\n schemaVersion: number,\n targetTrackId: number,\n regionStartPpq: number,\n regionEndPpq: number,\n payload: Uint8Array,\n ): void {\n this.native.setAssistSidecar(\n moduleId,\n schemaVersion,\n targetTrackId,\n regionStartPpq,\n regionEndPpq,\n payload,\n );\n }\n\n /** Number of assist sidecars currently stored on the project. */\n assistSidecarCount(): number {\n return this.native.assistSidecarCount();\n }\n\n /** Read one assist sidecar by stable project order. */\n getAssistSidecar(index: number): ProjectAssistSidecar {\n return this.native.getAssistSidecar(index);\n }\n\n /** Set the project's clip-overlap policy (SonareProjectOverlapPolicy ordinal). */\n setOverlapPolicy(policy: number): void {\n this.native.setOverlapPolicy(policy);\n }\n\n /** Read the project's clip-overlap policy (SonareProjectOverlapPolicy ordinal). */\n getOverlapPolicy(): number {\n return this.native.getOverlapPolicy();\n }\n\n /** Read the project sample rate in Hz. */\n getSampleRate(): number {\n return this.native.getSampleRate();\n }\n\n /** Replace the project's mixer scene from a scene JSON string. */\n setMixerSceneJson(sceneJson: string): void {\n this.native.setMixerSceneJson(sceneJson);\n }\n\n /**\n * Add or replace a marker. Pass `markerId` 0 to allocate a new id; returns the\n * stable marker id (the allocated id when 0 was passed).\n */\n setMarker(markerId: number, ppq: number, name: string): number {\n return this.native.setMarker(markerId, ppq, name);\n }\n\n /** Number of tracks in the project. */\n trackCount(): number {\n return this.native.trackCount();\n }\n\n /** Number of audio sources registered on the project. */\n sourceCount(): number {\n return this.native.sourceCount();\n }\n\n /** Number of tempo-map segments on the project. */\n tempoSegmentCount(): number {\n return this.native.tempoSegmentCount();\n }\n\n /** Number of time-signature segments on the project. */\n timeSignatureCount(): number {\n return this.native.timeSignatureCount();\n }\n\n /** Replace the project's tempo map with the given segments. */\n setTempoSegments(segments: ReadonlyArray<ProjectTempoSegment>): void {\n this.native.setTempoSegments(segments);\n }\n\n /** Replace the project's time-signature map with the given segments. */\n setTimeSignatures(segments: ReadonlyArray<ProjectTimeSignatureSegment>): void {\n this.native.setTimeSignatures(segments);\n }\n\n /**\n * Compile diagnostics produced by the most recent bounce on this project\n * (e.g. MIDI clips rendering silently without a bound instrument). When no\n * bounce has run, the result is empty with `hasTimeline` set.\n */\n lastBounceCompileResult(): ProjectCompileResult {\n return this.native.lastBounceCompileResult();\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.native.delete();\n }\n\n /** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */\n destroy(): void {\n this.delete();\n }\n}\n\nfunction projectTrackKindValue(kind: ProjectTrackKind | undefined): number {\n if (kind === undefined || kind === 'audio') {\n return 0;\n }\n if (kind === 'midi') {\n return 1;\n }\n if (kind === 'aux') {\n return 2;\n }\n return kind;\n}\n\nfunction projectWarpModeValue(mode: ProjectWarpMode | undefined): number {\n if (mode === undefined || mode === 'off') {\n return 0;\n }\n if (mode === 'repitch') {\n return 1;\n }\n if (mode === 'tempo-sync') {\n return 2;\n }\n return mode;\n}\n\nfunction projectLoopModeValue(mode: ProjectLoopMode | undefined): number {\n if (mode === undefined || mode === 'off') {\n return 0;\n }\n if (mode === 'loop') {\n return 1;\n }\n return mode;\n}\n","import { getSonareModule } from './module_state';\nimport type { SynthPatch } from './project';\nimport type {\n WasmClipPageRequest,\n WasmEngineAutomationPoint,\n WasmEngineBounceOptions,\n WasmEngineBounceResult,\n WasmEngineCaptureStatus,\n WasmEngineClip,\n WasmEngineFreezeOptions,\n WasmEngineFreezeResult,\n WasmEngineGraphSpec,\n WasmEngineMarker,\n WasmEngineMeterTelemetry,\n WasmEngineMetronomeConfig,\n WasmEngineParameterInfo,\n WasmEngineProcessWithMonitorResult,\n WasmEngineTelemetry,\n WasmEngineTransportState,\n WasmRealtimeEngine,\n} from './sonare.js';\n\nexport type EngineClip = WasmEngineClip;\nexport type ClipPageRequest = WasmClipPageRequest;\nexport type EngineParameterInfo = WasmEngineParameterInfo;\nexport type EngineAutomationPoint = WasmEngineAutomationPoint;\nexport type EngineMarker = WasmEngineMarker;\nexport type EngineMetronomeConfig = WasmEngineMetronomeConfig;\nexport type EngineGraphSpec = WasmEngineGraphSpec;\nexport type EngineCaptureStatus = WasmEngineCaptureStatus;\nexport type EngineBounceOptions = WasmEngineBounceOptions;\nexport type EngineBounceResult = WasmEngineBounceResult;\nexport type EngineFreezeOptions = WasmEngineFreezeOptions;\nexport type EngineFreezeResult = WasmEngineFreezeResult;\nexport type EngineTelemetry = WasmEngineTelemetry;\nexport type EngineMeterTelemetry = WasmEngineMeterTelemetry;\nexport type EngineTransportState = WasmEngineTransportState;\n\nexport const EXPECTED_ENGINE_ABI_VERSION = 3;\n\n/** Options for {@link RealtimeEngine.bindMidiCc}. All fields are optional. */\nexport interface MidiCcBindOptions {\n /** Lower end of the mapped parameter range. Default `0`. */\n minValue?: number;\n /** Upper end of the mapped parameter range. Default `1`. */\n maxValue?: number;\n}\n\nexport interface EngineCapabilities {\n engineAbiVersion: number;\n expectedEngineAbiVersion: number;\n abiCompatible: boolean;\n sharedArrayBuffer: boolean;\n atomics: boolean;\n audioWorklet: boolean;\n mode: 'sab' | 'postMessage';\n}\n\nexport function engineCapabilities(): EngineCapabilities {\n const abiVersion = getSonareModule().engineAbiVersion();\n const sharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function';\n const atomics = typeof globalThis.Atomics === 'object';\n const audioWorklet =\n typeof AudioWorkletNode !== 'undefined' ||\n typeof (globalThis as typeof globalThis & { AudioWorkletProcessor?: unknown })\n .AudioWorkletProcessor !== 'undefined';\n return {\n engineAbiVersion: abiVersion,\n expectedEngineAbiVersion: EXPECTED_ENGINE_ABI_VERSION,\n abiCompatible: abiVersion === EXPECTED_ENGINE_ABI_VERSION,\n sharedArrayBuffer,\n atomics,\n audioWorklet,\n mode: sharedArrayBuffer && atomics ? 'sab' : 'postMessage',\n };\n}\n\n// Methods added to the embind RealtimeEngine that the generated `sonare.js`\n// declarations only gain after a WASM rebuild. The native handle is cast to this\n// shape so the wrapper can reach them without a stale type error.\ninterface WasmRealtimeEngineExt {\n setBuiltinInstrument: (destinationId: number, config: object) => void;\n setSynthInstrument: (destinationId: number, patch: object | string) => void;\n loadSoundFont: (data: Uint8Array) => void;\n setSf2Instrument: (destinationId: number, config: object) => void;\n clearMidiInstrument: (destinationId: number) => void;\n midiInstrumentCount: () => number;\n bindMidiCc: (\n channel: number,\n controller: number,\n paramId: number,\n minValue: number,\n maxValue: number,\n ) => void;\n clearMidiCcBindings: () => void;\n midiCcBindingCount: () => number;\n setMidiFx: (destinationId: number, configJson: string) => void;\n clearMidiFx: (destinationId: number) => void;\n setMidiInputSource: (destinationId: number) => void;\n clearMidiInputSource: () => void;\n midiInputPendingCount: () => number;\n createClipPageProvider: (numChannels: number, numSamples: number, pageFrames: number) => number;\n supplyClipPage: (providerId: number, pageIndex: number, channels: Float32Array[]) => void;\n clearClipPage: (providerId: number, pageIndex: number) => void;\n destroyClipPageProvider: (providerId: number) => void;\n popClipPageRequest: () => ClipPageRequest | null;\n pushMidiInputNoteOn: (\n group: number,\n channel: number,\n note: number,\n velocity: number,\n portTimeSamples: number,\n ) => void;\n pushMidiInputNoteOff: (\n group: number,\n channel: number,\n note: number,\n velocity: number,\n portTimeSamples: number,\n ) => void;\n pushMidiInputCc: (\n group: number,\n channel: number,\n controller: number,\n value: number,\n portTimeSamples: number,\n ) => void;\n pushMidiNoteOn: (\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n renderFrame: number,\n ) => void;\n pushMidiNoteOff: (\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n renderFrame: number,\n ) => void;\n pushMidiCc: (\n destinationId: number,\n group: number,\n channel: number,\n controller: number,\n value: number,\n renderFrame: number,\n ) => void;\n pushMidiPanic: (renderFrame: number) => void;\n clearParameters: () => void;\n}\n\nexport class RealtimeEngine {\n private native: WasmRealtimeEngine;\n\n private nativeExt(): WasmRealtimeEngineExt {\n return this.native as unknown as WasmRealtimeEngineExt;\n }\n\n constructor(\n sampleRate = 48000,\n maxBlockSize = 128,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ) {\n const module = getSonareModule();\n const capabilities = engineCapabilities();\n if (!capabilities.abiCompatible) {\n throw new Error(\n `Engine ABI mismatch: wasm=${capabilities.engineAbiVersion}, expected=${capabilities.expectedEngineAbiVersion}`,\n );\n }\n this.native = new module.RealtimeEngine(\n sampleRate,\n maxBlockSize,\n commandCapacity,\n telemetryCapacity,\n );\n }\n\n prepare(\n sampleRate: number,\n maxBlockSize: number,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ): void {\n this.native.prepare(sampleRate, maxBlockSize, commandCapacity, telemetryCapacity);\n }\n\n /** Queue a sample-accurate parameter change (engine kSetParam). */\n setParameter(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameter(paramId, value, renderFrame);\n }\n\n /** Queue a smoothed parameter change (engine kSetParamSmoothed). */\n setParameterSmoothed(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameterSmoothed(paramId, value, renderFrame);\n }\n\n setBuiltinInstrument(\n config: { destinationId?: number } & Record<string, unknown> = {},\n destinationId = config.destinationId ?? 0,\n ): void {\n this.nativeExt().setBuiltinInstrument(destinationId, config);\n }\n\n /**\n * Bind the patch-driven NativeSynth to a realtime MIDI destination. `patch`\n * is a {@link SynthPatch} or a preset-name string (`'saw-lead'` /\n * `'va:saw-lead'`; see {@link synthPresetNames}), resolving exactly like\n * {@link Project.bounceWithSynthInstrument}. Live note/CC commands and\n * scheduled MIDI clips routed to that destination render through the synth.\n * Unknown preset names throw. An object patch's `destinationId` is a JS\n * binding convenience, not part of the NativeSynth patch itself.\n */\n setSynthInstrument(\n patch: SynthPatch | string = {},\n destinationId = (typeof patch === 'object' ? patch.destinationId : undefined) ?? 0,\n ): void {\n this.nativeExt().setSynthInstrument(destinationId, patch);\n }\n\n /**\n * Load (parse) SoundFont 2 bytes into the engine so SF2 instruments can be\n * bound with {@link setSf2Instrument}. The host fetches the `.sf2` and\n * passes the raw bytes; they are copied into linear memory for the call and\n * not referenced afterwards. Replaces any previously loaded SoundFont.\n */\n loadSoundFont(data: Uint8Array): void {\n this.nativeExt().loadSoundFont(data);\n }\n\n /**\n * Bind a GS-compatible SoundFont player to a realtime MIDI destination, fed\n * by the engine's loaded SoundFont ({@link loadSoundFont}). Live note/CC\n * commands and scheduled MIDI clips routed to that destination render\n * through the player (16 MIDI channels, channel 10 drums, GS NRPN part\n * edits, GS/GM SysEx resets). Without a loaded SoundFont — or for programs\n * the SoundFont does not cover — notes play through the built-in\n * synthesizer GM fallback bank (the data-free floor).\n */\n setSf2Instrument(\n config: { destinationId?: number; gain?: number; polyphony?: number } = {},\n destinationId = config.destinationId ?? 0,\n ): void {\n this.nativeExt().setSf2Instrument(destinationId, config);\n }\n\n clearMidiInstrument(destinationId = 0): void {\n this.nativeExt().clearMidiInstrument(destinationId);\n }\n\n midiInstrumentCount(): number {\n return this.nativeExt().midiInstrumentCount();\n }\n\n /**\n * Bind a live MIDI CC to an engine automation parameter. The MIDI event still\n * reaches the destination instrument; when bound, its 7-bit value is also\n * mapped into [minValue, maxValue] for `paramId`.\n */\n bindMidiCc(\n channel: number,\n controller: number,\n paramId: number,\n options: MidiCcBindOptions = {},\n ): void {\n this.nativeExt().bindMidiCc(\n channel,\n controller,\n paramId,\n options.minValue ?? 0,\n options.maxValue ?? 1,\n );\n }\n\n clearMidiCcBindings(): void {\n this.nativeExt().clearMidiCcBindings();\n }\n\n midiCcBindingCount(): number {\n return this.nativeExt().midiCcBindingCount();\n }\n\n /** Install/replace a live non-destructive MIDI-FX insert for one destination. */\n setMidiFx(destinationId: number, configJson: string): void {\n this.nativeExt().setMidiFx(destinationId, configJson);\n }\n\n clearMidiFx(destinationId = 0): void {\n this.nativeExt().clearMidiFx(destinationId);\n }\n\n /** Enable the engine-owned live MIDI input source for a destination. */\n setMidiInputSource(destinationId = 0): void {\n this.nativeExt().setMidiInputSource(destinationId);\n }\n\n clearMidiInputSource(): void {\n this.nativeExt().clearMidiInputSource();\n }\n\n midiInputPendingCount(): number {\n return this.nativeExt().midiInputPendingCount();\n }\n\n pushMidiInputNoteOn(\n group: number,\n channel: number,\n note: number,\n velocity: number,\n portTimeSamples = 0,\n ): void {\n this.nativeExt().pushMidiInputNoteOn(group, channel, note, velocity, portTimeSamples);\n }\n\n pushMidiInputNoteOff(\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n portTimeSamples = 0,\n ): void {\n this.nativeExt().pushMidiInputNoteOff(group, channel, note, velocity, portTimeSamples);\n }\n\n pushMidiInputCc(\n group: number,\n channel: number,\n controller: number,\n value: number,\n portTimeSamples = 0,\n ): void {\n this.nativeExt().pushMidiInputCc(group, channel, controller, value, portTimeSamples);\n }\n\n pushMidiNoteOn(\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n renderFrame = -1,\n ): void {\n this.nativeExt().pushMidiNoteOn(destinationId, group, channel, note, velocity, renderFrame);\n }\n\n pushMidiNoteOff(\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n renderFrame = -1,\n ): void {\n this.nativeExt().pushMidiNoteOff(destinationId, group, channel, note, velocity, renderFrame);\n }\n\n /**\n * Queue an immediate (live) MIDI control change to a MIDI destination\n * (engine kMidiCcImmediate). `group`/`channel` are 0..15; `controller`/`value`\n * are 7-bit (0..127). `renderFrame` is the frame to fire at, or -1 for\n * immediate. Mirrors the Node/Python/C-ABI `pushMidiCc`.\n */\n pushMidiCc(\n destinationId: number,\n group: number,\n channel: number,\n controller: number,\n value: number,\n renderFrame = -1,\n ): void {\n this.nativeExt().pushMidiCc(destinationId, group, channel, controller, value, renderFrame);\n }\n\n /**\n * Queue a MIDI panic (all-notes-off) releasing every sounding note at\n * `renderFrame` (-1 = immediate). Mirrors the C-ABI `pushMidiPanic`.\n */\n pushMidiPanic(renderFrame = -1): void {\n this.nativeExt().pushMidiPanic(renderFrame);\n }\n\n /**\n * Remove all registered parameters (and their automation lanes). Control-thread\n * only; not realtime-safe. Mirrors the C-ABI `clearParameters`.\n */\n clearParameters(): void {\n this.nativeExt().clearParameters();\n }\n\n /** Read back the current transport state snapshot. */\n getTransportState(): EngineTransportState {\n return this.native.getTransportState();\n }\n\n play(renderFrame = -1): void {\n this.native.play(renderFrame);\n }\n\n stop(renderFrame = -1): void {\n this.native.stop(renderFrame);\n }\n\n seekSample(timelineSample: number, renderFrame = -1): void {\n this.native.seekSample(timelineSample, renderFrame);\n }\n\n seekPpq(ppq: number, renderFrame = -1): void {\n this.native.seekPpq(ppq, renderFrame);\n }\n\n setTempo(bpm: number): void {\n this.native.setTempo(bpm);\n }\n\n setTimeSignature(numerator: number, denominator: number): void {\n this.native.setTimeSignature(numerator, denominator);\n }\n\n setLoop(startPpq: number, endPpq: number, enabled = true): void {\n this.native.setLoop(startPpq, endPpq, enabled);\n }\n\n addParameter(info: EngineParameterInfo): void {\n this.native.addParameter(info);\n }\n\n parameterCount(): number {\n return this.native.parameterCount();\n }\n\n parameterInfoByIndex(index: number): EngineParameterInfo {\n return this.native.parameterInfoByIndex(index);\n }\n\n parameterInfo(id: number): EngineParameterInfo {\n return this.native.parameterInfo(id);\n }\n\n setAutomationLane(paramId: number, points: EngineAutomationPoint[]): void {\n this.native.setAutomationLane(paramId, points);\n }\n\n automationLaneCount(): number {\n return this.native.automationLaneCount();\n }\n\n setMarkers(markers: EngineMarker[]): void {\n this.native.setMarkers(markers);\n }\n\n markerCount(): number {\n return this.native.markerCount();\n }\n\n markerByIndex(index: number): EngineMarker {\n return this.native.markerByIndex(index);\n }\n\n marker(id: number): EngineMarker {\n return this.native.marker(id);\n }\n\n seekMarker(markerId: number, renderFrame = -1): void {\n this.native.seekMarker(markerId, renderFrame);\n }\n\n setLoopFromMarkers(startMarkerId: number, endMarkerId: number): void {\n this.native.setLoopFromMarkers(startMarkerId, endMarkerId);\n }\n\n setMetronome(config: EngineMetronomeConfig): void {\n this.native.setMetronome(config);\n }\n\n metronome(): Required<EngineMetronomeConfig> {\n return this.native.metronome();\n }\n\n countInEndSample(startSample: number, bars: number): number {\n return Number(this.native.countInEndSample(startSample, bars));\n }\n\n setGraph(spec: EngineGraphSpec): void {\n this.native.setGraph(spec);\n }\n\n graphNodeCount(): number {\n return this.native.graphNodeCount();\n }\n\n graphConnectionCount(): number {\n return this.native.graphConnectionCount();\n }\n\n setClips(clips: EngineClip[]): void {\n this.native.setClips(\n clips.map((clip) => ({\n ...clip,\n pageProvider:\n typeof clip.pageProvider === 'object' && clip.pageProvider !== null\n ? clip.pageProvider.id\n : clip.pageProvider,\n })),\n );\n }\n\n clipCount(): number {\n return this.native.clipCount();\n }\n\n createClipPageProvider(\n numChannels: number,\n numSamples: number,\n pageFrames: number,\n ): ClipPageProvider {\n const id = this.nativeExt().createClipPageProvider(numChannels, numSamples, pageFrames);\n return new ClipPageProvider(this, id);\n }\n\n supplyClipPage(providerId: number, pageIndex: number, channels: Float32Array[]): void {\n this.nativeExt().supplyClipPage(providerId, pageIndex, channels);\n }\n\n clearClipPage(providerId: number, pageIndex: number): void {\n this.nativeExt().clearClipPage(providerId, pageIndex);\n }\n\n destroyClipPageProvider(providerId: number): void {\n this.nativeExt().destroyClipPageProvider(providerId);\n }\n\n popClipPageRequest(): ClipPageRequest | null {\n return this.nativeExt().popClipPageRequest();\n }\n\n setCaptureBuffer(numChannels: number, capacityFrames: number): void {\n this.native.setCaptureBuffer(numChannels, capacityFrames);\n }\n\n armCapture(armed = true): void {\n this.native.armCapture(armed);\n }\n\n setCapturePunch(startSample: number, endSample: number, enabled = true): void {\n this.native.setCapturePunch(startSample, endSample, enabled);\n }\n\n setCaptureSource(source: EngineCaptureStatus['source']): void {\n this.native.setCaptureSource(source);\n }\n\n setRecordOffsetSamples(offsetSamples: number): void {\n this.native.setRecordOffsetSamples(offsetSamples);\n }\n\n setInputMonitor(enabled: boolean, gain = 1): void {\n this.native.setInputMonitor(enabled, gain);\n }\n\n resetCapture(): void {\n this.native.resetCapture();\n }\n\n captureStatus(): EngineCaptureStatus {\n return this.native.captureStatus();\n }\n\n capturedAudio(): Float32Array[] {\n return this.native.capturedAudio();\n }\n\n process(channels: Float32Array[]): Float32Array[] {\n return this.native.process(channels);\n }\n\n /**\n * Allocates persistent per-channel WASM-heap scratch for the zero-copy\n * `getChannelBuffer` / `processPrepared` realtime path. Call once (off the\n * audio thread) before driving `processPrepared` from an AudioWorklet so the\n * render callback never allocates on the C++/JS heap.\n */\n prepareChannels(numChannels: number, maxFrames: number): void {\n this.native.prepareChannels(numChannels, maxFrames);\n }\n\n /**\n * Returns a Float32Array view onto the persistent WASM-heap scratch for one\n * channel (valid for up to `numFrames`). Fill it, call `processPrepared`, then\n * read the same view back. Re-acquire after WASM memory growth.\n */\n getChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.native.getChannelBuffer(channel, numFrames);\n }\n\n /**\n * Runs the engine in place over the prepared per-channel scratch buffers.\n * Allocation-free: safe to call on the AudioWorklet render thread after\n * `prepareChannels`.\n */\n processPrepared(numFrames: number): void {\n this.native.processPrepared(numFrames);\n }\n\n processWithMonitor(channels: Float32Array[]): WasmEngineProcessWithMonitorResult {\n return this.native.processWithMonitor(channels);\n }\n\n renderOffline(channels: Float32Array[], blockSize = 128): Float32Array[] {\n return this.native.renderOffline(channels, blockSize);\n }\n\n bounceOffline(options: EngineBounceOptions): EngineBounceResult {\n return this.native.bounceOffline(options);\n }\n\n freezeOffline(options: EngineFreezeOptions): EngineFreezeResult {\n return this.native.freezeOffline(options);\n }\n\n drainTelemetry(maxRecords = 1024): EngineTelemetry[] {\n return this.native.drainTelemetry(maxRecords);\n }\n\n drainMeterTelemetry(maxRecords = 1024): EngineMeterTelemetry[] {\n return this.native.drainMeterTelemetry(maxRecords);\n }\n\n destroy(): void {\n this.native.delete();\n }\n}\n\nexport class ClipPageProvider {\n private disposed = false;\n\n constructor(\n private readonly engine: RealtimeEngine,\n readonly id: number,\n ) {}\n\n supply(pageIndex: number, channels: Float32Array[]): void {\n if (this.disposed) {\n throw new Error('ClipPageProvider is destroyed');\n }\n this.engine.supplyClipPage(this.id, pageIndex, channels);\n }\n\n clear(pageIndex: number): void {\n if (this.disposed) {\n return;\n }\n this.engine.clearClipPage(this.id, pageIndex);\n }\n\n destroy(): void {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.engine.destroyClipPageProvider(this.id);\n }\n}\n","import { getSonareModule } from './module_state';\nimport { assertFiniteScalar } from './validation';\n\n// ============================================================================\n// Editing — 12-TET scale quantizer\n// ============================================================================\n\n/**\n * Snap a MIDI value to the nearest pitch class enabled by `modeMask`.\n *\n * `modeMask` is a 12-bit mask. For natural C major use `0b101010110101`.\n * `referenceMidi` defaults to A4 (69) when passed as 0.\n */\nexport function scaleQuantizeMidi(\n root: number,\n modeMask: number,\n midi: number,\n referenceMidi = 0,\n): number {\n assertFiniteScalar('scaleQuantizeMidi', midi, 'midi');\n assertFiniteScalar('scaleQuantizeMidi', referenceMidi, 'referenceMidi');\n return getSonareModule().scaleQuantizeMidi(root, modeMask, midi, referenceMidi);\n}\n\nexport function scaleCorrectionSemitones(\n root: number,\n modeMask: number,\n midi: number,\n referenceMidi = 0,\n): number {\n assertFiniteScalar('scaleCorrectionSemitones', midi, 'midi');\n assertFiniteScalar('scaleCorrectionSemitones', referenceMidi, 'referenceMidi');\n return getSonareModule().scaleCorrectionSemitones(root, modeMask, midi, referenceMidi);\n}\n\nexport function scalePitchClassEnabled(\n root: number,\n modeMask: number,\n pitchClass: number,\n): boolean {\n return getSonareModule().scalePitchClassEnabled(root, modeMask, pitchClass);\n}\n","import { getSonareModule } from './module_state';\nimport type { ChordQuality, PitchClass } from './public_types';\nimport type { WasmStreamAnalyzer } from './sonare.js';\nimport type {\n AnalyzerStats,\n FrameBuffer,\n StreamConfig,\n StreamConfigDefaults,\n StreamFramesI16,\n StreamFramesU8,\n StreamQuantizeConfig,\n} from './stream_types';\n\n// ============================================================================\n// StreamAnalyzer Class\n// ============================================================================\n\nexport function streamAnalyzerConfigDefaults(): StreamConfigDefaults {\n return getSonareModule().streamAnalyzerConfigDefault();\n}\n\n/**\n * Real-time streaming audio analyzer.\n *\n * @example\n * ```typescript\n * import { init, StreamAnalyzer } from '@libraz/libsonare';\n *\n * await init();\n *\n * const analyzer = new StreamAnalyzer({ sampleRate: 44100 });\n *\n * // In audio processing callback\n * analyzer.process(samples);\n *\n * // Get current analysis state\n * const stats = analyzer.stats();\n * console.log('BPM:', stats.estimate.bpm);\n * console.log('Key:', stats.estimate.key);\n * console.log('Chord progression:', stats.estimate.chordProgression);\n * ```\n */\nexport class StreamAnalyzer {\n private analyzer: WasmStreamAnalyzer;\n\n /**\n * Create a new StreamAnalyzer.\n *\n * @param config - Configuration options\n */\n constructor(config: StreamConfig = {}) {\n if (config.computeMagnitude) {\n throw new Error(\n 'computeMagnitude is not supported because magnitude frames are not exposed by StreamAnalyzer read paths.',\n );\n }\n const module = getSonareModule();\n const defaults = streamAnalyzerConfigDefaults();\n this.analyzer = new module.StreamAnalyzer(\n config.sampleRate ?? defaults.sampleRate,\n config.nFft ?? defaults.nFft,\n config.hopLength ?? defaults.hopLength,\n config.nMels ?? defaults.nMels,\n config.fmin ?? defaults.fmin,\n config.fmax ?? defaults.fmax,\n config.tuningRefHz ?? defaults.tuningRefHz,\n config.computeMagnitude ?? defaults.computeMagnitude,\n config.computeMel ?? defaults.computeMel,\n config.computeChroma ?? defaults.computeChroma,\n config.computeOnset ?? defaults.computeOnset,\n config.computeSpectral ?? defaults.computeSpectral,\n config.emitEveryNFrames ?? defaults.emitEveryNFrames,\n config.magnitudeDownsample ?? defaults.magnitudeDownsample,\n config.keyUpdateIntervalSec ?? defaults.keyUpdateIntervalSec,\n config.bpmUpdateIntervalSec ?? defaults.bpmUpdateIntervalSec,\n config.window ?? defaults.window,\n config.outputFormat ?? defaults.outputFormat,\n );\n }\n\n /**\n * Process audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n */\n process(samples: Float32Array): void {\n this.analyzer.process(samples);\n }\n\n /**\n * Process audio samples with explicit sample offset.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleOffset - Cumulative sample count at start of this chunk\n */\n processWithOffset(samples: Float32Array, sampleOffset: number): void {\n this.analyzer.processWithOffset(samples, sampleOffset);\n }\n\n /**\n * Flush the final partial frame with zero-padding.\n */\n finalize(): void {\n this.analyzer.finalize();\n }\n\n /**\n * Get the number of frames available to read.\n */\n availableFrames(): number {\n return this.analyzer.availableFrames();\n }\n\n /**\n * Read processed frames as Structure of Arrays.\n *\n * @param maxFrames - Maximum number of frames to read\n * @returns Frame buffer with analysis results\n */\n readFrames(maxFrames: number): FrameBuffer {\n return this.analyzer.readFramesSoa(maxFrames);\n }\n\n /**\n * Read frames as uint8-quantized arrays.\n *\n * @param maxFrames - Maximum number of frames to read\n * @param quantizeConfig - Optional quantization ranges; widen these for a\n * stream louder or quieter than the defaults (omitted keeps the defaults)\n */\n readFramesU8(maxFrames: number, quantizeConfig?: StreamQuantizeConfig): StreamFramesU8 {\n return this.analyzer.readFramesU8(maxFrames, quantizeConfig) as StreamFramesU8;\n }\n\n /**\n * Read frames as int16-quantized arrays.\n *\n * @param maxFrames - Maximum number of frames to read\n * @param quantizeConfig - Optional quantization ranges; widen these for a\n * stream louder or quieter than the defaults (omitted keeps the defaults)\n */\n readFramesI16(maxFrames: number, quantizeConfig?: StreamQuantizeConfig): StreamFramesI16 {\n return this.analyzer.readFramesI16(maxFrames, quantizeConfig) as StreamFramesI16;\n }\n\n /**\n * Reset the analyzer state.\n *\n * @param baseSampleOffset - Starting sample offset (default 0)\n */\n reset(baseSampleOffset = 0): void {\n this.analyzer.reset(baseSampleOffset);\n }\n\n /**\n * Get current statistics and progressive estimates.\n *\n * @returns Analyzer statistics including BPM, key, and chord progression\n */\n stats(): AnalyzerStats {\n const s = this.analyzer.stats();\n return {\n totalFrames: s.totalFrames,\n totalSamples: s.totalSamples,\n durationSeconds: s.durationSeconds,\n estimate: {\n bpm: s.estimate.bpm,\n bpmConfidence: s.estimate.bpmConfidence,\n bpmCandidateCount: s.estimate.bpmCandidateCount,\n key: s.estimate.key as PitchClass,\n keyMinor: s.estimate.keyMinor,\n keyConfidence: s.estimate.keyConfidence,\n chordRoot: s.estimate.chordRoot as PitchClass,\n chordQuality: s.estimate.chordQuality as ChordQuality,\n chordConfidence: s.estimate.chordConfidence,\n chordStartTime: s.estimate.chordStartTime,\n chordProgression: s.estimate.chordProgression.map((c) => ({\n root: c.root as PitchClass,\n quality: c.quality as ChordQuality,\n startTime: c.startTime,\n confidence: c.confidence,\n })),\n barChordProgression: s.estimate.barChordProgression.map((c) => ({\n barIndex: c.barIndex,\n root: c.root as PitchClass,\n quality: c.quality as ChordQuality,\n startTime: c.startTime,\n confidence: c.confidence,\n })),\n currentBar: s.estimate.currentBar,\n barDuration: s.estimate.barDuration,\n votedPattern: (s.estimate.votedPattern || []).map((c) => ({\n barIndex: c.barIndex,\n root: c.root as PitchClass,\n quality: c.quality as ChordQuality,\n startTime: c.startTime,\n confidence: c.confidence,\n })),\n patternLength: s.estimate.patternLength,\n detectedPatternName: s.estimate.detectedPatternName || '',\n detectedPatternScore: s.estimate.detectedPatternScore || 0,\n allPatternScores: (s.estimate.allPatternScores || []).map((p) => ({\n name: p.name,\n score: p.score,\n })),\n accumulatedSeconds: s.estimate.accumulatedSeconds,\n usedFrames: s.estimate.usedFrames,\n updated: s.estimate.updated,\n },\n };\n }\n\n /**\n * Get total frames processed.\n */\n frameCount(): number {\n return this.analyzer.frameCount();\n }\n\n /**\n * Get current time position in seconds.\n */\n currentTime(): number {\n return this.analyzer.currentTime();\n }\n\n /**\n * Get the sample rate.\n */\n sampleRate(): number {\n return this.analyzer.sampleRate();\n }\n\n /**\n * Set the expected total duration for pattern lock timing.\n *\n * @param durationSeconds - Total duration in seconds\n */\n setExpectedDuration(durationSeconds: number): void {\n this.analyzer.setExpectedDuration(durationSeconds);\n }\n\n /**\n * Set normalization gain for loud/compressed audio.\n *\n * @param gain - Gain factor to apply (e.g., 0.5 for -6dB reduction)\n */\n setNormalizationGain(gain: number): void {\n this.analyzer.setNormalizationGain(gain);\n }\n\n /**\n * Set tuning reference frequency for non-standard tuning.\n *\n * @param refHz - Reference frequency for A4 (default 440 Hz)\n * @example\n * // If audio is 1 semitone sharp (A4 = 466.16 Hz)\n * analyzer.setTuningRefHz(466.16);\n * // If audio is 1 semitone flat (A4 = 415.30 Hz)\n * analyzer.setTuningRefHz(415.30);\n */\n setTuningRefHz(refHz: number): void {\n this.analyzer.setTuningRefHz(refHz);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.analyzer.delete();\n }\n\n /** Alias for {@link delete}, kept for backward compatibility (historical name). */\n dispose(): void {\n this.delete();\n }\n}\n","import type { MidiCcBindOptions, RealtimeEngine } from './realtime_engine';\n\ntype MidiInputState = 'connected' | 'disconnected';\n\ninterface MidiPortLike {\n id: string;\n name?: string | null;\n manufacturer?: string | null;\n state?: MidiInputState;\n}\n\ninterface MidiMessageEventLike {\n data: ArrayLike<number>;\n timeStamp?: number;\n receivedTime?: number;\n target?: MidiPortLike;\n currentTarget?: MidiPortLike;\n}\n\ninterface MidiInputLike extends MidiPortLike {\n type?: 'input';\n onmidimessage: ((event: MidiMessageEventLike) => void) | null;\n addEventListener?: (type: 'midimessage', listener: (event: MidiMessageEventLike) => void) => void;\n removeEventListener?: (\n type: 'midimessage',\n listener: (event: MidiMessageEventLike) => void,\n ) => void;\n}\n\ninterface MidiConnectionEventLike {\n port?: MidiPortLike | null;\n}\n\ninterface MidiAccessLike {\n inputs: Map<string, MidiInputLike> | Iterable<[string, MidiInputLike]>;\n onstatechange: ((event: MidiConnectionEventLike) => void) | null;\n addEventListener?: (\n type: 'statechange',\n listener: (event: MidiConnectionEventLike) => void,\n ) => void;\n removeEventListener?: (\n type: 'statechange',\n listener: (event: MidiConnectionEventLike) => void,\n ) => void;\n}\n\ninterface NavigatorWithMidi {\n requestMIDIAccess?: (options?: {\n sysex?: boolean;\n software?: boolean;\n }) => Promise<MidiAccessLike>;\n}\n\nexport interface WebMidiCcBinding {\n channel: number;\n controller: number;\n paramId: number;\n options?: MidiCcBindOptions;\n}\n\nexport interface WebMidiInputInfo {\n id: string;\n name: string;\n manufacturer: string;\n state: MidiInputState;\n}\n\nexport interface BindWebMidiOptions {\n /** Realtime-engine MIDI destination receiving the live input source. Default `0`. */\n destinationId?: number;\n /** UMP group used for MIDI 1.0 channel voice events. Default `0`. */\n group?: number;\n /** Restrict binding to specific Web MIDI input ids. Omit or empty = all connected inputs. */\n inputIds?: readonly string[];\n /** Request SysEx-capable access from the browser. Default `false`. */\n sysex?: boolean;\n /** Request software ports from the browser where supported. Default `true`. */\n software?: boolean;\n /** Bind CC-to-parameter mappings before ports are connected. */\n ccBindings?: readonly WebMidiCcBinding[];\n /** Convert a Web MIDI event timestamp to engine port-time samples. */\n timestampToSamples?: (eventTimeMs: number) => number;\n /** Observe hot-plug updates after the helper rebinds matching inputs. */\n onInputsChanged?: (inputs: WebMidiInputInfo[]) => void;\n}\n\nexport interface WebMidiBinding {\n access: MidiAccessLike;\n inputs(): WebMidiInputInfo[];\n close(): void;\n}\n\ntype BoundInput = {\n input: MidiInputLike;\n listener: (event: MidiMessageEventLike) => void;\n};\n\nexport function isWebMidiAvailable(): boolean {\n return (\n typeof (globalThis.navigator as NavigatorWithMidi | undefined)?.requestMIDIAccess === 'function'\n );\n}\n\nexport async function bindWebMidi(\n engine: RealtimeEngine,\n options: BindWebMidiOptions = {},\n): Promise<WebMidiBinding> {\n const requestMIDIAccess = (globalThis.navigator as NavigatorWithMidi | undefined)\n ?.requestMIDIAccess;\n if (typeof requestMIDIAccess !== 'function') {\n throw new Error('Web MIDI is not available in this environment');\n }\n\n const group = options.group ?? 0;\n assertNibble('bindWebMidi', group, 'group');\n const destinationId = options.destinationId ?? 0;\n const selectedIds = new Set(options.inputIds ?? []);\n const access = await requestMIDIAccess({\n sysex: options.sysex ?? false,\n software: options.software ?? true,\n });\n\n for (const binding of options.ccBindings ?? []) {\n engine.bindMidiCc(binding.channel, binding.controller, binding.paramId, binding.options);\n }\n engine.setMidiInputSource(destinationId);\n\n const bound = new Map<string, BoundInput>();\n let closed = false;\n let runningStatus = 0;\n\n const shouldBind = (input: MidiInputLike) =>\n input.state !== 'disconnected' && (selectedIds.size === 0 || selectedIds.has(input.id));\n\n const snapshotInputs = (): WebMidiInputInfo[] =>\n Array.from(iterInputs(access), ([id, input]) => ({\n id,\n name: input.name ?? '',\n manufacturer: input.manufacturer ?? '',\n state: input.state ?? 'connected',\n }));\n\n const notify = () => options.onInputsChanged?.(snapshotInputs());\n\n const bindInput = (input: MidiInputLike) => {\n if (bound.has(input.id) || !shouldBind(input)) {\n return;\n }\n const listener = (event: MidiMessageEventLike) => {\n const status = dispatchMidiMessage(\n engine,\n event,\n group,\n runningStatus,\n options.timestampToSamples,\n );\n if (status !== 0) {\n runningStatus = status;\n }\n };\n if (input.addEventListener) {\n input.addEventListener('midimessage', listener);\n } else {\n input.onmidimessage = listener;\n }\n bound.set(input.id, { input, listener });\n };\n\n const unbindInput = (input: MidiInputLike) => {\n const entry = bound.get(input.id);\n if (!entry) {\n return;\n }\n if (entry.input.removeEventListener) {\n entry.input.removeEventListener('midimessage', entry.listener);\n } else if (entry.input.onmidimessage === entry.listener) {\n entry.input.onmidimessage = null;\n }\n bound.delete(input.id);\n };\n\n const refreshInputs = () => {\n for (const [, entry] of bound) {\n if (!shouldBind(entry.input)) {\n unbindInput(entry.input);\n }\n }\n for (const [, input] of iterInputs(access)) {\n bindInput(input);\n }\n notify();\n };\n\n const stateListener = (event: MidiConnectionEventLike) => {\n if (closed) {\n return;\n }\n if (event.port && 'onmidimessage' in event.port) {\n const input = event.port as MidiInputLike;\n if (shouldBind(input)) {\n bindInput(input);\n } else {\n unbindInput(input);\n }\n } else {\n refreshInputs();\n }\n notify();\n };\n\n refreshInputs();\n if (access.addEventListener) {\n access.addEventListener('statechange', stateListener);\n } else {\n access.onstatechange = stateListener;\n }\n\n return {\n access,\n inputs: snapshotInputs,\n close() {\n closed = true;\n if (access.removeEventListener) {\n access.removeEventListener('statechange', stateListener);\n } else if (access.onstatechange === stateListener) {\n access.onstatechange = null;\n }\n for (const [, entry] of Array.from(bound)) {\n unbindInput(entry.input);\n }\n engine.clearMidiInputSource();\n },\n };\n}\n\nfunction dispatchMidiMessage(\n engine: RealtimeEngine,\n event: MidiMessageEventLike,\n group: number,\n runningStatus: number,\n timestampToSamples?: (eventTimeMs: number) => number,\n): number {\n const data = event.data;\n if (data.length === 0) {\n return 0;\n }\n const first = data[0];\n if (first > 0xff) {\n dispatchUmpMessage(\n engine,\n data,\n timestampToSamples?.(event.receivedTime ?? event.timeStamp ?? 0) ?? 0,\n );\n return 0;\n }\n\n let offset = 0;\n let status = first & 0xff;\n if (status < 0x80) {\n if (runningStatus === 0) {\n return 0;\n }\n status = runningStatus;\n } else {\n offset = 1;\n }\n\n const message = status & 0xf0;\n const channel = status & 0x0f;\n if (message < 0x80 || message > 0xe0) {\n return status;\n }\n\n const a = readU7(data, offset);\n const b = readU7(data, offset + 1);\n if (a < 0) {\n return status;\n }\n\n const portTimeSamples = timestampToSamples\n ? timestampToSamples(event.receivedTime ?? event.timeStamp ?? 0)\n : 0;\n\n if (message === 0x80) {\n engine.pushMidiInputNoteOff(group, channel, a, b < 0 ? 0 : b, portTimeSamples);\n } else if (message === 0x90) {\n if ((b < 0 ? 0 : b) === 0) {\n engine.pushMidiInputNoteOff(group, channel, a, 0, portTimeSamples);\n } else {\n engine.pushMidiInputNoteOn(group, channel, a, b, portTimeSamples);\n }\n } else if (message === 0xb0 && b >= 0) {\n engine.pushMidiInputCc(group, channel, a, b, portTimeSamples);\n }\n\n return status;\n}\n\nfunction dispatchUmpMessage(\n engine: RealtimeEngine,\n words: ArrayLike<number>,\n portTimeSamples: number,\n): void {\n const word0 = words[0] >>> 0;\n const messageType = word0 >>> 28;\n const group = (word0 >>> 24) & 0x0f;\n\n if (messageType === 0x2) {\n const status = (word0 >>> 16) & 0xff;\n const message = status & 0xf0;\n const channel = status & 0x0f;\n const a = (word0 >>> 8) & 0x7f;\n const b = word0 & 0x7f;\n if (message === 0x80) {\n engine.pushMidiInputNoteOff(group, channel, a, b, portTimeSamples);\n } else if (message === 0x90) {\n if (b === 0) {\n engine.pushMidiInputNoteOff(group, channel, a, 0, portTimeSamples);\n } else {\n engine.pushMidiInputNoteOn(group, channel, a, b, portTimeSamples);\n }\n } else if (message === 0xb0) {\n engine.pushMidiInputCc(group, channel, a, b, portTimeSamples);\n }\n return;\n }\n\n if (messageType === 0x4 && words.length >= 2) {\n const status = (word0 >>> 20) & 0x0f;\n const channel = (word0 >>> 16) & 0x0f;\n const data1 = (word0 >>> 8) & 0x7f;\n const word1 = words[1] >>> 0;\n if (status === 0x8) {\n engine.pushMidiInputNoteOff(group, channel, data1, (word1 >>> 25) & 0x7f, portTimeSamples);\n } else if (status === 0x9) {\n const velocity = (word1 >>> 25) & 0x7f;\n if (velocity === 0) {\n engine.pushMidiInputNoteOff(group, channel, data1, 0, portTimeSamples);\n } else {\n engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);\n }\n } else if (status === 0xb) {\n engine.pushMidiInputCc(group, channel, data1, (word1 >>> 25) & 0x7f, portTimeSamples);\n }\n }\n}\n\nfunction readU7(data: ArrayLike<number>, index: number): number {\n if (index >= data.length) {\n return -1;\n }\n const value = data[index];\n if (!Number.isInteger(value) || value < 0 || value > 127) {\n return -1;\n }\n return value;\n}\n\nfunction assertNibble(fnName: string, value: number, field: string): void {\n if (!Number.isInteger(value) || value < 0 || value > 15) {\n throw new RangeError(`${fnName}: ${field} must be an integer in [0, 15]`);\n }\n}\n\nfunction iterInputs(access: MidiAccessLike): Iterable<[string, MidiInputLike]> {\n return access.inputs instanceof Map ? access.inputs.entries() : access.inputs;\n}\n","/**\n * sonare - Audio Analysis Library\n *\n * @example\n * ```typescript\n * import { init, detectBpm, detectKey, analyze } from '@libraz/libsonare';\n *\n * await init();\n *\n * // Detect BPM from audio samples\n * const bpm = detectBpm(samples, sampleRate);\n *\n * // Detect musical key\n * const key = detectKey(samples, sampleRate);\n *\n * // Full analysis\n * const result = analyze(samples, sampleRate);\n * ```\n */\n\nimport { setSonareModule } from './module_state';\nimport type { RealtimeVoiceChangerPodConfig, VoicePresetId } from './public_types';\nimport type {\n SonareModule,\n WasmDecomposeResult,\n WasmHpssWithResidualResult,\n WasmMatrix2dResult,\n} from './sonare.js';\n\nexport type { BrowserAudioDecodeOptions } from './audio';\nexport { Audio } from './audio';\nexport type {\n CompressorDetector,\n CompressorOptions,\n DeclickOptions,\n DeclipOptions,\n DecrackleMode,\n DecrackleOptions,\n DehumOptions,\n DenoiseClassicalMode,\n DenoiseClassicalNoiseEstimator,\n DenoiseClassicalOptions,\n DereverbClassicalOptions,\n DynamicsResult,\n GateOptions,\n TransientShaperOptions,\n TrimSilenceMode,\n TrimSilenceOptions,\n VoiceChangeOptions,\n VoiceChangeRealtimeOptions,\n} from './effects_mastering';\nexport {\n harmonic,\n hpss,\n masterAudio,\n masterAudioStereo,\n masterAudioStereoWithProgress,\n masterAudioWithProgress,\n mastering,\n masteringAssistantSuggest,\n masteringAudioProfile,\n masteringChain,\n masteringChainStereo,\n masteringChainStereoWithProgress,\n masteringChainWithProgress,\n masteringDynamicsCompressor,\n masteringDynamicsGate,\n masteringDynamicsTransientShaper,\n masteringInsertNames,\n masteringPairAnalysisNames,\n masteringPairAnalyze,\n masteringPairProcess,\n masteringPairProcessorNames,\n masteringPresetNames,\n masteringProcess,\n masteringProcessorNames,\n masteringProcessStereo,\n masteringRepairDeclick,\n masteringRepairDeclip,\n masteringRepairDecrackle,\n masteringRepairDehum,\n masteringRepairDenoiseClassical,\n masteringRepairDereverbClassical,\n masteringRepairTrimSilence,\n masteringStereoAnalysisNames,\n masteringStereoAnalyze,\n masteringStreamingPreview,\n mixingScenePresetJson,\n mixingScenePresetNames,\n mixStereo,\n normalize,\n noteStretch,\n percussive,\n pitchCorrectToMidi,\n pitchCorrectToMidiTimevarying,\n pitchShift,\n timeStretch,\n voiceChange,\n voiceChangeRealtime,\n} from './effects_mastering';\nexport type { MelodyOptions } from './feature_music';\nexport {\n amplitudeToDb,\n analyzeMelody,\n analyzeSections,\n bassChroma,\n chroma,\n chromaCens,\n cqt,\n cyclicTempogram,\n dbToAmplitude,\n dbToPower,\n decompose,\n decomposeWithInit,\n deemphasis,\n ebur128LoudnessRange,\n estimateTuning,\n fixFrames,\n fixLength,\n fourierTempogram,\n frameSignal,\n framesToSamples,\n framesToTime,\n hpssWithResidual,\n hybridCqt,\n hzToMel,\n hzToMidi,\n hzToNote,\n lufs,\n lufsInterleaved,\n melSpectrogram,\n melToAudio,\n melToHz,\n melToStft,\n mfcc,\n mfccToAudio,\n mfccToMel,\n midiToHz,\n momentaryLufs,\n nnFilter,\n nnlsChroma,\n noteToHz,\n onsetEnvelope,\n onsetStrengthMulti,\n padCenter,\n pcen,\n peakPick,\n phaseVocoder,\n pitchPyin,\n pitchTuning,\n pitchYin,\n plp,\n polyFeatures,\n powerToDb,\n preemphasis,\n pseudoCqt,\n remix,\n resample,\n rmsEnergy,\n samplesToFrames,\n shortTermLufs,\n spectralBandwidth,\n spectralCentroid,\n spectralContrast,\n spectralFlatness,\n spectralRolloff,\n splitSilence,\n stft,\n stftDb,\n tempogram,\n tempogramRatio,\n timeToFrames,\n tonnetz,\n trim,\n trimSilence,\n vectorNormalize,\n vqt,\n zeroCrossingRate,\n zeroCrossings,\n} from './features';\nexport type { BindMicrophoneInputOptions, MicrophoneInputBinding } from './live_audio';\nexport { bindMicrophoneInput } from './live_audio';\nexport type {\n ClippingRegion,\n ClippingReport,\n DynamicRangeReport,\n MeteringDetectClippingOptions,\n MeteringDynamicRangeOptions,\n PhaseScopeReport,\n SpectrumOptions,\n SpectrumReport,\n VectorscopeReport,\n WaveformPeakPyramidOptions,\n WaveformPeaksOptions,\n WaveformPeaksReport,\n} from './metering';\nexport {\n meteringCrestFactorDb,\n meteringDcOffset,\n meteringDetectClipping,\n meteringDynamicRange,\n meteringPeakDb,\n meteringPhaseScope,\n meteringPhaseScopeDecimated,\n meteringRmsDb,\n meteringSpectrum,\n meteringSpectrumFrame,\n meteringStereoCorrelation,\n meteringStereoWidth,\n meteringTruePeakDb,\n meteringVectorscope,\n meteringVectorscopeDecimated,\n waveformPeakPyramid,\n waveformPeaks,\n} from './metering';\nexport type {\n OpfsClipPageProviderBinding,\n OpfsClipPageProviderOptions,\n} from './opfs_clip_pages';\nexport {\n createOpfsClipPageProvider,\n createOpfsClipPageWorker,\n opfsClipPageWorkerSource,\n} from './opfs_clip_pages';\nexport type {\n BuiltinSynthBinding,\n BuiltinSynthConfig,\n BuiltinSynthWaveform,\n MidiCcLearnOptions,\n ProjectAssistSidecar,\n ProjectAutomationCurve,\n ProjectAutomationLaneDesc,\n ProjectAutomationPoint,\n ProjectBounceOptions,\n ProjectChordSymbol,\n ProjectClipCompSegment,\n ProjectClipDesc,\n ProjectClipFade,\n ProjectClipTake,\n ProjectCompileResult,\n ProjectFadeCurve,\n ProjectKeySegment,\n ProjectLoopMode,\n ProjectLoopRecordingDesc,\n ProjectLoopRecordingResult,\n ProjectMidiClipResult,\n ProjectMidiEvent,\n ProjectNotePairValidation,\n ProjectTrackDesc,\n ProjectTrackKind,\n ProjectWarpAnchor,\n ProjectWarpMapDesc,\n Sf2InstrumentConfig,\n Sf2ProgramStatus,\n SourceBackend,\n SynthBodyType,\n SynthEngineMode,\n SynthEnumTables,\n SynthFilterModel,\n SynthFilterOutput,\n SynthModDestination,\n SynthModRouting,\n SynthModSource,\n SynthOscWaveform,\n SynthPatch,\n} from './project';\nexport {\n EXPECTED_PROJECT_ABI_VERSION,\n Project,\n projectAbiVersion,\n SYNTH_BODY_TYPES,\n SYNTH_ENGINE_MODES,\n SYNTH_FILTER_MODELS,\n SYNTH_FILTER_OUTPUTS,\n SYNTH_MOD_DESTINATIONS,\n SYNTH_MOD_SOURCES,\n SYNTH_OSC_WAVEFORMS,\n synthEnumTables,\n synthPresetNames,\n synthPresetPatch,\n} from './project';\nexport type {\n AcousticOptions,\n AcousticResult,\n AnalysisResult,\n AnalyzeBpmOptions,\n AnalyzeDynamicsOptions,\n AnalyzeRhythmOptions,\n AnalyzeSectionsOptions,\n AnalyzeTimbreOptions,\n AutomationCurve,\n Beat,\n Chord,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChromaResult,\n CqtResult,\n Dynamics,\n EqBand,\n EqBandPhase,\n EqBandType,\n EqCoeffMode,\n EqMatchOptions,\n EqSpectrumSnapshot,\n EqStereoPlacement,\n GoniometerPoint,\n HpssResult,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n LufsResult,\n MasteringChainConfig,\n MasteringChainResult,\n MasteringOptions,\n MasteringPreset,\n MasteringProcessorParams,\n MasteringResult,\n MasteringStereoChainResult,\n MasteringStereoResult,\n MelodyPoint,\n MelodyResult,\n MelPowerResult,\n MelSpectrogramResult,\n MeterTap,\n MfccResult,\n MixerProcessResult,\n MixMeterSnapshot,\n MixOptions,\n MixResult,\n NoteStretchOptions,\n PairAnalysis,\n PairProcessor,\n PanLaw,\n PanMode,\n PitchResult,\n RealtimeVoiceChangerConfigInput,\n RealtimeVoiceChangerPodConfig,\n RhythmFeatures,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomGeometryOptions,\n RoomMorphOptions,\n Section,\n SendTiming,\n SoloProcessor,\n StereoAnalysis,\n StftPowerResult,\n StftResult,\n StreamingEqualizerConfig,\n StreamingMasteringChainConfig,\n StreamingPlatform,\n StreamingRetuneConfig,\n TempogramMode,\n Timbre,\n TimeSignature,\n VoicePresetId,\n} from './public_types';\nexport {\n ChordQuality,\n KeyProfile,\n Mode,\n PitchClass,\n SectionType,\n} from './public_types';\nexport type {\n BpmAnalysisResult,\n BpmCandidate,\n DynamicsAnalysisResult,\n RhythmAnalysisResult,\n TimbreAnalysisResult,\n TimbreFrame,\n} from './quick_analysis';\nexport {\n analyze,\n analyzeBpm,\n analyzeDynamics,\n analyzeImpulseResponse,\n analyzeRhythm,\n analyzeTimbre,\n analyzeWithProgress,\n chordFunctionalAnalysis,\n detectAcoustic,\n detectBeats,\n detectBpm,\n detectChords,\n detectDownbeats,\n detectKey,\n detectKeyCandidates,\n detectOnsets,\n estimateRoom,\n hasFfmpegSupport,\n roomMorph,\n synthesizeRir,\n} from './quick_analysis';\nexport type {\n EngineAutomationPoint,\n EngineBounceOptions,\n EngineBounceResult,\n EngineCapabilities,\n EngineCaptureStatus,\n EngineClip,\n EngineFreezeOptions,\n EngineFreezeResult,\n EngineGraphSpec,\n EngineMarker,\n EngineMeterTelemetry,\n EngineMetronomeConfig,\n EngineParameterInfo,\n EngineTelemetry,\n EngineTransportState,\n MidiCcBindOptions,\n} from './realtime_engine';\nexport { EXPECTED_ENGINE_ABI_VERSION, engineCapabilities, RealtimeEngine } from './realtime_engine';\nexport { scaleCorrectionSemitones, scalePitchClassEnabled, scaleQuantizeMidi } from './scale';\nexport type { ProgressCallback } from './sonare.js';\nexport { StreamAnalyzer, streamAnalyzerConfigDefaults } from './stream_analyzer';\nexport type {\n AnalyzerStats,\n BarChord,\n ChordChange,\n FrameBuffer,\n PatternScore,\n ProgressiveEstimate,\n StreamConfig,\n StreamConfigDefaults,\n StreamFramesI16,\n StreamFramesU8,\n StreamQuantizeConfig,\n} from './stream_types';\nexport type {\n MixerRealtimeBuffer,\n RealtimeVoiceChangerInterleavedBuffer,\n RealtimeVoiceChangerMonoBuffer,\n RealtimeVoiceChangerPlanarBuffer,\n} from './streaming_mixing';\nexport {\n Mixer,\n RealtimeVoiceChanger,\n realtimeVoiceChangerPresetJson,\n realtimeVoiceChangerPresetNames,\n StreamingEqualizer,\n StreamingMasteringChain,\n StreamingRetune,\n validateRealtimeVoiceChangerPresetJson,\n} from './streaming_mixing';\nexport type { ValidateOptions } from './validation';\nexport type {\n BindWebMidiOptions,\n WebMidiBinding,\n WebMidiCcBinding,\n WebMidiInputInfo,\n} from './web_midi';\nexport { bindWebMidi, isWebMidiAvailable } from './web_midi';\n\n/** Row-major 2-D matrix as a flat buffer plus its dimensions. */\nexport type Matrix2dResult = WasmMatrix2dResult;\n/** NMF factor matrices { w, h } from {@link decompose}. */\nexport type DecomposeResult = WasmDecomposeResult;\n/** Harmonic / percussive / residual signals from {@link hpssWithResidual}. */\nexport type HpssWithResidualResult = WasmHpssWithResidualResult;\n\n// ============================================================================\n// Module State\n// ============================================================================\n\nlet module: SonareModule | null = null;\nlet initPromise: Promise<void> | null = null;\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the WASM module.\n * Must be called before using any analysis functions.\n *\n * @param options - Optional module configuration\n * @returns Promise that resolves when initialization is complete\n */\nexport async function init(options?: {\n locateFile?: (path: string, prefix: string) => string;\n}): Promise<void> {\n if (module) {\n return;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n try {\n const createModule = (await import('./sonare.js')).default;\n module = await createModule(options);\n setSonareModule(module);\n } catch (error) {\n initPromise = null;\n throw error;\n }\n })();\n\n return initPromise;\n}\n\n/**\n * Check if the module is initialized.\n */\nexport function isInitialized(): boolean {\n return module !== null;\n}\n\n/**\n * Get the library version.\n */\nexport function version(): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.version();\n}\n\nexport function engineAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.engineAbiVersion();\n}\n\nexport function voiceChangerAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceChangerAbiVersion();\n}\n\n// Canonical ordinal order of the built-in voice-character presets, matching the\n// C ABI SonareVoiceCharacterPreset enum and SONARE_REALTIME_VOICE_CHANGER_PRESET_IDS.\nconst VOICE_PRESET_ORDINALS: readonly VoicePresetId[] = [\n 'neutral-monitor',\n 'bright-idol',\n 'soft-whisper',\n 'deep-narrator',\n 'robot-mascot',\n 'dark-villain',\n];\n\nfunction resolveVoicePresetOrdinal(preset: VoicePresetId | number): number {\n if (typeof preset === 'number') {\n return preset;\n }\n const ordinal = VOICE_PRESET_ORDINALS.indexOf(preset);\n if (ordinal < 0) {\n throw new Error(`Unknown voice character preset: ${preset}`);\n }\n return ordinal;\n}\n\n/**\n * Map a voice-character preset ordinal (or canonical id) to its canonical id\n * string (e.g. `'bright-idol'`). Returns `null` for an out-of-range ordinal.\n */\nexport function voiceCharacterPresetId(preset: VoicePresetId | number): string | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));\n}\n\n/**\n * Return the canonical (normalized) flat POD config for a built-in voice\n * preset, skipping the JSON round-trip. Accepts a canonical preset id or its\n * integer ordinal. Returns `null` for an out-of-range ordinal.\n */\nexport function realtimeVoiceChangerPresetConfig(\n preset: VoicePresetId | number,\n): RealtimeVoiceChangerPodConfig | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.realtimeVoiceChangerPresetConfig(resolveVoicePresetOrdinal(preset));\n}\n\n// ============================================================================\n// Re-exports\n// ============================================================================\n\nexport { PitchClass as Pitch } from './public_types';\n"],"mappings":"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","names":["module","module","module","module","input","processed","requireModule","onsetEnvelope","requireModule","onsetEnvelope","requireModule","requireModule","requireModule","init","requireModule","validatePositiveIntegers","requireModule","module","requireModule","module","module"]}
|