@libraz/libsonare 1.8.0 → 1.8.2
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 +5 -5
- package/dist/_effects_common.d.ts +2 -1
- package/dist/_effects_common.d.ts.map +1 -1
- package/dist/analysis.js +3 -0
- package/dist/analysis.js.map +1 -1
- package/dist/effects_mastering.d.ts +2 -2
- package/dist/effects_mastering.d.ts.map +1 -1
- package/dist/effects_note_ops.d.ts +55 -30
- package/dist/effects_note_ops.d.ts.map +1 -1
- package/dist/effects_timepitch.d.ts +17 -12
- package/dist/effects_timepitch.d.ts.map +1 -1
- package/dist/feature_decompose.d.ts +1 -1
- package/dist/feature_decompose.d.ts.map +1 -1
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2098 -155
- package/dist/index.js.map +1 -1
- package/dist/instrument_types.d.ts +27 -3
- package/dist/instrument_types.d.ts.map +1 -1
- package/dist/mastering_core.d.ts +30 -3
- package/dist/mastering_core.d.ts.map +1 -1
- package/dist/mixer.d.ts +2 -2
- package/dist/mixer.d.ts.map +1 -1
- package/dist/project.d.ts +5 -4
- package/dist/project.d.ts.map +1 -1
- package/dist/project_class.d.ts +57 -3
- package/dist/project_class.d.ts.map +1 -1
- package/dist/project_internal.d.ts +35 -1
- package/dist/project_internal.d.ts.map +1 -1
- package/dist/project_types.d.ts +17 -6
- package/dist/project_types.d.ts.map +1 -1
- package/dist/public_types.d.ts +1 -0
- package/dist/public_types.d.ts.map +1 -1
- package/dist/public_types_mastering.d.ts +19 -1
- package/dist/public_types_mastering.d.ts.map +1 -1
- package/dist/public_types_playback.d.ts +1 -0
- package/dist/public_types_playback.d.ts.map +1 -1
- package/dist/public_types_spectral.d.ts +5 -5
- package/dist/public_types_spectral.d.ts.map +1 -1
- package/dist/public_types_vocal_edit.d.ts +250 -0
- package/dist/public_types_vocal_edit.d.ts.map +1 -0
- package/dist/public_types_vocal_project.d.ts +63 -0
- package/dist/public_types_vocal_project.d.ts.map +1 -0
- package/dist/realtime_engine.d.ts +106 -16
- package/dist/realtime_engine.d.ts.map +1 -1
- package/dist/repair_dereverb.d.ts +1 -0
- package/dist/repair_dereverb.d.ts.map +1 -1
- package/dist/repair_noise.d.ts +1 -0
- package/dist/repair_noise.d.ts.map +1 -1
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.d.ts +89 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/streaming_processors.d.ts +5 -0
- package/dist/streaming_processors.d.ts.map +1 -1
- package/dist/vocal_edit.d.ts +131 -0
- package/dist/vocal_edit.d.ts.map +1 -0
- package/dist/vocal_edit_worker.d.ts +51 -0
- package/dist/vocal_edit_worker.d.ts.map +1 -0
- package/dist/vocal_edit_worker.js +1462 -0
- package/dist/vocal_edit_worker.js.map +1 -0
- package/dist/vocal_edit_worker_client.d.ts +118 -0
- package/dist/vocal_edit_worker_client.d.ts.map +1 -0
- package/dist/vocal_edit_worker_protocol.d.ts +139 -0
- package/dist/vocal_edit_worker_protocol.d.ts.map +1 -0
- package/dist/vocal_project.d.ts +17 -0
- package/dist/vocal_project.d.ts.map +1 -0
- package/dist/web_midi.d.ts +4 -0
- package/dist/web_midi.d.ts.map +1 -1
- package/dist/worker.js.map +1 -1
- package/dist/worklet/engine-mixer-facade.d.ts +42 -5
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -1
- package/dist/worklet/engine-node.d.ts +10 -0
- package/dist/worklet/engine-node.d.ts.map +1 -1
- package/dist/worklet/engine-processor.d.ts +6 -1
- package/dist/worklet/engine-processor.d.ts.map +1 -1
- package/dist/worklet/engine-register.d.ts.map +1 -1
- package/dist/worklet/engine-strips.d.ts +8 -4
- package/dist/worklet/engine-strips.d.ts.map +1 -1
- package/dist/worklet/engine-sync.d.ts +4 -2
- package/dist/worklet/engine-sync.d.ts.map +1 -1
- package/dist/worklet/engine.d.ts +42 -9
- package/dist/worklet/engine.d.ts.map +1 -1
- package/dist/worklet/guards.d.ts +10 -2
- package/dist/worklet/guards.d.ts.map +1 -1
- package/dist/worklet/messages.d.ts +54 -9
- package/dist/worklet/messages.d.ts.map +1 -1
- package/dist/worklet/mixer-processor.d.ts +2 -2
- package/dist/worklet/mixer-processor.d.ts.map +1 -1
- package/dist/worklet/protocol.d.ts +20 -2
- package/dist/worklet/protocol.d.ts.map +1 -1
- package/dist/worklet.d.ts +1 -1
- package/dist/worklet.d.ts.map +1 -1
- package/dist/worklet.js +808 -204
- package/dist/worklet.js.map +1 -1
- package/package.json +6 -1
- package/src/_effects_common.ts +36 -6
- package/src/effects_mastering.ts +4 -0
- package/src/effects_note_ops.ts +92 -44
- package/src/effects_timepitch.ts +42 -31
- package/src/feature_decompose.ts +2 -2
- package/src/index.ts +39 -0
- package/src/instrument_types.ts +29 -3
- package/src/mastering_core.ts +98 -2
- package/src/mixer.ts +41 -21
- package/src/project.ts +8 -1
- package/src/project_class.ts +136 -1
- package/src/project_internal.ts +90 -0
- package/src/project_types.ts +18 -6
- package/src/public_types.ts +1 -0
- package/src/public_types_mastering.ts +23 -0
- package/src/public_types_playback.ts +1 -0
- package/src/public_types_spectral.ts +5 -5
- package/src/public_types_vocal_edit.ts +289 -0
- package/src/public_types_vocal_project.ts +69 -0
- package/src/realtime_engine.ts +157 -24
- package/src/repair_dereverb.ts +1 -0
- package/src/repair_noise.ts +1 -0
- package/src/sonare.js.d.ts +89 -0
- package/src/streaming_processors.ts +8 -0
- package/src/vocal_edit.ts +885 -0
- package/src/vocal_edit_worker.ts +832 -0
- package/src/vocal_edit_worker_client.ts +812 -0
- package/src/vocal_edit_worker_protocol.ts +206 -0
- package/src/vocal_project.ts +327 -0
- package/src/web_midi.ts +100 -5
- package/src/worklet/engine-mixer-facade.ts +422 -87
- package/src/worklet/engine-node.ts +69 -4
- package/src/worklet/engine-processor.ts +129 -34
- package/src/worklet/engine-register.ts +3 -0
- package/src/worklet/engine-strips.ts +36 -14
- package/src/worklet/engine-sync.ts +6 -1
- package/src/worklet/engine.ts +76 -40
- package/src/worklet/guards.ts +81 -0
- package/src/worklet/messages.ts +63 -4
- package/src/worklet/mixer-processor.ts +10 -3
- package/src/worklet/protocol.ts +39 -8
- package/src/worklet.ts +2 -0
package/src/index.ts
CHANGED
|
@@ -61,6 +61,7 @@ export type {
|
|
|
61
61
|
DynamicsProcessorResult,
|
|
62
62
|
GateOptions,
|
|
63
63
|
MasteringAbMatchLoudnessRequest,
|
|
64
|
+
MasteringAbMatchLoudnessStereoRequest,
|
|
64
65
|
MasteringAmpPresetCatalogEntry,
|
|
65
66
|
MasteringAssistantParamsRequest,
|
|
66
67
|
MasteringAssistantStereoParamsRequest,
|
|
@@ -74,6 +75,7 @@ export type {
|
|
|
74
75
|
MasteringInsertTiming,
|
|
75
76
|
MasteringPairAnalyzeRequest,
|
|
76
77
|
MasteringPairProcessRequest,
|
|
78
|
+
MasteringPairProcessStereoRequest,
|
|
77
79
|
MasteringProcessorCatalogEntry,
|
|
78
80
|
MasteringProcessorCategory,
|
|
79
81
|
MasteringProcessRequest,
|
|
@@ -132,6 +134,7 @@ export {
|
|
|
132
134
|
masterAudioWithProgress,
|
|
133
135
|
mastering,
|
|
134
136
|
masteringAbMatchLoudness,
|
|
137
|
+
masteringAbMatchLoudnessStereo,
|
|
135
138
|
masteringAmpPresetCatalog,
|
|
136
139
|
masteringAssistantSuggest,
|
|
137
140
|
masteringAssistantSuggestChain,
|
|
@@ -154,6 +157,7 @@ export {
|
|
|
154
157
|
masteringPairAnalyze,
|
|
155
158
|
masteringPairProcess,
|
|
156
159
|
masteringPairProcessorNames,
|
|
160
|
+
masteringPairProcessStereo,
|
|
157
161
|
masteringPlatformNames,
|
|
158
162
|
masteringPresetNames,
|
|
159
163
|
masteringPresetParams,
|
|
@@ -542,6 +546,9 @@ export type {
|
|
|
542
546
|
MidiCcLearnOptions,
|
|
543
547
|
MpeDimension,
|
|
544
548
|
NoteTracking,
|
|
549
|
+
PartRig,
|
|
550
|
+
PartRigInsert,
|
|
551
|
+
PartRigMode,
|
|
545
552
|
ProjectAssistSidecar,
|
|
546
553
|
ProjectAssistSidecarInput,
|
|
547
554
|
ProjectAutomationCurve,
|
|
@@ -556,6 +563,7 @@ export type {
|
|
|
556
563
|
ProjectClipFade,
|
|
557
564
|
ProjectClipTake,
|
|
558
565
|
ProjectCompileResult,
|
|
566
|
+
ProjectCompileTimelineResult,
|
|
559
567
|
ProjectFadeCurve,
|
|
560
568
|
ProjectKeySegment,
|
|
561
569
|
ProjectLoopMode,
|
|
@@ -613,10 +621,13 @@ export {
|
|
|
613
621
|
MarkerKind,
|
|
614
622
|
MPE_DIMENSIONS,
|
|
615
623
|
NOTE_TRACKINGS,
|
|
624
|
+
PART_RIG_ALL_PARTS,
|
|
625
|
+
PART_RIG_MODES,
|
|
616
626
|
PROJECT_AUTOMATION_TARGET_OPAQUE,
|
|
617
627
|
PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB,
|
|
618
628
|
PROJECT_AUTOMATION_TARGET_TRACK_PAN,
|
|
619
629
|
Project,
|
|
630
|
+
ProjectTimeline,
|
|
620
631
|
projectAbiVersion,
|
|
621
632
|
SAMPLE_KEY_TRACKS,
|
|
622
633
|
SAMPLE_LOOP_MODES,
|
|
@@ -687,6 +698,7 @@ export type {
|
|
|
687
698
|
KeyDetectionOptions,
|
|
688
699
|
KeyProfileName,
|
|
689
700
|
LoudnessMatchResult,
|
|
701
|
+
LoudnessMatchStereoResult,
|
|
690
702
|
LufsResult,
|
|
691
703
|
LufsSeriesResult,
|
|
692
704
|
MasteringAssistantParams,
|
|
@@ -807,6 +819,7 @@ export type {
|
|
|
807
819
|
SpectralRegionOp,
|
|
808
820
|
StageGainReduction,
|
|
809
821
|
StereoAnalysis,
|
|
822
|
+
StereoPairProcessor,
|
|
810
823
|
StftPowerResult,
|
|
811
824
|
StftResult,
|
|
812
825
|
StreamingEqualizerConfig,
|
|
@@ -829,6 +842,7 @@ export {
|
|
|
829
842
|
PitchClass,
|
|
830
843
|
SectionType,
|
|
831
844
|
} from './public_types';
|
|
845
|
+
export type * from './public_types_vocal_edit';
|
|
832
846
|
export type {
|
|
833
847
|
AnalyzeBpmRequest,
|
|
834
848
|
AnalyzeDynamicsRequest,
|
|
@@ -953,6 +967,29 @@ export {
|
|
|
953
967
|
export type { TranscribeRequest } from './transcribe';
|
|
954
968
|
export { transcribe } from './transcribe';
|
|
955
969
|
export type { ValidateOptions } from './validation';
|
|
970
|
+
export {
|
|
971
|
+
createVocalEditSession,
|
|
972
|
+
restoreVocalEditSession,
|
|
973
|
+
VocalEditDraft,
|
|
974
|
+
VocalEditSession,
|
|
975
|
+
VocalRenderJob,
|
|
976
|
+
VocalRenderSnapshot,
|
|
977
|
+
vocalEditApiVersion,
|
|
978
|
+
vocalEditAvailable,
|
|
979
|
+
} from './vocal_edit';
|
|
980
|
+
export type {
|
|
981
|
+
VocalEditWorker,
|
|
982
|
+
VocalEditWorkerCallOptions,
|
|
983
|
+
VocalEditWorkerClientOptions,
|
|
984
|
+
VocalEditWorkerTransferOptions,
|
|
985
|
+
} from './vocal_edit_worker_client';
|
|
986
|
+
export {
|
|
987
|
+
VocalEditWorkerClient,
|
|
988
|
+
VocalEditWorkerSession,
|
|
989
|
+
VocalEditWorkerStaleResultError,
|
|
990
|
+
VocalEditWorkerTask,
|
|
991
|
+
} from './vocal_edit_worker_client';
|
|
992
|
+
export type * from './vocal_edit_worker_protocol';
|
|
956
993
|
export type {
|
|
957
994
|
BindWebMidiOptions,
|
|
958
995
|
WebMidiBinding,
|
|
@@ -1148,3 +1185,5 @@ export function realtimeVoiceChangerPresetConfig(
|
|
|
1148
1185
|
// ============================================================================
|
|
1149
1186
|
|
|
1150
1187
|
export { PitchClass as Pitch } from './public_types';
|
|
1188
|
+
|
|
1189
|
+
export type * from './public_types_vocal_project';
|
package/src/instrument_types.ts
CHANGED
|
@@ -228,6 +228,16 @@ export const CONTROLLER_AXES = [
|
|
|
228
228
|
*/
|
|
229
229
|
export const ARTICULATIONS = ['poly', 'mono-retrigger', 'mono-legato'] as const;
|
|
230
230
|
|
|
231
|
+
/**
|
|
232
|
+
* How a part's signal path is built. `'bank'` keeps whatever the instrument's
|
|
233
|
+
* own bank/program selection resolves to, `'none'` bypasses the rig stage, and
|
|
234
|
+
* `'chain'` replaces it with an explicit insert chain.
|
|
235
|
+
*/
|
|
236
|
+
export const PART_RIG_MODES = ['bank', 'none', 'chain'] as const;
|
|
237
|
+
|
|
238
|
+
/** The `part` value that addresses a destination's default instead of one part (0-15). */
|
|
239
|
+
export const PART_RIG_ALL_PARTS = 0xff;
|
|
240
|
+
|
|
231
241
|
/** The three dimensions MPE carries per note ({@link RealtimeEngine.setControllerNoteTracking}). */
|
|
232
242
|
export const MPE_DIMENSIONS = ['bend', 'pressure', 'timbre'] as const;
|
|
233
243
|
|
|
@@ -380,6 +390,23 @@ export type ControllerAxis = (typeof CONTROLLER_AXES)[number];
|
|
|
380
390
|
/** Per-channel note-overlap rule ({@link RealtimeEngine.setArticulation}). */
|
|
381
391
|
export type Articulation = (typeof ARTICULATIONS)[number];
|
|
382
392
|
|
|
393
|
+
/** How a part's rig is built ({@link PART_RIG_MODES}). */
|
|
394
|
+
export type PartRigMode = (typeof PART_RIG_MODES)[number];
|
|
395
|
+
|
|
396
|
+
/** One stage of a `'chain'` part rig: a processor name and its parameters. */
|
|
397
|
+
export interface PartRigInsert {
|
|
398
|
+
processor: string;
|
|
399
|
+
/** Processor parameters, as an object or an already-serialized JSON object string. */
|
|
400
|
+
params?: Record<string, unknown> | string;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/** A part rig as stored on a project ({@link Project.getPartRig}). */
|
|
404
|
+
export interface PartRig {
|
|
405
|
+
mode: PartRigMode;
|
|
406
|
+
/** Present for `'chain'` only; `params` is the parsed parameter object. */
|
|
407
|
+
inserts?: { processor: string; params: Record<string, unknown> }[];
|
|
408
|
+
}
|
|
409
|
+
|
|
383
410
|
/** One per-note MPE dimension ({@link MPE_DIMENSIONS}). */
|
|
384
411
|
export type MpeDimension = (typeof MPE_DIMENSIONS)[number];
|
|
385
412
|
|
|
@@ -582,9 +609,8 @@ export interface SynthPatch {
|
|
|
582
609
|
* whose per-note kit patch replaces this whole section and never reads it.
|
|
583
610
|
*
|
|
584
611
|
* Also automatable under this same name through
|
|
585
|
-
* {@link RealtimeEngine.resolveInstrumentAutomationId}; it
|
|
586
|
-
*
|
|
587
|
-
* next note.
|
|
612
|
+
* {@link RealtimeEngine.resolveInstrumentAutomationId}; it reaches
|
|
613
|
+
* already-sounding voices from the next processed block.
|
|
588
614
|
*/
|
|
589
615
|
pitchOffsetCents?: number;
|
|
590
616
|
ampAttackMs?: number;
|
package/src/mastering_core.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ErrorCode, SonareError } from './errors';
|
|
|
2
2
|
import { getSonareModule } from './module_state';
|
|
3
3
|
import type {
|
|
4
4
|
LoudnessMatchResult,
|
|
5
|
+
LoudnessMatchStereoResult,
|
|
5
6
|
MasteringAssistantParams,
|
|
6
7
|
MasteringInsertParamChoice,
|
|
7
8
|
MasteringInsertSlot,
|
|
@@ -13,6 +14,7 @@ import type {
|
|
|
13
14
|
PairProcessor,
|
|
14
15
|
SoloProcessor,
|
|
15
16
|
StereoAnalysis,
|
|
17
|
+
StereoPairProcessor,
|
|
16
18
|
StreamingPlatform,
|
|
17
19
|
} from './public_types';
|
|
18
20
|
|
|
@@ -52,6 +54,17 @@ export interface MasteringPairProcessRequest {
|
|
|
52
54
|
params?: MasteringProcessorParams;
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
/** Canonical request form for a stereo two-input match processor. */
|
|
58
|
+
export interface MasteringPairProcessStereoRequest {
|
|
59
|
+
processorName: StereoPairProcessor;
|
|
60
|
+
sourceLeft: Float32Array;
|
|
61
|
+
sourceRight: Float32Array;
|
|
62
|
+
referenceLeft: Float32Array;
|
|
63
|
+
referenceRight: Float32Array;
|
|
64
|
+
sampleRate?: number;
|
|
65
|
+
params?: MasteringProcessorParams;
|
|
66
|
+
}
|
|
67
|
+
|
|
55
68
|
/** Canonical request form for {@link masteringAbMatchLoudness}. */
|
|
56
69
|
export interface MasteringAbMatchLoudnessRequest {
|
|
57
70
|
/** The take to gain-match. */
|
|
@@ -61,6 +74,15 @@ export interface MasteringAbMatchLoudnessRequest {
|
|
|
61
74
|
sampleRate?: number;
|
|
62
75
|
}
|
|
63
76
|
|
|
77
|
+
/** Canonical request form for stereo AB loudness matching. */
|
|
78
|
+
export interface MasteringAbMatchLoudnessStereoRequest {
|
|
79
|
+
sourceLeft: Float32Array;
|
|
80
|
+
sourceRight: Float32Array;
|
|
81
|
+
referenceLeft: Float32Array;
|
|
82
|
+
referenceRight: Float32Array;
|
|
83
|
+
sampleRate?: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
64
86
|
/** Canonical request form for a two-input match analysis. */
|
|
65
87
|
export interface MasteringPairAnalyzeRequest {
|
|
66
88
|
analysisName: PairAnalysis;
|
|
@@ -548,6 +570,60 @@ export function masteringPairProcess(
|
|
|
548
570
|
);
|
|
549
571
|
}
|
|
550
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Apply the stereo `match.abCrossfade` processor. Source and reference stereo
|
|
575
|
+
* pairs may have independent lengths, but each pair must have equal channels.
|
|
576
|
+
*/
|
|
577
|
+
export function masteringPairProcessStereo(
|
|
578
|
+
request: MasteringPairProcessStereoRequest,
|
|
579
|
+
): MasteringStereoResult;
|
|
580
|
+
export function masteringPairProcessStereo(
|
|
581
|
+
processorName: StereoPairProcessor,
|
|
582
|
+
sourceLeft: Float32Array,
|
|
583
|
+
sourceRight: Float32Array,
|
|
584
|
+
referenceLeft: Float32Array,
|
|
585
|
+
referenceRight: Float32Array,
|
|
586
|
+
sampleRate?: number,
|
|
587
|
+
params?: MasteringProcessorParams,
|
|
588
|
+
): MasteringStereoResult;
|
|
589
|
+
export function masteringPairProcessStereo(
|
|
590
|
+
processorName: StereoPairProcessor | MasteringPairProcessStereoRequest,
|
|
591
|
+
sourceLeft?: Float32Array,
|
|
592
|
+
sourceRight?: Float32Array,
|
|
593
|
+
referenceLeft?: Float32Array,
|
|
594
|
+
referenceRight?: Float32Array,
|
|
595
|
+
sampleRate = 22050,
|
|
596
|
+
params: MasteringProcessorParams = {},
|
|
597
|
+
): MasteringStereoResult {
|
|
598
|
+
const request =
|
|
599
|
+
typeof processorName === 'string'
|
|
600
|
+
? {
|
|
601
|
+
processorName,
|
|
602
|
+
sourceLeft: sourceLeft as Float32Array,
|
|
603
|
+
sourceRight: sourceRight as Float32Array,
|
|
604
|
+
referenceLeft: referenceLeft as Float32Array,
|
|
605
|
+
referenceRight: referenceRight as Float32Array,
|
|
606
|
+
sampleRate,
|
|
607
|
+
params,
|
|
608
|
+
}
|
|
609
|
+
: processorName;
|
|
610
|
+
if (request.sourceLeft.length !== request.sourceRight.length) {
|
|
611
|
+
throw new Error('Source left and right channel lengths must match.');
|
|
612
|
+
}
|
|
613
|
+
if (request.referenceLeft.length !== request.referenceRight.length) {
|
|
614
|
+
throw new Error('Reference left and right channel lengths must match.');
|
|
615
|
+
}
|
|
616
|
+
return requireModule().masteringPairProcessStereo(
|
|
617
|
+
request.processorName,
|
|
618
|
+
request.sourceLeft,
|
|
619
|
+
request.sourceRight,
|
|
620
|
+
request.referenceLeft,
|
|
621
|
+
request.referenceRight,
|
|
622
|
+
request.sampleRate ?? 22050,
|
|
623
|
+
request.params ?? {},
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
|
|
551
627
|
/**
|
|
552
628
|
* Analyze a `source` against a `reference` with a two-input analysis. The two
|
|
553
629
|
* buffers may have independent lengths.
|
|
@@ -616,6 +692,25 @@ export function masteringAbMatchLoudness(
|
|
|
616
692
|
);
|
|
617
693
|
}
|
|
618
694
|
|
|
695
|
+
/** Gain-match a stereo source to a stereo reference with one shared gain. */
|
|
696
|
+
export function masteringAbMatchLoudnessStereo(
|
|
697
|
+
request: MasteringAbMatchLoudnessStereoRequest,
|
|
698
|
+
): LoudnessMatchStereoResult {
|
|
699
|
+
if (request.sourceLeft.length !== request.sourceRight.length) {
|
|
700
|
+
throw new Error('Source left and right channel lengths must match.');
|
|
701
|
+
}
|
|
702
|
+
if (request.referenceLeft.length !== request.referenceRight.length) {
|
|
703
|
+
throw new Error('Reference left and right channel lengths must match.');
|
|
704
|
+
}
|
|
705
|
+
return requireModule().masteringAbMatchLoudnessStereo(
|
|
706
|
+
request.sourceLeft,
|
|
707
|
+
request.sourceRight,
|
|
708
|
+
request.referenceLeft,
|
|
709
|
+
request.referenceRight,
|
|
710
|
+
request.sampleRate ?? 22050,
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
|
|
619
714
|
export function masteringStereoAnalyze(request: MasteringStereoAnalyzeRequest): string;
|
|
620
715
|
export function masteringStereoAnalyze(
|
|
621
716
|
analysisName: StereoAnalysis,
|
|
@@ -829,11 +924,12 @@ export function masteringAssistantSuggestChainStereo(
|
|
|
829
924
|
/**
|
|
830
925
|
* Mastering assistant profile of a stereo pair, as shared JSON.
|
|
831
926
|
*
|
|
832
|
-
*
|
|
927
|
+
* The `loudness` block is measured from the two channels: integrated LUFS
|
|
833
928
|
* and LRA come from the channel-summed program and the true peak is the larger
|
|
834
929
|
* of the two. The spectral, dynamics and tempo fields describe shape and timing
|
|
835
930
|
* rather than absolute level and are measured on the downmix, which keeps them
|
|
836
|
-
* comparable with {@link masteringAudioProfile}.
|
|
931
|
+
* comparable with {@link masteringAudioProfile}. Defect detectors run on each
|
|
932
|
+
* channel and their results are aggregated.
|
|
837
933
|
*/
|
|
838
934
|
export function masteringAudioProfileStereo(request: MasteringStereoParamsRequest): string {
|
|
839
935
|
return requireModule().masteringAudioProfileStereo(
|
package/src/mixer.ts
CHANGED
|
@@ -188,50 +188,70 @@ export class Mixer {
|
|
|
188
188
|
* after {@link delete}.
|
|
189
189
|
*/
|
|
190
190
|
createRealtimeBuffer(): MixerRealtimeBuffer {
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
let rightInputs: Float32Array[] = [];
|
|
191
|
+
const leftInputs: Float32Array[] = [];
|
|
192
|
+
const rightInputs: Float32Array[] = [];
|
|
194
193
|
let outLeft = this.mixer.outputLeftView();
|
|
195
194
|
let outRight = this.mixer.outputRightView();
|
|
195
|
+
let acquiredStripCount = -1;
|
|
196
|
+
|
|
197
|
+
// Every view shares one heap buffer, so a growth detaches the output views too.
|
|
198
|
+
const viewsDetached = (): boolean => outLeft.byteLength === 0 || outRight.byteLength === 0;
|
|
199
|
+
|
|
196
200
|
const acquire = (): void => {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
201
|
+
const stripCount = this.stripCount();
|
|
202
|
+
const detached = viewsDetached();
|
|
203
|
+
if (detached) {
|
|
204
|
+
// A heap growth detached every view: reacquire all planes.
|
|
205
|
+
leftInputs.length = 0;
|
|
206
|
+
rightInputs.length = 0;
|
|
207
|
+
} else {
|
|
208
|
+
// Topology growth keeps existing planes in place: append views for new strips only.
|
|
209
|
+
leftInputs.length = Math.min(leftInputs.length, stripCount);
|
|
210
|
+
rightInputs.length = Math.min(rightInputs.length, stripCount);
|
|
211
|
+
}
|
|
212
|
+
for (let index = leftInputs.length; index < stripCount; index++) {
|
|
200
213
|
leftInputs.push(this.mixer.inputLeftView(index));
|
|
214
|
+
}
|
|
215
|
+
for (let index = rightInputs.length; index < stripCount; index++) {
|
|
201
216
|
rightInputs.push(this.mixer.inputRightView(index));
|
|
202
217
|
}
|
|
203
|
-
|
|
204
|
-
|
|
218
|
+
if (detached) {
|
|
219
|
+
outLeft = this.mixer.outputLeftView();
|
|
220
|
+
outRight = this.mixer.outputRightView();
|
|
221
|
+
}
|
|
222
|
+
acquiredStripCount = stripCount;
|
|
205
223
|
};
|
|
206
224
|
acquire();
|
|
225
|
+
|
|
207
226
|
// The cached heap views can detach if WASM linear memory grows (the embind
|
|
208
|
-
// module is built ALLOW_MEMORY_GROWTH).
|
|
209
|
-
//
|
|
210
|
-
const
|
|
211
|
-
if (
|
|
227
|
+
// module is built ALLOW_MEMORY_GROWTH). Also refresh the view list when a
|
|
228
|
+
// caller adds a strip and recompiles the graph after this buffer was made.
|
|
229
|
+
const acquireIfNeeded = (): void => {
|
|
230
|
+
if (acquiredStripCount !== this.stripCount() || viewsDetached()) {
|
|
212
231
|
acquire();
|
|
213
232
|
}
|
|
214
233
|
};
|
|
215
234
|
return {
|
|
216
235
|
get leftInputs(): Float32Array[] {
|
|
217
|
-
|
|
236
|
+
acquireIfNeeded();
|
|
218
237
|
return leftInputs;
|
|
219
238
|
},
|
|
220
239
|
get rightInputs(): Float32Array[] {
|
|
221
|
-
|
|
240
|
+
acquireIfNeeded();
|
|
222
241
|
return rightInputs;
|
|
223
242
|
},
|
|
224
243
|
get outLeft(): Float32Array {
|
|
225
|
-
|
|
244
|
+
acquireIfNeeded();
|
|
226
245
|
return outLeft;
|
|
227
246
|
},
|
|
228
247
|
get outRight(): Float32Array {
|
|
229
|
-
|
|
248
|
+
acquireIfNeeded();
|
|
230
249
|
return outRight;
|
|
231
250
|
},
|
|
232
|
-
process: (numSamples
|
|
233
|
-
|
|
234
|
-
|
|
251
|
+
process: (numSamples?: number) => {
|
|
252
|
+
acquireIfNeeded();
|
|
253
|
+
// Resolve the default only after reacquiring: a detached view reports length 0.
|
|
254
|
+
this.mixer.processPreparedStereo(numSamples ?? outLeft.length);
|
|
235
255
|
},
|
|
236
256
|
};
|
|
237
257
|
}
|
|
@@ -484,8 +504,8 @@ export class Mixer {
|
|
|
484
504
|
}
|
|
485
505
|
|
|
486
506
|
/**
|
|
487
|
-
* Set a per-strip channel delay in samples
|
|
488
|
-
*
|
|
507
|
+
* Set a per-strip channel delay in samples, moving the strip later relative to
|
|
508
|
+
* the others. It is not latency: latency compensation does not undo it.
|
|
489
509
|
*/
|
|
490
510
|
setChannelDelaySamples(stripIndex: number, delaySamples: number): void {
|
|
491
511
|
this.mixer.setChannelDelaySamples(stripIndex, delaySamples);
|
package/src/project.ts
CHANGED
|
@@ -8,6 +8,9 @@ export type {
|
|
|
8
8
|
ControllerInput,
|
|
9
9
|
MpeDimension,
|
|
10
10
|
NoteTracking,
|
|
11
|
+
PartRig,
|
|
12
|
+
PartRigInsert,
|
|
13
|
+
PartRigMode,
|
|
11
14
|
SampleDesc,
|
|
12
15
|
SampleDescLoopMode,
|
|
13
16
|
SampleKeyTrack,
|
|
@@ -35,6 +38,8 @@ export {
|
|
|
35
38
|
CONTROLLER_INPUTS,
|
|
36
39
|
MPE_DIMENSIONS,
|
|
37
40
|
NOTE_TRACKINGS,
|
|
41
|
+
PART_RIG_ALL_PARTS,
|
|
42
|
+
PART_RIG_MODES,
|
|
38
43
|
SAMPLE_KEY_TRACKS,
|
|
39
44
|
SAMPLE_LOOP_MODES,
|
|
40
45
|
SYNTH_BODY_TYPES,
|
|
@@ -46,7 +51,7 @@ export {
|
|
|
46
51
|
SYNTH_OSC_WAVEFORMS,
|
|
47
52
|
SYNTH_RETRIGGERS,
|
|
48
53
|
} from './instrument_types';
|
|
49
|
-
export { Project } from './project_class';
|
|
54
|
+
export { Project, ProjectTimeline } from './project_class';
|
|
50
55
|
export {
|
|
51
56
|
controllerProfileNames,
|
|
52
57
|
projectAbiVersion,
|
|
@@ -79,6 +84,7 @@ export type {
|
|
|
79
84
|
ProjectClipFade,
|
|
80
85
|
ProjectClipTake,
|
|
81
86
|
ProjectCompileResult,
|
|
87
|
+
ProjectCompileTimelineResult,
|
|
82
88
|
ProjectDeserializeResult,
|
|
83
89
|
ProjectDiagnostic,
|
|
84
90
|
ProjectFadeCurve,
|
|
@@ -121,4 +127,5 @@ export {
|
|
|
121
127
|
PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB,
|
|
122
128
|
PROJECT_AUTOMATION_TARGET_TRACK_PAN,
|
|
123
129
|
} from './project_types';
|
|
130
|
+
export type * from './public_types_vocal_project';
|
|
124
131
|
export { SampleBank } from './sample_bank';
|
package/src/project_class.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BuiltinSynthBinding,
|
|
3
|
+
PartRig,
|
|
4
|
+
PartRigInsert,
|
|
5
|
+
PartRigMode,
|
|
3
6
|
Sf2InstrumentConfig,
|
|
4
7
|
Sf2ProgramStatus,
|
|
5
8
|
SynthPatch,
|
|
@@ -7,6 +10,8 @@ import type {
|
|
|
7
10
|
import {
|
|
8
11
|
assertProjectMidiEvents,
|
|
9
12
|
normalizeSynthInstrument,
|
|
13
|
+
partRigFromNative,
|
|
14
|
+
partRigInsertsJson,
|
|
10
15
|
projectAutomationPointValue,
|
|
11
16
|
projectAutomationTargetKindValue,
|
|
12
17
|
projectLoopModeValue,
|
|
@@ -14,7 +19,10 @@ import {
|
|
|
14
19
|
projectModule,
|
|
15
20
|
projectTrackKindValue,
|
|
16
21
|
projectWarpModeValue,
|
|
22
|
+
registerProjectTimeline,
|
|
23
|
+
unregisterProjectTimeline,
|
|
17
24
|
type WasmProject,
|
|
25
|
+
type WasmProjectTimeline,
|
|
18
26
|
} from './project_internal';
|
|
19
27
|
import type {
|
|
20
28
|
ExternalSeparatedStemImportRequest,
|
|
@@ -33,6 +41,7 @@ import type {
|
|
|
33
41
|
ProjectClipFade,
|
|
34
42
|
ProjectClipTake,
|
|
35
43
|
ProjectCompileResult,
|
|
44
|
+
ProjectCompileTimelineResult,
|
|
36
45
|
ProjectDeserializeResult,
|
|
37
46
|
ProjectKeySegment,
|
|
38
47
|
ProjectLoopMode,
|
|
@@ -60,6 +69,13 @@ import type {
|
|
|
60
69
|
ProjectWarpMapDesc,
|
|
61
70
|
ProjectWarpMode,
|
|
62
71
|
} from './project_types';
|
|
72
|
+
import type {
|
|
73
|
+
ProjectVocalEditApplyRequest,
|
|
74
|
+
ProjectVocalEditApplyResult,
|
|
75
|
+
ProjectVocalEditDependency,
|
|
76
|
+
ProjectVocalOriginalSource,
|
|
77
|
+
ProjectVocalRehydrateItem,
|
|
78
|
+
} from './public_types_vocal_project';
|
|
63
79
|
import {
|
|
64
80
|
assertBoundedInteger,
|
|
65
81
|
assertNibble,
|
|
@@ -67,6 +83,11 @@ import {
|
|
|
67
83
|
assertSamples,
|
|
68
84
|
assertU7,
|
|
69
85
|
} from './validation';
|
|
86
|
+
import {
|
|
87
|
+
projectApplyVocalEdit,
|
|
88
|
+
projectGetVocalEditDependencies,
|
|
89
|
+
projectRehydrateVocalEdits,
|
|
90
|
+
} from './vocal_project';
|
|
70
91
|
|
|
71
92
|
/**
|
|
72
93
|
* Folds the positional and request call forms of `bakeMidiFx` into one shape,
|
|
@@ -171,6 +192,47 @@ function midi2Byte(fnName: string, value: number, argName: string): number {
|
|
|
171
192
|
return value;
|
|
172
193
|
}
|
|
173
194
|
|
|
195
|
+
/**
|
|
196
|
+
* An immutable compiled snapshot of a {@link Project}, produced by
|
|
197
|
+
* {@link Project.compileTimeline} and installed into a stopped realtime engine
|
|
198
|
+
* with `RealtimeEngine.applyProjectTimeline`.
|
|
199
|
+
*
|
|
200
|
+
* An engine keeps its own reference after an apply, so {@link dispose} may be
|
|
201
|
+
* called right afterwards. The embind handle is not garbage-collected; release
|
|
202
|
+
* it when no further apply needs it.
|
|
203
|
+
*/
|
|
204
|
+
export class ProjectTimeline {
|
|
205
|
+
private native: WasmProjectTimeline | null;
|
|
206
|
+
|
|
207
|
+
/** @internal */
|
|
208
|
+
constructor(native: WasmProjectTimeline) {
|
|
209
|
+
this.native = native;
|
|
210
|
+
registerProjectTimeline(this, native);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Identity an engine names this timeline by, so no raw pointer crosses into JS.
|
|
215
|
+
*
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
get nativeId(): number {
|
|
219
|
+
if (this.native === null) {
|
|
220
|
+
throw new TypeError('ProjectTimeline is disposed');
|
|
221
|
+
}
|
|
222
|
+
return this.native.id;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Release the underlying WASM object. Idempotent. */
|
|
226
|
+
dispose(): void {
|
|
227
|
+
if (this.native === null) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
unregisterProjectTimeline(this);
|
|
231
|
+
this.native.delete();
|
|
232
|
+
this.native = null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
174
236
|
/**
|
|
175
237
|
* Headless DAW project (control-thread-only arrangement model).
|
|
176
238
|
*
|
|
@@ -199,7 +261,33 @@ function midi2Byte(fnName: string, value: number, argName: string): number {
|
|
|
199
261
|
*/
|
|
200
262
|
export class Project {
|
|
201
263
|
private native: WasmProject;
|
|
264
|
+
|
|
265
|
+
applyVocalEdit(request: ProjectVocalEditApplyRequest): ProjectVocalEditApplyResult {
|
|
266
|
+
return projectApplyVocalEdit(this.native, request);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
getVocalEditDependencies(): ProjectVocalEditDependency[] {
|
|
270
|
+
return projectGetVocalEditDependencies(this.native);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
rehydrateVocalEdits(
|
|
274
|
+
originals: readonly ProjectVocalOriginalSource[],
|
|
275
|
+
cancel?: () => boolean,
|
|
276
|
+
): ProjectVocalRehydrateItem[] {
|
|
277
|
+
this.activeVocalRehydrateCalls += 1;
|
|
278
|
+
try {
|
|
279
|
+
return projectRehydrateVocalEdits(this.native, originals, cancel);
|
|
280
|
+
} finally {
|
|
281
|
+
this.activeVocalRehydrateCalls -= 1;
|
|
282
|
+
if (this.activeVocalRehydrateCalls === 0 && this.deleteRequested) {
|
|
283
|
+
this.native.delete();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
202
288
|
private released = false;
|
|
289
|
+
private deleteRequested = false;
|
|
290
|
+
private activeVocalRehydrateCalls = 0;
|
|
203
291
|
|
|
204
292
|
constructor() {
|
|
205
293
|
this.native = new (projectModule().Project)();
|
|
@@ -798,6 +886,34 @@ export class Project {
|
|
|
798
886
|
this.native.setTrackGain(trackId, gain);
|
|
799
887
|
}
|
|
800
888
|
|
|
889
|
+
/**
|
|
890
|
+
* Set the rig of one part (0-15), or of the destination's default when `part`
|
|
891
|
+
* is {@link PART_RIG_ALL_PARTS}, on MIDI destination `destinationId`, via an
|
|
892
|
+
* undoable edit. `'chain'` takes 1-8 `inserts` and is the only mode that does;
|
|
893
|
+
* a destination no track references is stored and read back all the same.
|
|
894
|
+
* Refused: a malformed insert document (invalid format), an out-of-range part,
|
|
895
|
+
* an unknown mode or processor, or inserts on a non-chain mode (invalid
|
|
896
|
+
* parameter), and an insert chain in a build without mastering.
|
|
897
|
+
*/
|
|
898
|
+
setPartRig(
|
|
899
|
+
destinationId: number,
|
|
900
|
+
part: number,
|
|
901
|
+
mode: PartRigMode | number,
|
|
902
|
+
inserts?: PartRigInsert[],
|
|
903
|
+
): void {
|
|
904
|
+
this.native.setPartRig(destinationId, part, mode, partRigInsertsJson(inserts));
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/** The stored rig for `(destinationId, part)`, or null when none is stored. */
|
|
908
|
+
getPartRig(destinationId: number, part: number): PartRig | null {
|
|
909
|
+
return partRigFromNative(this.native.getPartRig(destinationId, part));
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/** Remove the stored rig for `(destinationId, part)` via an undoable edit (no-op when absent). */
|
|
913
|
+
clearPartRig(destinationId: number, part: number): void {
|
|
914
|
+
this.native.clearPartRig(destinationId, part);
|
|
915
|
+
}
|
|
916
|
+
|
|
801
917
|
/** Set a track's mute flag via an undoable edit (a muted track is silent). */
|
|
802
918
|
setTrackMute(trackId: number, mute: boolean): void {
|
|
803
919
|
this.native.setTrackMute(trackId, mute);
|
|
@@ -1059,6 +1175,17 @@ export class Project {
|
|
|
1059
1175
|
return this.native.compile();
|
|
1060
1176
|
}
|
|
1061
1177
|
|
|
1178
|
+
/**
|
|
1179
|
+
* Compile the project and keep the resulting timeline. The result is
|
|
1180
|
+
* {@link compile}'s plus `timeline`: a {@link ProjectTimeline} to install with
|
|
1181
|
+
* `RealtimeEngine.applyProjectTimeline`, or `null` when an error diagnostic
|
|
1182
|
+
* means nothing compiled.
|
|
1183
|
+
*/
|
|
1184
|
+
compileTimeline(): ProjectCompileTimelineResult {
|
|
1185
|
+
const { timeline, ...result } = this.native.compileTimeline();
|
|
1186
|
+
return { ...result, timeline: timeline === null ? null : new ProjectTimeline(timeline) };
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1062
1189
|
/**
|
|
1063
1190
|
* Compile + render the project offline to interleaved float audio. MIDI
|
|
1064
1191
|
* tracks render silently here (no instrument is bound) — use
|
|
@@ -1540,12 +1667,20 @@ export class Project {
|
|
|
1540
1667
|
return this.native.lastBounceCompileResult();
|
|
1541
1668
|
}
|
|
1542
1669
|
|
|
1543
|
-
/**
|
|
1670
|
+
/**
|
|
1671
|
+
* Release the underlying WASM object. Idempotent, as the Node facade is.
|
|
1672
|
+
* Called from a rehydrate cancel callback, the release happens when the
|
|
1673
|
+
* outermost {@link rehydrateVocalEdits} call returns.
|
|
1674
|
+
*/
|
|
1544
1675
|
delete(): void {
|
|
1545
1676
|
if (this.released) {
|
|
1546
1677
|
return;
|
|
1547
1678
|
}
|
|
1548
1679
|
this.released = true;
|
|
1680
|
+
if (this.activeVocalRehydrateCalls !== 0) {
|
|
1681
|
+
this.deleteRequested = true;
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1549
1684
|
this.native.delete();
|
|
1550
1685
|
}
|
|
1551
1686
|
|