@libraz/libsonare 1.5.5 → 1.6.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 +109 -20
- package/dist/analysis.d.ts +5730 -0
- package/dist/analysis.js +2464 -0
- package/dist/analysis.js.map +1 -0
- package/dist/index.d.ts +759 -35
- package/dist/index.js +904 -209
- package/dist/index.js.map +1 -1
- package/dist/schemas/realtime-voice-changer-preset-pack.schema.json +27 -0
- package/dist/schemas/realtime-voice-changer-preset.schema.json +140 -0
- package/dist/sonare-analysis.js +2 -0
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worker.d.ts +65 -0
- package/dist/worker.js +707 -0
- package/dist/worker.js.map +1 -0
- package/dist/worklet.d.ts +574 -86
- package/dist/worklet.js +1634 -235
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -11
- package/src/_chain_config.ts +5 -3
- package/src/analysis.ts +137 -0
- package/src/analysis_helpers.ts +6 -0
- package/src/clip_page_streamer.ts +62 -8
- package/src/codes.ts +51 -64
- package/src/effects_mastering.ts +1 -0
- package/src/errors.ts +1 -0
- package/src/feature_core.ts +140 -2
- package/src/feature_music.ts +17 -2
- package/src/feature_pitch.ts +70 -1
- package/src/feature_spectral.ts +231 -5
- package/src/feature_spectrogram.ts +159 -0
- package/src/features.ts +16 -1
- package/src/index.ts +101 -7
- package/src/mastering_chain.ts +20 -8
- package/src/mastering_core.ts +5 -0
- package/src/mastering_dynamics.ts +7 -1
- package/src/metering.ts +6 -1
- package/src/opfs_clip_pages.ts +26 -1
- package/src/project.ts +7 -0
- package/src/project_class.ts +62 -8
- package/src/project_internal.ts +24 -29
- package/src/project_types.ts +69 -10
- package/src/public_types.ts +68 -0
- package/src/public_types_mastering.ts +22 -0
- package/src/public_types_mixing.ts +11 -2
- package/src/public_types_music.ts +9 -0
- package/src/public_types_spectral.ts +33 -0
- package/src/quick_analysis.ts +25 -7
- package/src/realtime_engine.ts +153 -3
- package/src/realtime_voice_changer.ts +51 -77
- package/src/sonare-analysis.js.d.ts +8 -0
- package/src/sonare.js.d.ts +276 -6
- package/src/streaming_processors.ts +15 -0
- package/src/web_midi.ts +36 -4
- package/src/worker.ts +196 -0
- package/src/worker_client.ts +352 -0
- package/src/worker_protocol.ts +59 -0
- package/src/worklet/engine-automation.ts +2 -1
- package/src/worklet/engine-capture-facade.ts +13 -4
- package/src/worklet/engine-clips.ts +12 -3
- package/src/worklet/engine-node.ts +212 -4
- package/src/worklet/engine-offline.ts +7 -2
- package/src/worklet/engine-parameter-facade.ts +26 -5
- package/src/worklet/engine-processor.ts +383 -42
- package/src/worklet/engine-register.ts +8 -0
- package/src/worklet/engine-strips.ts +17 -1
- package/src/worklet/engine-sync.ts +2 -6
- package/src/worklet/engine-tempo-facade.ts +8 -6
- package/src/worklet/engine.ts +380 -13
- package/src/worklet/guards.ts +22 -1
- package/src/worklet/messages.ts +125 -7
- package/src/worklet/protocol.ts +301 -17
- package/src/worklet/voice-changer-processor.ts +12 -15
- package/src/worklet.ts +20 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
(BPM, key, chords, loudness), master and mix to broadcast loudness, and render
|
|
13
13
|
MIDI through built-in instruments, all client-side via WebAssembly — the same
|
|
14
14
|
C++ engine that runs natively, with zero dependencies and no Python or model
|
|
15
|
-
weights.
|
|
15
|
+
weights. 88 named mastering DSP processors implemented against published
|
|
16
16
|
references (ITU-R BS.1770-4 true-peak limiting, Linkwitz-Riley crossovers,
|
|
17
17
|
Vicanek matched-Z biquads, ADAA-antialiased saturation); analysis defaults match
|
|
18
18
|
librosa where the two overlap.
|
|
@@ -31,17 +31,26 @@ Everything runs client-side — no server, nothing uploaded.
|
|
|
31
31
|
npm install @libraz/libsonare
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
For BPM/key/chord detection, feature extraction, and metering without the
|
|
35
|
+
mastering, mixing, or realtime-engine APIs, import the smaller analysis entry:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { detectBpm, init } from '@libraz/libsonare/analysis';
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
With emsdk 5.0.2, the analysis binary is 0.86 MiB raw / 347 KiB gzip; the full
|
|
42
|
+
entry is 3.76 MiB raw / 1.26 MiB gzip. The analysis entry deliberately has no
|
|
43
|
+
`masterAudio`, `mixStereo`, `Project`, `Mixer`, or `RealtimeEngine` export.
|
|
44
|
+
|
|
34
45
|
## Quick Start
|
|
35
46
|
|
|
36
47
|
`init()` loads the WASM module once; every API is available afterwards. Top-level
|
|
37
48
|
one-shot functions accept a request object (recommended) or positional arguments.
|
|
38
49
|
|
|
39
|
-
> **Audio input:**
|
|
40
|
-
>
|
|
41
|
-
>
|
|
42
|
-
>
|
|
43
|
-
> package [`@libraz/libsonare-native`](https://github.com/libraz/libsonare/tree/main/bindings/node)
|
|
44
|
-
> to read files from disk.
|
|
50
|
+
> **Audio input:** start with `Audio.fromMemoryWithBrowserFallback(bytes)`. It
|
|
51
|
+
> decodes WAV/MP3 in WASM, then uses the browser's `decodeAudioData` for other
|
|
52
|
+
> browser-supported formats. Pass a decoded mono `Float32Array` only when one is
|
|
53
|
+
> already available.
|
|
45
54
|
|
|
46
55
|
> **Platform constraints:** the WebAssembly build is single-threaded (analysis
|
|
47
56
|
> runs to completion on the calling thread — there is no non-blocking variant)
|
|
@@ -49,17 +58,14 @@ one-shot functions accept a request object (recommended) or positional arguments
|
|
|
49
58
|
> to keep the UI responsive.
|
|
50
59
|
|
|
51
60
|
```typescript
|
|
52
|
-
import {
|
|
61
|
+
import { Audio, init } from '@libraz/libsonare';
|
|
53
62
|
|
|
54
63
|
await init();
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
const
|
|
65
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
66
|
+
const audio = await Audio.fromMemoryWithBrowserFallback(bytes);
|
|
67
|
+
const { bpm, key } = audio.analyze();
|
|
58
68
|
console.log(`BPM: ${bpm} Key: ${key.name}`);
|
|
59
|
-
|
|
60
|
-
// Master toward a target loudness with a named preset
|
|
61
|
-
const mastered = masterAudio({ samples, sampleRate, preset: 'streaming' });
|
|
62
|
-
console.log(mastered.outputLufs, mastered.appliedGainDb);
|
|
63
69
|
```
|
|
64
70
|
|
|
65
71
|
Render a MIDI arrangement through a built-in instrument with the headless
|
|
@@ -83,16 +89,52 @@ try {
|
|
|
83
89
|
}
|
|
84
90
|
```
|
|
85
91
|
|
|
86
|
-
###
|
|
92
|
+
### Using already-decoded audio
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
Use `Float32Array` directly when another API already decoded the audio:
|
|
89
95
|
|
|
90
96
|
```typescript
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
|
|
97
|
+
const audio = Audio.fromBuffer(decoded.getChannelData(0), decoded.sampleRate);
|
|
98
|
+
const { bpm, key } = audio.analyze();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Offline Worker for longer audio
|
|
102
|
+
|
|
103
|
+
For audio longer than roughly 30 seconds, use `OfflineWorkerClient` to keep
|
|
104
|
+
analysis or preset mastering off the UI thread. The published `./worker`
|
|
105
|
+
subpath is resolved automatically. It intentionally exposes only one-shot
|
|
106
|
+
value APIs (`analyze`, BPM/key/chord detection, and `masterAudio`): native
|
|
107
|
+
handles such as `Project`, `Mixer`, and realtime engines stay in their owning
|
|
108
|
+
JavaScript realm.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { OfflineWorkerClient } from '@libraz/libsonare';
|
|
112
|
+
|
|
113
|
+
const offline = new OfflineWorkerClient();
|
|
114
|
+
const task = offline.analyze(
|
|
115
|
+
{ samples, sampleRate },
|
|
116
|
+
{
|
|
117
|
+
onProgress: ({ progress, stage }) => updateProgress(progress, stage),
|
|
118
|
+
// copy: true, // retain `samples`; the default transfers and detaches it
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
cancelButton.onclick = () => task.cancel();
|
|
123
|
+
try {
|
|
124
|
+
const result = await task;
|
|
125
|
+
console.log(result.bpm, result.key.name);
|
|
126
|
+
} finally {
|
|
127
|
+
offline.dispose();
|
|
128
|
+
}
|
|
94
129
|
```
|
|
95
130
|
|
|
131
|
+
By default the input `Float32Array` is transferred, so its buffer is detached
|
|
132
|
+
on the calling thread. Pass `{ copy: true }` when it must remain usable. Prompt
|
|
133
|
+
cancellation of a running synchronous WASM call uses `SharedArrayBuffer`; serve
|
|
134
|
+
the page with cross-origin isolation (COOP/COEP) when a cancel button must take
|
|
135
|
+
effect immediately. `workerUrl` lets a host point the client at a separately
|
|
136
|
+
hosted copy of `@libraz/libsonare/worker`.
|
|
137
|
+
|
|
96
138
|
### Loading the `.wasm` file
|
|
97
139
|
|
|
98
140
|
Bundlers that don't auto-resolve the `.wasm` asset need its URL. Pass a
|
|
@@ -109,13 +151,60 @@ From a CDN, `import { init } from 'https://esm.sh/@libraz/libsonare'` resolves t
|
|
|
109
151
|
[getting-started guide](https://libsonare.libraz.net/docs/getting-started) for
|
|
110
152
|
per-bundler setup and the AudioWorklet bridge.
|
|
111
153
|
|
|
154
|
+
### Realtime voice changer preset schemas
|
|
155
|
+
|
|
156
|
+
The published package includes the JSON Schema documents for third-party voice
|
|
157
|
+
changer presets. Resolve them through the package exports rather than copying a
|
|
158
|
+
schema from the repository:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
@libraz/libsonare/schemas/realtime-voice-changer-preset.schema.json
|
|
162
|
+
@libraz/libsonare/schemas/realtime-voice-changer-preset-pack.schema.json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Validate data against the schema before saving it, then pass the JSON text to
|
|
166
|
+
`validateRealtimeVoiceChangerPresetJson()` before applying it. The runtime check
|
|
167
|
+
is authoritative and also rejects malformed JSON such as duplicate keys.
|
|
168
|
+
|
|
169
|
+
### Bounded-memory OPFS clip streaming
|
|
170
|
+
|
|
171
|
+
For long raw float32 clips stored in OPFS, `attachOpfsClipStream` supplies only
|
|
172
|
+
the current playback window to WASM. It primes the first page, then fetches page
|
|
173
|
+
misses on the main thread and evicts pages outside the configured read-ahead /
|
|
174
|
+
retain-behind window. The AudioWorklet path uses the same helper: the worklet
|
|
175
|
+
posts a bounded batch of misses, and it outputs silence until a page arrives.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { attachOpfsClipStream } from '@libraz/libsonare';
|
|
179
|
+
import { SonareEngine } from '@libraz/libsonare/worklet';
|
|
180
|
+
|
|
181
|
+
const engine = await SonareEngine.create(audioContext);
|
|
182
|
+
const stream = await attachOpfsClipStream(engine, {
|
|
183
|
+
path: 'takes/lead.f32',
|
|
184
|
+
clipId: 42,
|
|
185
|
+
numChannels: 2,
|
|
186
|
+
numSamples: 48_000 * 600,
|
|
187
|
+
pageFrames: 16_384,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// `clipId` must equal the explicit id supplied here.
|
|
191
|
+
engine.addClip(trackId, stream.provider, 0, { id: 42 });
|
|
192
|
+
|
|
193
|
+
// Close the returned binding after removing the clip (or when the host closes).
|
|
194
|
+
stream.binding.close();
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The bounded-memory guarantee applies only to an OPFS/page-provider source.
|
|
198
|
+
Passing a `Float32Array[]` to `addClip` keeps that full array in the JavaScript
|
|
199
|
+
heap, so it is appropriate for short clips but does not make long clips bounded.
|
|
200
|
+
|
|
112
201
|
## Capabilities
|
|
113
202
|
|
|
114
203
|
Every area below has runnable examples and the full API in the
|
|
115
204
|
[documentation](https://libsonare.libraz.net/docs/wasm).
|
|
116
205
|
|
|
117
206
|
- **Analysis** — BPM, key (+ candidates), chords, downbeats, sections, melody, tuning; pitch (YIN / pYIN), timbre, and the full spectral feature set (STFT, mel, MFCC, chroma, CQT/VQT, spectral contrast); metering (true-peak, LUFS, correlation, vectorscope, waveform peaks). → [API](https://libsonare.libraz.net/docs/wasm)
|
|
118
|
-
- **Mastering** —
|
|
207
|
+
- **Mastering** — 88 named DSP processors, the configurable `masteringChain`, 25 named presets via `masterAudio`, and reference-matching. → [Mastering processors](https://libsonare.libraz.net/docs/mastering-processors)
|
|
119
208
|
- **Mixing** — offline `mixStereo` and the block-based `Mixer` with scene presets. → [Mixing](https://libsonare.libraz.net/docs/mixing)
|
|
120
209
|
- **Editing DSP** — time-stretch, pitch-shift, HPSS (+ residual), phase vocoder, normalize, trim, remix. → [Editing DSP](https://libsonare.libraz.net/docs/editing-dsp)
|
|
121
210
|
- **Room acoustics** — blind RT60 / EDT, impulse-response clarity metrics, RIR synthesis, room estimation and morphing. → [Room acoustics](https://libsonare.libraz.net/docs/acoustic-analysis)
|