@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/project_internal.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { projectAutomationCurveCode, resolveEnumOrdinal } from './codes';
|
|
2
2
|
import type {
|
|
3
3
|
BuiltinSynthBinding,
|
|
4
|
+
PartRig,
|
|
5
|
+
PartRigInsert,
|
|
6
|
+
PartRigMode,
|
|
4
7
|
SampleDesc,
|
|
5
8
|
SampleZoneDesc,
|
|
6
9
|
Sf2InstrumentConfig,
|
|
@@ -77,6 +80,38 @@ export interface WasmSampleBank {
|
|
|
77
80
|
delete: () => void;
|
|
78
81
|
}
|
|
79
82
|
|
|
83
|
+
// Embind handle for the C++ `ProjectTimelineWasm` class. Registered next to the
|
|
84
|
+
// project, so a build without arrangement support has neither.
|
|
85
|
+
export interface WasmProjectTimeline {
|
|
86
|
+
readonly id: number;
|
|
87
|
+
delete: () => void;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const projectTimelineHandles = new WeakMap<object, WasmProjectTimeline>();
|
|
91
|
+
|
|
92
|
+
/** Internal: registers the facade object whose identity may cross to the engine. */
|
|
93
|
+
export function registerProjectTimeline(owner: object, native: WasmProjectTimeline): void {
|
|
94
|
+
projectTimelineHandles.set(owner, native);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Internal: removes a disposed facade from the identity registry. */
|
|
98
|
+
export function unregisterProjectTimeline(owner: object): void {
|
|
99
|
+
projectTimelineHandles.delete(owner);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Internal: resolves only a timeline facade created by this module. */
|
|
103
|
+
export function projectTimelineNativeId(owner: unknown): number | undefined {
|
|
104
|
+
if (owner === null || (typeof owner !== 'object' && typeof owner !== 'function')) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
return projectTimelineHandles.get(owner)?.id;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** `compileTimeline` as the embind layer returns it, before the facade wraps the handle. */
|
|
111
|
+
export type NativeProjectCompileTimelineResult = ProjectCompileResult & {
|
|
112
|
+
timeline: WasmProjectTimeline | null;
|
|
113
|
+
};
|
|
114
|
+
|
|
80
115
|
/**
|
|
81
116
|
* Swaps a facade {@link SampleBank} in a synth patch descriptor for the id the
|
|
82
117
|
* embind layer looks the native bank up by, leaving every other field alone.
|
|
@@ -114,12 +149,55 @@ export function normalizeSynthInstrument(patch: unknown): NativeSynthBinding | s
|
|
|
114
149
|
return { ...rest, sampleBankId: sampleBank.nativeId };
|
|
115
150
|
}
|
|
116
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Serializes a part rig's inserts into the JSON array the native layer reads
|
|
154
|
+
* (`params` always a JSON object string), or undefined when none were given.
|
|
155
|
+
*/
|
|
156
|
+
export function partRigInsertsJson(inserts: PartRigInsert[] | undefined): string | undefined {
|
|
157
|
+
if (inserts === undefined || inserts === null) {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
if (!Array.isArray(inserts)) {
|
|
161
|
+
throw new TypeError('inserts must be an array');
|
|
162
|
+
}
|
|
163
|
+
return JSON.stringify(
|
|
164
|
+
inserts.map((insert) => {
|
|
165
|
+
const { processor, params } = insert;
|
|
166
|
+
return params === undefined
|
|
167
|
+
? { processor }
|
|
168
|
+
: { processor, params: typeof params === 'string' ? params : JSON.stringify(params) };
|
|
169
|
+
}),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Reads a native `{ mode, insertsJson }` part rig back into the public shape. */
|
|
174
|
+
export function partRigFromNative(
|
|
175
|
+
native: { mode: PartRig['mode']; insertsJson: string | null } | null,
|
|
176
|
+
): PartRig | null {
|
|
177
|
+
if (native === null) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
if (native.insertsJson === null) {
|
|
181
|
+
return { mode: native.mode };
|
|
182
|
+
}
|
|
183
|
+
const inserts = (JSON.parse(native.insertsJson) as { processor: string; params: string }[]).map(
|
|
184
|
+
({ processor, params }) => ({
|
|
185
|
+
processor,
|
|
186
|
+
params: JSON.parse(params) as Record<string, unknown>,
|
|
187
|
+
}),
|
|
188
|
+
);
|
|
189
|
+
return { mode: native.mode, inserts };
|
|
190
|
+
}
|
|
191
|
+
|
|
117
192
|
// Embind handle for the C++ `ProjectWasm` class. `SonareModule` describes the
|
|
118
193
|
// raw module's free functions and does not carry bound-class handles, so the
|
|
119
194
|
// module is narrowed through this shape here — which is also where the
|
|
120
195
|
// arrangement surface is probed for, since a build without arrangement support
|
|
121
196
|
// registers neither the class nor its free functions.
|
|
122
197
|
export interface WasmProject {
|
|
198
|
+
applyVocalEdit: (request: unknown) => unknown;
|
|
199
|
+
getVocalEditDependencies: () => unknown;
|
|
200
|
+
rehydrateVocalEdits: (originals: unknown, cancel?: unknown) => unknown;
|
|
123
201
|
toJson: () => string;
|
|
124
202
|
setSampleRate: (sampleRate: number) => void;
|
|
125
203
|
addTrack: (desc: { kind?: number | string; name?: string }) => number;
|
|
@@ -140,6 +218,17 @@ export interface WasmProject {
|
|
|
140
218
|
setTrackMute: (trackId: number, mute: boolean) => void;
|
|
141
219
|
setTrackSolo: (trackId: number, solo: boolean) => void;
|
|
142
220
|
setTrackPan: (trackId: number, pan: number) => void;
|
|
221
|
+
setPartRig: (
|
|
222
|
+
destinationId: number,
|
|
223
|
+
part: number,
|
|
224
|
+
mode: PartRigMode | number,
|
|
225
|
+
insertsJson: string | undefined,
|
|
226
|
+
) => void;
|
|
227
|
+
getPartRig: (
|
|
228
|
+
destinationId: number,
|
|
229
|
+
part: number,
|
|
230
|
+
) => { mode: PartRigMode; insertsJson: string | null } | null;
|
|
231
|
+
clearPartRig: (destinationId: number, part: number) => void;
|
|
143
232
|
undo: () => void;
|
|
144
233
|
redo: () => void;
|
|
145
234
|
clearHistory: () => void;
|
|
@@ -186,6 +275,7 @@ export interface WasmProject {
|
|
|
186
275
|
) => number;
|
|
187
276
|
snapToGrid: (ppq: number, strength: number, division: number) => number;
|
|
188
277
|
compile: () => ProjectCompileResult;
|
|
278
|
+
compileTimeline: () => NativeProjectCompileTimelineResult;
|
|
189
279
|
bounce: (options: ProjectBounceOptions) => Float32Array;
|
|
190
280
|
bounceWithBuiltinInstrument: (
|
|
191
281
|
bindings: BuiltinSynthBinding | ReadonlyArray<BuiltinSynthBinding> | undefined,
|
package/src/project_types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Type-only, so the erased import adds no runtime edge to the codes module.
|
|
2
2
|
import type { PROJECT_AUTOMATION_CURVE_VALUES } from './codes';
|
|
3
|
-
import type { Project } from './project_class';
|
|
3
|
+
import type { Project, ProjectTimeline } from './project_class';
|
|
4
4
|
|
|
5
5
|
// ============================================================================
|
|
6
6
|
// Headless DAW Project
|
|
@@ -532,7 +532,7 @@ export interface MidiCcLearnOptions {
|
|
|
532
532
|
minValue?: number;
|
|
533
533
|
/** Upper end of the mapped parameter range. Default `1`. */
|
|
534
534
|
maxValue?: number;
|
|
535
|
-
/**
|
|
535
|
+
/** Activity threshold in 7-bit CC units (integer 0-127) a controller must move to be learned. Default `0`. */
|
|
536
536
|
minMovement?: number;
|
|
537
537
|
}
|
|
538
538
|
|
|
@@ -630,12 +630,14 @@ export interface TranscribeOptions {
|
|
|
630
630
|
*/
|
|
631
631
|
referenceHz?: number;
|
|
632
632
|
/**
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
633
|
+
* F0 tracker range in Hz. Both paths use these bounds; the polyphonic path
|
|
634
|
+
* applies them to the salience estimator's F0 axis while its cent-spectrum
|
|
635
|
+
* bounds remain independent. When omitted, the monophonic defaults are `65`
|
|
636
|
+
* and `2093`, while the polyphonic defaults are `55` and `1760`. Explicit
|
|
637
|
+
* values must be finite and positive, and `fmax` must exceed `fmin`.
|
|
636
638
|
*/
|
|
637
639
|
fmin?: number;
|
|
638
|
-
/** Upper end of the
|
|
640
|
+
/** Upper end of the F0 tracker range in Hz; omitted defaults to `2093` mono or `1760` poly. */
|
|
639
641
|
fmax?: number;
|
|
640
642
|
/** Shortest span kept as a note, in milliseconds. Default `30`; must be positive. */
|
|
641
643
|
minNoteMs?: number;
|
|
@@ -719,6 +721,16 @@ export interface ProjectCompileResult {
|
|
|
719
721
|
diagnostics: ProjectDiagnostic[];
|
|
720
722
|
}
|
|
721
723
|
|
|
724
|
+
/** Result of {@link Project.compileTimeline}: the compile diagnostics plus the timeline they produced. */
|
|
725
|
+
export interface ProjectCompileTimelineResult extends ProjectCompileResult {
|
|
726
|
+
/**
|
|
727
|
+
* The compiled timeline, or `null` when compilation produced none (an error
|
|
728
|
+
* diagnostic; read {@link ProjectCompileResult.diagnostics}). Release it with
|
|
729
|
+
* {@link ProjectTimeline.dispose}.
|
|
730
|
+
*/
|
|
731
|
+
timeline: ProjectTimeline | null;
|
|
732
|
+
}
|
|
733
|
+
|
|
722
734
|
export interface ProjectDeserializeResult {
|
|
723
735
|
project: Project;
|
|
724
736
|
diagnostics: string;
|
package/src/public_types.ts
CHANGED
|
@@ -41,6 +41,7 @@ export interface SonareCapabilities {
|
|
|
41
41
|
arrangement: boolean;
|
|
42
42
|
acousticSim: boolean;
|
|
43
43
|
pitchEditor: boolean;
|
|
44
|
+
vocalEdit: boolean;
|
|
44
45
|
voiceChanger: boolean;
|
|
45
46
|
/** True when the playback renderer (upmix, binaural, speaker output) is compiled in. */
|
|
46
47
|
playback: boolean;
|
|
@@ -80,6 +80,7 @@ export const SOLO_PROCESSORS = [
|
|
|
80
80
|
'effects.acoustic.roomMorph',
|
|
81
81
|
'effects.delay.stereo',
|
|
82
82
|
'effects.filter.vowel',
|
|
83
|
+
'effects.gsEfx',
|
|
83
84
|
'effects.modulation.autoWah',
|
|
84
85
|
'effects.modulation.chorus',
|
|
85
86
|
'effects.modulation.ensemble',
|
|
@@ -131,9 +132,11 @@ export const SOLO_PROCESSORS = [
|
|
|
131
132
|
'repair.trimSilence',
|
|
132
133
|
'saturation.ampSim',
|
|
133
134
|
'saturation.bitcrusher',
|
|
135
|
+
'saturation.distortion',
|
|
134
136
|
'saturation.exciter',
|
|
135
137
|
'saturation.hardClipper',
|
|
136
138
|
'saturation.multibandExciter',
|
|
139
|
+
'saturation.overdrive',
|
|
137
140
|
'saturation.softClipper',
|
|
138
141
|
'saturation.tape',
|
|
139
142
|
'saturation.transformer',
|
|
@@ -162,6 +165,9 @@ export type PairProcessor =
|
|
|
162
165
|
| 'match.abSwitch'
|
|
163
166
|
| 'match.abCrossfade';
|
|
164
167
|
|
|
168
|
+
/** Pair processors with a stereo entry point. */
|
|
169
|
+
export type StereoPairProcessor = 'match.abCrossfade';
|
|
170
|
+
|
|
165
171
|
export type PairAnalysis =
|
|
166
172
|
| 'match.referenceLoudness'
|
|
167
173
|
| 'match.tonalBalance'
|
|
@@ -213,6 +219,23 @@ export interface LoudnessMatchResult {
|
|
|
213
219
|
matchedTruePeakDbtp: number;
|
|
214
220
|
}
|
|
215
221
|
|
|
222
|
+
/** Stereo counterpart of {@link LoudnessMatchResult}. */
|
|
223
|
+
export interface LoudnessMatchStereoResult {
|
|
224
|
+
/** The left source channel, gain-matched to the reference loudness. */
|
|
225
|
+
left: Float32Array;
|
|
226
|
+
/** The right source channel, gain-matched with the same gain as `left`. */
|
|
227
|
+
right: Float32Array;
|
|
228
|
+
sampleRate: number;
|
|
229
|
+
/** The reference program's BS.1770 integrated loudness. */
|
|
230
|
+
referenceLufs: number;
|
|
231
|
+
/** The stereo source program's loudness before the gain. */
|
|
232
|
+
sourceLufs: number;
|
|
233
|
+
/** One gain applied to both source channels, in dB. */
|
|
234
|
+
appliedGainDb: number;
|
|
235
|
+
/** Maximum true peak across the matched left and right channels, in dBTP. */
|
|
236
|
+
matchedTruePeakDbtp: number;
|
|
237
|
+
}
|
|
238
|
+
|
|
216
239
|
/**
|
|
217
240
|
* Mastering loudness/true-peak processing result
|
|
218
241
|
*/
|
|
@@ -158,6 +158,7 @@ export interface PlaybackDiagnostics {
|
|
|
158
158
|
loudness_gain_clamped: boolean;
|
|
159
159
|
/** True when an `hrtf` was supplied to a speakers target, which ignores it. */
|
|
160
160
|
hrtf_ignored: boolean;
|
|
161
|
+
/** Deepest last-block gain reduction across the main and LFE limiters, in dB (<= 0). */
|
|
161
162
|
limiter_gain_reduction_db: number;
|
|
162
163
|
non_finite_discards: number;
|
|
163
164
|
}
|
|
@@ -34,10 +34,10 @@ export interface PitchCorrectOptions extends ValidateOptions {
|
|
|
34
34
|
retuneSpeedMs?: number;
|
|
35
35
|
/** Corrections below this are bypassed to preserve vibrato (cents). Default 20. */
|
|
36
36
|
vibratoThresholdCents?: number;
|
|
37
|
-
/** Per-frame voiced flags (truthy = voiced);
|
|
38
|
-
voiced?: VoicedFlags;
|
|
39
|
-
/** Per-frame voicing probability in `[0, 1]`;
|
|
40
|
-
voicedProb?: Float32Array;
|
|
37
|
+
/** Per-frame voiced flags (truthy = voiced); when supplied, these take precedence over `voicedProb`. Omit or pass `null` to use `voicedProb`; with neither, all frames are treated as voiced. */
|
|
38
|
+
voiced?: VoicedFlags | null;
|
|
39
|
+
/** Per-frame voicing probability in `[0, 1]`; used only when `voiced` is omitted or `null`, and ignored when flags are supplied. */
|
|
40
|
+
voicedProb?: Float32Array | null;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/** Options for `noteStretch`. All fields are optional. */
|
|
@@ -68,7 +68,7 @@ export interface NoteExtractorOptions {
|
|
|
68
68
|
referenceHz?: number;
|
|
69
69
|
/**
|
|
70
70
|
* Value of `voicedProb` at or above which a frame counts as voiced, in
|
|
71
|
-
* `[0, 1]`. Read only when `voiced` is omitted
|
|
71
|
+
* `[0, 1]`. Read only when `voiced` is omitted or `null`. Default 0.5.
|
|
72
72
|
*
|
|
73
73
|
* pYIN's `voicedProb` is a frame's voiced observation mass and rises with F0
|
|
74
74
|
* for a fixed frame length, so this default silently drops low registers —
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/** Public value types for the monophonic vocal edit surface. */
|
|
2
|
+
|
|
3
|
+
/** A uint64 value crossing the JavaScript boundary is decimal text. */
|
|
4
|
+
export type VocalUint64 = string;
|
|
5
|
+
|
|
6
|
+
export interface VocalRange {
|
|
7
|
+
startSample: number;
|
|
8
|
+
endSample: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface VocalStateToken {
|
|
12
|
+
sessionEpoch: VocalUint64;
|
|
13
|
+
revision: VocalUint64;
|
|
14
|
+
draftId: VocalUint64;
|
|
15
|
+
generation: VocalUint64;
|
|
16
|
+
requestId: VocalUint64;
|
|
17
|
+
profileId: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface VocalPitchPoint {
|
|
21
|
+
sourceSample: number;
|
|
22
|
+
midi: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type VocalPitchTarget =
|
|
26
|
+
| { mode: 'none' }
|
|
27
|
+
| { mode: 'center'; midi: number }
|
|
28
|
+
| { mode: 'curve'; points: readonly VocalPitchPoint[] };
|
|
29
|
+
|
|
30
|
+
export interface VocalPitchEdit {
|
|
31
|
+
target: VocalPitchTarget;
|
|
32
|
+
amount: number;
|
|
33
|
+
speedMs: number;
|
|
34
|
+
maxCorrectionSemitones: number;
|
|
35
|
+
transposeSemitones: number;
|
|
36
|
+
driftScale: number;
|
|
37
|
+
vibratoScale: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type VocalFormantMode = 'preserve' | 'shift';
|
|
41
|
+
|
|
42
|
+
export interface VocalFormantEdit {
|
|
43
|
+
mode: VocalFormantMode;
|
|
44
|
+
shiftSemitones: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface VocalNoteEdit {
|
|
48
|
+
pitch: VocalPitchEdit;
|
|
49
|
+
destinationStartSample: number;
|
|
50
|
+
destinationLengthSamples: number;
|
|
51
|
+
gainDb: number;
|
|
52
|
+
muted: boolean;
|
|
53
|
+
amplitudeEnvelope: readonly number[];
|
|
54
|
+
formant: VocalFormantEdit;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface VocalNote {
|
|
58
|
+
id: number;
|
|
59
|
+
sourceStartSample: number;
|
|
60
|
+
sourceEndSample: number;
|
|
61
|
+
analysisFrameStart: VocalUint64;
|
|
62
|
+
analysisFrameEnd: VocalUint64;
|
|
63
|
+
hasPitch: boolean;
|
|
64
|
+
medianHz: number;
|
|
65
|
+
centerMidi: number;
|
|
66
|
+
f0Stability: number;
|
|
67
|
+
amplitude: Float32Array;
|
|
68
|
+
edit: VocalNoteEdit;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface VocalTransition {
|
|
72
|
+
leftNoteId: number;
|
|
73
|
+
rightNoteId: number;
|
|
74
|
+
leftWindowSamples: number;
|
|
75
|
+
rightWindowSamples: number;
|
|
76
|
+
strength: number;
|
|
77
|
+
curve: 'smoothstep';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface VocalNotesResult {
|
|
81
|
+
notes: VocalNote[];
|
|
82
|
+
transitions: VocalTransition[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface VocalAnalysis {
|
|
86
|
+
frameOriginSample: number;
|
|
87
|
+
samplesPerFrame: number;
|
|
88
|
+
frameLengthSamples: number;
|
|
89
|
+
f0Hz: Float32Array;
|
|
90
|
+
voiced: Uint8Array;
|
|
91
|
+
algorithmId: string;
|
|
92
|
+
algorithmVersion: number;
|
|
93
|
+
sourceLengthSamples: number;
|
|
94
|
+
sampleRate: number;
|
|
95
|
+
sourceSha256: string;
|
|
96
|
+
analysisSha256: string;
|
|
97
|
+
fminHz: number;
|
|
98
|
+
fmaxHz: number;
|
|
99
|
+
yinThreshold: number;
|
|
100
|
+
voicedThreshold: number;
|
|
101
|
+
centered: boolean;
|
|
102
|
+
segmentationThresholdCents: number;
|
|
103
|
+
minNoteMs: number;
|
|
104
|
+
referenceHz: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface VocalCapabilities {
|
|
108
|
+
apiVersion: number;
|
|
109
|
+
profileId: number;
|
|
110
|
+
monophonicOnly: true;
|
|
111
|
+
analysisCancellable: boolean;
|
|
112
|
+
minimumFormantShiftSemitones: number;
|
|
113
|
+
maximumFormantShiftSemitones: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface VocalHistory {
|
|
117
|
+
canUndo: boolean;
|
|
118
|
+
canRedo: boolean;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export type VocalHistoryState = VocalHistory;
|
|
122
|
+
|
|
123
|
+
export interface VocalSessionLimits {
|
|
124
|
+
maxHistoryBytes?: VocalUint64;
|
|
125
|
+
maxCacheBytes?: VocalUint64;
|
|
126
|
+
maxUndoDepth?: number;
|
|
127
|
+
maxRenderJobs?: number;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface VocalAnalysisInput {
|
|
131
|
+
frameOriginSample: number;
|
|
132
|
+
samplesPerFrame: number;
|
|
133
|
+
frameLengthSamples: number;
|
|
134
|
+
f0Hz: Float32Array;
|
|
135
|
+
voiced: Uint8Array;
|
|
136
|
+
algorithmId?: string;
|
|
137
|
+
algorithmVersion?: number;
|
|
138
|
+
fminHz?: number;
|
|
139
|
+
fmaxHz?: number;
|
|
140
|
+
yinThreshold?: number;
|
|
141
|
+
voicedThreshold?: number;
|
|
142
|
+
centered?: boolean;
|
|
143
|
+
segmentationThresholdCents?: number;
|
|
144
|
+
minNoteMs?: number;
|
|
145
|
+
referenceHz?: number;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface VocalCreateOptions {
|
|
149
|
+
outputLengthSamples?: number;
|
|
150
|
+
edgeFadeMs?: number;
|
|
151
|
+
vibratoCutoffHz?: number;
|
|
152
|
+
segmentationThresholdCents?: number;
|
|
153
|
+
minNoteMs?: number;
|
|
154
|
+
frameLengthSamples?: number;
|
|
155
|
+
hopLengthSamples?: number;
|
|
156
|
+
fminHz?: number;
|
|
157
|
+
fmaxHz?: number;
|
|
158
|
+
yinThreshold?: number;
|
|
159
|
+
voicedThreshold?: number;
|
|
160
|
+
centered?: boolean;
|
|
161
|
+
referenceHz?: number;
|
|
162
|
+
limits?: VocalSessionLimits;
|
|
163
|
+
analysis?: VocalAnalysisInput;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface VocalCreateRequest extends VocalCreateOptions {
|
|
167
|
+
samples: Float32Array;
|
|
168
|
+
sampleRate: number;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface VocalRestoreRequest {
|
|
172
|
+
samples: Float32Array;
|
|
173
|
+
sampleRate: number;
|
|
174
|
+
state: Uint8Array;
|
|
175
|
+
/** Runtime limits; omitted fields take the same defaults as session creation. */
|
|
176
|
+
limits?: VocalSessionLimits;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface VocalSetEditOperation {
|
|
180
|
+
kind: 'setEdit';
|
|
181
|
+
noteId: number;
|
|
182
|
+
edit: VocalNoteEdit;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface VocalSetSourceSpanOperation {
|
|
186
|
+
kind: 'setSourceSpan';
|
|
187
|
+
noteId: number;
|
|
188
|
+
sourceStartSample: number;
|
|
189
|
+
sourceEndSample: number;
|
|
190
|
+
destinationStartSample: number;
|
|
191
|
+
destinationLengthSamples: number;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface VocalSplitOperation {
|
|
195
|
+
kind: 'split';
|
|
196
|
+
noteId: number;
|
|
197
|
+
sourceSample: number;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface VocalMergeOperation {
|
|
201
|
+
kind: 'merge';
|
|
202
|
+
noteIds: readonly number[];
|
|
203
|
+
policy?: 'preserve' | 'reset';
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface VocalSetTransitionOperation {
|
|
207
|
+
kind: 'setTransition';
|
|
208
|
+
transition: VocalTransition;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface VocalRemoveTransitionOperation {
|
|
212
|
+
kind: 'removeTransition';
|
|
213
|
+
leftNoteId: number;
|
|
214
|
+
rightNoteId: number;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface VocalResetOperation {
|
|
218
|
+
kind: 'reset';
|
|
219
|
+
noteIds: readonly number[];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export type VocalEditOperation =
|
|
223
|
+
| VocalSetEditOperation
|
|
224
|
+
| VocalSetSourceSpanOperation
|
|
225
|
+
| VocalSplitOperation
|
|
226
|
+
| VocalMergeOperation
|
|
227
|
+
| VocalSetTransitionOperation
|
|
228
|
+
| VocalRemoveTransitionOperation
|
|
229
|
+
| VocalResetOperation;
|
|
230
|
+
|
|
231
|
+
export interface VocalApplyRequest {
|
|
232
|
+
expectedGeneration: VocalUint64;
|
|
233
|
+
operations: readonly VocalEditOperation[];
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface VocalIdChange {
|
|
237
|
+
operationIndex: number;
|
|
238
|
+
retiredId: number;
|
|
239
|
+
newIds: readonly number[];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface VocalEditResult {
|
|
243
|
+
token: VocalStateToken;
|
|
244
|
+
dirtyRanges: readonly VocalRange[];
|
|
245
|
+
idChanges: readonly VocalIdChange[];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface VocalPitchEvaluation {
|
|
249
|
+
sourceSamples: Float64Array;
|
|
250
|
+
measuredMidi: Float64Array;
|
|
251
|
+
targetMidi: Float64Array;
|
|
252
|
+
effectiveMidi: Float64Array;
|
|
253
|
+
voiced: Uint8Array;
|
|
254
|
+
hasTarget: Uint8Array;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface VocalRenderRequest {
|
|
258
|
+
/** Omit to render the complete destination output. */
|
|
259
|
+
range?: VocalRange;
|
|
260
|
+
requestId?: VocalUint64;
|
|
261
|
+
signal?: AbortSignal;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface VocalRenderResult {
|
|
265
|
+
samples: Float32Array;
|
|
266
|
+
startSample: number;
|
|
267
|
+
token: VocalStateToken;
|
|
268
|
+
processedRanges: readonly VocalRange[];
|
|
269
|
+
cacheHitUnits: VocalUint64;
|
|
270
|
+
dryPassedFrames: VocalUint64;
|
|
271
|
+
limitedCorrectionFrames: VocalUint64;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export interface VocalStateBytes {
|
|
275
|
+
data: Uint8Array;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface VocalJobProgress {
|
|
279
|
+
complete: boolean;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface VocalErrorShape {
|
|
283
|
+
readonly reason: number;
|
|
284
|
+
readonly field: string;
|
|
285
|
+
readonly expected: VocalUint64;
|
|
286
|
+
readonly actual: VocalUint64;
|
|
287
|
+
readonly expectedText: string;
|
|
288
|
+
readonly actualText: string;
|
|
289
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { VocalStateToken, VocalUint64 } from './public_types_vocal_edit';
|
|
2
|
+
|
|
3
|
+
/** A full source render and persisted vocal session ready for Project apply. */
|
|
4
|
+
export interface ProjectVocalEditApplyRequest {
|
|
5
|
+
clipId: number;
|
|
6
|
+
/** Zero selects the clip's base source; a non-zero id selects a take. */
|
|
7
|
+
takeId?: number;
|
|
8
|
+
expectedSourceId: number;
|
|
9
|
+
expectedSourceSampleRate: number;
|
|
10
|
+
expectedSourceSampleCount: number;
|
|
11
|
+
/** Canonical source digest as exactly 64 hexadecimal characters. */
|
|
12
|
+
expectedSourceSha256: string;
|
|
13
|
+
expectedClipLengthPpq: number;
|
|
14
|
+
expectedSourceOffsetPpq: number;
|
|
15
|
+
/** Full-source mono render. The v1 Project adapter requires startSample 0. */
|
|
16
|
+
renderedMono: Float32Array;
|
|
17
|
+
renderedSampleRate: number;
|
|
18
|
+
renderedStartSample?: number;
|
|
19
|
+
renderToken: VocalStateToken;
|
|
20
|
+
/** SVE1 state exported from the committed vocal edit session. */
|
|
21
|
+
sve1: Uint8Array;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ProjectVocalEditApplyResult {
|
|
25
|
+
clipId: number;
|
|
26
|
+
takeId: number;
|
|
27
|
+
originalSourceId: number;
|
|
28
|
+
derivedSourceId: number;
|
|
29
|
+
committedRevision: VocalUint64;
|
|
30
|
+
profileId: number;
|
|
31
|
+
derivedSourceSha256: string;
|
|
32
|
+
sidecarKey: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type ProjectVocalReason = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
36
|
+
|
|
37
|
+
export interface ProjectVocalEditDependency {
|
|
38
|
+
clipId: number;
|
|
39
|
+
takeId: number;
|
|
40
|
+
originalSourceId: number;
|
|
41
|
+
derivedSourceId: number;
|
|
42
|
+
sourceSampleRate: number;
|
|
43
|
+
profileId: number;
|
|
44
|
+
sourceSampleCount: number;
|
|
45
|
+
committedRevision: VocalUint64;
|
|
46
|
+
originalSourceSha256: string;
|
|
47
|
+
derivedSourceSha256: string;
|
|
48
|
+
originalPcmAvailable: boolean;
|
|
49
|
+
derivedPcmAvailable: boolean;
|
|
50
|
+
reason: ProjectVocalReason | number;
|
|
51
|
+
sidecarKey: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ProjectVocalOriginalSource {
|
|
55
|
+
sourceId: number;
|
|
56
|
+
mono: Float32Array;
|
|
57
|
+
sampleRate: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Native status values from SonareProjectVocalRehydrateStatus. */
|
|
61
|
+
export type ProjectVocalRehydrateStatus = 0 | 1 | 2;
|
|
62
|
+
|
|
63
|
+
export interface ProjectVocalRehydrateItem {
|
|
64
|
+
clipId: number;
|
|
65
|
+
takeId: number;
|
|
66
|
+
derivedSourceId: number;
|
|
67
|
+
status: ProjectVocalRehydrateStatus;
|
|
68
|
+
reason: ProjectVocalReason | number;
|
|
69
|
+
}
|