@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.
Files changed (138) hide show
  1. package/README.md +5 -5
  2. package/dist/_effects_common.d.ts +2 -1
  3. package/dist/_effects_common.d.ts.map +1 -1
  4. package/dist/analysis.js +3 -0
  5. package/dist/analysis.js.map +1 -1
  6. package/dist/effects_mastering.d.ts +2 -2
  7. package/dist/effects_mastering.d.ts.map +1 -1
  8. package/dist/effects_note_ops.d.ts +55 -30
  9. package/dist/effects_note_ops.d.ts.map +1 -1
  10. package/dist/effects_timepitch.d.ts +17 -12
  11. package/dist/effects_timepitch.d.ts.map +1 -1
  12. package/dist/feature_decompose.d.ts +1 -1
  13. package/dist/feature_decompose.d.ts.map +1 -1
  14. package/dist/index.d.ts +11 -5
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2098 -155
  17. package/dist/index.js.map +1 -1
  18. package/dist/instrument_types.d.ts +27 -3
  19. package/dist/instrument_types.d.ts.map +1 -1
  20. package/dist/mastering_core.d.ts +30 -3
  21. package/dist/mastering_core.d.ts.map +1 -1
  22. package/dist/mixer.d.ts +2 -2
  23. package/dist/mixer.d.ts.map +1 -1
  24. package/dist/project.d.ts +5 -4
  25. package/dist/project.d.ts.map +1 -1
  26. package/dist/project_class.d.ts +57 -3
  27. package/dist/project_class.d.ts.map +1 -1
  28. package/dist/project_internal.d.ts +35 -1
  29. package/dist/project_internal.d.ts.map +1 -1
  30. package/dist/project_types.d.ts +17 -6
  31. package/dist/project_types.d.ts.map +1 -1
  32. package/dist/public_types.d.ts +1 -0
  33. package/dist/public_types.d.ts.map +1 -1
  34. package/dist/public_types_mastering.d.ts +19 -1
  35. package/dist/public_types_mastering.d.ts.map +1 -1
  36. package/dist/public_types_playback.d.ts +1 -0
  37. package/dist/public_types_playback.d.ts.map +1 -1
  38. package/dist/public_types_spectral.d.ts +5 -5
  39. package/dist/public_types_spectral.d.ts.map +1 -1
  40. package/dist/public_types_vocal_edit.d.ts +250 -0
  41. package/dist/public_types_vocal_edit.d.ts.map +1 -0
  42. package/dist/public_types_vocal_project.d.ts +63 -0
  43. package/dist/public_types_vocal_project.d.ts.map +1 -0
  44. package/dist/realtime_engine.d.ts +106 -16
  45. package/dist/realtime_engine.d.ts.map +1 -1
  46. package/dist/repair_dereverb.d.ts +1 -0
  47. package/dist/repair_dereverb.d.ts.map +1 -1
  48. package/dist/repair_noise.d.ts +1 -0
  49. package/dist/repair_noise.d.ts.map +1 -1
  50. package/dist/sonare-analysis.wasm +0 -0
  51. package/dist/sonare.d.ts +89 -0
  52. package/dist/sonare.js +1 -1
  53. package/dist/sonare.wasm +0 -0
  54. package/dist/streaming_processors.d.ts +5 -0
  55. package/dist/streaming_processors.d.ts.map +1 -1
  56. package/dist/vocal_edit.d.ts +131 -0
  57. package/dist/vocal_edit.d.ts.map +1 -0
  58. package/dist/vocal_edit_worker.d.ts +51 -0
  59. package/dist/vocal_edit_worker.d.ts.map +1 -0
  60. package/dist/vocal_edit_worker.js +1462 -0
  61. package/dist/vocal_edit_worker.js.map +1 -0
  62. package/dist/vocal_edit_worker_client.d.ts +118 -0
  63. package/dist/vocal_edit_worker_client.d.ts.map +1 -0
  64. package/dist/vocal_edit_worker_protocol.d.ts +139 -0
  65. package/dist/vocal_edit_worker_protocol.d.ts.map +1 -0
  66. package/dist/vocal_project.d.ts +17 -0
  67. package/dist/vocal_project.d.ts.map +1 -0
  68. package/dist/web_midi.d.ts +4 -0
  69. package/dist/web_midi.d.ts.map +1 -1
  70. package/dist/worker.js.map +1 -1
  71. package/dist/worklet/engine-mixer-facade.d.ts +42 -5
  72. package/dist/worklet/engine-mixer-facade.d.ts.map +1 -1
  73. package/dist/worklet/engine-node.d.ts +10 -0
  74. package/dist/worklet/engine-node.d.ts.map +1 -1
  75. package/dist/worklet/engine-processor.d.ts +6 -1
  76. package/dist/worklet/engine-processor.d.ts.map +1 -1
  77. package/dist/worklet/engine-register.d.ts.map +1 -1
  78. package/dist/worklet/engine-strips.d.ts +8 -4
  79. package/dist/worklet/engine-strips.d.ts.map +1 -1
  80. package/dist/worklet/engine-sync.d.ts +4 -2
  81. package/dist/worklet/engine-sync.d.ts.map +1 -1
  82. package/dist/worklet/engine.d.ts +42 -9
  83. package/dist/worklet/engine.d.ts.map +1 -1
  84. package/dist/worklet/guards.d.ts +10 -2
  85. package/dist/worklet/guards.d.ts.map +1 -1
  86. package/dist/worklet/messages.d.ts +54 -9
  87. package/dist/worklet/messages.d.ts.map +1 -1
  88. package/dist/worklet/mixer-processor.d.ts +2 -2
  89. package/dist/worklet/mixer-processor.d.ts.map +1 -1
  90. package/dist/worklet/protocol.d.ts +20 -2
  91. package/dist/worklet/protocol.d.ts.map +1 -1
  92. package/dist/worklet.d.ts +1 -1
  93. package/dist/worklet.d.ts.map +1 -1
  94. package/dist/worklet.js +808 -204
  95. package/dist/worklet.js.map +1 -1
  96. package/package.json +6 -1
  97. package/src/_effects_common.ts +36 -6
  98. package/src/effects_mastering.ts +4 -0
  99. package/src/effects_note_ops.ts +92 -44
  100. package/src/effects_timepitch.ts +42 -31
  101. package/src/feature_decompose.ts +2 -2
  102. package/src/index.ts +39 -0
  103. package/src/instrument_types.ts +29 -3
  104. package/src/mastering_core.ts +98 -2
  105. package/src/mixer.ts +41 -21
  106. package/src/project.ts +8 -1
  107. package/src/project_class.ts +136 -1
  108. package/src/project_internal.ts +90 -0
  109. package/src/project_types.ts +18 -6
  110. package/src/public_types.ts +1 -0
  111. package/src/public_types_mastering.ts +23 -0
  112. package/src/public_types_playback.ts +1 -0
  113. package/src/public_types_spectral.ts +5 -5
  114. package/src/public_types_vocal_edit.ts +289 -0
  115. package/src/public_types_vocal_project.ts +69 -0
  116. package/src/realtime_engine.ts +157 -24
  117. package/src/repair_dereverb.ts +1 -0
  118. package/src/repair_noise.ts +1 -0
  119. package/src/sonare.js.d.ts +89 -0
  120. package/src/streaming_processors.ts +8 -0
  121. package/src/vocal_edit.ts +885 -0
  122. package/src/vocal_edit_worker.ts +832 -0
  123. package/src/vocal_edit_worker_client.ts +812 -0
  124. package/src/vocal_edit_worker_protocol.ts +206 -0
  125. package/src/vocal_project.ts +327 -0
  126. package/src/web_midi.ts +100 -5
  127. package/src/worklet/engine-mixer-facade.ts +422 -87
  128. package/src/worklet/engine-node.ts +69 -4
  129. package/src/worklet/engine-processor.ts +129 -34
  130. package/src/worklet/engine-register.ts +3 -0
  131. package/src/worklet/engine-strips.ts +36 -14
  132. package/src/worklet/engine-sync.ts +6 -1
  133. package/src/worklet/engine.ts +76 -40
  134. package/src/worklet/guards.ts +81 -0
  135. package/src/worklet/messages.ts +63 -4
  136. package/src/worklet/mixer-processor.ts +10 -3
  137. package/src/worklet/protocol.ts +39 -8
  138. package/src/worklet.ts +2 -0
@@ -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,
@@ -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
- /** Minimum normalized CC movement required to learn a binding. Default `0`. */
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
- * Monophonic tracker range in Hz. Defaults `65` and `2093`; both must be
634
- * finite and positive, and `fmax` must exceed `fmin`. The polyphonic chain
635
- * sets its own range and reads neither.
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 monophonic tracker range in Hz. Default `2093`. */
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;
@@ -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); omit to treat all frames as voiced. */
38
- voiced?: VoicedFlags;
39
- /** Per-frame voicing probability in `[0, 1]`; omit to derive from `voiced`. */
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. Default 0.5.
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
+ }