@libraz/libsonare 1.7.2 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +178 -0
- package/README.md +26 -203
- package/dist/_chain_config.d.ts +14 -0
- package/dist/_chain_config.d.ts.map +1 -0
- package/dist/_effects_common.d.ts +7 -0
- package/dist/_effects_common.d.ts.map +1 -0
- package/dist/_feature_validation.d.ts +8 -0
- package/dist/_feature_validation.d.ts.map +1 -0
- package/dist/_fft_options.d.ts +24 -0
- package/dist/_fft_options.d.ts.map +1 -0
- package/dist/align_take.d.ts +50 -0
- package/dist/align_take.d.ts.map +1 -0
- package/dist/analysis.d.ts +29 -5840
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +874 -722
- package/dist/analysis.js.map +1 -1
- package/dist/analysis_helpers.d.ts +9 -0
- package/dist/analysis_helpers.d.ts.map +1 -0
- package/dist/audio.d.ts +163 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/clip_page_streamer.d.ts +133 -0
- package/dist/clip_page_streamer.d.ts.map +1 -0
- package/dist/codes.d.ts +44 -0
- package/dist/codes.d.ts.map +1 -0
- package/dist/effects_mastering.d.ts +23 -0
- package/dist/effects_mastering.d.ts.map +1 -0
- package/dist/effects_note_ops.d.ts +502 -0
- package/dist/effects_note_ops.d.ts.map +1 -0
- package/dist/effects_percussive.d.ts +185 -0
- package/dist/effects_percussive.d.ts.map +1 -0
- package/dist/effects_separation.d.ts +65 -0
- package/dist/effects_separation.d.ts.map +1 -0
- package/dist/effects_spectral.d.ts +28 -0
- package/dist/effects_spectral.d.ts.map +1 -0
- package/dist/effects_timepitch.d.ts +134 -0
- package/dist/effects_timepitch.d.ts.map +1 -0
- package/dist/effects_voice_change.d.ts +53 -0
- package/dist/effects_voice_change.d.ts.map +1 -0
- package/dist/errors.d.ts +51 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/feature_core.d.ts +341 -0
- package/dist/feature_core.d.ts.map +1 -0
- package/dist/feature_decompose.d.ts +278 -0
- package/dist/feature_decompose.d.ts.map +1 -0
- package/dist/feature_inverse.d.ts +128 -0
- package/dist/feature_inverse.d.ts.map +1 -0
- package/dist/feature_loudness.d.ts +66 -0
- package/dist/feature_loudness.d.ts.map +1 -0
- package/dist/feature_music.d.ts +307 -0
- package/dist/feature_music.d.ts.map +1 -0
- package/dist/feature_pitch.d.ts +108 -0
- package/dist/feature_pitch.d.ts.map +1 -0
- package/dist/feature_resample.d.ts +16 -0
- package/dist/feature_resample.d.ts.map +1 -0
- package/dist/feature_spectral.d.ts +137 -0
- package/dist/feature_spectral.d.ts.map +1 -0
- package/dist/feature_spectrogram.d.ts +198 -0
- package/dist/feature_spectrogram.d.ts.map +1 -0
- package/dist/features.d.ts +10 -0
- package/dist/features.d.ts.map +1 -0
- package/dist/hrtf/default.shrf +0 -0
- package/dist/index.d.ts +74 -7431
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4173 -1621
- package/dist/index.js.map +1 -1
- package/dist/instrument_types.d.ts +517 -0
- package/dist/instrument_types.d.ts.map +1 -0
- package/dist/live_audio.d.ts +35 -0
- package/dist/live_audio.d.ts.map +1 -0
- package/dist/mastering_chain.d.ts +213 -0
- package/dist/mastering_chain.d.ts.map +1 -0
- package/dist/mastering_core.d.ts +483 -0
- package/dist/mastering_core.d.ts.map +1 -0
- package/dist/mastering_dynamics.d.ts +80 -0
- package/dist/mastering_dynamics.d.ts.map +1 -0
- package/dist/metering.d.ts +287 -0
- package/dist/metering.d.ts.map +1 -0
- package/dist/mixer.d.ts +464 -0
- package/dist/mixer.d.ts.map +1 -0
- package/dist/mixing_assistant.d.ts +62 -0
- package/dist/mixing_assistant.d.ts.map +1 -0
- package/dist/mixing_oneshot.d.ts +40 -0
- package/dist/mixing_oneshot.d.ts.map +1 -0
- package/dist/module_state.d.ts +15 -0
- package/dist/module_state.d.ts.map +1 -0
- package/dist/opfs_clip_pages.d.ts +28 -0
- package/dist/opfs_clip_pages.d.ts.map +1 -0
- package/dist/playback_renderer.d.ts +128 -0
- package/dist/playback_renderer.d.ts.map +1 -0
- package/dist/polyphony.d.ts +202 -0
- package/dist/polyphony.d.ts.map +1 -0
- package/dist/project.d.ts +8 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project_class.d.ts +562 -0
- package/dist/project_class.d.ts.map +1 -0
- package/dist/project_internal.d.ts +194 -0
- package/dist/project_internal.d.ts.map +1 -0
- package/dist/project_synth.d.ts +74 -0
- package/dist/project_synth.d.ts.map +1 -0
- package/dist/project_types.d.ts +654 -0
- package/dist/project_types.d.ts.map +1 -0
- package/dist/public_types.d.ts +185 -0
- package/dist/public_types.d.ts.map +1 -0
- package/dist/public_types_acoustic.d.ts +215 -0
- package/dist/public_types_acoustic.d.ts.map +1 -0
- package/dist/public_types_mastering.d.ts +528 -0
- package/dist/public_types_mastering.d.ts.map +1 -0
- package/dist/public_types_mixing.d.ts +436 -0
- package/dist/public_types_mixing.d.ts.map +1 -0
- package/dist/public_types_music.d.ts +619 -0
- package/dist/public_types_music.d.ts.map +1 -0
- package/dist/public_types_playback.d.ts +165 -0
- package/dist/public_types_playback.d.ts.map +1 -0
- package/dist/public_types_realtime.d.ts +174 -0
- package/dist/public_types_realtime.d.ts.map +1 -0
- package/dist/public_types_repair.d.ts +424 -0
- package/dist/public_types_repair.d.ts.map +1 -0
- package/dist/public_types_spectral.d.ts +697 -0
- package/dist/public_types_spectral.d.ts.map +1 -0
- package/dist/quick_analysis.d.ts +445 -0
- package/dist/quick_analysis.d.ts.map +1 -0
- package/dist/realtime_engine.d.ts +893 -0
- package/dist/realtime_engine.d.ts.map +1 -0
- package/dist/realtime_voice_changer.d.ts +158 -0
- package/dist/realtime_voice_changer.d.ts.map +1 -0
- package/dist/repair_dereverb.d.ts +187 -0
- package/dist/repair_dereverb.d.ts.map +1 -0
- package/dist/repair_impulsive.d.ts +186 -0
- package/dist/repair_impulsive.d.ts.map +1 -0
- package/dist/repair_noise.d.ts +239 -0
- package/dist/repair_noise.d.ts.map +1 -0
- package/dist/repair_trim.d.ts +123 -0
- package/dist/repair_trim.d.ts.map +1 -0
- package/dist/sample_bank.d.ts +84 -0
- package/dist/sample_bank.d.ts.map +1 -0
- package/dist/scale.d.ts +10 -0
- package/dist/scale.d.ts.map +1 -0
- package/dist/schemas/mixer-scene.schema.json +393 -0
- package/dist/schemas/playback-renderer-config.schema.json +392 -0
- package/dist/sonare-analysis.d.ts +8 -0
- package/dist/sonare-analysis.js +2 -2
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.d.ts +3945 -0
- package/dist/sonare.js +2 -2
- package/dist/sonare.wasm +0 -0
- package/dist/stream_analyzer.d.ts +163 -0
- package/dist/stream_analyzer.d.ts.map +1 -0
- package/dist/stream_types.d.ts +214 -0
- package/dist/stream_types.d.ts.map +1 -0
- package/dist/streaming_mixing.d.ts +6 -0
- package/dist/streaming_mixing.d.ts.map +1 -0
- package/dist/streaming_processors.d.ts +340 -0
- package/dist/streaming_processors.d.ts.map +1 -0
- package/dist/transcribe.d.ts +77 -0
- package/dist/transcribe.d.ts.map +1 -0
- package/dist/validation.d.ts +140 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/web_midi.d.ts +77 -0
- package/dist/web_midi.d.ts.map +1 -0
- package/dist/worker.d.ts +5 -48
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +94 -41
- package/dist/worker.js.map +1 -1
- package/dist/worker_client.d.ts +96 -0
- package/dist/worker_client.d.ts.map +1 -0
- package/dist/worker_protocol.d.ts +43 -0
- package/dist/worker_protocol.d.ts.map +1 -0
- package/dist/worklet/audio_types.d.ts +21 -0
- package/dist/worklet/audio_types.d.ts.map +1 -0
- package/dist/worklet/engine-automation.d.ts +29 -0
- package/dist/worklet/engine-automation.d.ts.map +1 -0
- package/dist/worklet/engine-capture-facade.d.ts +35 -0
- package/dist/worklet/engine-capture-facade.d.ts.map +1 -0
- package/dist/worklet/engine-clips.d.ts +23 -0
- package/dist/worklet/engine-clips.d.ts.map +1 -0
- package/dist/worklet/engine-markers.d.ts +40 -0
- package/dist/worklet/engine-markers.d.ts.map +1 -0
- package/dist/worklet/engine-mixer-facade.d.ts +164 -0
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
- package/dist/worklet/engine-node.d.ts +83 -0
- package/dist/worklet/engine-node.d.ts.map +1 -0
- package/dist/worklet/engine-offline.d.ts +81 -0
- package/dist/worklet/engine-offline.d.ts.map +1 -0
- package/dist/worklet/engine-options.d.ts +12 -0
- package/dist/worklet/engine-options.d.ts.map +1 -0
- package/dist/worklet/engine-parameter-facade.d.ts +106 -0
- package/dist/worklet/engine-parameter-facade.d.ts.map +1 -0
- package/dist/worklet/engine-processor.d.ts +72 -0
- package/dist/worklet/engine-processor.d.ts.map +1 -0
- package/dist/worklet/engine-register.d.ts +2 -0
- package/dist/worklet/engine-register.d.ts.map +1 -0
- package/dist/worklet/engine-strips.d.ts +75 -0
- package/dist/worklet/engine-strips.d.ts.map +1 -0
- package/dist/worklet/engine-sync.d.ts +39 -0
- package/dist/worklet/engine-sync.d.ts.map +1 -0
- package/dist/worklet/engine-tempo-facade.d.ts +48 -0
- package/dist/worklet/engine-tempo-facade.d.ts.map +1 -0
- package/dist/worklet/engine.d.ts +418 -0
- package/dist/worklet/engine.d.ts.map +1 -0
- package/dist/worklet/guards.d.ts +53 -0
- package/dist/worklet/guards.d.ts.map +1 -0
- package/dist/worklet/messages.d.ts +710 -0
- package/dist/worklet/messages.d.ts.map +1 -0
- package/dist/worklet/mixer-processor.d.ts +46 -0
- package/dist/worklet/mixer-processor.d.ts.map +1 -0
- package/dist/worklet/playback-processor.d.ts +62 -0
- package/dist/worklet/playback-processor.d.ts.map +1 -0
- package/dist/worklet/protocol.d.ts +331 -0
- package/dist/worklet/protocol.d.ts.map +1 -0
- package/dist/worklet/voice-changer-processor.d.ts +41 -0
- package/dist/worklet/voice-changer-processor.d.ts.map +1 -0
- package/dist/worklet.d.ts +16 -2515
- package/dist/worklet.d.ts.map +1 -0
- package/dist/worklet.js +3200 -541
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -12
- package/src/_effects_common.ts +47 -0
- package/src/_feature_validation.ts +34 -0
- package/src/_fft_options.ts +39 -0
- package/src/align_take.ts +64 -0
- package/src/analysis.ts +56 -3
- package/src/analysis_helpers.ts +7 -0
- package/src/audio.ts +106 -3
- package/src/codes.ts +39 -2
- package/src/effects_mastering.ts +101 -22
- package/src/effects_note_ops.ts +683 -0
- package/src/effects_percussive.ts +217 -0
- package/src/effects_separation.ts +150 -0
- package/src/effects_spectral.ts +60 -0
- package/src/effects_timepitch.ts +388 -0
- package/src/errors.ts +23 -1
- package/src/feature_core.ts +127 -2
- package/src/feature_decompose.ts +633 -0
- package/src/feature_inverse.ts +454 -0
- package/src/feature_loudness.ts +125 -0
- package/src/feature_music.ts +107 -14
- package/src/feature_pitch.ts +96 -1
- package/src/feature_spectral.ts +16 -611
- package/src/feature_spectrogram.ts +63 -450
- package/src/features.ts +36 -22
- package/src/index.ts +288 -30
- package/src/instrument_types.ts +645 -0
- package/src/live_audio.ts +27 -1
- package/src/mastering_chain.ts +184 -0
- package/src/mastering_core.ts +441 -32
- package/src/mastering_dynamics.ts +22 -11
- package/src/metering.ts +67 -24
- package/src/mixer.ts +251 -22
- package/src/mixing_assistant.ts +138 -0
- package/src/mixing_oneshot.ts +10 -5
- package/src/module_state.ts +24 -2
- package/src/playback_renderer.ts +252 -0
- package/src/polyphony.ts +279 -0
- package/src/project.ts +61 -24
- package/src/project_class.ts +450 -27
- package/src/project_internal.ts +149 -42
- package/src/project_synth.ts +67 -1
- package/src/project_types.ts +271 -271
- package/src/public_types.ts +122 -3
- package/src/public_types_acoustic.ts +112 -3
- package/src/public_types_mastering.ts +275 -73
- package/src/public_types_mixing.ts +363 -1
- package/src/public_types_music.ts +312 -2
- package/src/public_types_playback.ts +196 -0
- package/src/public_types_realtime.ts +39 -7
- package/src/public_types_repair.ts +446 -0
- package/src/public_types_spectral.ts +491 -5
- package/src/quick_analysis.ts +203 -26
- package/src/realtime_engine.ts +773 -34
- package/src/realtime_voice_changer.ts +55 -1
- package/src/repair_dereverb.ts +299 -0
- package/src/repair_impulsive.ts +395 -0
- package/src/repair_noise.ts +425 -0
- package/src/repair_trim.ts +226 -0
- package/src/sample_bank.ts +113 -0
- package/src/sonare.js.d.ts +1158 -30
- package/src/stream_analyzer.ts +36 -4
- package/src/stream_types.ts +37 -0
- package/src/streaming_mixing.ts +1 -1
- package/src/streaming_processors.ts +202 -10
- package/src/transcribe.ts +89 -0
- package/src/validation.ts +285 -11
- package/src/web_midi.ts +1 -6
- package/src/worker.ts +18 -2
- package/src/worklet/audio_types.ts +37 -0
- package/src/worklet/engine-mixer-facade.ts +800 -32
- package/src/worklet/engine-node.ts +99 -29
- package/src/worklet/engine-offline.ts +14 -8
- package/src/worklet/engine-parameter-facade.ts +21 -0
- package/src/worklet/engine-processor.ts +332 -93
- package/src/worklet/engine-register.ts +32 -18
- package/src/worklet/engine-strips.ts +275 -9
- package/src/worklet/engine-sync.ts +20 -7
- package/src/worklet/engine.ts +394 -48
- package/src/worklet/guards.ts +195 -44
- package/src/worklet/messages.ts +229 -2
- package/src/worklet/mixer-processor.ts +117 -48
- package/src/worklet/playback-processor.ts +300 -0
- package/src/worklet/protocol.ts +82 -11
- package/src/worklet/voice-changer-processor.ts +17 -11
- package/src/worklet.ts +17 -0
- package/src/effects_transform.ts +0 -718
- package/src/mastering_repair.ts +0 -273
package/src/worklet/protocol.ts
CHANGED
|
@@ -25,12 +25,26 @@ export interface SonareWorkletMeterSnapshot {
|
|
|
25
25
|
rmsDbL: number;
|
|
26
26
|
rmsDbR: number;
|
|
27
27
|
correlation: number;
|
|
28
|
+
/**
|
|
29
|
+
* Left-channel inter-sample (true) peak in dB, from the ITU-R BS.1770-4
|
|
30
|
+
* polyphase reconstruction at 4x. A streaming measurement, and the render
|
|
31
|
+
* quantum makes that visible here: the centered reconstruction stencil needs a
|
|
32
|
+
* few future samples a realtime path does not have, so each block's last
|
|
33
|
+
* samples read marginally low (about 0.1 dB across 64..8192-sample blocks on a
|
|
34
|
+
* near-Nyquist tone, always under-reading). Use `meteringTruePeakDb` over the
|
|
35
|
+
* whole signal for an exact dBTP number.
|
|
36
|
+
*/
|
|
28
37
|
truePeakDbL: number;
|
|
38
|
+
/** Right-channel inter-sample (true) peak in dB. See {@link truePeakDbL}. */
|
|
29
39
|
truePeakDbR: number;
|
|
30
40
|
momentaryLufs: number;
|
|
31
41
|
shortTermLufs: number;
|
|
32
42
|
integratedLufs: number;
|
|
33
43
|
gainReductionDb: number;
|
|
44
|
+
/** Maximum pre-trim input peak for the left channel, in dBFS. */
|
|
45
|
+
inputPeakDbL: number;
|
|
46
|
+
/** Maximum pre-trim input peak for the right channel, in dBFS. */
|
|
47
|
+
inputPeakDbR: number;
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
export interface SonareWorkletSpectrumSnapshot {
|
|
@@ -42,18 +56,21 @@ export interface SonareWorkletSpectrumSnapshot {
|
|
|
42
56
|
export const SONARE_METER_RING_HEADER_INTS = 4;
|
|
43
57
|
// Record layout: [frameLo, frameHi, targetId, peakDbL, peakDbR, rmsDbL, rmsDbR,
|
|
44
58
|
// correlation, truePeakDbL, truePeakDbR, momentaryLufs, shortTermLufs,
|
|
45
|
-
// integratedLufs, gainReductionDb].
|
|
59
|
+
// integratedLufs, gainReductionDb, inputPeakDbL, inputPeakDbR].
|
|
46
60
|
// The sample-frame index is monotonically increasing and quickly exceeds the
|
|
47
61
|
// 2^24 exact-integer range of a single Float32 slot (~349 s at 48 kHz), so it is
|
|
48
62
|
// stored split across two Float32 lanes (low 24 bits + high bits) for exact
|
|
49
63
|
// reconstruction. See encodeFrameLo/encodeFrameHi/decodeFrame.
|
|
50
|
-
export const SONARE_METER_RING_RECORD_FLOATS =
|
|
64
|
+
export const SONARE_METER_RING_RECORD_FLOATS = 16;
|
|
51
65
|
export const SONARE_SPECTRUM_RING_HEADER_INTS = 5;
|
|
52
66
|
// Scope ring header: [writeIndex, capacity, recordFloats, bands, maxPoints,
|
|
53
67
|
// reserved]. Record layout: [frameLo, frameHi, targetId, bandCount, pointCount,
|
|
54
68
|
// band0..band(bands-1), l0, r0, l1, r1, ... (maxPoints stereo pairs)].
|
|
55
69
|
export const SONARE_SCOPE_RING_HEADER_INTS = 6;
|
|
56
70
|
export const SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS = 5;
|
|
71
|
+
/** Scope band and goniometer point counts used when a caller supplies none. */
|
|
72
|
+
export const SONARE_SCOPE_DEFAULT_BANDS = 48;
|
|
73
|
+
export const SONARE_SCOPE_DEFAULT_MAX_POINTS = 32;
|
|
57
74
|
|
|
58
75
|
/** Base for splitting a frame index into two exactly-representable Float32 lanes. */
|
|
59
76
|
const SONARE_FRAME_LANE_BASE = 0x1000000; // 2^24
|
|
@@ -111,6 +128,10 @@ export enum SonareEngineCommandType {
|
|
|
111
128
|
// Queueable lane monitor-mode transition. The worklet command vocabulary
|
|
112
129
|
// deliberately leaves 18..25 unused; this is the stable ABI-v3 ordinal.
|
|
113
130
|
SetTrackMonitorMode = 26,
|
|
131
|
+
// Queueable master-meter integrated-loudness reset. Numeric value 28 mirrors
|
|
132
|
+
// rt::CommandType::kResetMasterMeterIntegrated; 27 remains the appended MIDI
|
|
133
|
+
// UMP slot command in the native vocabulary.
|
|
134
|
+
ResetMasterLoudnessMeter = 28,
|
|
114
135
|
}
|
|
115
136
|
|
|
116
137
|
export enum SonareEngineTelemetryType {
|
|
@@ -140,6 +161,7 @@ export enum SonareEngineTelemetryError {
|
|
|
140
161
|
MetronomeOverflow = 18,
|
|
141
162
|
InvalidCommand = 19,
|
|
142
163
|
MaxChannelsExceeded = 20,
|
|
164
|
+
ParameterBaseOverflow = 21,
|
|
143
165
|
}
|
|
144
166
|
|
|
145
167
|
export interface SonareMeterRingBuffer {
|
|
@@ -307,8 +329,24 @@ export interface SharedSpectrumRingWriter {
|
|
|
307
329
|
recordFloats: number;
|
|
308
330
|
}
|
|
309
331
|
|
|
332
|
+
/**
|
|
333
|
+
* Shared finite dB floor (`sonare::constants::kFloorDb`). Every level-in-dB
|
|
334
|
+
* field on a worklet snapshot bottoms out here rather than at `-Infinity`.
|
|
335
|
+
*/
|
|
336
|
+
export const SONARE_FLOOR_DB = -120;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Magnitude to dB with the shared finite floor.
|
|
340
|
+
*
|
|
341
|
+
* `-Infinity` is not a usable value for a meter reading: it propagates NaN
|
|
342
|
+
* through the usual `(db + 60) / 60 * height` bar geometry, serializes to
|
|
343
|
+
* `null` through `JSON.stringify`, and poisons `Math.min`/`Math.max`
|
|
344
|
+
* aggregation. The native meters have always floored at `kFloorDb`, so a
|
|
345
|
+
* producer emitting `-Infinity` also made the two worklets disagree about
|
|
346
|
+
* silence.
|
|
347
|
+
*/
|
|
310
348
|
export function toDb(value: number): number {
|
|
311
|
-
return value > 0 ? 20 * Math.log10(value) :
|
|
349
|
+
return value > 0 ? Math.max(20 * Math.log10(value), SONARE_FLOOR_DB) : SONARE_FLOOR_DB;
|
|
312
350
|
}
|
|
313
351
|
|
|
314
352
|
export function isRecord(value: unknown): value is Record<string, unknown> {
|
|
@@ -360,6 +398,8 @@ export function readSonareMeterRingBuffer(
|
|
|
360
398
|
shortTermLufs: ring.records[offset + 11],
|
|
361
399
|
integratedLufs: ring.records[offset + 12],
|
|
362
400
|
gainReductionDb: ring.records[offset + 13],
|
|
401
|
+
inputPeakDbL: ring.records[offset + 14],
|
|
402
|
+
inputPeakDbR: ring.records[offset + 15],
|
|
363
403
|
});
|
|
364
404
|
}
|
|
365
405
|
return { nextReadIndex: writeIndex, meters };
|
|
@@ -429,8 +469,8 @@ export function sonareScopeRingRecordFloats(bands: number, maxPoints: number): n
|
|
|
429
469
|
|
|
430
470
|
export function sonareScopeRingBufferByteLength(
|
|
431
471
|
capacity: number,
|
|
432
|
-
bands =
|
|
433
|
-
maxPoints =
|
|
472
|
+
bands = SONARE_SCOPE_DEFAULT_BANDS,
|
|
473
|
+
maxPoints = SONARE_SCOPE_DEFAULT_MAX_POINTS,
|
|
434
474
|
): number {
|
|
435
475
|
const clampedCapacity = Math.max(1, Math.floor(capacity));
|
|
436
476
|
const clampedBands = Math.max(1, Math.floor(bands));
|
|
@@ -445,8 +485,8 @@ export function sonareScopeRingBufferByteLength(
|
|
|
445
485
|
|
|
446
486
|
export function createSonareScopeRingBuffer(
|
|
447
487
|
capacity = 64,
|
|
448
|
-
bands =
|
|
449
|
-
maxPoints =
|
|
488
|
+
bands = SONARE_SCOPE_DEFAULT_BANDS,
|
|
489
|
+
maxPoints = SONARE_SCOPE_DEFAULT_MAX_POINTS,
|
|
450
490
|
): SonareScopeRingBuffer {
|
|
451
491
|
const clampedCapacity = Math.max(1, Math.floor(capacity));
|
|
452
492
|
const clampedBands = Math.max(1, Math.floor(bands));
|
|
@@ -525,8 +565,14 @@ export function scopeRingFromSharedBuffer(
|
|
|
525
565
|
const existingBands = Atomics.load(header, 3);
|
|
526
566
|
const existingMaxPoints = Atomics.load(header, 4);
|
|
527
567
|
const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));
|
|
528
|
-
const bands = Math.max(
|
|
529
|
-
|
|
568
|
+
const bands = Math.max(
|
|
569
|
+
1,
|
|
570
|
+
Math.floor(existingBands || fallbackBands || SONARE_SCOPE_DEFAULT_BANDS),
|
|
571
|
+
);
|
|
572
|
+
const maxPoints = Math.max(
|
|
573
|
+
0,
|
|
574
|
+
Math.floor(existingMaxPoints || (fallbackMaxPoints ?? SONARE_SCOPE_DEFAULT_MAX_POINTS)),
|
|
575
|
+
);
|
|
530
576
|
const recordFloats = sonareScopeRingRecordFloats(bands, maxPoints);
|
|
531
577
|
const minBytes = sonareScopeRingBufferByteLength(capacity, bands, maxPoints);
|
|
532
578
|
if (sharedBuffer.byteLength < minBytes) {
|
|
@@ -948,6 +994,27 @@ function recordOffset(index: number, capacity: number, recordBytes: number): num
|
|
|
948
994
|
return (index % capacity) * recordBytes;
|
|
949
995
|
}
|
|
950
996
|
|
|
997
|
+
/**
|
|
998
|
+
* The domain of a uint32 record slot: no fraction, no sign, no overflow.
|
|
999
|
+
*
|
|
1000
|
+
* `setUint32` folds anything outside it into a legal value, so a negative id
|
|
1001
|
+
* becomes a large one and 2**32 becomes 0. An absent value is out of domain;
|
|
1002
|
+
* a slot with a default resolves it before asking.
|
|
1003
|
+
*/
|
|
1004
|
+
export function isUint32Slot(value: number | undefined): boolean {
|
|
1005
|
+
return (
|
|
1006
|
+
typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 && value <= 0xffff_ffff
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
function toUint32Slot(value: number | undefined, fallback: number, name: string): number {
|
|
1011
|
+
const resolved = value ?? fallback;
|
|
1012
|
+
if (!isUint32Slot(resolved)) {
|
|
1013
|
+
throw new RangeError(`${name} must be an integer within [0, 4294967295]`);
|
|
1014
|
+
}
|
|
1015
|
+
return resolved;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
951
1018
|
function toSafeInteger(value: number | bigint | undefined, fallback: number): number {
|
|
952
1019
|
const resolved = typeof value === 'bigint' ? Number(value) : value;
|
|
953
1020
|
if (resolved === undefined) {
|
|
@@ -976,8 +1043,10 @@ function writeEngineCommandRecord(
|
|
|
976
1043
|
offset: number,
|
|
977
1044
|
command: SonareEngineCommandRecord,
|
|
978
1045
|
): void {
|
|
979
|
-
|
|
980
|
-
|
|
1046
|
+
// Both slots are uint32 and the readers are unsigned, so the writer holds
|
|
1047
|
+
// them to that domain; the command vocabulary itself is the node's check.
|
|
1048
|
+
view.setUint32(offset, toUint32Slot(command.type, 0, 'type'), true);
|
|
1049
|
+
view.setUint32(offset + 4, toUint32Slot(command.targetId, 0, 'targetId'), true);
|
|
981
1050
|
writeInt64Words(view, offset + 8, toSafeInteger(command.sampleTime, -1));
|
|
982
1051
|
// argFloat occupies a full 8-byte Float64 slot (replacing the old Float32 +
|
|
983
1052
|
// 4-byte pad) so PPQ scalars carried here keep full double precision over the
|
|
@@ -1052,6 +1121,8 @@ export function meterFromEngine(meter: EngineMeterTelemetry): SonareWorkletMeter
|
|
|
1052
1121
|
shortTermLufs: meter.shortTermLufs,
|
|
1053
1122
|
integratedLufs: meter.integratedLufs,
|
|
1054
1123
|
gainReductionDb: meter.gainReductionDb,
|
|
1124
|
+
inputPeakDbL: meter.inputPeakDbL,
|
|
1125
|
+
inputPeakDbR: meter.inputPeakDbR,
|
|
1055
1126
|
};
|
|
1056
1127
|
}
|
|
1057
1128
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RealtimeVoiceChanger } from '../index';
|
|
2
|
-
import type
|
|
3
|
-
import { isRealtimeVoiceChangerMessage } from './guards';
|
|
2
|
+
import { copyPlanesToOutput, type WorkletInput, type WorkletOutput } from './audio_types';
|
|
3
|
+
import { isRealtimeVoiceChangerMessage, requireChannelCount } from './guards';
|
|
4
4
|
import type {
|
|
5
5
|
SonareRealtimeVoiceChangerMessage,
|
|
6
6
|
SonareRealtimeVoiceChangerWorkletProcessorOptions,
|
|
@@ -25,12 +25,14 @@ export class SonareRealtimeVoiceChangerWorkletProcessor {
|
|
|
25
25
|
// Float32Arrays, so this avoids the per-sample interleave/deinterleave
|
|
26
26
|
// passes that the older interleaved path needed.
|
|
27
27
|
private planarChannels: Float32Array[];
|
|
28
|
+
// Reused so the mono fan-out never builds an array on the audio thread.
|
|
29
|
+
private readonly monoPlane: Float32Array[] = [new Float32Array(0)];
|
|
28
30
|
private destroyed = false;
|
|
29
31
|
|
|
30
32
|
constructor(options: SonareRealtimeVoiceChangerWorkletProcessorOptions = {}) {
|
|
31
33
|
this.sampleRate = options.sampleRate ?? 48000;
|
|
32
34
|
this.blockSize = options.blockSize ?? 128;
|
|
33
|
-
this.channelCount =
|
|
35
|
+
this.channelCount = requireChannelCount(options.channelCount, 1);
|
|
34
36
|
this.changer = new RealtimeVoiceChanger(options.preset ?? 'neutral-monitor');
|
|
35
37
|
this.changer.prepare(this.sampleRate, this.blockSize, this.channelCount);
|
|
36
38
|
// Acquire WASM-heap views once, sized to the worst case. These are alive
|
|
@@ -100,7 +102,14 @@ export class SonareRealtimeVoiceChangerWorkletProcessor {
|
|
|
100
102
|
this.monoInput.fill(0, 0, frames);
|
|
101
103
|
}
|
|
102
104
|
this.changer.processPreparedMono(frames);
|
|
103
|
-
output
|
|
105
|
+
// One plane fans out to every output channel and anything it does not
|
|
106
|
+
// fill is zeroed. Writing only output[0] left a stereo host hard-panned
|
|
107
|
+
// left -- the default `channelCount` here is 1 while AudioWorkletNode's
|
|
108
|
+
// default `channelCountMode: 'max'` gives a 2-channel output, so that was
|
|
109
|
+
// the ordinary configuration -- and left the previous block's samples in
|
|
110
|
+
// the channels it skipped.
|
|
111
|
+
this.monoPlane[0] = this.monoOutput;
|
|
112
|
+
copyPlanesToOutput(output, this.monoPlane, frames);
|
|
104
113
|
return true;
|
|
105
114
|
}
|
|
106
115
|
|
|
@@ -122,13 +131,10 @@ export class SonareRealtimeVoiceChangerWorkletProcessor {
|
|
|
122
131
|
}
|
|
123
132
|
}
|
|
124
133
|
this.changer.processPreparedPlanar(frames);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
// No `for frame` inner loop needed; output[ch] is a Float32Array.
|
|
131
|
-
}
|
|
134
|
+
// Same rule as the mono branch: an output channel past the last processed
|
|
135
|
+
// plane is silence rather than a duplicate of plane 0, and the tail past
|
|
136
|
+
// `frames` is zeroed.
|
|
137
|
+
copyPlanesToOutput(output, this.planarChannels, frames);
|
|
132
138
|
return true;
|
|
133
139
|
}
|
|
134
140
|
|
package/src/worklet.ts
CHANGED
|
@@ -26,6 +26,7 @@ export type {
|
|
|
26
26
|
SonareEngineClipPageRequestMessage,
|
|
27
27
|
SonareEngineSyncAutomationMessage,
|
|
28
28
|
SonareEngineSyncBuiltinInstrumentMessage,
|
|
29
|
+
SonareEngineSyncBusStripEqBandMessage,
|
|
29
30
|
SonareEngineSyncCaptureMessage,
|
|
30
31
|
SonareEngineSyncClipsDeltaMessage,
|
|
31
32
|
SonareEngineSyncClipsMessage,
|
|
@@ -48,6 +49,17 @@ export type {
|
|
|
48
49
|
SonareEngineTransportFacade,
|
|
49
50
|
SonareEngineTransportRequestMessage,
|
|
50
51
|
SonareEngineTransportResponseMessage,
|
|
52
|
+
SonarePlaybackConfigMessage,
|
|
53
|
+
SonarePlaybackDestroyMessage,
|
|
54
|
+
SonarePlaybackDiagnosticsReplyMessage,
|
|
55
|
+
SonarePlaybackDiagnosticsRequestMessage,
|
|
56
|
+
SonarePlaybackErrorMessage,
|
|
57
|
+
SonarePlaybackMessage,
|
|
58
|
+
SonarePlaybackNodeOptions,
|
|
59
|
+
SonarePlaybackOrientationMessage,
|
|
60
|
+
SonarePlaybackResetMessage,
|
|
61
|
+
SonarePlaybackWorkletDiagnostics,
|
|
62
|
+
SonarePlaybackWorkletProcessorOptions,
|
|
51
63
|
SonareRealtimeEngineNodeCapabilities,
|
|
52
64
|
SonareRealtimeEngineNodeOptions,
|
|
53
65
|
SonareRealtimeEngineWorkletProcessorOptions,
|
|
@@ -67,6 +79,11 @@ export {
|
|
|
67
79
|
registerSonareWorkletProcessor,
|
|
68
80
|
SonareWorkletProcessor,
|
|
69
81
|
} from './worklet/mixer-processor';
|
|
82
|
+
export {
|
|
83
|
+
createSonarePlaybackNode,
|
|
84
|
+
registerSonarePlaybackWorkletProcessor,
|
|
85
|
+
SonarePlaybackWorkletProcessor,
|
|
86
|
+
} from './worklet/playback-processor';
|
|
70
87
|
export {
|
|
71
88
|
createSonareClipPageRequestRingBuffer,
|
|
72
89
|
createSonareEngineCommandRingBuffer,
|