@libraz/libsonare 1.3.1 → 1.3.2
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 +232 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +114 -4
- package/dist/index.js.map +1 -1
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +51 -1
- package/dist/worklet.js +92 -4
- package/dist/worklet.js.map +1 -1
- package/package.json +1 -1
- package/src/effects_mastering.ts +16 -0
- package/src/errors.ts +44 -0
- package/src/index.ts +2 -0
- package/src/mixer.ts +11 -0
- package/src/module_state.ts +115 -4
- package/src/sonare.js.d.ts +6 -0
package/README.md
CHANGED
|
@@ -21,6 +21,11 @@ no model weights.
|
|
|
21
21
|
> If you need to read WAV/MP3/M4A files directly in Node, use the native
|
|
22
22
|
> N-API package [`@libraz/libsonare-native`](https://github.com/libraz/libsonare/tree/main/bindings/node) instead.
|
|
23
23
|
|
|
24
|
+
> **Platform constraints:** the WebAssembly build is single-threaded (analysis
|
|
25
|
+
> runs to completion on the calling thread — there is no non-blocking variant),
|
|
26
|
+
> has no host filesystem access, and expects pre-decoded `Float32Array` sample
|
|
27
|
+
> buffers. Drive long-running calls from a Web Worker to keep the UI responsive.
|
|
28
|
+
|
|
24
29
|
## Installation
|
|
25
30
|
|
|
26
31
|
```bash
|
|
@@ -124,6 +129,54 @@ const room = analyzeImpulseResponse(irSamples, sampleRate);
|
|
|
124
129
|
console.log(blind.rt60, room.c50);
|
|
125
130
|
```
|
|
126
131
|
|
|
132
|
+
Acoustic simulation adds `synthesizeRir` (synthesize a shoebox-room impulse
|
|
133
|
+
response from geometry), `estimateRoom` (recover an equivalent room from a
|
|
134
|
+
recording or IR), and `roomMorph` (creatively re-reverberate audio toward a
|
|
135
|
+
target room — not dereverberation).
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { init, synthesizeRir, estimateRoom, roomMorph } from '@libraz/libsonare';
|
|
139
|
+
|
|
140
|
+
await init();
|
|
141
|
+
|
|
142
|
+
const { rir, hasError } = synthesizeRir({
|
|
143
|
+
lengthM: 6,
|
|
144
|
+
widthM: 4,
|
|
145
|
+
heightM: 3,
|
|
146
|
+
absorption: 0.2,
|
|
147
|
+
sampleRate: 48000,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const room = estimateRoom(samples, 48000); // { volume, length, width, height, ... }
|
|
151
|
+
const morphed = roomMorph(samples, sampleRate, { lengthM: 12, widthM: 9, wet: 0.5 });
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Error handling
|
|
155
|
+
|
|
156
|
+
Native (C++) failures are thrown as a `SonareError` carrying a numeric `code`
|
|
157
|
+
(an `ErrorCode` value) and its canonical `codeName`, so you can branch on the
|
|
158
|
+
cause instead of matching message text. Use the `isSonareError` type guard in a
|
|
159
|
+
`catch`:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import { init, analyze, ErrorCode, isSonareError } from '@libraz/libsonare';
|
|
163
|
+
|
|
164
|
+
await init();
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const result = analyze(samples, sampleRate);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if (isSonareError(error)) {
|
|
170
|
+
console.error(`${error.codeName} (${error.code}): ${error.message}`);
|
|
171
|
+
if (error.code === ErrorCode.InvalidParameter) {
|
|
172
|
+
// recover...
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
127
180
|
### Decoding files in the browser
|
|
128
181
|
|
|
129
182
|
```typescript
|
|
@@ -331,6 +384,149 @@ try {
|
|
|
331
384
|
}
|
|
332
385
|
```
|
|
333
386
|
|
|
387
|
+
#### Clip warp
|
|
388
|
+
|
|
389
|
+
A clip can be time-warped during an offline `bounce`. `setClipWarpMode` selects
|
|
390
|
+
the playback mode (`ProjectWarpMode`: `'off'` | `'repitch'` | `'tempo-sync'`),
|
|
391
|
+
`setClipWarpRef` binds it to a warp map, and `setWarpMap` registers a first-class
|
|
392
|
+
warp map (anchors mapping warp-timeline samples to source samples).
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
project.setWarpMap({
|
|
396
|
+
id: 1,
|
|
397
|
+
name: 'main',
|
|
398
|
+
anchors: [
|
|
399
|
+
{ warpSample: 0, sourceSample: 0 },
|
|
400
|
+
{ warpSample: 48000, sourceSample: 24000 },
|
|
401
|
+
],
|
|
402
|
+
});
|
|
403
|
+
project.setClipWarpRef(clipId, 1);
|
|
404
|
+
project.setClipWarpMode(clipId, 'tempo-sync');
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
> Warp is an offline `Project.bounce` feature only. Realtime warp playback is
|
|
408
|
+
> **not** available in `RealtimeEngine`.
|
|
409
|
+
|
|
410
|
+
### Instruments and synthesis
|
|
411
|
+
|
|
412
|
+
MIDI tracks bounce silently unless an instrument is bound. `Project` offers
|
|
413
|
+
three instrument backends, each as a `bounceWith…` variant that takes a binding
|
|
414
|
+
(or array of bindings) plus the usual `ProjectBounceOptions`:
|
|
415
|
+
|
|
416
|
+
- `bounceWithBuiltinInstrument(binding?, options?)` — simple built-in oscillator
|
|
417
|
+
synth (`BuiltinSynthConfig` / `BuiltinSynthBinding`: waveform + ADSR + gain).
|
|
418
|
+
- `bounceWithSynthInstrument(patchOrName?, options?)` — patch-driven NativeSynth
|
|
419
|
+
(`SynthPatch`, or a preset-name string like `'saw-lead'`).
|
|
420
|
+
- `bounceWithSf2Instrument(config?, options?)` — GS-compatible SoundFont player
|
|
421
|
+
(`Sf2InstrumentConfig`), fed by `loadSoundFont()`.
|
|
422
|
+
|
|
423
|
+
Discover NativeSynth presets with `synthPresetNames()` and fetch one as an
|
|
424
|
+
editable patch with `synthPresetPatch(name)`.
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
import { init, Project, synthPresetNames, synthPresetPatch } from '@libraz/libsonare';
|
|
428
|
+
|
|
429
|
+
await init();
|
|
430
|
+
|
|
431
|
+
const project = new Project();
|
|
432
|
+
try {
|
|
433
|
+
const { clipId } = project.addMidiClip(0, 4);
|
|
434
|
+
project.setMidiEvents(clipId, [
|
|
435
|
+
Project.midiNoteOn(0, 0, 0, 60, 100),
|
|
436
|
+
Project.midiNoteOff(1, 0, 0, 60),
|
|
437
|
+
]);
|
|
438
|
+
|
|
439
|
+
// Built-in oscillator synth.
|
|
440
|
+
const a = project.bounceWithBuiltinInstrument({ waveform: 'saw' }, { numChannels: 2 });
|
|
441
|
+
|
|
442
|
+
// NativeSynth from a named preset, tweaked.
|
|
443
|
+
const patch = synthPresetPatch(synthPresetNames()[0]);
|
|
444
|
+
patch.cutoffHz = 4000;
|
|
445
|
+
const b = project.bounceWithSynthInstrument(patch, { numChannels: 2 });
|
|
446
|
+
|
|
447
|
+
// SoundFont player (requires loadSoundFont first).
|
|
448
|
+
project.loadSoundFont(sf2Bytes);
|
|
449
|
+
const c = project.bounceWithSf2Instrument({ gain: 0.6 }, { numChannels: 2 });
|
|
450
|
+
} finally {
|
|
451
|
+
project.delete();
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Real-time engine
|
|
456
|
+
|
|
457
|
+
`RealtimeEngine` is a control-thread-driven transport + render engine: it plays
|
|
458
|
+
a clip/automation timeline, hosts MIDI instruments, accepts live MIDI, and
|
|
459
|
+
renders blocks (or bounces offline). Bind it to an AudioWorklet for browser
|
|
460
|
+
playback — see the [AudioWorklet bridge](#audioworklet-bridge) below; the engine
|
|
461
|
+
is the offline/headless half, the worklet is the audio-thread half.
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
import { init, RealtimeEngine } from '@libraz/libsonare';
|
|
465
|
+
|
|
466
|
+
await init();
|
|
467
|
+
|
|
468
|
+
const engine = new RealtimeEngine(48000, 128); // sampleRate, maxBlockSize
|
|
469
|
+
try {
|
|
470
|
+
engine.setSynthInstrument('saw-lead', 0); // patch (or name), destinationId
|
|
471
|
+
engine.play();
|
|
472
|
+
engine.pushMidiNoteOn(0, 0, 0, 60, 100); // destination, group, channel, note, velocity
|
|
473
|
+
engine.pushMidiNoteOff(0, 0, 0, 60);
|
|
474
|
+
|
|
475
|
+
const blockL = new Float32Array(128);
|
|
476
|
+
const blockR = new Float32Array(128);
|
|
477
|
+
const out = engine.process([blockL, blockR]); // Float32Array[] per channel
|
|
478
|
+
const telemetry = engine.drainTelemetry();
|
|
479
|
+
} finally {
|
|
480
|
+
engine.destroy();
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Capabilities:
|
|
485
|
+
|
|
486
|
+
- **Transport**: `play` / `stop` / `seekSample` / `seekPpq` / `setTempo` /
|
|
487
|
+
`setTimeSignature` / `setLoop`, plus `getTransportState`.
|
|
488
|
+
- **Instruments**: `setBuiltinInstrument` / `setSynthInstrument` /
|
|
489
|
+
`setSf2Instrument` (+ `loadSoundFont`) per MIDI destination id.
|
|
490
|
+
- **Live MIDI**: `pushMidiNoteOn` / `pushMidiNoteOff` / `pushMidiCc` /
|
|
491
|
+
`pushMidiPanic`, and `bindMidiCc(channel, controller, paramId, options?)` to
|
|
492
|
+
map a CC to an automation parameter.
|
|
493
|
+
- **Process / bounce**: `process` (real-time blocks), the allocation-free
|
|
494
|
+
`prepareChannels` + `getChannelBuffer` + `processPrepared` worklet path,
|
|
495
|
+
`renderOffline`, `bounceOffline`, `freezeOffline`.
|
|
496
|
+
- **Clip page providers**: `createClipPageProvider` + `supplyClipPage` for
|
|
497
|
+
streaming large clip audio in pages; pair with the OPFS helpers
|
|
498
|
+
(`createOpfsClipPageProvider`).
|
|
499
|
+
- **Telemetry**: `drainTelemetry` / `drainMeterTelemetry`. Inspect runtime
|
|
500
|
+
capabilities (ABI compatibility, SharedArrayBuffer/Atomics) via
|
|
501
|
+
`engineCapabilities()`.
|
|
502
|
+
|
|
503
|
+
### Real-time voice changer
|
|
504
|
+
|
|
505
|
+
`RealtimeVoiceChanger` runs a block-by-block voice transformation chain (retune,
|
|
506
|
+
formant shaping, EQ, gate, compressor). Construct it from a preset id (see
|
|
507
|
+
`realtimeVoiceChangerPresetNames()`) or a full config object, then process blocks.
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
import { init, RealtimeVoiceChanger, voiceChangeRealtime } from '@libraz/libsonare';
|
|
511
|
+
|
|
512
|
+
await init();
|
|
513
|
+
|
|
514
|
+
const changer = new RealtimeVoiceChanger('bright-idol');
|
|
515
|
+
try {
|
|
516
|
+
changer.prepare(48000, 128, 1); // sampleRate, maxBlockSize, channels
|
|
517
|
+
const out = changer.processMono(block);
|
|
518
|
+
} finally {
|
|
519
|
+
changer.delete();
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Whole-buffer convenience wrapper (constructs/prepares/disposes internally).
|
|
523
|
+
const processed = voiceChangeRealtime(samples, { preset: 'deep-narrator', sampleRate: 48000 });
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
For a simple offline pitch + formant shift without the full chain, use
|
|
527
|
+
`voiceChange(samples, sampleRate, { pitchSemitones: -2, formantFactor: 1.1 })`.
|
|
528
|
+
Inspect a preset with `realtimeVoiceChangerPresetJson(name)`.
|
|
529
|
+
|
|
334
530
|
### AudioWorklet bridge
|
|
335
531
|
|
|
336
532
|
The package exposes an optional worklet entry that uses the same `sonare.wasm`
|
|
@@ -476,17 +672,50 @@ chain.reset();
|
|
|
476
672
|
chain.delete(); // release WASM memory
|
|
477
673
|
```
|
|
478
674
|
|
|
675
|
+
### Streaming equalizer and retune
|
|
676
|
+
|
|
677
|
+
`StreamingEqualizer` wraps the unified `EqualizerProcessor` (up to 24 bands,
|
|
678
|
+
RBJ/Vicanek biquads, dynamic EQ, linear-phase FIR, mid/side, auto-gain) with
|
|
679
|
+
state maintained across calls. `StreamingRetune` is a block-by-block mono voice
|
|
680
|
+
retune / pitch shifter.
|
|
681
|
+
|
|
682
|
+
```typescript
|
|
683
|
+
import { init, StreamingEqualizer, StreamingRetune } from '@libraz/libsonare';
|
|
684
|
+
|
|
685
|
+
await init();
|
|
686
|
+
|
|
687
|
+
const eq = new StreamingEqualizer({ sampleRate: 48000, maxBlockSize: 512 });
|
|
688
|
+
try {
|
|
689
|
+
eq.setBand(0, { type: 'HighShelf', frequencyHz: 8000, gainDb: 6, enabled: true });
|
|
690
|
+
const { left: eqL, right: eqR } = eq.processStereo(left, right);
|
|
691
|
+
} finally {
|
|
692
|
+
eq.delete();
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const retune = new StreamingRetune({ semitones: 2, mix: 1.0 });
|
|
696
|
+
try {
|
|
697
|
+
retune.prepare(48000, 512); // sampleRate, maxBlockSize
|
|
698
|
+
const shifted = retune.processMono(monoBlock);
|
|
699
|
+
} finally {
|
|
700
|
+
retune.delete();
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
479
704
|
## Features
|
|
480
705
|
|
|
481
|
-
- **Detection**:
|
|
706
|
+
- **Detection**: `detectBeats`, `detectOnsets`, `detectDownbeats`, `detectChords`, `detectKey`, `detectKeyCandidates`, `chordFunctionalAnalysis`, sections
|
|
707
|
+
- **Analysis**: `analyze`, `analyzeWithProgress`, `analyzeBpm`, `analyzeRhythm`, `analyzeDynamics`, `analyzeTimbre`; `hasFfmpegSupport` capability check
|
|
482
708
|
- **Effects**: HPSS, HPSS with residual, time stretch, phase vocoder, pitch shift, normalize, trim, remix
|
|
483
709
|
- **Mastering**: EQ, compressor, tape/exciter, air band, stereo imaging,
|
|
484
710
|
true-peak limiting, loudness optimization
|
|
485
711
|
- **Features**: STFT, mel spectrogram, MFCC, chroma, CQT/VQT, spectral contrast, poly features, zero crossings
|
|
486
712
|
- **Pitch**: YIN, pYIN algorithms with optional `fillNa`
|
|
487
713
|
- **Decomposition & loudness**: NMF decomposition, nearest-neighbour filtering, multichannel LUFS, EBU R128 LRA
|
|
488
|
-
- **Streaming**: Real-time analysis with progressive estimates
|
|
489
|
-
- **
|
|
714
|
+
- **Streaming**: Real-time analysis with progressive estimates; streaming mastering chain, equalizer, and retune
|
|
715
|
+
- **Instruments**: built-in synth, patch-driven NativeSynth, SoundFont (SF2) player — bound to `Project` bounces or the `RealtimeEngine`
|
|
716
|
+
- **Real-time**: `RealtimeEngine` transport/MIDI/render, `RealtimeVoiceChanger`, AudioWorklet bridge
|
|
717
|
+
- **Room acoustics**: blind RT60/EDT, impulse-response clarity metrics, RIR synthesis, room estimation, room morphing
|
|
718
|
+
- **Headless DAW**: `Project` arrangement model — audio/MIDI tracks & clips, undo/redo, MIDI sequencing, clip warp, SMF / MIDI 2.0 Clip File I/O, deterministic JSON, offline `bounce`
|
|
490
719
|
- **Conversions**: Hz/mel/MIDI/note, frames/time, resample
|
|
491
720
|
|
|
492
721
|
## Also available
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { A as AcousticOptions, a as AcousticResult, b as AnalysisResult, c as AnalyzeBpmOptions, d as AnalyzeDynamicsOptions, e as AnalyzeRhythmOptions, f as AnalyzeSectionsOptions, g as AnalyzeTimbreOptions, h as AnalyzerStats, i as Audio, j as AutomationCurve, B as BarChord, k as Beat, l as BindMicrophoneInputOptions, m as BindWebMidiOptions, n as BpmAnalysisResult, o as BpmCandidate, p as BrowserAudioDecodeOptions, q as BuiltinSynthBinding, r as BuiltinSynthConfig, s as BuiltinSynthWaveform, C as Chord, t as ChordAnalysisResult, u as ChordChange, v as ChordDetectionOptions, w as ChordQuality, x as ChromaResult, y as ClippingRegion, z as ClippingReport, D as CompressorDetector, E as CompressorOptions, F as CqtResult, G as DeclickOptions, H as DeclipOptions, I as DecomposeResult, J as DecrackleMode, K as DecrackleOptions, L as DehumOptions, M as DenoiseClassicalMode, N as DenoiseClassicalNoiseEstimator, O as DenoiseClassicalOptions, P as DereverbClassicalOptions, Q as DynamicRangeReport, R as Dynamics, S as DynamicsAnalysisResult, T as DynamicsResult, U as EXPECTED_ENGINE_ABI_VERSION, V as EXPECTED_PROJECT_ABI_VERSION, W as EngineAutomationPoint, X as EngineBounceOptions, Y as EngineBounceResult, Z as EngineCapabilities, _ as EngineCaptureStatus, $ as EngineClip, a0 as EngineFreezeOptions, a1 as EngineFreezeResult, a2 as EngineGraphSpec, a3 as EngineMarker, a4 as EngineMeterTelemetry, a5 as EngineMetronomeConfig, a6 as EngineParameterInfo, a7 as EngineTelemetry, a8 as EngineTransportState, a9 as EqBand, aa as EqBandPhase, ab as EqBandType, ac as EqCoeffMode, ad as EqMatchOptions, ae as EqSpectrumSnapshot, af as EqStereoPlacement, ag as
|
|
1
|
+
export { A as AcousticOptions, a as AcousticResult, b as AnalysisResult, c as AnalyzeBpmOptions, d as AnalyzeDynamicsOptions, e as AnalyzeRhythmOptions, f as AnalyzeSectionsOptions, g as AnalyzeTimbreOptions, h as AnalyzerStats, i as Audio, j as AutomationCurve, B as BarChord, k as Beat, l as BindMicrophoneInputOptions, m as BindWebMidiOptions, n as BpmAnalysisResult, o as BpmCandidate, p as BrowserAudioDecodeOptions, q as BuiltinSynthBinding, r as BuiltinSynthConfig, s as BuiltinSynthWaveform, C as Chord, t as ChordAnalysisResult, u as ChordChange, v as ChordDetectionOptions, w as ChordQuality, x as ChromaResult, y as ClippingRegion, z as ClippingReport, D as CompressorDetector, E as CompressorOptions, F as CqtResult, G as DeclickOptions, H as DeclipOptions, I as DecomposeResult, J as DecrackleMode, K as DecrackleOptions, L as DehumOptions, M as DenoiseClassicalMode, N as DenoiseClassicalNoiseEstimator, O as DenoiseClassicalOptions, P as DereverbClassicalOptions, Q as DynamicRangeReport, R as Dynamics, S as DynamicsAnalysisResult, T as DynamicsResult, U as EXPECTED_ENGINE_ABI_VERSION, V as EXPECTED_PROJECT_ABI_VERSION, W as EngineAutomationPoint, X as EngineBounceOptions, Y as EngineBounceResult, Z as EngineCapabilities, _ as EngineCaptureStatus, $ as EngineClip, a0 as EngineFreezeOptions, a1 as EngineFreezeResult, a2 as EngineGraphSpec, a3 as EngineMarker, a4 as EngineMeterTelemetry, a5 as EngineMetronomeConfig, a6 as EngineParameterInfo, a7 as EngineTelemetry, a8 as EngineTransportState, a9 as EqBand, aa as EqBandPhase, ab as EqBandType, ac as EqCoeffMode, ad as EqMatchOptions, ae as EqSpectrumSnapshot, af as EqStereoPlacement, ag as ErrorCode, ah as FrameBuffer, ai as GateOptions, aj as GoniometerPoint, ak as HpssResult, al as HpssWithResidualResult, am as Key, an as KeyCandidate, ao as KeyDetectionOptions, ap as KeyProfile, aq as KeyProfileName, ar as LufsResult, as as MasteringChainConfig, at as MasteringChainResult, au as MasteringOptions, av as MasteringPreset, aw as MasteringProcessorParams, ax as MasteringResult, ay as MasteringStereoChainResult, az as MasteringStereoResult, aA as Matrix2dResult, aB as MelPowerResult, aC as MelSpectrogramResult, aD as MelodyOptions, aE as MelodyPoint, aF as MelodyResult, aG as MeterTap, aH as MeteringDetectClippingOptions, aI as MeteringDynamicRangeOptions, aJ as MfccResult, aK as MicrophoneInputBinding, aL as MidiCcBindOptions, aM as MidiCcLearnOptions, aN as MixMeterSnapshot, aO as MixOptions, aP as MixResult, aQ as Mixer, aR as MixerProcessResult, aS as MixerRealtimeBuffer, aT as Mode, aU as NoteStretchOptions, aV as OpfsClipPageProviderBinding, aW as OpfsClipPageProviderOptions, aX as PairAnalysis, aY as PairProcessor, aZ as PanLaw, a_ as PanMode, a$ as PatternScore, b0 as PhaseScopeReport, b1 as Pitch, b1 as PitchClass, b2 as PitchResult, b3 as ProgressiveEstimate, b4 as Project, b5 as ProjectAssistSidecar, b6 as ProjectAutomationCurve, b7 as ProjectAutomationLaneDesc, b8 as ProjectAutomationPoint, b9 as ProjectBounceOptions, ba as ProjectChordSymbol, bb as ProjectClipCompSegment, bc as ProjectClipDesc, bd as ProjectClipFade, be as ProjectClipTake, bf as ProjectCompileResult, bg as ProjectFadeCurve, bh as ProjectKeySegment, bi as ProjectLoopMode, bj as ProjectLoopRecordingDesc, bk as ProjectLoopRecordingResult, bl as ProjectMidiClipResult, bm as ProjectMidiEvent, bn as ProjectNotePairValidation, bo as ProjectTrackDesc, bp as ProjectTrackKind, bq as ProjectWarpAnchor, br as ProjectWarpMapDesc, bs as RealtimeEngine, bt as RealtimeVoiceChanger, bu as RealtimeVoiceChangerConfigInput, bv as RealtimeVoiceChangerInterleavedBuffer, bw as RealtimeVoiceChangerMonoBuffer, bx as RealtimeVoiceChangerPlanarBuffer, by as RealtimeVoiceChangerPodConfig, bz as RhythmAnalysisResult, bA as RhythmFeatures, bB as RirResult, bC as RirSynthOptions, bD as RoomEstimateOptions, bE as RoomEstimateResult, bF as RoomGeometryOptions, bG as RoomMorphOptions, bH as SYNTH_BODY_TYPES, bI as SYNTH_ENGINE_MODES, bJ as SYNTH_FILTER_MODELS, bK as SYNTH_FILTER_OUTPUTS, bL as SYNTH_MOD_DESTINATIONS, bM as SYNTH_MOD_SOURCES, bN as SYNTH_OSC_WAVEFORMS, bO as Section, bP as SectionType, bQ as SendTiming, bR as Sf2InstrumentConfig, bS as Sf2ProgramStatus, bT as SoloProcessor, bU as SonareError, bV as SourceBackend, bW as SpectrumOptions, bX as SpectrumReport, bY as StereoAnalysis, bZ as StftPowerResult, b_ as StftResult, b$ as StreamAnalyzer, c0 as StreamConfig, c1 as StreamConfigDefaults, c2 as StreamFramesI16, c3 as StreamFramesU8, c4 as StreamQuantizeConfig, c5 as StreamingEqualizer, c6 as StreamingEqualizerConfig, c7 as StreamingMasteringChain, c8 as StreamingMasteringChainConfig, c9 as StreamingPlatform, ca as StreamingRetune, cb as StreamingRetuneConfig, cc as SynthBodyType, cd as SynthEngineMode, ce as SynthEnumTables, cf as SynthFilterModel, cg as SynthFilterOutput, ch as SynthModDestination, ci as SynthModRouting, cj as SynthModSource, ck as SynthOscWaveform, cl as SynthPatch, cm as TempogramMode, cn as Timbre, co as TimbreAnalysisResult, cp as TimbreFrame, cq as TimeSignature, cr as TransientShaperOptions, cs as TrimSilenceMode, ct as TrimSilenceOptions, cu as ValidateOptions, cv as VectorscopeReport, cw as VoiceChangeOptions, cx as VoiceChangeRealtimeOptions, cy as VoicePresetId, cz as WaveformPeakPyramidOptions, cA as WaveformPeaksOptions, cB as WaveformPeaksReport, cC as WebMidiBinding, cD as WebMidiCcBinding, cE as WebMidiInputInfo, cF as amplitudeToDb, cG as analyze, cH as analyzeBpm, cI as analyzeDynamics, cJ as analyzeImpulseResponse, cK as analyzeMelody, cL as analyzeRhythm, cM as analyzeSections, cN as analyzeTimbre, cO as analyzeWithProgress, cP as bassChroma, cQ as bindMicrophoneInput, cR as bindWebMidi, cS as chordFunctionalAnalysis, cT as chroma, cU as chromaCens, cV as cqt, cW as createOpfsClipPageProvider, cX as createOpfsClipPageWorker, cY as cyclicTempogram, cZ as dbToAmplitude, c_ as dbToPower, c$ as decompose, d0 as decomposeWithInit, d1 as deemphasis, d2 as detectAcoustic, d3 as detectBeats, d4 as detectBpm, d5 as detectChords, d6 as detectDownbeats, d7 as detectKey, d8 as detectKeyCandidates, d9 as detectOnsets, da as ebur128LoudnessRange, db as engineAbiVersion, dc as engineCapabilities, dd as estimateRoom, de as estimateTuning, df as fixFrames, dg as fixLength, dh as fourierTempogram, di as frameSignal, dj as framesToSamples, dk as framesToTime, dl as harmonic, dm as hasFfmpegSupport, dn as hpss, dp as hpssWithResidual, dq as hybridCqt, dr as hzToMel, ds as hzToMidi, dt as hzToNote, init, isInitialized, du as isSonareError, dv as isWebMidiAvailable, dw as lufs, dx as lufsInterleaved, dy as masterAudio, dz as masterAudioStereo, dA as masterAudioStereoWithProgress, dB as masterAudioWithProgress, dC as mastering, dD as masteringAssistantSuggest, dE as masteringAudioProfile, dF as masteringChain, dG as masteringChainStereo, dH as masteringChainStereoWithProgress, dI as masteringChainWithProgress, dJ as masteringDynamicsCompressor, dK as masteringDynamicsGate, dL as masteringDynamicsTransientShaper, dM as masteringInsertNames, dN as masteringInsertParamNames, dO as masteringPairAnalysisNames, dP as masteringPairAnalyze, dQ as masteringPairProcess, dR as masteringPairProcessorNames, dS as masteringPresetNames, dT as masteringProcess, dU as masteringProcessStereo, dV as masteringProcessorNames, dW as masteringRepairDeclick, dX as masteringRepairDeclip, dY as masteringRepairDecrackle, dZ as masteringRepairDehum, d_ as masteringRepairDenoiseClassical, d$ as masteringRepairDereverbClassical, e0 as masteringRepairTrimSilence, e1 as masteringStereoAnalysisNames, e2 as masteringStereoAnalyze, e3 as masteringStreamingPreview, e4 as melSpectrogram, e5 as melToAudio, e6 as melToHz, e7 as melToStft, e8 as meteringCrestFactorDb, e9 as meteringDcOffset, ea as meteringDetectClipping, eb as meteringDynamicRange, ec as meteringPeakDb, ed as meteringPhaseScope, ee as meteringPhaseScopeDecimated, ef as meteringRmsDb, eg as meteringSpectrum, eh as meteringSpectrumFrame, ei as meteringStereoCorrelation, ej as meteringStereoWidth, ek as meteringTruePeakDb, el as meteringVectorscope, em as meteringVectorscopeDecimated, en as mfcc, eo as mfccToAudio, ep as mfccToMel, eq as midiToHz, er as mixStereo, es as mixingScenePresetJson, et as mixingScenePresetNames, eu as momentaryLufs, ev as nnFilter, ew as nnlsChroma, ex as normalize, ey as noteStretch, ez as noteToHz, eA as onsetEnvelope, eB as onsetStrengthMulti, eC as opfsClipPageWorkerSource, eD as padCenter, eE as pcen, eF as peakPick, eG as percussive, eH as phaseVocoder, eI as pitchCorrectToMidi, eJ as pitchCorrectToMidiTimevarying, eK as pitchPyin, eL as pitchShift, eM as pitchTuning, eN as pitchYin, eO as plp, eP as polyFeatures, eQ as powerToDb, eR as preemphasis, eS as projectAbiVersion, eT as pseudoCqt, eU as realtimeVoiceChangerPresetConfig, eV as realtimeVoiceChangerPresetJson, eW as realtimeVoiceChangerPresetNames, eX as remix, eY as resample, eZ as rmsEnergy, e_ as roomMorph, e$ as samplesToFrames, f0 as scaleCorrectionSemitones, f1 as scalePitchClassEnabled, f2 as scaleQuantizeMidi, f3 as shortTermLufs, f4 as spectralBandwidth, f5 as spectralCentroid, f6 as spectralContrast, f7 as spectralFlatness, f8 as spectralRolloff, f9 as splitSilence, fa as stft, fb as stftDb, fc as streamAnalyzerConfigDefaults, fd as synthEnumTables, fe as synthPresetNames, ff as synthPresetPatch, fg as synthesizeRir, fh as tempogram, fi as tempogramRatio, fj as timeStretch, fk as timeToFrames, fl as tonnetz, fm as trim, fn as trimSilence, fo as validateRealtimeVoiceChangerPresetJson, fp as vectorNormalize, fq as version, fr as voiceChange, fs as voiceChangeRealtime, ft as voiceChangerAbiVersion, fu as voiceCharacterPresetId, fv as vqt, fw as waveformPeakPyramid, fx as waveformPeaks, fy as zeroCrossingRate, fz as zeroCrossings } from './worklet.js';
|
|
2
2
|
export { ProgressCallback } from './sonare.js';
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,106 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
3
|
+
ErrorCode2[ErrorCode2["Ok"] = 0] = "Ok";
|
|
4
|
+
ErrorCode2[ErrorCode2["FileNotFound"] = 1] = "FileNotFound";
|
|
5
|
+
ErrorCode2[ErrorCode2["InvalidFormat"] = 2] = "InvalidFormat";
|
|
6
|
+
ErrorCode2[ErrorCode2["DecodeFailed"] = 3] = "DecodeFailed";
|
|
7
|
+
ErrorCode2[ErrorCode2["InvalidParameter"] = 4] = "InvalidParameter";
|
|
8
|
+
ErrorCode2[ErrorCode2["OutOfMemory"] = 5] = "OutOfMemory";
|
|
9
|
+
ErrorCode2[ErrorCode2["NotSupported"] = 6] = "NotSupported";
|
|
10
|
+
ErrorCode2[ErrorCode2["InvalidState"] = 7] = "InvalidState";
|
|
11
|
+
ErrorCode2[ErrorCode2["Unknown"] = 99] = "Unknown";
|
|
12
|
+
return ErrorCode2;
|
|
13
|
+
})(ErrorCode || {});
|
|
14
|
+
var SonareError = class extends Error {
|
|
15
|
+
constructor(code, codeName, message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = "SonareError";
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.codeName = codeName;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function isSonareError(value) {
|
|
23
|
+
return value instanceof Error && value.name === "SonareError" && typeof value.code === "number";
|
|
24
|
+
}
|
|
25
|
+
|
|
1
26
|
// src/module_state.ts
|
|
2
|
-
var
|
|
27
|
+
var wrappedModule = null;
|
|
28
|
+
function nativeExceptionPtr(error) {
|
|
29
|
+
if (typeof error === "number") {
|
|
30
|
+
return error;
|
|
31
|
+
}
|
|
32
|
+
if (error !== null && typeof error === "object") {
|
|
33
|
+
const ptr = error.excPtr;
|
|
34
|
+
if (typeof ptr === "number") {
|
|
35
|
+
return ptr;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function makeSonareError(raw, thrown) {
|
|
41
|
+
let code = 99 /* Unknown */;
|
|
42
|
+
let codeName = "Unknown";
|
|
43
|
+
let message = `libsonare native exception (${thrown})`;
|
|
44
|
+
try {
|
|
45
|
+
const info = raw.sonareExceptionInfo?.(thrown);
|
|
46
|
+
if (info) {
|
|
47
|
+
code = info.code ?? code;
|
|
48
|
+
codeName = info.codeName ?? codeName;
|
|
49
|
+
message = info.message || message;
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
return new SonareError(code, codeName, message);
|
|
54
|
+
}
|
|
55
|
+
function wrapModuleErrors(raw) {
|
|
56
|
+
const cache = /* @__PURE__ */ new Map();
|
|
57
|
+
const convert = (error) => {
|
|
58
|
+
const ptr = nativeExceptionPtr(error);
|
|
59
|
+
if (ptr !== null) {
|
|
60
|
+
throw makeSonareError(raw, ptr);
|
|
61
|
+
}
|
|
62
|
+
throw error;
|
|
63
|
+
};
|
|
64
|
+
return new Proxy(raw, {
|
|
65
|
+
get(target, prop, receiver) {
|
|
66
|
+
const value = Reflect.get(target, prop, receiver);
|
|
67
|
+
if (typeof value !== "function") {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
const cached = cache.get(prop);
|
|
71
|
+
if (cached) {
|
|
72
|
+
return cached;
|
|
73
|
+
}
|
|
74
|
+
const fn = value;
|
|
75
|
+
const wrapped = new Proxy(fn, {
|
|
76
|
+
apply(t, thisArg, args) {
|
|
77
|
+
try {
|
|
78
|
+
return Reflect.apply(t, thisArg, args);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
return convert(error);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
construct(t, args, newTarget) {
|
|
84
|
+
try {
|
|
85
|
+
return Reflect.construct(t, args, newTarget);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return convert(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
cache.set(prop, wrapped);
|
|
92
|
+
return wrapped;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
3
96
|
function setSonareModule(module2) {
|
|
4
|
-
|
|
97
|
+
wrappedModule = wrapModuleErrors(module2);
|
|
5
98
|
}
|
|
6
99
|
function getSonareModule() {
|
|
7
|
-
if (!
|
|
100
|
+
if (!wrappedModule) {
|
|
8
101
|
throw new Error("Module not initialized. Call init() first.");
|
|
9
102
|
}
|
|
10
|
-
return
|
|
103
|
+
return wrappedModule;
|
|
11
104
|
}
|
|
12
105
|
|
|
13
106
|
// src/codes.ts
|
|
@@ -82,6 +175,16 @@ var Mixer = class _Mixer {
|
|
|
82
175
|
compile() {
|
|
83
176
|
this.mixer.compile();
|
|
84
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Non-fatal warnings captured when this mixer was built from scene JSON: one
|
|
180
|
+
* entry per channel-strip insert that was handed param keys it does not read
|
|
181
|
+
* (a likely typo, or a key meant for a different processor). The scene still
|
|
182
|
+
* loaded; these keys simply took no effect. Empty when every key was consumed.
|
|
183
|
+
* Use {@link masteringInsertParamNames} to discover the keys an insert accepts.
|
|
184
|
+
*/
|
|
185
|
+
sceneWarnings() {
|
|
186
|
+
return this.mixer.sceneWarnings();
|
|
187
|
+
}
|
|
85
188
|
/**
|
|
86
189
|
* Mix one block of per-strip stereo audio into the stereo master.
|
|
87
190
|
*
|
|
@@ -1019,6 +1122,9 @@ function masteringProcessorNames() {
|
|
|
1019
1122
|
function masteringInsertNames() {
|
|
1020
1123
|
return requireModule().masteringInsertNames();
|
|
1021
1124
|
}
|
|
1125
|
+
function masteringInsertParamNames(name) {
|
|
1126
|
+
return requireModule().masteringInsertParamNames(name);
|
|
1127
|
+
}
|
|
1022
1128
|
function masteringPairProcessorNames() {
|
|
1023
1129
|
return requireModule().masteringPairProcessorNames();
|
|
1024
1130
|
}
|
|
@@ -4278,6 +4384,7 @@ export {
|
|
|
4278
4384
|
ChordQuality,
|
|
4279
4385
|
EXPECTED_ENGINE_ABI_VERSION,
|
|
4280
4386
|
EXPECTED_PROJECT_ABI_VERSION,
|
|
4387
|
+
ErrorCode,
|
|
4281
4388
|
KeyProfile,
|
|
4282
4389
|
Mixer,
|
|
4283
4390
|
Mode,
|
|
@@ -4294,6 +4401,7 @@ export {
|
|
|
4294
4401
|
SYNTH_MOD_SOURCES,
|
|
4295
4402
|
SYNTH_OSC_WAVEFORMS,
|
|
4296
4403
|
SectionType,
|
|
4404
|
+
SonareError,
|
|
4297
4405
|
StreamAnalyzer,
|
|
4298
4406
|
StreamingEqualizer,
|
|
4299
4407
|
StreamingMasteringChain,
|
|
@@ -4352,6 +4460,7 @@ export {
|
|
|
4352
4460
|
hzToNote,
|
|
4353
4461
|
init,
|
|
4354
4462
|
isInitialized,
|
|
4463
|
+
isSonareError,
|
|
4355
4464
|
isWebMidiAvailable,
|
|
4356
4465
|
lufs,
|
|
4357
4466
|
lufsInterleaved,
|
|
@@ -4370,6 +4479,7 @@ export {
|
|
|
4370
4479
|
masteringDynamicsGate,
|
|
4371
4480
|
masteringDynamicsTransientShaper,
|
|
4372
4481
|
masteringInsertNames,
|
|
4482
|
+
masteringInsertParamNames,
|
|
4373
4483
|
masteringPairAnalysisNames,
|
|
4374
4484
|
masteringPairAnalyze,
|
|
4375
4485
|
masteringPairProcess,
|