@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/engine.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type {
|
|
|
22
22
|
MidiCcBindOptions,
|
|
23
23
|
PanLaw,
|
|
24
24
|
PanMode,
|
|
25
|
+
SidechainSourceKind,
|
|
25
26
|
} from '../index';
|
|
26
27
|
import { RealtimeEngine } from '../index';
|
|
27
28
|
import { createOpfsClipPageProvider, type OpfsClipPageProviderBinding } from '../opfs_clip_pages';
|
|
@@ -34,7 +35,7 @@ import type { EngineClipContext } from './engine-clips';
|
|
|
34
35
|
import * as clips from './engine-clips';
|
|
35
36
|
import type { EngineMarkerContext } from './engine-markers';
|
|
36
37
|
import * as markers from './engine-markers';
|
|
37
|
-
import type { EngineMixerContext } from './engine-mixer-facade';
|
|
38
|
+
import type { EngineMixerContext, InsertParamOverrideMap } from './engine-mixer-facade';
|
|
38
39
|
import * as mixer from './engine-mixer-facade';
|
|
39
40
|
import { SonareRealtimeEngineNode } from './engine-node';
|
|
40
41
|
import { buildTransportFacade, type CaptureOptions } from './engine-offline';
|
|
@@ -94,19 +95,30 @@ export class SonareEngine {
|
|
|
94
95
|
private readonly offlineBlockSize: number;
|
|
95
96
|
private readonly offlineChannelCount: number;
|
|
96
97
|
private readonly automationLanes = new Map<number, EngineAutomationPoint[]>();
|
|
98
|
+
private readonly insertAutomationIdsByTarget = new Map<string, Set<number>>();
|
|
97
99
|
private readonly clips = new Map<number, EngineClip>();
|
|
98
100
|
private readonly midiClips = new Map<number, EngineMidiClipSchedule>();
|
|
99
101
|
private readonly markers = new Map<number, EngineMarker>();
|
|
100
102
|
private readonly trackLaneIds: number[] = [];
|
|
101
103
|
private readonly trackSends = new Map<number, EngineTrackSend[]>();
|
|
102
104
|
private readonly trackOutputBus = new Map<number, number>();
|
|
105
|
+
private readonly trackSourceChannelLayout = new Map<number, number>();
|
|
103
106
|
private readonly laneSidechains = new Map<
|
|
104
107
|
string,
|
|
105
108
|
{ trackId: number; insertIndex: number; sourceTrackId: number }
|
|
106
109
|
>();
|
|
110
|
+
private readonly busSidechains = new Map<
|
|
111
|
+
string,
|
|
112
|
+
{ busId: number; insertIndex: number; sourceKind: number; sourceId: number }
|
|
113
|
+
>();
|
|
114
|
+
private readonly masterSidechains = new Map<
|
|
115
|
+
number,
|
|
116
|
+
{ insertIndex: number; sourceKind: number; sourceId: number }
|
|
117
|
+
>();
|
|
107
118
|
private readonly buses: EngineBus[] = [];
|
|
108
119
|
private readonly trackStripJson = new Map<number, string>();
|
|
109
120
|
private readonly busStripJson = new Map<number, string>();
|
|
121
|
+
private readonly insertParamOverrides: InsertParamOverrideMap = new Map();
|
|
110
122
|
private masterStripJson: string | undefined;
|
|
111
123
|
private captureConfig: Omit<SonareEngineSyncCaptureMessage, 'type'> | undefined;
|
|
112
124
|
private tempoBpm = 120;
|
|
@@ -231,6 +243,11 @@ export class SonareEngine {
|
|
|
231
243
|
tempo.setTimeSignatureSegments(this.tempoContext, segments);
|
|
232
244
|
}
|
|
233
245
|
|
|
246
|
+
/**
|
|
247
|
+
* A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
|
|
248
|
+
* centred pitch bend on every channel played since the last reset, so
|
|
249
|
+
* controller values set before a loop region are not restored at the wrap.
|
|
250
|
+
*/
|
|
234
251
|
setLoop(startPpq: number, endPpq: number, enabled = true): boolean {
|
|
235
252
|
return tempo.setLoop(this.tempoContext, startPpq, endPpq, enabled);
|
|
236
253
|
}
|
|
@@ -310,6 +327,15 @@ export class SonareEngine {
|
|
|
310
327
|
* mixer lane first (like automationParamId) so the offline engine resolves the
|
|
311
328
|
* same strip selector the realtime engine uses.
|
|
312
329
|
*
|
|
330
|
+
* The returned id uses the track's current positional lane selector. When
|
|
331
|
+
* setTrackLanes successfully changes lane order or membership, the engine
|
|
332
|
+
* remaps already queued and published track automation by track id, but it
|
|
333
|
+
* cannot update a numeric id retained by the caller. Re-resolve every track
|
|
334
|
+
* insert id after such a topology change before passing it to
|
|
335
|
+
* setAutomationLane. Use setTrackStripInsertParamByName when the operation
|
|
336
|
+
* needs a stable track identity. Master and bus insert ids are separate and
|
|
337
|
+
* are not invalidated by track-lane changes.
|
|
338
|
+
*
|
|
313
339
|
* @param target Track id (declares a mixer lane on first use).
|
|
314
340
|
* @param insertIndex Index into the strip's combined insert sequence.
|
|
315
341
|
* @param paramName Processor JSON-key parameter name.
|
|
@@ -320,12 +346,17 @@ export class SonareEngine {
|
|
|
320
346
|
insertIndex: number,
|
|
321
347
|
paramName: string,
|
|
322
348
|
): number {
|
|
323
|
-
|
|
349
|
+
const id = parameter.resolveTrackInsertAutomationId(
|
|
324
350
|
this.parameterContext,
|
|
325
351
|
target,
|
|
326
352
|
insertIndex,
|
|
327
353
|
paramName,
|
|
328
354
|
);
|
|
355
|
+
if (id >= 0) {
|
|
356
|
+
const trackId = this.trackLaneIds[this.ensureTrackLane(target)];
|
|
357
|
+
this.rememberInsertAutomationId({ kind: 'track', trackId }, id);
|
|
358
|
+
}
|
|
359
|
+
return id;
|
|
329
360
|
}
|
|
330
361
|
|
|
331
362
|
/**
|
|
@@ -337,7 +368,15 @@ export class SonareEngine {
|
|
|
337
368
|
* @returns Reserved insert-automation id, or -1 when insert/key unknown.
|
|
338
369
|
*/
|
|
339
370
|
resolveMasterInsertAutomationId(insertIndex: number, paramName: string): number {
|
|
340
|
-
|
|
371
|
+
const id = parameter.resolveMasterInsertAutomationId(
|
|
372
|
+
this.parameterContext,
|
|
373
|
+
insertIndex,
|
|
374
|
+
paramName,
|
|
375
|
+
);
|
|
376
|
+
if (id >= 0) {
|
|
377
|
+
this.rememberInsertAutomationId({ kind: 'master' }, id);
|
|
378
|
+
}
|
|
379
|
+
return id;
|
|
341
380
|
}
|
|
342
381
|
|
|
343
382
|
/**
|
|
@@ -351,12 +390,30 @@ export class SonareEngine {
|
|
|
351
390
|
* @returns Reserved insert-automation id, or -1 when bus/insert/key unknown.
|
|
352
391
|
*/
|
|
353
392
|
resolveBusInsertAutomationId(busId: number, insertIndex: number, paramName: string): number {
|
|
354
|
-
|
|
393
|
+
const id = parameter.resolveBusInsertAutomationId(
|
|
355
394
|
this.parameterContext,
|
|
356
395
|
busId,
|
|
357
396
|
insertIndex,
|
|
358
397
|
paramName,
|
|
359
398
|
);
|
|
399
|
+
if (id >= 0) {
|
|
400
|
+
this.rememberInsertAutomationId({ kind: 'bus', busId }, id);
|
|
401
|
+
}
|
|
402
|
+
return id;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Resolves a hosted instrument's continuous parameter to its reserved
|
|
407
|
+
* instrument-automation id, so an instrument parameter follows a breakpoint
|
|
408
|
+
* lane at audio-block precision like a strip insert. Bind the instrument
|
|
409
|
+
* (`setSynthInstrument`) before resolving.
|
|
410
|
+
*
|
|
411
|
+
* @param destinationId MIDI destination the instrument is bound to.
|
|
412
|
+
* @param paramName Instrument JSON-key parameter name (e.g. `cutoffHz`).
|
|
413
|
+
* @returns Reserved instrument-automation id, or -1 when destination/key unknown.
|
|
414
|
+
*/
|
|
415
|
+
resolveInstrumentAutomationId(destinationId: number, paramName: string): number {
|
|
416
|
+
return parameter.resolveInstrumentAutomationId(this.parameterContext, destinationId, paramName);
|
|
360
417
|
}
|
|
361
418
|
|
|
362
419
|
/**
|
|
@@ -397,21 +454,39 @@ export class SonareEngine {
|
|
|
397
454
|
}
|
|
398
455
|
|
|
399
456
|
setStripGain(target: string | number, db: number): boolean {
|
|
400
|
-
|
|
457
|
+
const sent = this.sendSmoothedParam(this.stripParamId(target, ENGINE_MIXER_PARAM_FADER_DB), db);
|
|
458
|
+
if (sent && target === 'master') {
|
|
459
|
+
strips.cacheMasterStripScalar(this.stripContext, 'faderDb', db);
|
|
460
|
+
}
|
|
461
|
+
return sent;
|
|
401
462
|
}
|
|
402
463
|
|
|
403
464
|
setStripPan(target: string | number, pan: number): boolean {
|
|
404
|
-
|
|
465
|
+
const sent = this.sendSmoothedParam(this.stripParamId(target, ENGINE_MIXER_PARAM_PAN), pan);
|
|
466
|
+
if (sent && target === 'master') {
|
|
467
|
+
strips.cacheMasterStripScalar(this.stripContext, 'pan', pan);
|
|
468
|
+
}
|
|
469
|
+
return sent;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/** Resets the master's integrated loudness accumulator in both engine mirrors. */
|
|
473
|
+
resetMasterLoudnessMeter(renderFrame = -1): boolean {
|
|
474
|
+
this.offlineEngine.resetMasterLoudnessMeter(renderFrame);
|
|
475
|
+
return this.sendMirroredCommand({
|
|
476
|
+
type: SonareEngineCommandType.ResetMasterLoudnessMeter,
|
|
477
|
+
sampleTime: renderFrame,
|
|
478
|
+
});
|
|
405
479
|
}
|
|
406
480
|
|
|
407
481
|
/**
|
|
408
482
|
* Declares the mixer track lanes in an explicit order.
|
|
409
483
|
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
* track's send list; entries without `sends` leave
|
|
484
|
+
* A successful call may reorder existing track ids, remove track ids, or add
|
|
485
|
+
* new ones. Existing queued and published track automation follows the track
|
|
486
|
+
* id, while numeric track-insert automation ids retained by the caller do
|
|
487
|
+
* not; re-resolve those ids after every topology change. Entries carrying
|
|
488
|
+
* `sends` replace that track's send list; entries without `sends` leave
|
|
489
|
+
* existing sends untouched.
|
|
415
490
|
*
|
|
416
491
|
* @param lanes Track ids or lane descriptors in the desired lane order.
|
|
417
492
|
*/
|
|
@@ -448,15 +523,48 @@ export class SonareEngine {
|
|
|
448
523
|
mixer.setTrackBuses(this.mixerContext, buses);
|
|
449
524
|
}
|
|
450
525
|
|
|
526
|
+
/**
|
|
527
|
+
* Keys one insert of a bus strip from a track lane or another bus
|
|
528
|
+
* (ducking/sidechainRouter inserts). `sourceId` 0 removes the binding.
|
|
529
|
+
*/
|
|
530
|
+
setBusSidechain(
|
|
531
|
+
busId: number,
|
|
532
|
+
insertIndex: number,
|
|
533
|
+
sourceKind: SidechainSourceKind | number,
|
|
534
|
+
sourceId: number,
|
|
535
|
+
): void {
|
|
536
|
+
mixer.setBusSidechain(this.mixerContext, busId, insertIndex, sourceKind, sourceId);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Keys one insert of the master strip from a track lane or a bus. Same
|
|
541
|
+
* source rules as {@link setBusSidechain}.
|
|
542
|
+
*/
|
|
543
|
+
setMasterSidechain(
|
|
544
|
+
insertIndex: number,
|
|
545
|
+
sourceKind: SidechainSourceKind | number,
|
|
546
|
+
sourceId: number,
|
|
547
|
+
): void {
|
|
548
|
+
mixer.setMasterSidechain(this.mixerContext, insertIndex, sourceKind, sourceId);
|
|
549
|
+
}
|
|
550
|
+
|
|
451
551
|
setBusGain(busId: number, db: number): boolean {
|
|
452
552
|
return mixer.setBusGain(this.mixerContext, busId, db);
|
|
453
553
|
}
|
|
454
554
|
|
|
455
555
|
setTrackStripJson(target: string | number, sceneJson: string): void {
|
|
556
|
+
// Parse before declaring a new lane so malformed text cannot declare one.
|
|
557
|
+
mixer.decodedInsertSignature(sceneJson, { kind: 'track', trackId: 0 });
|
|
456
558
|
const laneIndex = this.ensureTrackLane(target);
|
|
457
559
|
const trackId = this.trackLaneIds[laneIndex];
|
|
458
|
-
|
|
459
|
-
|
|
560
|
+
const { insertBaseResets, constructionOverrides } = strips.setTrackStripJson(
|
|
561
|
+
this.stripContext,
|
|
562
|
+
trackId,
|
|
563
|
+
sceneJson,
|
|
564
|
+
this.trackStripJson,
|
|
565
|
+
);
|
|
566
|
+
mixer.pruneStripSidechains(this.mixerContext, { kind: 'track', trackId }, sceneJson);
|
|
567
|
+
this.syncMixer(insertBaseResets, constructionOverrides);
|
|
460
568
|
}
|
|
461
569
|
|
|
462
570
|
setTrackStripEqBand(target: string | number, bandIndex: number, band: EqBand | string): void {
|
|
@@ -541,9 +649,7 @@ export class SonareEngine {
|
|
|
541
649
|
}
|
|
542
650
|
|
|
543
651
|
setMasterStripJson(sceneJson: string): void {
|
|
544
|
-
|
|
545
|
-
this.masterStripJson = sceneJson;
|
|
546
|
-
this.syncMixer();
|
|
652
|
+
mixer.setMasterStripJson(this.mixerContext, sceneJson);
|
|
547
653
|
}
|
|
548
654
|
|
|
549
655
|
setMasterStripEqBand(bandIndex: number, band: EqBand | string): void {
|
|
@@ -572,6 +678,58 @@ export class SonareEngine {
|
|
|
572
678
|
strips.setBusStripInsertParamByName(this.stripContext, busId, insertIndex, paramName, value);
|
|
573
679
|
}
|
|
574
680
|
|
|
681
|
+
/**
|
|
682
|
+
* Bus-strip counterpart of {@link setStripInsertBypassed}. A bus is addressed
|
|
683
|
+
* by its numeric id, which the `target` of the track/master form cannot
|
|
684
|
+
* express, so it is its own method exactly like
|
|
685
|
+
* {@link setBusStripInsertParamByName}. Bypassing keeps the insert's internal
|
|
686
|
+
* state (reverb tail, compressor envelope) unless `resetOnBypass` is set;
|
|
687
|
+
* re-posting the bus scene JSON, the only workaround before this existed,
|
|
688
|
+
* rebuilds the chain and loses it.
|
|
689
|
+
*/
|
|
690
|
+
setBusStripInsertBypassed(
|
|
691
|
+
busId: number,
|
|
692
|
+
insertIndex: number,
|
|
693
|
+
bypassed: boolean,
|
|
694
|
+
resetOnBypass = false,
|
|
695
|
+
): void {
|
|
696
|
+
this.ensureBus(busId);
|
|
697
|
+
strips.setBusStripInsertBypassed(
|
|
698
|
+
this.stripContext,
|
|
699
|
+
busId,
|
|
700
|
+
insertIndex,
|
|
701
|
+
bypassed,
|
|
702
|
+
resetOnBypass,
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/** Bus-strip counterpart of {@link setTrackStripEqBand}. */
|
|
707
|
+
setBusStripEqBand(busId: number, bandIndex: number, band: EqBand | string): void {
|
|
708
|
+
this.ensureBus(busId);
|
|
709
|
+
strips.setBusStripEqBand(this.stripContext, busId, bandIndex, band);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/** Bus-strip counterpart of {@link setTrackStripPan}; refused on a surround bus. */
|
|
713
|
+
setBusStripPan(busId: number, pan: number): void {
|
|
714
|
+
this.ensureBus(busId);
|
|
715
|
+
strips.setBusStripPan(this.stripContext, busId, pan);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
setBusStripPanLaw(busId: number, panLaw: PanLaw | number): void {
|
|
719
|
+
this.ensureBus(busId);
|
|
720
|
+
strips.setBusStripPanLaw(this.stripContext, busId, panLaw);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
setBusStripPanMode(busId: number, panMode: PanMode | number): void {
|
|
724
|
+
this.ensureBus(busId);
|
|
725
|
+
strips.setBusStripPanMode(this.stripContext, busId, panMode);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
setBusStripDualPan(busId: number, leftPan: number, rightPan: number): void {
|
|
729
|
+
this.ensureBus(busId);
|
|
730
|
+
strips.setBusStripDualPan(this.stripContext, busId, leftPan, rightPan);
|
|
731
|
+
}
|
|
732
|
+
|
|
575
733
|
setStripInsertParamByName(
|
|
576
734
|
target: string | number,
|
|
577
735
|
insertIndex: number,
|
|
@@ -664,6 +822,52 @@ export class SonareEngine {
|
|
|
664
822
|
return { binding, provider: binding.provider };
|
|
665
823
|
}
|
|
666
824
|
|
|
825
|
+
/**
|
|
826
|
+
* Sets the clip-page look-ahead window in timeline frames on both the worklet
|
|
827
|
+
* engine and this thread's offline engine.
|
|
828
|
+
*
|
|
829
|
+
* The audio thread reports the pages it is *about to* read that are not
|
|
830
|
+
* resident yet, so the sliding-window streamer can service them before the
|
|
831
|
+
* playhead reaches them. Without look-ahead a page miss is only reported
|
|
832
|
+
* after the read already produced silence, which costs one block of silence
|
|
833
|
+
* at every page boundary that was not primed.
|
|
834
|
+
*
|
|
835
|
+
* Defaults to half a second at the engine's sample rate. `0` disables it.
|
|
836
|
+
* Safe to call during playback.
|
|
837
|
+
*/
|
|
838
|
+
setClipPagePrefetchFrames(frames: number): void {
|
|
839
|
+
if (this.destroyed) {
|
|
840
|
+
throw new Error('SonareEngine is destroyed.');
|
|
841
|
+
}
|
|
842
|
+
if (!Number.isFinite(frames) || frames < 0) {
|
|
843
|
+
throw new Error('clip page prefetch frames must be a finite value >= 0.');
|
|
844
|
+
}
|
|
845
|
+
this.offlineEngine.setClipPagePrefetchFrames(frames);
|
|
846
|
+
this.postSync({ type: 'syncClipPagePrefetchFrames', frames });
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Sets the number of concurrent time-stretch voices on both this thread's
|
|
851
|
+
* offline engine and the live worklet engine. `voices` must be an integer
|
|
852
|
+
* in `[0, 64]`; a non-integer, negative, or larger value throws and leaves
|
|
853
|
+
* the capacity unchanged on both engines. Default is 8. Capacity 0 disables
|
|
854
|
+
* time-stretch, so every warped clip plays resampled instead. A change
|
|
855
|
+
* applied while the engine is running restarts the splice state of any clip
|
|
856
|
+
* stretching through a voice at that moment.
|
|
857
|
+
*/
|
|
858
|
+
setWarpVoiceCapacity(voices: number): void {
|
|
859
|
+
if (this.destroyed) {
|
|
860
|
+
throw new Error('SonareEngine is destroyed.');
|
|
861
|
+
}
|
|
862
|
+
this.offlineEngine.setWarpVoiceCapacity(voices);
|
|
863
|
+
this.postSync({ type: 'syncWarpVoiceCapacity', voices });
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/** Reads the current time-stretch voice capacity (default 8). */
|
|
867
|
+
warpVoiceCapacity(): number {
|
|
868
|
+
return this.offlineEngine.warpVoiceCapacity();
|
|
869
|
+
}
|
|
870
|
+
|
|
667
871
|
addClip(
|
|
668
872
|
trackId: string | number,
|
|
669
873
|
buffer: Float32Array[] | ClipPageProvider,
|
|
@@ -703,6 +907,8 @@ export class SonareEngine {
|
|
|
703
907
|
gain?: number;
|
|
704
908
|
polyphony?: number;
|
|
705
909
|
preferModelForModeledFamilies?: boolean;
|
|
910
|
+
clearBankRig?: boolean;
|
|
911
|
+
gsEfxRealization?: 'modern' | 'classic';
|
|
706
912
|
} = {},
|
|
707
913
|
): void {
|
|
708
914
|
strips.setSf2Instrument(this.stripContext, trackId, config);
|
|
@@ -711,7 +917,10 @@ export class SonareEngine {
|
|
|
711
917
|
/**
|
|
712
918
|
* Route a track's MIDI to the external output (drained via {@link onMidiOut})
|
|
713
919
|
* instead of an internal instrument, so the track plays an external device.
|
|
714
|
-
* Pass `external=false` to restore internal-synth playback.
|
|
920
|
+
* Pass `external=false` to restore internal-synth playback. The change takes
|
|
921
|
+
* effect at the next processed block; switching a destination's route first
|
|
922
|
+
* releases its notes and resets its controllers through the old route, and
|
|
923
|
+
* drops its pending MIDI-FX events.
|
|
715
924
|
*/
|
|
716
925
|
setMidiDestinationExternal(trackId: string | number, external: boolean): void {
|
|
717
926
|
strips.setMidiDestinationExternal(this.stripContext, trackId, external);
|
|
@@ -776,6 +985,52 @@ export class SonareEngine {
|
|
|
776
985
|
strips.pushMidiCc(this.stripContext, trackId, group, channel, controller, value, renderFrame);
|
|
777
986
|
}
|
|
778
987
|
|
|
988
|
+
pushMidiPitchBend(
|
|
989
|
+
trackId: string | number,
|
|
990
|
+
group: number,
|
|
991
|
+
channel: number,
|
|
992
|
+
bend14: number,
|
|
993
|
+
renderFrame = -1,
|
|
994
|
+
): void {
|
|
995
|
+
strips.pushMidiPitchBend(this.stripContext, trackId, group, channel, bend14, renderFrame);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
pushMidiChannelPressure(
|
|
999
|
+
trackId: string | number,
|
|
1000
|
+
group: number,
|
|
1001
|
+
channel: number,
|
|
1002
|
+
pressure: number,
|
|
1003
|
+
renderFrame = -1,
|
|
1004
|
+
): void {
|
|
1005
|
+
strips.pushMidiChannelPressure(
|
|
1006
|
+
this.stripContext,
|
|
1007
|
+
trackId,
|
|
1008
|
+
group,
|
|
1009
|
+
channel,
|
|
1010
|
+
pressure,
|
|
1011
|
+
renderFrame,
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
pushMidiPolyPressure(
|
|
1016
|
+
trackId: string | number,
|
|
1017
|
+
group: number,
|
|
1018
|
+
channel: number,
|
|
1019
|
+
note: number,
|
|
1020
|
+
pressure: number,
|
|
1021
|
+
renderFrame = -1,
|
|
1022
|
+
): void {
|
|
1023
|
+
strips.pushMidiPolyPressure(
|
|
1024
|
+
this.stripContext,
|
|
1025
|
+
trackId,
|
|
1026
|
+
group,
|
|
1027
|
+
channel,
|
|
1028
|
+
note,
|
|
1029
|
+
pressure,
|
|
1030
|
+
renderFrame,
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
779
1034
|
pushMidiUmp(trackId: string | number, word0: number, renderFrame = -1): void {
|
|
780
1035
|
strips.pushMidiUmp(this.stripContext, trackId, word0, renderFrame);
|
|
781
1036
|
}
|
|
@@ -860,6 +1115,58 @@ export class SonareEngine {
|
|
|
860
1115
|
});
|
|
861
1116
|
}
|
|
862
1117
|
|
|
1118
|
+
pushMidiInputPitchBend(
|
|
1119
|
+
group: number,
|
|
1120
|
+
channel: number,
|
|
1121
|
+
bend14: number,
|
|
1122
|
+
portTimeSamples = 0,
|
|
1123
|
+
): void {
|
|
1124
|
+
this.offlineEngine.pushMidiInputPitchBend(group, channel, bend14, portTimeSamples);
|
|
1125
|
+
this.postSync({
|
|
1126
|
+
type: 'syncMidiInputPitchBend',
|
|
1127
|
+
group,
|
|
1128
|
+
channel,
|
|
1129
|
+
data0: bend14,
|
|
1130
|
+
data1: 0,
|
|
1131
|
+
portTimeSamples,
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
pushMidiInputChannelPressure(
|
|
1136
|
+
group: number,
|
|
1137
|
+
channel: number,
|
|
1138
|
+
pressure: number,
|
|
1139
|
+
portTimeSamples = 0,
|
|
1140
|
+
): void {
|
|
1141
|
+
this.offlineEngine.pushMidiInputChannelPressure(group, channel, pressure, portTimeSamples);
|
|
1142
|
+
this.postSync({
|
|
1143
|
+
type: 'syncMidiInputChannelPressure',
|
|
1144
|
+
group,
|
|
1145
|
+
channel,
|
|
1146
|
+
data0: pressure,
|
|
1147
|
+
data1: 0,
|
|
1148
|
+
portTimeSamples,
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
pushMidiInputPolyPressure(
|
|
1153
|
+
group: number,
|
|
1154
|
+
channel: number,
|
|
1155
|
+
note: number,
|
|
1156
|
+
pressure: number,
|
|
1157
|
+
portTimeSamples = 0,
|
|
1158
|
+
): void {
|
|
1159
|
+
this.offlineEngine.pushMidiInputPolyPressure(group, channel, note, pressure, portTimeSamples);
|
|
1160
|
+
this.postSync({
|
|
1161
|
+
type: 'syncMidiInputPolyPressure',
|
|
1162
|
+
group,
|
|
1163
|
+
channel,
|
|
1164
|
+
data0: note,
|
|
1165
|
+
data1: pressure,
|
|
1166
|
+
portTimeSamples,
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
|
|
863
1170
|
pushMidiPanic(renderFrame = -1): void {
|
|
864
1171
|
this.offlineEngine.pushMidiPanic(renderFrame);
|
|
865
1172
|
this.postSync({ type: 'syncMidiPanic', renderFrame });
|
|
@@ -1106,8 +1413,45 @@ export class SonareEngine {
|
|
|
1106
1413
|
return mixer.mixerLanes(this.mixerContext);
|
|
1107
1414
|
}
|
|
1108
1415
|
|
|
1109
|
-
private syncMixer(
|
|
1110
|
-
mixer.
|
|
1416
|
+
private syncMixer(
|
|
1417
|
+
insertBaseResets: mixer.StripJsonTarget[] = [],
|
|
1418
|
+
oneShotInsertParamOverrides: mixer.InsertParamOverride[] = [],
|
|
1419
|
+
): void {
|
|
1420
|
+
mixer.syncMixer(this.mixerContext, false, insertBaseResets, oneShotInsertParamOverrides);
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
private insertAutomationTargetKey(target: mixer.StripJsonTarget): string {
|
|
1424
|
+
return target.kind === 'track'
|
|
1425
|
+
? `track:${target.trackId}`
|
|
1426
|
+
: target.kind === 'bus'
|
|
1427
|
+
? `bus:${target.busId}`
|
|
1428
|
+
: 'master';
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
private rememberInsertAutomationId(target: mixer.StripJsonTarget, id: number): void {
|
|
1432
|
+
const key = this.insertAutomationTargetKey(target);
|
|
1433
|
+
const ids = this.insertAutomationIdsByTarget.get(key) ?? new Set<number>();
|
|
1434
|
+
ids.add(id);
|
|
1435
|
+
this.insertAutomationIdsByTarget.set(key, ids);
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
private clearInsertAutomationLanes(
|
|
1439
|
+
target: mixer.StripJsonTarget,
|
|
1440
|
+
forgetResolvedIds = false,
|
|
1441
|
+
): void {
|
|
1442
|
+
const key = this.insertAutomationTargetKey(target);
|
|
1443
|
+
const ids = this.insertAutomationIdsByTarget.get(key);
|
|
1444
|
+
if (!ids) {
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
for (const id of ids) {
|
|
1448
|
+
if (this.automationLanes.has(id)) {
|
|
1449
|
+
this.setAutomationLane(id, []);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
if (forgetResolvedIds) {
|
|
1453
|
+
this.insertAutomationIdsByTarget.delete(key);
|
|
1454
|
+
}
|
|
1111
1455
|
}
|
|
1112
1456
|
|
|
1113
1457
|
private postInstrumentSync(message: SonareEngineInstrumentSyncMessage): void {
|
|
@@ -1138,22 +1482,17 @@ export class SonareEngine {
|
|
|
1138
1482
|
if (this.destroyed) {
|
|
1139
1483
|
return;
|
|
1140
1484
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
this.realtimeNode.node.port.postMessage(message);
|
|
1146
|
-
}
|
|
1147
|
-
} finally {
|
|
1148
|
-
this.flushOfflineMirror();
|
|
1485
|
+
if (transfer && transfer.length > 0) {
|
|
1486
|
+
this.realtimeNode.node.port.postMessage(message, transfer);
|
|
1487
|
+
} else {
|
|
1488
|
+
this.realtimeNode.node.port.postMessage(message);
|
|
1149
1489
|
}
|
|
1150
1490
|
}
|
|
1151
1491
|
|
|
1152
|
-
// The
|
|
1153
|
-
//
|
|
1154
|
-
// call this from the worklet/audio path: it is intentionally control-only.
|
|
1492
|
+
// The control-only mirror applies due commands immediately while preserving
|
|
1493
|
+
// scheduled ones for its next render block.
|
|
1155
1494
|
private flushOfflineMirror(): void {
|
|
1156
|
-
this.offlineEngine.
|
|
1495
|
+
this.offlineEngine.applyCommandsDueNowPreservingFuture();
|
|
1157
1496
|
}
|
|
1158
1497
|
|
|
1159
1498
|
private sendMirroredCommand(
|
|
@@ -1174,17 +1513,28 @@ export class SonareEngine {
|
|
|
1174
1513
|
trackLaneIds: this.trackLaneIds,
|
|
1175
1514
|
trackSends: this.trackSends,
|
|
1176
1515
|
trackOutputBus: this.trackOutputBus,
|
|
1516
|
+
trackSourceChannelLayout: this.trackSourceChannelLayout,
|
|
1177
1517
|
laneSidechains: this.laneSidechains,
|
|
1518
|
+
busSidechains: this.busSidechains,
|
|
1519
|
+
masterSidechains: this.masterSidechains,
|
|
1178
1520
|
buses: this.buses,
|
|
1179
1521
|
trackStripJson: this.trackStripJson,
|
|
1180
1522
|
busStripJson: this.busStripJson,
|
|
1523
|
+
insertParamOverrides: this.insertParamOverrides,
|
|
1524
|
+
flushOfflineMirror: () => this.flushOfflineMirror(),
|
|
1181
1525
|
postSync: (message) => this.postSync(message),
|
|
1182
1526
|
ensureTrackLane: (target) => this.ensureTrackLane(target),
|
|
1183
1527
|
ensureBus: (busId) => this.ensureBus(busId),
|
|
1184
1528
|
mixerLanes: () => this.mixerLanes(),
|
|
1185
|
-
syncMixer: () =>
|
|
1529
|
+
syncMixer: (insertBaseResets, oneShotInsertParamOverrides) =>
|
|
1530
|
+
this.syncMixer(insertBaseResets, oneShotInsertParamOverrides),
|
|
1531
|
+
clearInsertAutomationLanes: (target, forgetResolvedIds) =>
|
|
1532
|
+
this.clearInsertAutomationLanes(target, forgetResolvedIds),
|
|
1186
1533
|
sendSmoothedParam: (paramId, value) => this.sendSmoothedParam(paramId, value),
|
|
1187
1534
|
getMasterStripJson: () => this.masterStripJson,
|
|
1535
|
+
cacheMasterStripJson: (sceneJson) => {
|
|
1536
|
+
this.masterStripJson = sceneJson;
|
|
1537
|
+
},
|
|
1188
1538
|
};
|
|
1189
1539
|
}
|
|
1190
1540
|
|
|
@@ -1199,6 +1549,11 @@ export class SonareEngine {
|
|
|
1199
1549
|
postInstrumentSync: (message) => this.postInstrumentSync(message),
|
|
1200
1550
|
ensureTrackLane: (target) => this.ensureTrackLane(target),
|
|
1201
1551
|
resolveTargetId: (target) => this.resolveTargetId(target),
|
|
1552
|
+
readStripJson: (target) => mixer.cachedStripJson(this.mixerContext, target),
|
|
1553
|
+
writeStripJson: (target, sceneJson) =>
|
|
1554
|
+
mixer.cacheStripJson(this.mixerContext, target, sceneJson),
|
|
1555
|
+
insertParamOverrides: this.insertParamOverrides,
|
|
1556
|
+
clearInsertAutomationLanes: (target) => this.clearInsertAutomationLanes(target),
|
|
1202
1557
|
};
|
|
1203
1558
|
}
|
|
1204
1559
|
|
|
@@ -1350,29 +1705,20 @@ export class SonareEngine {
|
|
|
1350
1705
|
}
|
|
1351
1706
|
|
|
1352
1707
|
private ensureTrackLane(target: string | number): number {
|
|
1353
|
-
|
|
1354
|
-
if (!Number.isInteger(trackId) || trackId <= 0) {
|
|
1355
|
-
throw new Error(`Invalid track id for mixer lane: ${String(target)}`);
|
|
1356
|
-
}
|
|
1357
|
-
const existing = this.trackLaneIds.indexOf(trackId);
|
|
1358
|
-
if (existing >= 0) {
|
|
1359
|
-
return existing;
|
|
1360
|
-
}
|
|
1361
|
-
this.trackLaneIds.push(trackId);
|
|
1362
|
-
this.syncMixer();
|
|
1363
|
-
return this.trackLaneIds.length - 1;
|
|
1708
|
+
return mixer.ensureTrackLane(this.mixerContext, target);
|
|
1364
1709
|
}
|
|
1365
1710
|
|
|
1366
1711
|
private ensureBus(busId: number): number {
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1712
|
+
// Tested on the raw id: truncating first leaves the integrality check
|
|
1713
|
+
// unreachable, and registers a bus under an id the caller never named.
|
|
1714
|
+
if (!Number.isInteger(busId) || busId <= 0) {
|
|
1715
|
+
throw new RangeError(`Invalid bus id for mixer bus: ${String(busId)}`);
|
|
1370
1716
|
}
|
|
1371
|
-
const existing = this.buses.findIndex((bus) => bus.busId ===
|
|
1717
|
+
const existing = this.buses.findIndex((bus) => bus.busId === busId);
|
|
1372
1718
|
if (existing >= 0) {
|
|
1373
1719
|
return existing;
|
|
1374
1720
|
}
|
|
1375
|
-
this.buses.push({ busId
|
|
1721
|
+
this.buses.push({ busId });
|
|
1376
1722
|
this.syncMixer();
|
|
1377
1723
|
return this.buses.length - 1;
|
|
1378
1724
|
}
|