@libraz/libsonare 1.5.4 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -20
- package/dist/analysis.d.ts +5730 -0
- package/dist/analysis.js +2464 -0
- package/dist/analysis.js.map +1 -0
- package/dist/index.d.ts +873 -63
- package/dist/index.js +1037 -265
- package/dist/index.js.map +1 -1
- package/dist/schemas/realtime-voice-changer-preset-pack.schema.json +27 -0
- package/dist/schemas/realtime-voice-changer-preset.schema.json +140 -0
- package/dist/sonare-analysis.js +2 -0
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worker.d.ts +65 -0
- package/dist/worker.js +707 -0
- package/dist/worker.js.map +1 -0
- package/dist/worklet.d.ts +596 -86
- package/dist/worklet.js +1658 -235
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -11
- package/src/_chain_config.ts +5 -23
- package/src/analysis.ts +137 -0
- package/src/analysis_helpers.ts +29 -0
- package/src/audio.ts +5 -3
- package/src/clip_page_streamer.ts +62 -8
- package/src/codes.ts +51 -64
- package/src/effects_mastering.ts +1 -0
- package/src/effects_transform.ts +12 -6
- package/src/errors.ts +1 -0
- package/src/feature_core.ts +159 -3
- package/src/feature_music.ts +35 -16
- package/src/feature_pitch.ts +75 -6
- package/src/feature_spectral.ts +234 -8
- package/src/feature_spectrogram.ts +186 -5
- package/src/features.ts +16 -1
- package/src/index.ts +104 -7
- package/src/mastering_chain.ts +20 -8
- package/src/mastering_core.ts +7 -0
- package/src/mastering_dynamics.ts +7 -1
- package/src/metering.ts +51 -5
- package/src/mixer.ts +14 -1
- package/src/opfs_clip_pages.ts +26 -1
- package/src/project.ts +7 -0
- package/src/project_class.ts +74 -13
- package/src/project_internal.ts +24 -29
- package/src/project_types.ts +69 -10
- package/src/public_types.ts +68 -0
- package/src/public_types_mastering.ts +28 -0
- package/src/public_types_mixing.ts +11 -2
- package/src/public_types_music.ts +13 -0
- package/src/public_types_spectral.ts +43 -3
- package/src/quick_analysis.ts +48 -12
- package/src/realtime_engine.ts +162 -4
- package/src/realtime_voice_changer.ts +51 -77
- package/src/sonare-analysis.js.d.ts +8 -0
- package/src/sonare.js.d.ts +305 -9
- package/src/streaming_processors.ts +22 -1
- package/src/validation.ts +6 -0
- package/src/web_midi.ts +36 -4
- package/src/worker.ts +196 -0
- package/src/worker_client.ts +352 -0
- package/src/worker_protocol.ts +59 -0
- package/src/worklet/engine-automation.ts +2 -1
- package/src/worklet/engine-capture-facade.ts +13 -4
- package/src/worklet/engine-clips.ts +12 -3
- package/src/worklet/engine-node.ts +212 -4
- package/src/worklet/engine-offline.ts +7 -2
- package/src/worklet/engine-parameter-facade.ts +26 -5
- package/src/worklet/engine-processor.ts +383 -42
- package/src/worklet/engine-register.ts +8 -0
- package/src/worklet/engine-strips.ts +17 -1
- package/src/worklet/engine-sync.ts +2 -6
- package/src/worklet/engine-tempo-facade.ts +8 -6
- package/src/worklet/engine.ts +380 -13
- package/src/worklet/guards.ts +22 -1
- package/src/worklet/messages.ts +141 -9
- package/src/worklet/protocol.ts +303 -17
- package/src/worklet/voice-changer-processor.ts +12 -15
- package/src/worklet.ts +20 -1
package/src/opfs_clip_pages.ts
CHANGED
|
@@ -8,12 +8,20 @@ export interface OpfsClipPageProviderOptions {
|
|
|
8
8
|
dataOffsetBytes?: number;
|
|
9
9
|
worker?: Worker;
|
|
10
10
|
terminateWorkerOnClose?: boolean;
|
|
11
|
+
/** Internal bridge hook used to mirror a supplied page into an AudioWorklet. */
|
|
12
|
+
onPageSupplied?: (pageIndex: number, channels: Float32Array[]) => void;
|
|
13
|
+
/** Internal bridge hook used to mirror an eviction into an AudioWorklet. */
|
|
14
|
+
onPageCleared?: (pageIndex: number) => void;
|
|
15
|
+
/** Internal bridge hook called after the local provider is destroyed. */
|
|
16
|
+
onClose?: () => void;
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
export interface OpfsClipPageProviderBinding {
|
|
14
20
|
provider: ClipPageProvider;
|
|
15
21
|
supplyPage(pageIndex: number): Promise<boolean>;
|
|
16
22
|
supplyRequest(request: ClipPageRequest): Promise<boolean>;
|
|
23
|
+
/** Evict one resident page from every configured consumer. */
|
|
24
|
+
clearPage?(pageIndex: number): void;
|
|
17
25
|
close(): void;
|
|
18
26
|
}
|
|
19
27
|
|
|
@@ -116,7 +124,15 @@ self.onmessage = async (event) => {
|
|
|
116
124
|
|
|
117
125
|
export function createOpfsClipPageWorker(): Worker {
|
|
118
126
|
const blob = new Blob([opfsClipPageWorkerSource], { type: 'text/javascript' });
|
|
119
|
-
|
|
127
|
+
const url = URL.createObjectURL(blob);
|
|
128
|
+
try {
|
|
129
|
+
return new Worker(url);
|
|
130
|
+
} finally {
|
|
131
|
+
// Worker construction retains the script URL internally; keeping this
|
|
132
|
+
// object URL alive after construction leaks one browser registration per
|
|
133
|
+
// attach/close cycle.
|
|
134
|
+
URL.revokeObjectURL(url);
|
|
135
|
+
}
|
|
120
136
|
}
|
|
121
137
|
|
|
122
138
|
export function createOpfsClipPageProvider(
|
|
@@ -166,6 +182,7 @@ export function createOpfsClipPageProvider(
|
|
|
166
182
|
}
|
|
167
183
|
try {
|
|
168
184
|
provider.supply(response.pageIndex, channels);
|
|
185
|
+
options.onPageSupplied?.(response.pageIndex, channels);
|
|
169
186
|
} catch {
|
|
170
187
|
entry.resolve(false);
|
|
171
188
|
return;
|
|
@@ -218,6 +235,13 @@ export function createOpfsClipPageProvider(
|
|
|
218
235
|
supplyRequest(request: ClipPageRequest) {
|
|
219
236
|
return supplyPage(Math.floor(request.sample / options.pageFrames));
|
|
220
237
|
},
|
|
238
|
+
clearPage(pageIndex: number) {
|
|
239
|
+
if (closed) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
provider.clear(pageIndex);
|
|
243
|
+
options.onPageCleared?.(pageIndex);
|
|
244
|
+
},
|
|
221
245
|
close() {
|
|
222
246
|
if (closed) {
|
|
223
247
|
return;
|
|
@@ -229,6 +253,7 @@ export function createOpfsClipPageProvider(
|
|
|
229
253
|
}
|
|
230
254
|
pending.clear();
|
|
231
255
|
provider.destroy();
|
|
256
|
+
options.onClose?.();
|
|
232
257
|
if (ownsWorker) {
|
|
233
258
|
worker.terminate();
|
|
234
259
|
}
|
package/src/project.ts
CHANGED
|
@@ -10,6 +10,9 @@ export type {
|
|
|
10
10
|
BuiltinSynthBinding,
|
|
11
11
|
BuiltinSynthConfig,
|
|
12
12
|
BuiltinSynthWaveform,
|
|
13
|
+
ExternalSeparatedStem,
|
|
14
|
+
ExternalSeparatedStemImportRequest,
|
|
15
|
+
ExternalSeparatedStemImportResult,
|
|
13
16
|
MidiCcLearnOptions,
|
|
14
17
|
ProjectAssistSidecar,
|
|
15
18
|
ProjectAutomationCurve,
|
|
@@ -17,6 +20,7 @@ export type {
|
|
|
17
20
|
ProjectAutomationPoint,
|
|
18
21
|
ProjectBounceOptions,
|
|
19
22
|
ProjectChordSymbol,
|
|
23
|
+
ProjectClip,
|
|
20
24
|
ProjectClipCompSegment,
|
|
21
25
|
ProjectClipDesc,
|
|
22
26
|
ProjectClipFade,
|
|
@@ -37,8 +41,10 @@ export type {
|
|
|
37
41
|
ProjectMidiRouteConfig,
|
|
38
42
|
ProjectMidiRouteResult,
|
|
39
43
|
ProjectNotePairValidation,
|
|
44
|
+
ProjectSource,
|
|
40
45
|
ProjectTempoSegment,
|
|
41
46
|
ProjectTimeSignatureSegment,
|
|
47
|
+
ProjectTrack,
|
|
42
48
|
ProjectTrackDesc,
|
|
43
49
|
ProjectTrackKind,
|
|
44
50
|
ProjectWarpAnchor,
|
|
@@ -59,6 +65,7 @@ export type {
|
|
|
59
65
|
SynthPatch,
|
|
60
66
|
} from './project_types';
|
|
61
67
|
export {
|
|
68
|
+
BUILTIN_SYNTH_WAVEFORMS,
|
|
62
69
|
EXPECTED_PROJECT_ABI_VERSION,
|
|
63
70
|
MarkerKind,
|
|
64
71
|
SYNTH_BODY_TYPES,
|
package/src/project_class.ts
CHANGED
|
@@ -9,12 +9,15 @@ import {
|
|
|
9
9
|
} from './project_internal';
|
|
10
10
|
import type {
|
|
11
11
|
BuiltinSynthBinding,
|
|
12
|
+
ExternalSeparatedStemImportRequest,
|
|
13
|
+
ExternalSeparatedStemImportResult,
|
|
12
14
|
MidiCcLearnOptions,
|
|
13
15
|
ProjectAssistSidecar,
|
|
14
16
|
ProjectAutomationLaneDesc,
|
|
15
17
|
ProjectAutomationPoint,
|
|
16
18
|
ProjectBounceOptions,
|
|
17
19
|
ProjectChordSymbol,
|
|
20
|
+
ProjectClip,
|
|
18
21
|
ProjectClipCompSegment,
|
|
19
22
|
ProjectClipDesc,
|
|
20
23
|
ProjectClipFade,
|
|
@@ -32,9 +35,11 @@ import type {
|
|
|
32
35
|
ProjectMidiRouteConfig,
|
|
33
36
|
ProjectMidiRouteResult,
|
|
34
37
|
ProjectNotePairValidation,
|
|
38
|
+
ProjectSource,
|
|
35
39
|
ProjectTempoCandidate,
|
|
36
40
|
ProjectTempoSegment,
|
|
37
41
|
ProjectTimeSignatureSegment,
|
|
42
|
+
ProjectTrack,
|
|
38
43
|
ProjectTrackDesc,
|
|
39
44
|
ProjectTrackKind,
|
|
40
45
|
ProjectWarpMapDesc,
|
|
@@ -337,6 +342,19 @@ export class Project {
|
|
|
337
342
|
return this.native.addClip(desc);
|
|
338
343
|
}
|
|
339
344
|
|
|
345
|
+
/** Import host-separated PCM through the normal audio-track/clip path. */
|
|
346
|
+
importExternalStems(
|
|
347
|
+
request: ExternalSeparatedStemImportRequest,
|
|
348
|
+
): ExternalSeparatedStemImportResult {
|
|
349
|
+
return this.native.importExternalStems({
|
|
350
|
+
...request,
|
|
351
|
+
stems: request.stems.map((stem) => ({
|
|
352
|
+
...stem,
|
|
353
|
+
layout: stem.layout === 'mono' ? 1 : stem.layout === 'stereo' ? 2 : stem.layout,
|
|
354
|
+
})),
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
340
358
|
/** Split captured loop-recording audio into takes and add one clip. */
|
|
341
359
|
addLoopRecordingTakes(desc: ProjectLoopRecordingDesc): ProjectLoopRecordingResult {
|
|
342
360
|
return this.native.addLoopRecordingTakes(desc);
|
|
@@ -391,7 +409,11 @@ export class Project {
|
|
|
391
409
|
* Route a track's MIDI to host-instrument `destinationId` (0 = default). The
|
|
392
410
|
* compiler stamps every MIDI clip on the track with this id so the engine
|
|
393
411
|
* dispatches its events to the instrument registered for that destination.
|
|
394
|
-
* Routes through an undoable edit command.
|
|
412
|
+
* Routes through an undoable edit command. Builtin, NativeSynth, and SF2
|
|
413
|
+
* instruments retain source-track provenance inside a shared destination
|
|
414
|
+
* voice pool. With only zero-latency instruments bound, live lanes and
|
|
415
|
+
* channel-strip bounces remain aligned. Configure one live lane per source
|
|
416
|
+
* track that needs strip processing.
|
|
395
417
|
*/
|
|
396
418
|
setTrackMidiDestination(trackId: number, destinationId: number): void {
|
|
397
419
|
this.native.setTrackMidiDestination(trackId, destinationId);
|
|
@@ -449,7 +471,11 @@ export class Project {
|
|
|
449
471
|
this.native.setMidiEvents(clipId, events);
|
|
450
472
|
}
|
|
451
473
|
|
|
452
|
-
/**
|
|
474
|
+
/**
|
|
475
|
+
* Import an in-memory SMF buffer; returns the first added clip id.
|
|
476
|
+
* Malformed or partially truncated tracks are rejected instead of installing
|
|
477
|
+
* a silently shortened clip.
|
|
478
|
+
*/
|
|
453
479
|
importSmf(data: Uint8Array): number {
|
|
454
480
|
return this.native.importSmf(data);
|
|
455
481
|
}
|
|
@@ -498,7 +524,10 @@ export class Project {
|
|
|
498
524
|
this.native.setProgramOnChannel(clipId, group, channel, program, bank);
|
|
499
525
|
}
|
|
500
526
|
|
|
501
|
-
/**
|
|
527
|
+
/**
|
|
528
|
+
* Destructively bake a MIDI-FX chain into all stored events. Large clips are
|
|
529
|
+
* drained without truncation; failure leaves the original clip unchanged.
|
|
530
|
+
*/
|
|
502
531
|
bakeMidiFx(clipId: number, configJson: string): void {
|
|
503
532
|
this.native.bakeMidiFx(clipId, configJson);
|
|
504
533
|
}
|
|
@@ -510,9 +539,9 @@ export class Project {
|
|
|
510
539
|
|
|
511
540
|
/**
|
|
512
541
|
* Pre-flight check for hanging / unmatched notes in a MIDI clip: reports
|
|
513
|
-
* whether every note-on
|
|
514
|
-
*
|
|
515
|
-
* or not a MIDI clip.
|
|
542
|
+
* whether every note-on in the exported half-open playback window has a
|
|
543
|
+
* matching note-off (FIFO per group+channel+note). Useful before bouncing to
|
|
544
|
+
* catch a stuck note. Throws if `clipId` is unknown or not a MIDI clip.
|
|
516
545
|
*/
|
|
517
546
|
validateMidiNotes(clipId: number): ProjectNotePairValidation {
|
|
518
547
|
return this.native.validateMidiNotes(clipId);
|
|
@@ -678,6 +707,21 @@ export class Project {
|
|
|
678
707
|
this.native.setClipFade(clipId, fadeIn, fadeOut);
|
|
679
708
|
}
|
|
680
709
|
|
|
710
|
+
/** Audio source ids that need decoded PCM after deserialization. */
|
|
711
|
+
unresolvedAudioSourceIds(): number[] {
|
|
712
|
+
return this.native.unresolvedAudioSourceIds();
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/** Register decoded interleaved PCM for an existing audio source (undoable). */
|
|
716
|
+
setSourceAudio(
|
|
717
|
+
sourceId: number,
|
|
718
|
+
audio: Float32Array,
|
|
719
|
+
channels: number,
|
|
720
|
+
sampleRate: number,
|
|
721
|
+
): void {
|
|
722
|
+
this.native.setSourceAudio(sourceId, audio, channels, sampleRate);
|
|
723
|
+
}
|
|
724
|
+
|
|
681
725
|
/** Replace a clip's take list and active take id (undoable). */
|
|
682
726
|
setClipTakes(clipId: number, takes: ReadonlyArray<ProjectClipTake>, activeTakeId = 0): void {
|
|
683
727
|
this.native.setClipTakes(clipId, takes, activeTakeId);
|
|
@@ -732,7 +776,7 @@ export class Project {
|
|
|
732
776
|
this.native.setTrackRoute(trackId, channelStripRef ?? '', outputTarget ?? '');
|
|
733
777
|
}
|
|
734
778
|
|
|
735
|
-
/** Append an automation lane
|
|
779
|
+
/** Append an automation lane; returns its stable target parameter id (undoable). */
|
|
736
780
|
addAutomationLane(trackId: number, desc: ProjectAutomationLaneDesc): number {
|
|
737
781
|
return this.native.addAutomationLane(trackId, {
|
|
738
782
|
targetParamId: desc.targetParamId,
|
|
@@ -740,17 +784,21 @@ export class Project {
|
|
|
740
784
|
});
|
|
741
785
|
}
|
|
742
786
|
|
|
743
|
-
/** Replace
|
|
744
|
-
editAutomationLane(
|
|
745
|
-
|
|
787
|
+
/** Replace the lane identified by its stable target parameter id (undoable). */
|
|
788
|
+
editAutomationLane(
|
|
789
|
+
trackId: number,
|
|
790
|
+
targetParamId: number,
|
|
791
|
+
desc: ProjectAutomationLaneDesc,
|
|
792
|
+
): void {
|
|
793
|
+
this.native.editAutomationLane(trackId, targetParamId, {
|
|
746
794
|
targetParamId: desc.targetParamId,
|
|
747
795
|
points: desc.points,
|
|
748
796
|
});
|
|
749
797
|
}
|
|
750
798
|
|
|
751
|
-
/** Remove
|
|
752
|
-
removeAutomationLane(trackId: number,
|
|
753
|
-
this.native.removeAutomationLane(trackId,
|
|
799
|
+
/** Remove the lane identified by its stable target parameter id (undoable). */
|
|
800
|
+
removeAutomationLane(trackId: number, targetParamId: number): void {
|
|
801
|
+
this.native.removeAutomationLane(trackId, targetParamId);
|
|
754
802
|
}
|
|
755
803
|
|
|
756
804
|
/** Replace the project's key annotation stream (undoable). */
|
|
@@ -834,6 +882,19 @@ export class Project {
|
|
|
834
882
|
return this.native.markerByIndex(index);
|
|
835
883
|
}
|
|
836
884
|
|
|
885
|
+
/** Read a stored project track by 0-based index. */
|
|
886
|
+
trackByIndex(index: number): ProjectTrack {
|
|
887
|
+
return this.native.trackByIndex(index);
|
|
888
|
+
}
|
|
889
|
+
/** Read a stored project clip by 0-based index. */
|
|
890
|
+
clipByIndex(index: number): ProjectClip {
|
|
891
|
+
return this.native.clipByIndex(index);
|
|
892
|
+
}
|
|
893
|
+
/** Read a stored project source by 0-based index. */
|
|
894
|
+
sourceByIndex(index: number): ProjectSource {
|
|
895
|
+
return this.native.sourceByIndex(index);
|
|
896
|
+
}
|
|
897
|
+
|
|
837
898
|
/** Number of markers in the project. */
|
|
838
899
|
markerCount(): number {
|
|
839
900
|
return this.native.markerCount();
|
package/src/project_internal.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveEnumOrdinal } from './codes';
|
|
1
2
|
import { getSonareModule } from './module_state';
|
|
2
3
|
import type {
|
|
3
4
|
BuiltinSynthBinding,
|
|
@@ -5,6 +6,7 @@ import type {
|
|
|
5
6
|
ProjectAutomationPoint,
|
|
6
7
|
ProjectBounceOptions,
|
|
7
8
|
ProjectChordSymbol,
|
|
9
|
+
ProjectClip,
|
|
8
10
|
ProjectClipCompSegment,
|
|
9
11
|
ProjectClipDesc,
|
|
10
12
|
ProjectClipFade,
|
|
@@ -21,9 +23,11 @@ import type {
|
|
|
21
23
|
ProjectMidiRouteConfig,
|
|
22
24
|
ProjectMidiRouteResult,
|
|
23
25
|
ProjectNotePairValidation,
|
|
26
|
+
ProjectSource,
|
|
24
27
|
ProjectTempoCandidate,
|
|
25
28
|
ProjectTempoSegment,
|
|
26
29
|
ProjectTimeSignatureSegment,
|
|
30
|
+
ProjectTrack,
|
|
27
31
|
ProjectTrackKind,
|
|
28
32
|
ProjectWarpMapDesc,
|
|
29
33
|
ProjectWarpMode,
|
|
@@ -41,6 +45,7 @@ export interface WasmProject {
|
|
|
41
45
|
setSampleRate: (sampleRate: number) => void;
|
|
42
46
|
addTrack: (desc: { kind?: number | string; name?: string }) => number;
|
|
43
47
|
addClip: (desc: ProjectClipDesc) => number;
|
|
48
|
+
importExternalStems: (request: unknown) => { trackIds: number[]; clipIds: number[] };
|
|
44
49
|
addLoopRecordingTakes: (desc: ProjectLoopRecordingDesc) => ProjectLoopRecordingResult;
|
|
45
50
|
addMidiClip: (startPpq: number, lengthPpq: number) => ProjectMidiClipResult;
|
|
46
51
|
splitClip: (clipId: number, splitPpq: number) => number;
|
|
@@ -108,6 +113,13 @@ export interface WasmProject {
|
|
|
108
113
|
removeClip: (clipId: number) => void;
|
|
109
114
|
setClipGain: (clipId: number, gain: number) => void;
|
|
110
115
|
setClipFade: (clipId: number, fadeIn: ProjectClipFade, fadeOut: ProjectClipFade) => void;
|
|
116
|
+
unresolvedAudioSourceIds: () => number[];
|
|
117
|
+
setSourceAudio: (
|
|
118
|
+
sourceId: number,
|
|
119
|
+
audio: Float32Array,
|
|
120
|
+
channels: number,
|
|
121
|
+
sampleRate: number,
|
|
122
|
+
) => void;
|
|
111
123
|
setClipTakes: (
|
|
112
124
|
clipId: number,
|
|
113
125
|
takes: ReadonlyArray<ProjectClipTake>,
|
|
@@ -131,10 +143,10 @@ export interface WasmProject {
|
|
|
131
143
|
) => number;
|
|
132
144
|
editAutomationLane: (
|
|
133
145
|
trackId: number,
|
|
134
|
-
|
|
146
|
+
targetParamId: number,
|
|
135
147
|
desc: { targetParamId: number; points: ReadonlyArray<ProjectAutomationPoint> },
|
|
136
148
|
) => void;
|
|
137
|
-
removeAutomationLane: (trackId: number,
|
|
149
|
+
removeAutomationLane: (trackId: number, targetParamId: number) => void;
|
|
138
150
|
annotateKeys: (keys: ReadonlyArray<ProjectKeySegment>) => void;
|
|
139
151
|
annotateChords: (chords: ReadonlyArray<ProjectChordSymbol>) => void;
|
|
140
152
|
setAssistSidecar: (
|
|
@@ -154,6 +166,9 @@ export interface WasmProject {
|
|
|
154
166
|
setMarker: (markerId: number, ppq: number, name: string) => number;
|
|
155
167
|
setMarkerEx: (marker: ProjectMarker) => number;
|
|
156
168
|
markerByIndex: (index: number) => ProjectMarker;
|
|
169
|
+
trackByIndex: (index: number) => ProjectTrack;
|
|
170
|
+
clipByIndex: (index: number) => ProjectClip;
|
|
171
|
+
sourceByIndex: (index: number) => ProjectSource;
|
|
157
172
|
markerCount: () => number;
|
|
158
173
|
trackCount: () => number;
|
|
159
174
|
clipCount: () => number;
|
|
@@ -307,37 +322,17 @@ export function assertProjectMidiEvents(
|
|
|
307
322
|
}
|
|
308
323
|
|
|
309
324
|
export function projectTrackKindValue(kind: ProjectTrackKind | undefined): number {
|
|
310
|
-
|
|
311
|
-
return 0;
|
|
312
|
-
}
|
|
313
|
-
if (kind === 'midi') {
|
|
314
|
-
return 1;
|
|
315
|
-
}
|
|
316
|
-
if (kind === 'aux') {
|
|
317
|
-
return 2;
|
|
318
|
-
}
|
|
319
|
-
return kind;
|
|
325
|
+
return resolveEnumOrdinal(kind ?? 'audio', { audio: 0, midi: 1, aux: 2 }, 'project track kind');
|
|
320
326
|
}
|
|
321
327
|
|
|
322
328
|
export function projectWarpModeValue(mode: ProjectWarpMode | undefined): number {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
329
|
-
if (mode === 'tempo-sync') {
|
|
330
|
-
return 2;
|
|
331
|
-
}
|
|
332
|
-
return mode;
|
|
329
|
+
return resolveEnumOrdinal(
|
|
330
|
+
mode ?? 'off',
|
|
331
|
+
{ off: 0, repitch: 1, 'tempo-sync': 2 },
|
|
332
|
+
'project warp mode',
|
|
333
|
+
);
|
|
333
334
|
}
|
|
334
335
|
|
|
335
336
|
export function projectLoopModeValue(mode: ProjectLoopMode | undefined): number {
|
|
336
|
-
|
|
337
|
-
return 0;
|
|
338
|
-
}
|
|
339
|
-
if (mode === 'loop') {
|
|
340
|
-
return 1;
|
|
341
|
-
}
|
|
342
|
-
return mode;
|
|
337
|
+
return resolveEnumOrdinal(mode ?? 'off', { off: 0, loop: 1 }, 'project loop mode');
|
|
343
338
|
}
|
package/src/project_types.ts
CHANGED
|
@@ -25,6 +25,29 @@ export interface ProjectBounceOptions {
|
|
|
25
25
|
instrumentLatencySamples?: number;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
/** One decoded output from a host-owned source-separation model. */
|
|
29
|
+
export interface ExternalSeparatedStem {
|
|
30
|
+
name: string;
|
|
31
|
+
/** Optional host metadata; it does not change DSP. */
|
|
32
|
+
role?: string;
|
|
33
|
+
layout: 'mono' | 'stereo' | 1 | 2;
|
|
34
|
+
planarSamples: Float32Array[];
|
|
35
|
+
/** Absolute project-rate frame at which this stem begins. */
|
|
36
|
+
startFrame?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Request for {@link Project.importExternalStems}. */
|
|
40
|
+
export interface ExternalSeparatedStemImportRequest {
|
|
41
|
+
sampleRate: number;
|
|
42
|
+
stems: ExternalSeparatedStem[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Ids of the normal tracks and clips created by the import. */
|
|
46
|
+
export interface ExternalSeparatedStemImportResult {
|
|
47
|
+
trackIds: number[];
|
|
48
|
+
clipIds: number[];
|
|
49
|
+
}
|
|
50
|
+
|
|
28
51
|
/**
|
|
29
52
|
* Marker kind ordinals. Mirrors `SonareMarkerKind` in `src/sonare_c_types.h`;
|
|
30
53
|
* the values are part of the ABI and must not be renumbered.
|
|
@@ -53,17 +76,47 @@ export interface ProjectMarker {
|
|
|
53
76
|
keyMinor?: boolean;
|
|
54
77
|
}
|
|
55
78
|
|
|
79
|
+
/** Read-only stored project track returned by {@link Project.trackByIndex}. */
|
|
80
|
+
export interface ProjectTrack {
|
|
81
|
+
id: number;
|
|
82
|
+
kind: number;
|
|
83
|
+
midiDestinationId: number;
|
|
84
|
+
gain: number;
|
|
85
|
+
pan: number;
|
|
86
|
+
mute: boolean;
|
|
87
|
+
solo: boolean;
|
|
88
|
+
name: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Read-only stored project clip returned by {@link Project.clipByIndex}. */
|
|
92
|
+
export interface ProjectClip {
|
|
93
|
+
id: number;
|
|
94
|
+
trackId: number;
|
|
95
|
+
sourceId: number;
|
|
96
|
+
sourceKind: number;
|
|
97
|
+
startPpq: number;
|
|
98
|
+
lengthPpq: number;
|
|
99
|
+
sourceOffsetPpq: number;
|
|
100
|
+
gain: number;
|
|
101
|
+
loopMode: number;
|
|
102
|
+
loopLengthPpq: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Read-only stored project source returned by {@link Project.sourceByIndex}. */
|
|
106
|
+
export interface ProjectSource {
|
|
107
|
+
id: number;
|
|
108
|
+
kind: number;
|
|
109
|
+
channelCount: number;
|
|
110
|
+
storageHandleId: number;
|
|
111
|
+
sampleRateHint: number;
|
|
112
|
+
nameOrUri: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Names accepted by the minimal built-in oscillator synth. */
|
|
116
|
+
export const BUILTIN_SYNTH_WAVEFORMS = ['sine', 'saw', 'sawtooth', 'square', 'triangle'] as const;
|
|
117
|
+
|
|
56
118
|
/** Oscillator waveform for the built-in synth. */
|
|
57
|
-
export type BuiltinSynthWaveform =
|
|
58
|
-
| 'sine'
|
|
59
|
-
| 'saw'
|
|
60
|
-
| 'sawtooth'
|
|
61
|
-
| 'square'
|
|
62
|
-
| 'triangle'
|
|
63
|
-
| 0
|
|
64
|
-
| 1
|
|
65
|
-
| 2
|
|
66
|
-
| 3;
|
|
119
|
+
export type BuiltinSynthWaveform = (typeof BUILTIN_SYNTH_WAVEFORMS)[number] | 0 | 1 | 2 | 3;
|
|
67
120
|
|
|
68
121
|
/**
|
|
69
122
|
* Built-in synth patch + MIDI routing for
|
|
@@ -111,6 +164,8 @@ export interface Sf2InstrumentConfig {
|
|
|
111
164
|
gain?: number;
|
|
112
165
|
/** Max simultaneous voices (0 => 48, clamped to [1, 64]). */
|
|
113
166
|
polyphony?: number;
|
|
167
|
+
/** Prefer dedicated physical models for covered melodic GM programs. Defaults to false; drums stay SF2-first. */
|
|
168
|
+
preferModelForModeledFamilies?: boolean;
|
|
114
169
|
}
|
|
115
170
|
|
|
116
171
|
/** Source backend a resolved MIDI program renders through. */
|
|
@@ -198,6 +253,7 @@ export const SYNTH_MOD_DESTINATIONS = [
|
|
|
198
253
|
export interface SynthEnumTables {
|
|
199
254
|
engineModes: string[];
|
|
200
255
|
waveforms: string[];
|
|
256
|
+
builtinWaveforms: string[];
|
|
201
257
|
filterModels: string[];
|
|
202
258
|
filterOutputs: string[];
|
|
203
259
|
bodyTypes: string[];
|
|
@@ -312,8 +368,11 @@ export type ProjectFadeCurve =
|
|
|
312
368
|
| 'equal-power'
|
|
313
369
|
| 'equal_power'
|
|
314
370
|
| 'equalPower'
|
|
371
|
+
| 'equalpower'
|
|
315
372
|
| 'exponential'
|
|
373
|
+
| 'exp'
|
|
316
374
|
| 'logarithmic'
|
|
375
|
+
| 'log'
|
|
317
376
|
| 0
|
|
318
377
|
| 1
|
|
319
378
|
| 2
|
package/src/public_types.ts
CHANGED
|
@@ -4,3 +4,71 @@ export * from './public_types_mixing';
|
|
|
4
4
|
export * from './public_types_music';
|
|
5
5
|
export * from './public_types_realtime';
|
|
6
6
|
export * from './public_types_spectral';
|
|
7
|
+
|
|
8
|
+
/** Runtime capabilities reported by the loaded libsonare build. */
|
|
9
|
+
export interface SonareCapabilities {
|
|
10
|
+
version: string;
|
|
11
|
+
abi: {
|
|
12
|
+
project: number;
|
|
13
|
+
engine: number;
|
|
14
|
+
};
|
|
15
|
+
platform: string;
|
|
16
|
+
features: {
|
|
17
|
+
mastering: boolean;
|
|
18
|
+
mixing: boolean;
|
|
19
|
+
fx: boolean;
|
|
20
|
+
ffmpeg: boolean;
|
|
21
|
+
};
|
|
22
|
+
decode: {
|
|
23
|
+
builtin: string[];
|
|
24
|
+
ffmpeg: string[];
|
|
25
|
+
};
|
|
26
|
+
simd: string;
|
|
27
|
+
hardwareConcurrency: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** One parameter descriptor in the cross-surface capability catalog. */
|
|
31
|
+
export interface CapabilityCatalogParameter {
|
|
32
|
+
name: string;
|
|
33
|
+
id: number;
|
|
34
|
+
rtSafe: boolean;
|
|
35
|
+
type: 'boolean' | 'number';
|
|
36
|
+
min: number | null;
|
|
37
|
+
max: number | null;
|
|
38
|
+
default: boolean | number | null;
|
|
39
|
+
unit: string | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** One named mastering processor and its host-facing capabilities. */
|
|
43
|
+
export interface CapabilityCatalogProcessor {
|
|
44
|
+
id: string;
|
|
45
|
+
kind: 'realtime' | 'offline' | 'pair';
|
|
46
|
+
realtimeInsertable: boolean;
|
|
47
|
+
stereoOnly: boolean;
|
|
48
|
+
latencySamples: number;
|
|
49
|
+
tailSamples: number;
|
|
50
|
+
/** Coarse realtime work estimate, or null when the processor is not an insert. */
|
|
51
|
+
realtimeCost: 'low' | 'moderate' | 'high' | null;
|
|
52
|
+
channelPolicy: 'multichannel' | 'stereoPairOnly' | 'perChannel' | 'passthrough';
|
|
53
|
+
category: string;
|
|
54
|
+
params: CapabilityCatalogParameter[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Built-in preset names grouped by feature family. */
|
|
58
|
+
export interface CapabilityCatalogPresets {
|
|
59
|
+
mastering: string[];
|
|
60
|
+
synth: string[];
|
|
61
|
+
mixingScene: string[];
|
|
62
|
+
voiceChanger: string[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Complete runtime catalog exposed by {@link capabilityCatalog}. */
|
|
66
|
+
export interface CapabilityCatalog {
|
|
67
|
+
version: string;
|
|
68
|
+
abi: SonareCapabilities['abi'];
|
|
69
|
+
processors: CapabilityCatalogProcessor[];
|
|
70
|
+
presets: CapabilityCatalogPresets;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Synchronous progress callback for offline operations. Its return value is ignored. */
|
|
74
|
+
export type ProgressCallback = (progress: number, stage: string) => void;
|
|
@@ -138,6 +138,8 @@ export interface MasteringResult {
|
|
|
138
138
|
inputLufs: number;
|
|
139
139
|
outputLufs: number;
|
|
140
140
|
appliedGainDb: number;
|
|
141
|
+
/** True when peak headroom prevented the requested LUFS target. */
|
|
142
|
+
loudnessTargetLimited?: boolean;
|
|
141
143
|
latencySamples?: number;
|
|
142
144
|
}
|
|
143
145
|
|
|
@@ -329,6 +331,7 @@ export interface MasteringChainConfig {
|
|
|
329
331
|
monoMaker?: {
|
|
330
332
|
enabled?: boolean;
|
|
331
333
|
amount?: number;
|
|
334
|
+
frequencyHz?: number;
|
|
332
335
|
};
|
|
333
336
|
};
|
|
334
337
|
maximizer?: {
|
|
@@ -391,6 +394,26 @@ export interface StageGainReduction {
|
|
|
391
394
|
gainReductionDb: number;
|
|
392
395
|
}
|
|
393
396
|
|
|
397
|
+
/** Existing EBU R128 measurements captured before or after mastering. */
|
|
398
|
+
export interface MasteringLoudnessSummary {
|
|
399
|
+
integratedLufs: number;
|
|
400
|
+
maxMomentaryLufs: number;
|
|
401
|
+
maxShortTermLufs: number;
|
|
402
|
+
truePeakDbtp: number;
|
|
403
|
+
loudnessRange: number;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/** Compact explanation of how an offline mastering chain changed a program. */
|
|
407
|
+
export interface MasteringReport {
|
|
408
|
+
before: MasteringLoudnessSummary;
|
|
409
|
+
after: MasteringLoudnessSummary;
|
|
410
|
+
appliedGainDb: number;
|
|
411
|
+
maxGainReductionDb: number;
|
|
412
|
+
loudnessTargetLimited: boolean;
|
|
413
|
+
/** 32 logarithmically-spaced after-minus-before spectral energy deltas (dB). */
|
|
414
|
+
bandEnergyDeltaDb: Float32Array;
|
|
415
|
+
}
|
|
416
|
+
|
|
394
417
|
export interface MasteringChainResult {
|
|
395
418
|
/** Latency-compensated offline output; no separate latency field is reported. */
|
|
396
419
|
samples: Float32Array;
|
|
@@ -407,8 +430,11 @@ export interface MasteringChainResult {
|
|
|
407
430
|
outputTruePeakDbtp: number;
|
|
408
431
|
/** EBU Tech 3342 Loudness Range of the output (LU). */
|
|
409
432
|
outputLra: number;
|
|
433
|
+
/** True when peak headroom prevented the requested LUFS target. */
|
|
434
|
+
loudnessTargetLimited: boolean;
|
|
410
435
|
/** Per-stage gain reductions for the dynamics/maximizer stages (a subset of `stages`). */
|
|
411
436
|
stageGainReductions: StageGainReduction[];
|
|
437
|
+
report: MasteringReport;
|
|
412
438
|
}
|
|
413
439
|
|
|
414
440
|
export interface MasteringChainStereoResult {
|
|
@@ -422,7 +448,9 @@ export interface MasteringChainStereoResult {
|
|
|
422
448
|
/** See {@link MasteringChainResult} for field semantics. */
|
|
423
449
|
outputTruePeakDbtp: number;
|
|
424
450
|
outputLra: number;
|
|
451
|
+
loudnessTargetLimited: boolean;
|
|
425
452
|
stageGainReductions: StageGainReduction[];
|
|
453
|
+
report: MasteringReport;
|
|
426
454
|
}
|
|
427
455
|
|
|
428
456
|
/**
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
export type PanMode =
|
|
1
|
+
export type PanMode =
|
|
2
|
+
| 'balance'
|
|
3
|
+
| 'pan'
|
|
4
|
+
| 'stereoPan'
|
|
5
|
+
| 'stereo-pan'
|
|
6
|
+
| 'dualPan'
|
|
7
|
+
| 'dual-pan'
|
|
8
|
+
| number;
|
|
2
9
|
|
|
3
10
|
/**
|
|
4
11
|
* Surround pan position for a strip feeding a >2-channel bus. Phase 1 honors
|
|
@@ -77,7 +84,9 @@ export type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';
|
|
|
77
84
|
|
|
78
85
|
/**
|
|
79
86
|
* Pan law applied when computing left/right gains from a pan position
|
|
80
|
-
* (see {@link Mixer.setPanLaw}).
|
|
87
|
+
* (see {@link Mixer.setPanLaw}). On mono strips it changes the centre gain;
|
|
88
|
+
* on stereo Balance strips it changes only the far-channel taper, while centre
|
|
89
|
+
* remains unity. Maps to the underlying integer code.
|
|
81
90
|
*/
|
|
82
91
|
export type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';
|
|
83
92
|
|