@libraz/libsonare 1.5.5 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -20
- package/dist/analysis.d.ts +5809 -0
- package/dist/analysis.js +2574 -0
- package/dist/analysis.js.map +1 -0
- package/dist/index.d.ts +884 -55
- package/dist/index.js +1302 -292
- package/dist/index.js.map +1 -1
- package/dist/schemas/realtime-voice-changer-preset-pack.schema.json +27 -0
- package/dist/schemas/realtime-voice-changer-preset.schema.json +140 -0
- package/dist/sonare-analysis.js +2 -0
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worker.d.ts +65 -0
- package/dist/worker.js +734 -0
- package/dist/worker.js.map +1 -0
- package/dist/worklet.d.ts +628 -88
- package/dist/worklet.js +1816 -266
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -11
- package/src/_chain_config.ts +5 -3
- package/src/analysis.ts +137 -0
- package/src/analysis_helpers.ts +40 -29
- package/src/audio.ts +7 -2
- package/src/clip_page_streamer.ts +62 -8
- package/src/codes.ts +87 -64
- package/src/effects_mastering.ts +1 -0
- package/src/effects_transform.ts +179 -10
- package/src/errors.ts +1 -0
- package/src/feature_core.ts +140 -2
- package/src/feature_music.ts +25 -3
- package/src/feature_pitch.ts +70 -1
- package/src/feature_spectral.ts +295 -7
- package/src/feature_spectrogram.ts +203 -3
- package/src/features.ts +16 -1
- package/src/index.ts +120 -8
- package/src/mastering_chain.ts +20 -8
- package/src/mastering_core.ts +5 -0
- package/src/mastering_dynamics.ts +7 -1
- package/src/metering.ts +6 -1
- package/src/mixer.ts +3 -3
- package/src/opfs_clip_pages.ts +26 -1
- package/src/project.ts +13 -0
- package/src/project_class.ts +204 -23
- package/src/project_internal.ts +38 -34
- package/src/project_types.ts +114 -11
- package/src/public_types.ts +68 -0
- package/src/public_types_mastering.ts +22 -0
- package/src/public_types_mixing.ts +27 -2
- package/src/public_types_music.ts +9 -0
- package/src/public_types_realtime.ts +23 -5
- package/src/public_types_spectral.ts +33 -0
- package/src/quick_analysis.ts +46 -10
- package/src/realtime_engine.ts +167 -6
- package/src/realtime_voice_changer.ts +51 -77
- package/src/sonare-analysis.js.d.ts +8 -0
- package/src/sonare.js.d.ts +340 -6
- package/src/stream_analyzer.ts +6 -1
- package/src/streaming_processors.ts +15 -0
- package/src/web_midi.ts +46 -11
- package/src/worker.ts +196 -0
- package/src/worker_client.ts +352 -0
- package/src/worker_protocol.ts +59 -0
- package/src/worklet/engine-automation.ts +2 -1
- package/src/worklet/engine-capture-facade.ts +13 -4
- package/src/worklet/engine-clips.ts +12 -3
- package/src/worklet/engine-node.ts +264 -21
- package/src/worklet/engine-offline.ts +7 -2
- package/src/worklet/engine-parameter-facade.ts +55 -5
- package/src/worklet/engine-processor.ts +435 -62
- package/src/worklet/engine-register.ts +9 -1
- package/src/worklet/engine-strips.ts +19 -3
- package/src/worklet/engine-sync.ts +2 -6
- package/src/worklet/engine-tempo-facade.ts +8 -6
- package/src/worklet/engine.ts +390 -13
- package/src/worklet/guards.ts +121 -8
- package/src/worklet/messages.ts +166 -8
- package/src/worklet/protocol.ts +305 -17
- package/src/worklet/voice-changer-processor.ts +12 -15
- package/src/worklet.ts +20 -1
package/src/worklet/guards.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { EngineCaptureStatus } from '../index';
|
|
1
2
|
import type {
|
|
2
3
|
SonareEngineCaptureRequestMessage,
|
|
3
|
-
|
|
4
|
+
SonareEngineCaptureResponseMessageInternal,
|
|
5
|
+
SonareEngineClipPageRequestMessage,
|
|
4
6
|
SonareEngineSyncMessage,
|
|
5
7
|
SonareEngineTransportRequestMessage,
|
|
6
8
|
SonareEngineTransportResponseMessage,
|
|
@@ -39,7 +41,9 @@ export function isEngineSyncMessage(value: unknown): value is SonareEngineSyncMe
|
|
|
39
41
|
value.type === 'syncClipsDelta' ||
|
|
40
42
|
value.type === 'syncClipPageProvider' ||
|
|
41
43
|
value.type === 'syncClipPage' ||
|
|
44
|
+
value.type === 'syncClipPageClear' ||
|
|
42
45
|
value.type === 'syncClipPageCommit' ||
|
|
46
|
+
value.type === 'syncClipPageDestroy' ||
|
|
43
47
|
value.type === 'syncMidiClips' ||
|
|
44
48
|
value.type === 'syncMarkers' ||
|
|
45
49
|
value.type === 'syncMetronome' ||
|
|
@@ -68,10 +72,12 @@ export function isEngineSyncMessage(value: unknown): value is SonareEngineSyncMe
|
|
|
68
72
|
value.type === 'syncMidiNoteOn' ||
|
|
69
73
|
value.type === 'syncMidiNoteOff' ||
|
|
70
74
|
value.type === 'syncMidiCc' ||
|
|
75
|
+
value.type === 'syncMidiUmp' ||
|
|
71
76
|
value.type === 'syncMidiSysex' ||
|
|
72
77
|
value.type === 'syncMidiPanic' ||
|
|
73
78
|
value.type === 'syncMidiDestinationExternal' ||
|
|
74
|
-
value.type === 'syncExternalMidiClock'
|
|
79
|
+
value.type === 'syncExternalMidiClock' ||
|
|
80
|
+
value.type === 'destroy'
|
|
75
81
|
);
|
|
76
82
|
}
|
|
77
83
|
|
|
@@ -86,17 +92,108 @@ export function isEngineCaptureRequestMessage(
|
|
|
86
92
|
);
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
|
|
90
|
-
value: unknown,
|
|
91
|
-
): value is SonareEngineCaptureResponseMessage {
|
|
95
|
+
function isCaptureStatus(value: unknown): value is EngineCaptureStatus {
|
|
92
96
|
return (
|
|
93
97
|
isRecord(value) &&
|
|
94
|
-
value.
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
typeof value.capturedFrames === 'number' &&
|
|
99
|
+
Number.isSafeInteger(value.capturedFrames) &&
|
|
100
|
+
value.capturedFrames >= 0 &&
|
|
101
|
+
typeof value.overflowCount === 'number' &&
|
|
102
|
+
Number.isSafeInteger(value.overflowCount) &&
|
|
103
|
+
value.overflowCount >= 0 &&
|
|
104
|
+
typeof value.armed === 'boolean' &&
|
|
105
|
+
typeof value.punchEnabled === 'boolean' &&
|
|
106
|
+
(value.source === 'input' || value.source === 'output') &&
|
|
107
|
+
typeof value.recordOffsetSamples === 'number' &&
|
|
108
|
+
Number.isSafeInteger(value.recordOffsetSamples)
|
|
97
109
|
);
|
|
98
110
|
}
|
|
99
111
|
|
|
112
|
+
function isCaptureChannel(value: unknown): value is Float32Array {
|
|
113
|
+
// Capture responses are transferred out of the worklet. A typed view onto
|
|
114
|
+
// the WASM heap or a SharedArrayBuffer must not cross that boundary: the
|
|
115
|
+
// former can be detached by memory growth and the latter cannot be listed
|
|
116
|
+
// in a transfer list. `instanceof` also rejects boxed number arrays.
|
|
117
|
+
return (
|
|
118
|
+
value instanceof Float32Array &&
|
|
119
|
+
typeof ArrayBuffer !== 'undefined' &&
|
|
120
|
+
value.buffer instanceof ArrayBuffer
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isCaptureChannels(value: unknown): value is Float32Array[] {
|
|
125
|
+
return Array.isArray(value) && value.every((channel) => isCaptureChannel(channel));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function hasOwn(value: Record<string, unknown>, key: string): boolean {
|
|
129
|
+
// biome-ignore lint/suspicious/noPrototypeBuiltins: Object.hasOwn is newer than the ES2020 target.
|
|
130
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Return a request ID even when the response payload itself is malformed. */
|
|
134
|
+
export function engineCaptureResponseRequestId(value: unknown): number | undefined {
|
|
135
|
+
if (
|
|
136
|
+
!isRecord(value) ||
|
|
137
|
+
value.type !== 'captureResponse' ||
|
|
138
|
+
typeof value.requestId !== 'number' ||
|
|
139
|
+
!Number.isSafeInteger(value.requestId)
|
|
140
|
+
) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
return value.requestId;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function isEngineCaptureResponseMessage(
|
|
147
|
+
value: unknown,
|
|
148
|
+
): value is SonareEngineCaptureResponseMessageInternal {
|
|
149
|
+
const requestId = engineCaptureResponseRequestId(value);
|
|
150
|
+
if (requestId === undefined || !isRecord(value)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (value.ok === false) {
|
|
154
|
+
return (
|
|
155
|
+
typeof value.error === 'string' && !hasOwn(value, 'status') && !hasOwn(value, 'channels')
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (value.ok !== true || hasOwn(value, 'error')) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const hasStatus = hasOwn(value, 'status');
|
|
162
|
+
const hasChannels = hasOwn(value, 'channels');
|
|
163
|
+
if (hasStatus && hasChannels) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
if (hasStatus) {
|
|
167
|
+
return isCaptureStatus(value.status);
|
|
168
|
+
}
|
|
169
|
+
if (hasChannels) {
|
|
170
|
+
return isCaptureChannels(value.channels);
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Check that a strict success response belongs to the requested operation.
|
|
177
|
+
* Failure responses are operation-independent and are therefore valid for
|
|
178
|
+
* every pending request (the node rejects them after this check).
|
|
179
|
+
*/
|
|
180
|
+
export function isEngineCaptureResponseForOperation(
|
|
181
|
+
response: SonareEngineCaptureResponseMessageInternal,
|
|
182
|
+
op: SonareEngineCaptureRequestMessage['op'],
|
|
183
|
+
): boolean {
|
|
184
|
+
if (!response.ok) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
switch (op) {
|
|
188
|
+
case 'status':
|
|
189
|
+
return 'status' in response;
|
|
190
|
+
case 'read':
|
|
191
|
+
return 'channels' in response;
|
|
192
|
+
case 'reset':
|
|
193
|
+
return !('status' in response) && !('channels' in response);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
100
197
|
export function isEngineTransportRequestMessage(
|
|
101
198
|
value: unknown,
|
|
102
199
|
): value is SonareEngineTransportRequestMessage {
|
|
@@ -147,6 +244,22 @@ export function isExternalMidiBatchMessage(
|
|
|
147
244
|
return isRecord(value) && value.type === 'externalMidi' && Array.isArray(value.events);
|
|
148
245
|
}
|
|
149
246
|
|
|
247
|
+
export function isClipPageRequestMessage(
|
|
248
|
+
value: unknown,
|
|
249
|
+
): value is SonareEngineClipPageRequestMessage {
|
|
250
|
+
return (
|
|
251
|
+
isRecord(value) &&
|
|
252
|
+
value.type === 'clipPageRequest' &&
|
|
253
|
+
Array.isArray(value.requests) &&
|
|
254
|
+
value.requests.every(
|
|
255
|
+
(request) =>
|
|
256
|
+
isRecord(request) &&
|
|
257
|
+
typeof request.clipId === 'number' &&
|
|
258
|
+
typeof request.pageIndex === 'number',
|
|
259
|
+
)
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
150
263
|
export function isMeterSnapshot(value: unknown): value is SonareWorkletMeterSnapshot {
|
|
151
264
|
return (
|
|
152
265
|
isRecord(value) &&
|
package/src/worklet/messages.ts
CHANGED
|
@@ -6,11 +6,13 @@ import type {
|
|
|
6
6
|
EngineMarker,
|
|
7
7
|
EngineMetronomeConfig,
|
|
8
8
|
EngineMidiClipSchedule,
|
|
9
|
+
EngineParameterInfo,
|
|
9
10
|
EngineTempoSegment,
|
|
10
11
|
EngineTimeSignatureSegment,
|
|
11
12
|
EngineTrackLane,
|
|
12
13
|
EngineTransportState,
|
|
13
14
|
RealtimeVoiceChangerConfigInput,
|
|
15
|
+
RealtimeVoiceChangerPodConfig,
|
|
14
16
|
} from '../index';
|
|
15
17
|
import type { AutomationCurve } from '../public_types';
|
|
16
18
|
import type {
|
|
@@ -55,6 +57,16 @@ export interface SonareRealtimeEngineWorkletProcessorOptions {
|
|
|
55
57
|
scopeBands?: number;
|
|
56
58
|
scopeSharedBuffer?: SharedArrayBuffer;
|
|
57
59
|
scopeRingCapacity?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Lock-free SPSC queue for clip-page cache misses. Supplying this is required
|
|
62
|
+
* for realtime-safe OPFS streaming: it avoids both embind object creation and
|
|
63
|
+
* postMessage structured cloning from AudioWorklet process().
|
|
64
|
+
*/
|
|
65
|
+
clipPageRequestSharedBuffer?: SharedArrayBuffer;
|
|
66
|
+
clipPageRequestRingCapacity?: number;
|
|
67
|
+
/** Lock-free worklet-to-main-thread MIDI-1 output ring. */
|
|
68
|
+
externalMidiSharedBuffer?: SharedArrayBuffer;
|
|
69
|
+
externalMidiRingCapacity?: number;
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
export interface SonareRealtimeVoiceChangerWorkletProcessorOptions {
|
|
@@ -66,7 +78,8 @@ export interface SonareRealtimeVoiceChangerWorkletProcessorOptions {
|
|
|
66
78
|
|
|
67
79
|
export interface SonareRealtimeVoiceChangerSetConfigMessage {
|
|
68
80
|
type: 'setConfig';
|
|
69
|
-
|
|
81
|
+
/** Pre-normalized by the main thread; never JSON parsed in the worklet. */
|
|
82
|
+
config: RealtimeVoiceChangerPodConfig;
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
export interface SonareRealtimeVoiceChangerResetMessage {
|
|
@@ -88,6 +101,10 @@ export interface SonareRealtimeEngineNodeCapabilities {
|
|
|
88
101
|
sharedArrayBuffer: boolean;
|
|
89
102
|
atomics: boolean;
|
|
90
103
|
audioWorklet: boolean;
|
|
104
|
+
/** True only when clip-page misses use the bounded SAB ring. */
|
|
105
|
+
clipPageRequestsRealtimeSafe: boolean;
|
|
106
|
+
/** True when external MIDI uses the SAB output ring rather than postMessage. */
|
|
107
|
+
externalMidiRealtimeSafe: boolean;
|
|
91
108
|
engineAbiVersion?: number;
|
|
92
109
|
expectedEngineAbiVersion?: number;
|
|
93
110
|
abiCompatible?: boolean;
|
|
@@ -161,18 +178,27 @@ export interface SonareWorkletExternalMidiMessage {
|
|
|
161
178
|
events: SonareWorkletExternalMidiEvent[];
|
|
162
179
|
}
|
|
163
180
|
|
|
181
|
+
/** A control-plane sync message that the worklet rejected without crashing. */
|
|
182
|
+
export interface SonareEngineSyncErrorMessage {
|
|
183
|
+
type: 'syncError';
|
|
184
|
+
syncType: SonareEngineSyncMessage['type'];
|
|
185
|
+
message: string;
|
|
186
|
+
}
|
|
187
|
+
|
|
164
188
|
export type SonareWorkletTransportMessage =
|
|
165
189
|
| SonareWorkletMeterSnapshot
|
|
166
190
|
| SonareWorkletSpectrumSnapshot
|
|
167
191
|
| SonareWorkletExternalMidiMessage
|
|
192
|
+
| SonareEngineClipPageRequestMessage
|
|
168
193
|
| SonareEngineTelemetryRecord;
|
|
169
194
|
|
|
170
195
|
export interface WorkletTransport {
|
|
171
196
|
postMessage?: (
|
|
172
197
|
message:
|
|
173
198
|
| SonareWorkletTransportMessage
|
|
174
|
-
|
|
|
175
|
-
| SonareEngineTransportResponseMessage
|
|
199
|
+
| SonareEngineCaptureResponseMessageInternal
|
|
200
|
+
| SonareEngineTransportResponseMessage
|
|
201
|
+
| SonareEngineSyncErrorMessage,
|
|
176
202
|
transfer?: Transferable[],
|
|
177
203
|
) => void;
|
|
178
204
|
onMeter?: (meter: SonareWorkletMeterSnapshot) => void;
|
|
@@ -183,6 +209,7 @@ export interface ResolvedMetronomeConfig {
|
|
|
183
209
|
beatGain: number;
|
|
184
210
|
accentGain: number;
|
|
185
211
|
clickSamples: number;
|
|
212
|
+
clickSeconds: number;
|
|
186
213
|
}
|
|
187
214
|
|
|
188
215
|
// Fallback metronome gains/click length used by the worklet consumer until the
|
|
@@ -192,6 +219,7 @@ export const DEFAULT_METRONOME_CONFIG: ResolvedMetronomeConfig = {
|
|
|
192
219
|
beatGain: 0.35,
|
|
193
220
|
accentGain: 0.7,
|
|
194
221
|
clickSamples: 0,
|
|
222
|
+
clickSeconds: 0,
|
|
195
223
|
};
|
|
196
224
|
|
|
197
225
|
export function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedMetronomeConfig {
|
|
@@ -199,6 +227,7 @@ export function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedM
|
|
|
199
227
|
beatGain: config.beatGain ?? DEFAULT_METRONOME_CONFIG.beatGain,
|
|
200
228
|
accentGain: config.accentGain ?? DEFAULT_METRONOME_CONFIG.accentGain,
|
|
201
229
|
clickSamples: config.clickSamples ?? DEFAULT_METRONOME_CONFIG.clickSamples,
|
|
230
|
+
clickSeconds: config.clickSeconds ?? DEFAULT_METRONOME_CONFIG.clickSeconds,
|
|
202
231
|
};
|
|
203
232
|
if (
|
|
204
233
|
!Number.isFinite(resolved.beatGain) ||
|
|
@@ -207,6 +236,8 @@ export function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedM
|
|
|
207
236
|
resolved.accentGain < 0 ||
|
|
208
237
|
!Number.isInteger(resolved.clickSamples) ||
|
|
209
238
|
resolved.clickSamples < 0 ||
|
|
239
|
+
!Number.isFinite(resolved.clickSeconds) ||
|
|
240
|
+
resolved.clickSeconds < 0 ||
|
|
210
241
|
resolved.clickSamples > 384000 ||
|
|
211
242
|
(config.clickSeconds !== undefined &&
|
|
212
243
|
(!Number.isFinite(config.clickSeconds) || config.clickSeconds < 0 || config.clickSeconds > 1))
|
|
@@ -220,8 +251,9 @@ export function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedM
|
|
|
220
251
|
// to the worklet engine processor over node.port. Unlike SonareEngineCommandRecord
|
|
221
252
|
// (a small POD POSTed/ringed every block) these carry bulk/structured payloads
|
|
222
253
|
// (clip audio buffers, marker lists, metronome config) that cannot fit the
|
|
223
|
-
// fixed-size SAB command record
|
|
224
|
-
//
|
|
254
|
+
// fixed-size SAB command record. Their port handlers still execute on the
|
|
255
|
+
// AudioWorklet rendering thread, so consumers must validate them without
|
|
256
|
+
// allocation and publish bounded snapshots for process() to consume.
|
|
225
257
|
export interface SonareEngineSyncClipsMessage {
|
|
226
258
|
type: 'syncClips';
|
|
227
259
|
clips: EngineClip[];
|
|
@@ -237,7 +269,8 @@ export interface SonareEngineSyncClipsDeltaMessage {
|
|
|
237
269
|
export interface SonareEngineSyncClipPageProviderMessage {
|
|
238
270
|
type: 'syncClipPageProvider';
|
|
239
271
|
clipId: number;
|
|
240
|
-
clip
|
|
272
|
+
/** Omitted when an OPFS stream is primed before its clip is scheduled. */
|
|
273
|
+
clip?: EngineClip;
|
|
241
274
|
numChannels: number;
|
|
242
275
|
numSamples: number;
|
|
243
276
|
pageFrames: number;
|
|
@@ -251,10 +284,41 @@ export interface SonareEngineSyncClipPageMessage {
|
|
|
251
284
|
channels: Float32Array[];
|
|
252
285
|
}
|
|
253
286
|
|
|
287
|
+
/** Evicts one page after the main-thread sliding window advances. */
|
|
288
|
+
export interface SonareEngineSyncClipPageClearMessage {
|
|
289
|
+
type: 'syncClipPageClear';
|
|
290
|
+
clipId: number;
|
|
291
|
+
pageIndex: number;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Releases a provider whose clip was removed or whose stream was closed. */
|
|
295
|
+
export interface SonareEngineSyncClipPageDestroyMessage {
|
|
296
|
+
type: 'syncClipPageDestroy';
|
|
297
|
+
clipId: number;
|
|
298
|
+
}
|
|
299
|
+
|
|
254
300
|
/** Makes a fully supplied paged clip visible to the audio engine. */
|
|
255
301
|
export interface SonareEngineSyncClipPageCommitMessage {
|
|
256
302
|
type: 'syncClipPageCommit';
|
|
257
303
|
clipId: number;
|
|
304
|
+
/**
|
|
305
|
+
* Clip schedule to publish with a provider that was primed before its
|
|
306
|
+
* schedule was known. The original pre-baked push path supplies it on the
|
|
307
|
+
* provider message instead.
|
|
308
|
+
*/
|
|
309
|
+
clip?: EngineClip;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* A bounded batch of page misses emitted by the AudioWorklet. The main thread
|
|
314
|
+
* resolves these from OPFS and responds with `syncClipPage`; a missing page is
|
|
315
|
+
* silent until that response arrives.
|
|
316
|
+
*/
|
|
317
|
+
export interface SonareEngineClipPageRequestMessage {
|
|
318
|
+
type: 'clipPageRequest';
|
|
319
|
+
requests: Array<{ clipId: number; pageIndex: number }>;
|
|
320
|
+
/** Number of misses dropped because a bounded native or SAB request queue was full. */
|
|
321
|
+
dropped?: number;
|
|
258
322
|
}
|
|
259
323
|
|
|
260
324
|
export interface SonareEngineSyncMidiClipsMessage {
|
|
@@ -278,6 +342,12 @@ export interface SonareEngineSyncAutomationMessage {
|
|
|
278
342
|
points: EngineAutomationPoint[];
|
|
279
343
|
}
|
|
280
344
|
|
|
345
|
+
/** Replaces the live engine's registered custom-parameter set. */
|
|
346
|
+
export interface SonareEngineSyncParametersMessage {
|
|
347
|
+
type: 'syncParameters';
|
|
348
|
+
parameters: EngineParameterInfo[];
|
|
349
|
+
}
|
|
350
|
+
|
|
281
351
|
export interface SonareEngineSyncTempoMessage {
|
|
282
352
|
type: 'syncTempo';
|
|
283
353
|
bpm: number;
|
|
@@ -403,7 +473,12 @@ export interface SonareEngineSyncSynthInstrumentMessage {
|
|
|
403
473
|
export interface SonareEngineSyncSf2InstrumentMessage {
|
|
404
474
|
type: 'syncSf2Instrument';
|
|
405
475
|
destinationId: number;
|
|
406
|
-
config: {
|
|
476
|
+
config: {
|
|
477
|
+
destinationId?: number;
|
|
478
|
+
gain?: number;
|
|
479
|
+
polyphony?: number;
|
|
480
|
+
preferModelForModeledFamilies?: boolean;
|
|
481
|
+
};
|
|
407
482
|
}
|
|
408
483
|
|
|
409
484
|
export interface SonareEngineSyncLoadSoundFontMessage {
|
|
@@ -438,6 +513,13 @@ export interface SonareEngineSyncMidiCcMessage {
|
|
|
438
513
|
renderFrame: number;
|
|
439
514
|
}
|
|
440
515
|
|
|
516
|
+
export interface SonareEngineSyncMidiUmpMessage {
|
|
517
|
+
type: 'syncMidiUmp';
|
|
518
|
+
destinationId: number;
|
|
519
|
+
word0: number;
|
|
520
|
+
renderFrame: number;
|
|
521
|
+
}
|
|
522
|
+
|
|
441
523
|
export interface SonareEngineSyncMidiSysexMessage {
|
|
442
524
|
type: 'syncMidiSysex';
|
|
443
525
|
destinationId: number;
|
|
@@ -461,6 +543,34 @@ export interface SonareEngineSyncExternalMidiClockMessage {
|
|
|
461
543
|
enabled: boolean;
|
|
462
544
|
}
|
|
463
545
|
|
|
546
|
+
export interface SonareEngineSyncMidiInputSourceMessage {
|
|
547
|
+
type: 'syncMidiInputSource' | 'syncClearMidiInputSource';
|
|
548
|
+
destinationId?: number;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export interface SonareEngineSyncMidiCcBindingMessage {
|
|
552
|
+
type: 'syncMidiCcBinding';
|
|
553
|
+
channel: number;
|
|
554
|
+
controller: number;
|
|
555
|
+
paramId: number;
|
|
556
|
+
minValue: number;
|
|
557
|
+
maxValue: number;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export interface SonareEngineSyncMidiInputEventMessage {
|
|
561
|
+
type: 'syncMidiInputNoteOn' | 'syncMidiInputNoteOff' | 'syncMidiInputCc';
|
|
562
|
+
group: number;
|
|
563
|
+
channel: number;
|
|
564
|
+
data0: number;
|
|
565
|
+
data1: number;
|
|
566
|
+
portTimeSamples: number;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/** Releases the realtime engine and all worklet-owned clip buffers. */
|
|
570
|
+
export interface SonareEngineDestroyMessage {
|
|
571
|
+
type: 'destroy';
|
|
572
|
+
}
|
|
573
|
+
|
|
464
574
|
export type SonareEngineInstrumentSyncMessage =
|
|
465
575
|
| SonareEngineSyncBuiltinInstrumentMessage
|
|
466
576
|
| SonareEngineSyncSynthInstrumentMessage
|
|
@@ -473,11 +583,14 @@ export type SonareEngineSyncMessage =
|
|
|
473
583
|
| SonareEngineSyncClipsDeltaMessage
|
|
474
584
|
| SonareEngineSyncClipPageProviderMessage
|
|
475
585
|
| SonareEngineSyncClipPageMessage
|
|
586
|
+
| SonareEngineSyncClipPageClearMessage
|
|
476
587
|
| SonareEngineSyncClipPageCommitMessage
|
|
588
|
+
| SonareEngineSyncClipPageDestroyMessage
|
|
477
589
|
| SonareEngineSyncMidiClipsMessage
|
|
478
590
|
| SonareEngineSyncMarkersMessage
|
|
479
591
|
| SonareEngineSyncMetronomeMessage
|
|
480
592
|
| SonareEngineSyncAutomationMessage
|
|
593
|
+
| SonareEngineSyncParametersMessage
|
|
481
594
|
| SonareEngineSyncTempoMessage
|
|
482
595
|
| SonareEngineSyncMixerMessage
|
|
483
596
|
| SonareEngineSyncCaptureMessage
|
|
@@ -500,10 +613,15 @@ export type SonareEngineSyncMessage =
|
|
|
500
613
|
| SonareEngineSyncMidiFxMessage
|
|
501
614
|
| SonareEngineSyncMidiNoteMessage
|
|
502
615
|
| SonareEngineSyncMidiCcMessage
|
|
616
|
+
| SonareEngineSyncMidiUmpMessage
|
|
503
617
|
| SonareEngineSyncMidiSysexMessage
|
|
504
618
|
| SonareEngineSyncMidiPanicMessage
|
|
505
619
|
| SonareEngineSyncMidiDestinationExternalMessage
|
|
506
|
-
| SonareEngineSyncExternalMidiClockMessage
|
|
620
|
+
| SonareEngineSyncExternalMidiClockMessage
|
|
621
|
+
| SonareEngineSyncMidiInputSourceMessage
|
|
622
|
+
| SonareEngineSyncMidiCcBindingMessage
|
|
623
|
+
| SonareEngineSyncMidiInputEventMessage
|
|
624
|
+
| SonareEngineDestroyMessage;
|
|
507
625
|
|
|
508
626
|
export interface WorkletPort {
|
|
509
627
|
postMessage?: (message: unknown, transfer?: Transferable[]) => void;
|
|
@@ -518,6 +636,12 @@ export interface SonareEngineCaptureRequestMessage {
|
|
|
518
636
|
op: 'status' | 'read' | 'reset';
|
|
519
637
|
}
|
|
520
638
|
|
|
639
|
+
/**
|
|
640
|
+
* Public capture response shape retained for source compatibility.
|
|
641
|
+
*
|
|
642
|
+
* The worklet wire protocol is stricter than this legacy structural type; use
|
|
643
|
+
* `SonareEngineCaptureResponseMessageInternal` inside the implementation.
|
|
644
|
+
*/
|
|
521
645
|
export interface SonareEngineCaptureResponseMessage {
|
|
522
646
|
type: 'captureResponse';
|
|
523
647
|
requestId: number;
|
|
@@ -527,6 +651,40 @@ export interface SonareEngineCaptureResponseMessage {
|
|
|
527
651
|
error?: string;
|
|
528
652
|
}
|
|
529
653
|
|
|
654
|
+
interface SonareEngineCaptureStatusResponseMessageInternal {
|
|
655
|
+
type: 'captureResponse';
|
|
656
|
+
requestId: number;
|
|
657
|
+
ok: true;
|
|
658
|
+
status: EngineCaptureStatus;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
interface SonareEngineCaptureReadResponseMessageInternal {
|
|
662
|
+
type: 'captureResponse';
|
|
663
|
+
requestId: number;
|
|
664
|
+
ok: true;
|
|
665
|
+
channels: Float32Array[];
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
interface SonareEngineCaptureResetResponseMessageInternal {
|
|
669
|
+
type: 'captureResponse';
|
|
670
|
+
requestId: number;
|
|
671
|
+
ok: true;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
interface SonareEngineCaptureErrorResponseMessageInternal {
|
|
675
|
+
type: 'captureResponse';
|
|
676
|
+
requestId: number;
|
|
677
|
+
ok: false;
|
|
678
|
+
error: string;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/** Strict wire response type used only by the worklet implementation. */
|
|
682
|
+
export type SonareEngineCaptureResponseMessageInternal =
|
|
683
|
+
| SonareEngineCaptureStatusResponseMessageInternal
|
|
684
|
+
| SonareEngineCaptureReadResponseMessageInternal
|
|
685
|
+
| SonareEngineCaptureResetResponseMessageInternal
|
|
686
|
+
| SonareEngineCaptureErrorResponseMessageInternal;
|
|
687
|
+
|
|
530
688
|
export interface SonareEngineTransportRequestMessage {
|
|
531
689
|
type: 'transportRequest';
|
|
532
690
|
requestId: number;
|