@libraz/libsonare 1.7.1 → 1.8.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/NOTICE +178 -0
- package/README.md +26 -170
- package/dist/_chain_config.d.ts +14 -0
- package/dist/_chain_config.d.ts.map +1 -0
- package/dist/_effects_common.d.ts +6 -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 -5837
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +873 -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 +477 -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 +129 -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 -7329
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3816 -1359
- 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 +457 -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 +652 -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 +510 -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 +164 -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 +850 -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 +3909 -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 +335 -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 +128 -0
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
- package/dist/worklet/engine-node.d.ts +81 -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 +68 -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 +73 -0
- package/dist/worklet/engine-strips.d.ts.map +1 -0
- package/dist/worklet/engine-sync.d.ts +37 -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 +397 -0
- package/dist/worklet/engine.d.ts.map +1 -0
- package/dist/worklet/guards.d.ts +47 -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 +323 -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 -2142
- package/dist/worklet.d.ts.map +1 -0
- package/dist/worklet.js +2889 -466
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -12
- package/src/_effects_common.ts +17 -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 +97 -22
- package/src/effects_note_ops.ts +635 -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 +377 -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 +285 -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 +346 -32
- package/src/mastering_dynamics.ts +22 -11
- package/src/metering.ts +67 -24
- package/src/mixer.ts +212 -3
- 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 +64 -24
- package/src/project_class.ts +502 -29
- package/src/project_internal.ts +151 -42
- package/src/project_synth.ts +67 -1
- package/src/project_types.ts +302 -270
- package/src/public_types.ts +122 -3
- package/src/public_types_acoustic.ts +112 -3
- package/src/public_types_mastering.ts +254 -73
- package/src/public_types_mixing.ts +363 -1
- package/src/public_types_music.ts +312 -2
- package/src/public_types_playback.ts +195 -0
- package/src/public_types_realtime.ts +39 -7
- package/src/public_types_repair.ts +446 -0
- package/src/public_types_spectral.ts +487 -1
- package/src/quick_analysis.ts +203 -26
- package/src/realtime_engine.ts +750 -28
- 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 +1125 -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 +212 -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 +444 -10
- package/src/worklet/engine-node.ts +85 -28
- package/src/worklet/engine-offline.ts +14 -8
- package/src/worklet/engine-parameter-facade.ts +21 -0
- package/src/worklet/engine-processor.ts +307 -71
- package/src/worklet/engine-register.ts +32 -18
- package/src/worklet/engine-strips.ts +280 -9
- package/src/worklet/engine-sync.ts +14 -6
- package/src/worklet/engine.ts +365 -31
- package/src/worklet/guards.ts +140 -44
- package/src/worklet/messages.ts +239 -2
- package/src/worklet/mixer-processor.ts +109 -47
- package/src/worklet/playback-processor.ts +300 -0
- package/src/worklet/protocol.ts +53 -3
- package/src/worklet/voice-changer-processor.ts +17 -11
- package/src/worklet.ts +22 -0
- package/src/effects_transform.ts +0 -718
- package/src/mastering_repair.ts +0 -273
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { EngineClip } from '../index';
|
|
2
2
|
import { RealtimeEngine } from '../index';
|
|
3
|
-
import type
|
|
3
|
+
import { copyPlanesToOutput, type WorkletInput, type WorkletOutput } from './audio_types';
|
|
4
|
+
import { emptyStripJson } from './engine-mixer-facade';
|
|
5
|
+
import { requireChannelCount, requireIntegerOption } from './guards';
|
|
4
6
|
import {
|
|
5
7
|
DEFAULT_METRONOME_CONFIG,
|
|
6
8
|
type ResolvedMetronomeConfig,
|
|
@@ -39,7 +41,6 @@ import {
|
|
|
39
41
|
type SonareEngineTelemetryRecord,
|
|
40
42
|
type SonareEngineTelemetryRingBuffer,
|
|
41
43
|
SonareEngineTelemetryType,
|
|
42
|
-
type SonareWorkletMeterSnapshot,
|
|
43
44
|
scopeRingFromSharedBuffer,
|
|
44
45
|
telemetryFromEngine,
|
|
45
46
|
writeInt64Words,
|
|
@@ -94,6 +95,11 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
94
95
|
// allocated per render quantum (the old engine.process() round-tripped fresh
|
|
95
96
|
// arrays on both heaps every block, an RT-safety hazard).
|
|
96
97
|
private channelBuffers: Float32Array[];
|
|
98
|
+
// Cue-bus plane, allocated only when the host asked for a separate PFL/AFL
|
|
99
|
+
// output. Empty otherwise, so a single-output host pays no heap and keeps the
|
|
100
|
+
// historical behaviour where process() folds the cue into the program mix.
|
|
101
|
+
private monitorBuffers: Float32Array[] = [];
|
|
102
|
+
private readonly cueOutput: boolean;
|
|
97
103
|
private readonly liveClips = new Map<number, EngineClip>();
|
|
98
104
|
private readonly pagedClipProviders = new Map<number, number>();
|
|
99
105
|
private readonly pagedClipPageFrames = new Map<number, number>();
|
|
@@ -112,9 +118,15 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
112
118
|
) {
|
|
113
119
|
this.sampleRate = options.sampleRate ?? 48000;
|
|
114
120
|
this.blockSize = options.blockSize ?? 128;
|
|
115
|
-
this.channelCount =
|
|
121
|
+
this.channelCount = requireChannelCount(options.channelCount, 2);
|
|
116
122
|
this.transport = transport;
|
|
117
|
-
|
|
123
|
+
// Zero is the off switch for meter publication, so the floor is 0.
|
|
124
|
+
this.meterIntervalFrames = requireIntegerOption(
|
|
125
|
+
options.meterIntervalFrames,
|
|
126
|
+
2048,
|
|
127
|
+
'meterIntervalFrames',
|
|
128
|
+
0,
|
|
129
|
+
);
|
|
118
130
|
this.commandRing = options.commandSharedBuffer
|
|
119
131
|
? this.commandRingFromSharedBuffer(options.commandSharedBuffer, options.commandRingCapacity)
|
|
120
132
|
: undefined;
|
|
@@ -146,10 +158,13 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
146
158
|
options.externalMidiRingCapacity,
|
|
147
159
|
)
|
|
148
160
|
: undefined;
|
|
161
|
+
if (this.commandRing && this.commandRing.capacity > 65536) {
|
|
162
|
+
throw new RangeError('commandRingCapacity must be at most 65536');
|
|
163
|
+
}
|
|
149
164
|
this.engine = new RealtimeEngine(
|
|
150
165
|
this.sampleRate,
|
|
151
166
|
this.blockSize,
|
|
152
|
-
1024,
|
|
167
|
+
Math.max(1024, this.commandRing?.capacity ?? 0),
|
|
153
168
|
1024,
|
|
154
169
|
this.channelCount,
|
|
155
170
|
);
|
|
@@ -160,11 +175,25 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
160
175
|
for (let ch = 0; ch < this.channelCount; ch++) {
|
|
161
176
|
this.channelBuffers[ch] = this.engine.getChannelBuffer(ch, this.blockSize);
|
|
162
177
|
}
|
|
178
|
+
this.cueOutput = options.cueOutput === true;
|
|
179
|
+
if (this.cueOutput) {
|
|
180
|
+
this.engine.prepareMonitorChannels(this.channelCount, this.blockSize);
|
|
181
|
+
this.monitorBuffers = new Array(this.channelCount);
|
|
182
|
+
for (let ch = 0; ch < this.channelCount; ch++) {
|
|
183
|
+
this.monitorBuffers[ch] = this.engine.getMonitorChannelBuffer(ch, this.blockSize);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
163
186
|
// Arm the engine's scope producer only when a scope ring was provided. The
|
|
164
187
|
// band count follows the ring's record layout so writeScopeRing never
|
|
165
188
|
// overruns its slot.
|
|
166
189
|
if (this.scopeRing) {
|
|
167
|
-
|
|
190
|
+
// Zero is the engine's own off switch for the scope tap, so the floor is 0.
|
|
191
|
+
const interval = requireIntegerOption(
|
|
192
|
+
options.scopeIntervalFrames,
|
|
193
|
+
this.blockSize,
|
|
194
|
+
'scopeIntervalFrames',
|
|
195
|
+
0,
|
|
196
|
+
);
|
|
168
197
|
this.engine.configureScopeTelemetry(interval, this.scopeRing.bands);
|
|
169
198
|
}
|
|
170
199
|
}
|
|
@@ -213,6 +242,9 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
213
242
|
if ((this.channelBuffers[0]?.byteLength ?? 0) === 0) {
|
|
214
243
|
this.reacquireChannelBuffers();
|
|
215
244
|
}
|
|
245
|
+
if (this.cueOutput && (this.monitorBuffers[0]?.byteLength ?? 0) === 0) {
|
|
246
|
+
this.reacquireMonitorBuffers();
|
|
247
|
+
}
|
|
216
248
|
|
|
217
249
|
const input = inputs[0];
|
|
218
250
|
// Write the AudioWorklet input straight into the engine's WASM-heap views;
|
|
@@ -227,19 +259,20 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
227
259
|
}
|
|
228
260
|
}
|
|
229
261
|
|
|
230
|
-
// Run the engine in place over the prepared scratch (allocation-free).
|
|
231
|
-
|
|
262
|
+
// Run the engine in place over the prepared scratch (allocation-free). The
|
|
263
|
+
// monitor variant keeps the cue bus out of the program planes so it can go
|
|
264
|
+
// to its own output; the plain call folds it in, as it always has.
|
|
265
|
+
if (this.cueOutput) {
|
|
266
|
+
this.engine.processPreparedWithMonitor(usableFrames);
|
|
267
|
+
} else {
|
|
268
|
+
this.engine.processPrepared(usableFrames);
|
|
269
|
+
}
|
|
232
270
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
if (target.length > usableFrames) {
|
|
239
|
-
target.fill(0, usableFrames);
|
|
240
|
-
}
|
|
241
|
-
} else {
|
|
242
|
-
target.fill(0);
|
|
271
|
+
copyPlanesToOutput(output, this.channelBuffers, usableFrames);
|
|
272
|
+
if (this.cueOutput) {
|
|
273
|
+
const cue = outputs[1];
|
|
274
|
+
if (cue) {
|
|
275
|
+
copyPlanesToOutput(cue, this.monitorBuffers, usableFrames);
|
|
243
276
|
}
|
|
244
277
|
}
|
|
245
278
|
this.publishClipPageRequests();
|
|
@@ -256,6 +289,12 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
256
289
|
}
|
|
257
290
|
}
|
|
258
291
|
|
|
292
|
+
private reacquireMonitorBuffers(): void {
|
|
293
|
+
for (let ch = 0; ch < this.channelCount; ch++) {
|
|
294
|
+
this.monitorBuffers[ch] = this.engine.getMonitorChannelBuffer(ch, this.blockSize);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
259
298
|
receiveCommand(command: SonareEngineCommandRecord): void {
|
|
260
299
|
if (!this.closed) {
|
|
261
300
|
this.safeApplyCommand(command);
|
|
@@ -348,6 +387,14 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
348
387
|
}
|
|
349
388
|
break;
|
|
350
389
|
}
|
|
390
|
+
case 'syncClipPagePrefetchFrames': {
|
|
391
|
+
this.engine.setClipPagePrefetchFrames(message.frames);
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
case 'syncWarpVoiceCapacity': {
|
|
395
|
+
this.engine.setWarpVoiceCapacity(message.voices);
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
351
398
|
case 'syncClipPageCommit': {
|
|
352
399
|
const providerId = this.pagedClipProviders.get(message.clipId);
|
|
353
400
|
const clip = message.clip ?? this.pendingPagedClips.get(message.clipId);
|
|
@@ -408,11 +455,69 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
408
455
|
);
|
|
409
456
|
}
|
|
410
457
|
break;
|
|
411
|
-
case 'syncMixer':
|
|
458
|
+
case 'syncMixer': {
|
|
459
|
+
if (message.sidechainDelta === true) {
|
|
460
|
+
// Sidechain setters send a binding delta through this message type.
|
|
461
|
+
// Their `lanes` field is context, not a request to rebuild routing;
|
|
462
|
+
// rebuilding it here would discard live insert smoother slots.
|
|
463
|
+
for (const binding of message.laneSidechains ?? []) {
|
|
464
|
+
this.engine.setLaneSidechain(
|
|
465
|
+
binding.trackId,
|
|
466
|
+
binding.insertIndex,
|
|
467
|
+
binding.sourceTrackId,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
for (const binding of message.busSidechains ?? []) {
|
|
471
|
+
this.engine.setBusSidechain(
|
|
472
|
+
binding.busId,
|
|
473
|
+
binding.insertIndex,
|
|
474
|
+
binding.sourceKind,
|
|
475
|
+
binding.sourceId,
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
for (const binding of message.masterSidechains ?? []) {
|
|
479
|
+
this.engine.setMasterSidechain(
|
|
480
|
+
binding.insertIndex,
|
|
481
|
+
binding.sourceKind,
|
|
482
|
+
binding.sourceId,
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
// SAB commands are published before the control thread posts this
|
|
488
|
+
// structural sync. Drain the whole snapshot so a future command past
|
|
489
|
+
// the normal 64-per-render budget cannot enter native after the strip
|
|
490
|
+
// replacement has invalidated its target.
|
|
491
|
+
if (this.commandRing) {
|
|
492
|
+
const write = Atomics.load(this.commandRing.header, 0);
|
|
493
|
+
const read = Atomics.load(this.commandRing.header, 1);
|
|
494
|
+
this.drainCommands(Math.min(this.commandRing.capacity, Math.max(0, write - read)));
|
|
495
|
+
}
|
|
496
|
+
// Complete earlier immediate edits in message order. Scheduled
|
|
497
|
+
// commands remain queued for their render frame.
|
|
498
|
+
this.engine.applyCommandsDueNowPreservingFuture();
|
|
499
|
+
this.engine.settleInsertParameters();
|
|
412
500
|
if (message.buses) {
|
|
413
501
|
this.engine.setTrackBuses(message.buses);
|
|
414
502
|
}
|
|
415
503
|
this.engine.setTrackLanes(message.lanes);
|
|
504
|
+
for (const target of message.forceInsertResets ?? []) {
|
|
505
|
+
const emptyJson = emptyStripJson(target);
|
|
506
|
+
switch (target.kind) {
|
|
507
|
+
case 'track':
|
|
508
|
+
this.engine.clearTrackInsertParameterBases(target.trackId);
|
|
509
|
+
this.engine.setTrackStripJson(target.trackId, emptyJson);
|
|
510
|
+
break;
|
|
511
|
+
case 'bus':
|
|
512
|
+
this.engine.clearBusInsertParameterBases(target.busId);
|
|
513
|
+
this.engine.setBusStripJson(target.busId, emptyJson);
|
|
514
|
+
break;
|
|
515
|
+
case 'master':
|
|
516
|
+
this.engine.clearMasterInsertParameterBases();
|
|
517
|
+
this.engine.setMasterStripJson(emptyJson);
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
416
521
|
for (const strip of message.trackStrips ?? []) {
|
|
417
522
|
this.engine.setTrackStripJson(strip.trackId, strip.sceneJson);
|
|
418
523
|
}
|
|
@@ -425,7 +530,46 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
425
530
|
for (const binding of message.laneSidechains ?? []) {
|
|
426
531
|
this.engine.setLaneSidechain(binding.trackId, binding.insertIndex, binding.sourceTrackId);
|
|
427
532
|
}
|
|
533
|
+
for (const binding of message.busSidechains ?? []) {
|
|
534
|
+
this.engine.setBusSidechain(
|
|
535
|
+
binding.busId,
|
|
536
|
+
binding.insertIndex,
|
|
537
|
+
binding.sourceKind,
|
|
538
|
+
binding.sourceId,
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
for (const binding of message.masterSidechains ?? []) {
|
|
542
|
+
this.engine.setMasterSidechain(binding.insertIndex, binding.sourceKind, binding.sourceId);
|
|
543
|
+
}
|
|
544
|
+
for (const override of message.insertParamOverrides ?? []) {
|
|
545
|
+
switch (override.kind) {
|
|
546
|
+
case 'track':
|
|
547
|
+
this.engine.restoreTrackStripInsertParamByName(
|
|
548
|
+
override.trackId,
|
|
549
|
+
override.insertIndex,
|
|
550
|
+
override.paramName,
|
|
551
|
+
override.value,
|
|
552
|
+
);
|
|
553
|
+
break;
|
|
554
|
+
case 'bus':
|
|
555
|
+
this.engine.restoreBusStripInsertParamByName(
|
|
556
|
+
override.busId,
|
|
557
|
+
override.insertIndex,
|
|
558
|
+
override.paramName,
|
|
559
|
+
override.value,
|
|
560
|
+
);
|
|
561
|
+
break;
|
|
562
|
+
case 'master':
|
|
563
|
+
this.engine.restoreMasterStripInsertParamByName(
|
|
564
|
+
override.insertIndex,
|
|
565
|
+
override.paramName,
|
|
566
|
+
override.value,
|
|
567
|
+
);
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
428
571
|
break;
|
|
572
|
+
}
|
|
429
573
|
case 'syncCapture':
|
|
430
574
|
this.engine.setCaptureBuffer(message.channels, message.bufferFrames);
|
|
431
575
|
this.engine.setCaptureSource(message.source);
|
|
@@ -438,6 +582,9 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
438
582
|
case 'syncMasterStripEqBand':
|
|
439
583
|
this.engine.setMasterStripEqBandJson(message.bandIndex, message.bandJson);
|
|
440
584
|
break;
|
|
585
|
+
case 'syncBusStripEqBand':
|
|
586
|
+
this.engine.setBusStripEqBandJson(message.busId, message.bandIndex, message.bandJson);
|
|
587
|
+
break;
|
|
441
588
|
case 'syncTrackStripInsertBypassed':
|
|
442
589
|
this.engine.setTrackStripInsertBypassed(
|
|
443
590
|
message.trackId,
|
|
@@ -454,26 +601,65 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
454
601
|
);
|
|
455
602
|
break;
|
|
456
603
|
case 'syncTrackStripInsertParamByName':
|
|
457
|
-
this.engine.
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
604
|
+
this.engine.applyCommandsDueNowPreservingFuture();
|
|
605
|
+
if (
|
|
606
|
+
!this.engine.applyTrackStripInsertParamByNameNow(
|
|
607
|
+
message.trackId,
|
|
608
|
+
message.insertIndex,
|
|
609
|
+
message.paramName,
|
|
610
|
+
message.value,
|
|
611
|
+
)
|
|
612
|
+
) {
|
|
613
|
+
// A burst can exhaust the fixed smoother slots before the next
|
|
614
|
+
// render quantum. Apply the last knob value exactly in that case.
|
|
615
|
+
this.engine.restoreTrackStripInsertParamByName(
|
|
616
|
+
message.trackId,
|
|
617
|
+
message.insertIndex,
|
|
618
|
+
message.paramName,
|
|
619
|
+
message.value,
|
|
620
|
+
);
|
|
621
|
+
}
|
|
463
622
|
break;
|
|
464
623
|
case 'syncMasterStripInsertParamByName':
|
|
465
|
-
this.engine.
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
624
|
+
this.engine.applyCommandsDueNowPreservingFuture();
|
|
625
|
+
if (
|
|
626
|
+
!this.engine.applyMasterStripInsertParamByNameNow(
|
|
627
|
+
message.insertIndex,
|
|
628
|
+
message.paramName,
|
|
629
|
+
message.value,
|
|
630
|
+
)
|
|
631
|
+
) {
|
|
632
|
+
this.engine.restoreMasterStripInsertParamByName(
|
|
633
|
+
message.insertIndex,
|
|
634
|
+
message.paramName,
|
|
635
|
+
message.value,
|
|
636
|
+
);
|
|
637
|
+
}
|
|
470
638
|
break;
|
|
471
639
|
case 'syncBusStripInsertParamByName':
|
|
472
|
-
this.engine.
|
|
640
|
+
this.engine.applyCommandsDueNowPreservingFuture();
|
|
641
|
+
if (
|
|
642
|
+
!this.engine.applyBusStripInsertParamByNameNow(
|
|
643
|
+
message.busId,
|
|
644
|
+
message.insertIndex,
|
|
645
|
+
message.paramName,
|
|
646
|
+
message.value,
|
|
647
|
+
)
|
|
648
|
+
) {
|
|
649
|
+
this.engine.restoreBusStripInsertParamByName(
|
|
650
|
+
message.busId,
|
|
651
|
+
message.insertIndex,
|
|
652
|
+
message.paramName,
|
|
653
|
+
message.value,
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
break;
|
|
657
|
+
case 'syncBusStripInsertBypassed':
|
|
658
|
+
this.engine.setBusStripInsertBypassed(
|
|
473
659
|
message.busId,
|
|
474
660
|
message.insertIndex,
|
|
475
|
-
message.
|
|
476
|
-
message.
|
|
661
|
+
message.bypassed,
|
|
662
|
+
message.resetOnBypass,
|
|
477
663
|
);
|
|
478
664
|
break;
|
|
479
665
|
case 'syncTrackStripPan':
|
|
@@ -488,6 +674,18 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
488
674
|
case 'syncTrackStripDualPan':
|
|
489
675
|
this.engine.setTrackStripDualPan(message.trackId, message.leftPan, message.rightPan);
|
|
490
676
|
break;
|
|
677
|
+
case 'syncBusStripPan':
|
|
678
|
+
this.engine.setBusStripPan(message.busId, message.pan);
|
|
679
|
+
break;
|
|
680
|
+
case 'syncBusStripPanLaw':
|
|
681
|
+
this.engine.setBusStripPanLaw(message.busId, message.panLaw);
|
|
682
|
+
break;
|
|
683
|
+
case 'syncBusStripPanMode':
|
|
684
|
+
this.engine.setBusStripPanMode(message.busId, message.panMode);
|
|
685
|
+
break;
|
|
686
|
+
case 'syncBusStripDualPan':
|
|
687
|
+
this.engine.setBusStripDualPan(message.busId, message.leftPan, message.rightPan);
|
|
688
|
+
break;
|
|
491
689
|
case 'syncTrackStripChannelDelaySamples':
|
|
492
690
|
this.engine.setTrackStripChannelDelaySamples(message.trackId, message.delaySamples);
|
|
493
691
|
break;
|
|
@@ -539,8 +737,36 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
539
737
|
message.renderFrame,
|
|
540
738
|
);
|
|
541
739
|
break;
|
|
740
|
+
case 'syncMidiPitchBend':
|
|
741
|
+
this.engine.pushMidiPitchBend(
|
|
742
|
+
message.destinationId,
|
|
743
|
+
message.group,
|
|
744
|
+
message.channel,
|
|
745
|
+
message.data0,
|
|
746
|
+
message.renderFrame,
|
|
747
|
+
);
|
|
748
|
+
break;
|
|
749
|
+
case 'syncMidiChannelPressure':
|
|
750
|
+
this.engine.pushMidiChannelPressure(
|
|
751
|
+
message.destinationId,
|
|
752
|
+
message.group,
|
|
753
|
+
message.channel,
|
|
754
|
+
message.data0,
|
|
755
|
+
message.renderFrame,
|
|
756
|
+
);
|
|
757
|
+
break;
|
|
758
|
+
case 'syncMidiPolyPressure':
|
|
759
|
+
this.engine.pushMidiPolyPressure(
|
|
760
|
+
message.destinationId,
|
|
761
|
+
message.group,
|
|
762
|
+
message.channel,
|
|
763
|
+
message.data0,
|
|
764
|
+
message.data1,
|
|
765
|
+
message.renderFrame,
|
|
766
|
+
);
|
|
767
|
+
break;
|
|
542
768
|
case 'syncMidiUmp':
|
|
543
|
-
this.engine.pushMidiUmp(message.destinationId, message.word0, message.renderFrame);
|
|
769
|
+
this.engine.pushMidiUmp(message.destinationId, [message.word0], message.renderFrame);
|
|
544
770
|
break;
|
|
545
771
|
case 'syncMidiSysex':
|
|
546
772
|
this.engine.pushMidiSysex(message.destinationId, message.data, message.renderFrame);
|
|
@@ -593,6 +819,31 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
593
819
|
message.portTimeSamples,
|
|
594
820
|
);
|
|
595
821
|
break;
|
|
822
|
+
case 'syncMidiInputPitchBend':
|
|
823
|
+
this.engine.pushMidiInputPitchBend(
|
|
824
|
+
message.group,
|
|
825
|
+
message.channel,
|
|
826
|
+
message.data0,
|
|
827
|
+
message.portTimeSamples,
|
|
828
|
+
);
|
|
829
|
+
break;
|
|
830
|
+
case 'syncMidiInputChannelPressure':
|
|
831
|
+
this.engine.pushMidiInputChannelPressure(
|
|
832
|
+
message.group,
|
|
833
|
+
message.channel,
|
|
834
|
+
message.data0,
|
|
835
|
+
message.portTimeSamples,
|
|
836
|
+
);
|
|
837
|
+
break;
|
|
838
|
+
case 'syncMidiInputPolyPressure':
|
|
839
|
+
this.engine.pushMidiInputPolyPressure(
|
|
840
|
+
message.group,
|
|
841
|
+
message.channel,
|
|
842
|
+
message.data0,
|
|
843
|
+
message.data1,
|
|
844
|
+
message.portTimeSamples,
|
|
845
|
+
);
|
|
846
|
+
break;
|
|
596
847
|
}
|
|
597
848
|
}
|
|
598
849
|
|
|
@@ -680,11 +931,11 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
680
931
|
}
|
|
681
932
|
}
|
|
682
933
|
|
|
683
|
-
private drainCommands(): void {
|
|
934
|
+
private drainCommands(limit = 64): void {
|
|
684
935
|
if (!this.commandRing) {
|
|
685
936
|
return;
|
|
686
937
|
}
|
|
687
|
-
for (let i = 0; i <
|
|
938
|
+
for (let i = 0; i < limit; i++) {
|
|
688
939
|
const command = popSonareEngineCommandRingBuffer(this.commandRing);
|
|
689
940
|
if (!command) {
|
|
690
941
|
return;
|
|
@@ -900,14 +1151,15 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
900
1151
|
if (meter.frame !== this.lastMeterFrame) {
|
|
901
1152
|
this.lastMeterFrame = meter.frame;
|
|
902
1153
|
}
|
|
903
|
-
//
|
|
904
|
-
//
|
|
905
|
-
//
|
|
906
|
-
//
|
|
907
|
-
|
|
908
|
-
|
|
1154
|
+
// The ring branch returned above, so this is the structured-clone
|
|
1155
|
+
// fallback. `onMeter` and `postMessage` are alternative channels for the
|
|
1156
|
+
// same record, not a broadcast pair: the AudioWorklet registration
|
|
1157
|
+
// resolves BOTH to `port.postMessage`, so calling them in turn delivered
|
|
1158
|
+
// every record twice and doubled the host's peak-hold decay rate. Take
|
|
1159
|
+
// the first channel the transport offers.
|
|
1160
|
+
if (this.transport?.onMeter) {
|
|
1161
|
+
this.transport.onMeter(meter);
|
|
909
1162
|
} else {
|
|
910
|
-
this.transport?.onMeter?.(meter);
|
|
911
1163
|
this.transport?.postMessage?.(meter);
|
|
912
1164
|
}
|
|
913
1165
|
}
|
|
@@ -926,34 +1178,18 @@ export class SonareRealtimeEngineWorkletProcessor {
|
|
|
926
1178
|
Atomics.store(ring.header, 0, writeIndex + 1);
|
|
927
1179
|
}
|
|
928
1180
|
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
ring.records[offset + 5] = meter.rmsDbL;
|
|
942
|
-
ring.records[offset + 6] = meter.rmsDbR;
|
|
943
|
-
ring.records[offset + 7] = meter.correlation;
|
|
944
|
-
ring.records[offset + 8] = meter.truePeakDbL;
|
|
945
|
-
ring.records[offset + 9] = meter.truePeakDbR;
|
|
946
|
-
ring.records[offset + 10] = meter.momentaryLufs;
|
|
947
|
-
ring.records[offset + 11] = meter.shortTermLufs;
|
|
948
|
-
ring.records[offset + 12] = meter.integratedLufs;
|
|
949
|
-
ring.records[offset + 13] = meter.gainReductionDb;
|
|
950
|
-
Atomics.store(ring.header, 0, writeIndex + 1);
|
|
951
|
-
// writeIndex is a free-running monotonic counter, so an overflow guard here
|
|
952
|
-
// would fire on essentially every write past the first `capacity` records
|
|
953
|
-
// and store an ever-growing value, not a dropped-record count. Readers
|
|
954
|
-
// already detect silent overrun via firstReadable = max(readIndex,
|
|
955
|
-
// writeIndex - capacity), so header slot 3 is left at its initial 0.
|
|
956
|
-
}
|
|
1181
|
+
// A snapshot-object ring writer used to live here as well. It was
|
|
1182
|
+
// unreachable: publishMeters returns after the writeMeterScratch loop
|
|
1183
|
+
// whenever a ring exists, so the ring is never fed from a materialised
|
|
1184
|
+
// snapshot. writeMeterScratch above is the only ring writer, and it keeps the
|
|
1185
|
+
// render callback allocation-free by reading the engine's scratch registers
|
|
1186
|
+
// directly.
|
|
1187
|
+
//
|
|
1188
|
+
// writeIndex is a free-running monotonic counter, so an overflow guard would
|
|
1189
|
+
// fire on essentially every write past the first `capacity` records and store
|
|
1190
|
+
// an ever-growing value, not a dropped-record count. Readers already detect
|
|
1191
|
+
// silent overrun via firstReadable = max(readIndex, writeIndex - capacity),
|
|
1192
|
+
// so header slot 3 is left at its initial 0.
|
|
957
1193
|
|
|
958
1194
|
// Drains the engine's scope producer (FFT spectrum + goniometer points) into
|
|
959
1195
|
// the lock-free SAB scope ring. No allocation on the render path: records are
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
isEngineTransportRequestMessage,
|
|
10
10
|
} from './guards';
|
|
11
11
|
import type { SonareRealtimeEngineWorkletProcessorOptions, WorkletPort } from './messages';
|
|
12
|
+
import { isRecord } from './protocol';
|
|
12
13
|
|
|
13
14
|
export function registerSonareRealtimeEngineWorkletProcessor(
|
|
14
15
|
name = 'sonare-realtime-engine-processor',
|
|
@@ -43,15 +44,7 @@ export function registerSonareRealtimeEngineWorkletProcessor(
|
|
|
43
44
|
}
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
-
this.bridge.receiveCommand(event.data);
|
|
48
|
-
} else if (isEngineSyncMessage(event.data)) {
|
|
49
|
-
this.bridge.receiveSync(event.data);
|
|
50
|
-
} else if (isEngineCaptureRequestMessage(event.data)) {
|
|
51
|
-
this.bridge.receiveCaptureRequest(event.data);
|
|
52
|
-
} else if (isEngineTransportRequestMessage(event.data)) {
|
|
53
|
-
this.bridge.receiveTransportRequest(event.data);
|
|
54
|
-
}
|
|
47
|
+
this.routeMessage(event.data);
|
|
55
48
|
};
|
|
56
49
|
if (port?.addEventListener) {
|
|
57
50
|
port.addEventListener('message', onMessage);
|
|
@@ -72,18 +65,39 @@ export function registerSonareRealtimeEngineWorkletProcessor(
|
|
|
72
65
|
return true;
|
|
73
66
|
}
|
|
74
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Single dispatch point for the port, shared with the buffered replay so
|
|
70
|
+
* the two cannot recognize different message sets.
|
|
71
|
+
*/
|
|
72
|
+
private routeMessage(data: unknown): void {
|
|
73
|
+
const bridge = this.bridge;
|
|
74
|
+
if (!bridge) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (isEngineCommandRecord(data)) {
|
|
78
|
+
bridge.receiveCommand(data);
|
|
79
|
+
} else if (isEngineSyncMessage(data)) {
|
|
80
|
+
bridge.receiveSync(data);
|
|
81
|
+
} else if (isEngineCaptureRequestMessage(data)) {
|
|
82
|
+
bridge.receiveCaptureRequest(data);
|
|
83
|
+
} else if (isEngineTransportRequestMessage(data)) {
|
|
84
|
+
bridge.receiveTransportRequest(data);
|
|
85
|
+
} else if (isRecord(data) && typeof data.type === 'string' && data.type.startsWith('sync')) {
|
|
86
|
+
// A sync the guard does not accept would otherwise vanish, leaving the
|
|
87
|
+
// live engine out of step with the offline mirror and nothing to see.
|
|
88
|
+
// Report it through the same channel as a sync the engine rejected.
|
|
89
|
+
this.port?.postMessage?.({
|
|
90
|
+
type: 'syncError',
|
|
91
|
+
syncType: data.type,
|
|
92
|
+
message: `Unrecognized worklet sync message: ${data.type}`,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
75
97
|
private replayPendingMessages(): void {
|
|
76
98
|
const messages = this.pendingMessages.splice(0);
|
|
77
99
|
for (const data of messages) {
|
|
78
|
-
|
|
79
|
-
this.bridge?.receiveCommand(data);
|
|
80
|
-
} else if (isEngineSyncMessage(data)) {
|
|
81
|
-
this.bridge?.receiveSync(data);
|
|
82
|
-
} else if (isEngineCaptureRequestMessage(data)) {
|
|
83
|
-
this.bridge?.receiveCaptureRequest(data);
|
|
84
|
-
} else if (isEngineTransportRequestMessage(data)) {
|
|
85
|
-
this.bridge?.receiveTransportRequest(data);
|
|
86
|
-
}
|
|
100
|
+
this.routeMessage(data);
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
103
|
|