@libraz/libsonare 1.7.2 → 1.8.1
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/NOTICE +178 -0
- package/README.md +26 -203
- package/dist/_chain_config.d.ts +14 -0
- package/dist/_chain_config.d.ts.map +1 -0
- package/dist/_effects_common.d.ts +7 -0
- package/dist/_effects_common.d.ts.map +1 -0
- package/dist/_feature_validation.d.ts +8 -0
- package/dist/_feature_validation.d.ts.map +1 -0
- package/dist/_fft_options.d.ts +24 -0
- package/dist/_fft_options.d.ts.map +1 -0
- package/dist/align_take.d.ts +50 -0
- package/dist/align_take.d.ts.map +1 -0
- package/dist/analysis.d.ts +29 -5840
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +874 -722
- package/dist/analysis.js.map +1 -1
- package/dist/analysis_helpers.d.ts +9 -0
- package/dist/analysis_helpers.d.ts.map +1 -0
- package/dist/audio.d.ts +163 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/clip_page_streamer.d.ts +133 -0
- package/dist/clip_page_streamer.d.ts.map +1 -0
- package/dist/codes.d.ts +44 -0
- package/dist/codes.d.ts.map +1 -0
- package/dist/effects_mastering.d.ts +23 -0
- package/dist/effects_mastering.d.ts.map +1 -0
- package/dist/effects_note_ops.d.ts +502 -0
- package/dist/effects_note_ops.d.ts.map +1 -0
- package/dist/effects_percussive.d.ts +185 -0
- package/dist/effects_percussive.d.ts.map +1 -0
- package/dist/effects_separation.d.ts +65 -0
- package/dist/effects_separation.d.ts.map +1 -0
- package/dist/effects_spectral.d.ts +28 -0
- package/dist/effects_spectral.d.ts.map +1 -0
- package/dist/effects_timepitch.d.ts +134 -0
- package/dist/effects_timepitch.d.ts.map +1 -0
- package/dist/effects_voice_change.d.ts +53 -0
- package/dist/effects_voice_change.d.ts.map +1 -0
- package/dist/errors.d.ts +51 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/feature_core.d.ts +341 -0
- package/dist/feature_core.d.ts.map +1 -0
- package/dist/feature_decompose.d.ts +278 -0
- package/dist/feature_decompose.d.ts.map +1 -0
- package/dist/feature_inverse.d.ts +128 -0
- package/dist/feature_inverse.d.ts.map +1 -0
- package/dist/feature_loudness.d.ts +66 -0
- package/dist/feature_loudness.d.ts.map +1 -0
- package/dist/feature_music.d.ts +307 -0
- package/dist/feature_music.d.ts.map +1 -0
- package/dist/feature_pitch.d.ts +108 -0
- package/dist/feature_pitch.d.ts.map +1 -0
- package/dist/feature_resample.d.ts +16 -0
- package/dist/feature_resample.d.ts.map +1 -0
- package/dist/feature_spectral.d.ts +137 -0
- package/dist/feature_spectral.d.ts.map +1 -0
- package/dist/feature_spectrogram.d.ts +198 -0
- package/dist/feature_spectrogram.d.ts.map +1 -0
- package/dist/features.d.ts +10 -0
- package/dist/features.d.ts.map +1 -0
- package/dist/hrtf/default.shrf +0 -0
- package/dist/index.d.ts +74 -7431
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4173 -1621
- package/dist/index.js.map +1 -1
- package/dist/instrument_types.d.ts +517 -0
- package/dist/instrument_types.d.ts.map +1 -0
- package/dist/live_audio.d.ts +35 -0
- package/dist/live_audio.d.ts.map +1 -0
- package/dist/mastering_chain.d.ts +213 -0
- package/dist/mastering_chain.d.ts.map +1 -0
- package/dist/mastering_core.d.ts +483 -0
- package/dist/mastering_core.d.ts.map +1 -0
- package/dist/mastering_dynamics.d.ts +80 -0
- package/dist/mastering_dynamics.d.ts.map +1 -0
- package/dist/metering.d.ts +287 -0
- package/dist/metering.d.ts.map +1 -0
- package/dist/mixer.d.ts +464 -0
- package/dist/mixer.d.ts.map +1 -0
- package/dist/mixing_assistant.d.ts +62 -0
- package/dist/mixing_assistant.d.ts.map +1 -0
- package/dist/mixing_oneshot.d.ts +40 -0
- package/dist/mixing_oneshot.d.ts.map +1 -0
- package/dist/module_state.d.ts +15 -0
- package/dist/module_state.d.ts.map +1 -0
- package/dist/opfs_clip_pages.d.ts +28 -0
- package/dist/opfs_clip_pages.d.ts.map +1 -0
- package/dist/playback_renderer.d.ts +128 -0
- package/dist/playback_renderer.d.ts.map +1 -0
- package/dist/polyphony.d.ts +202 -0
- package/dist/polyphony.d.ts.map +1 -0
- package/dist/project.d.ts +8 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project_class.d.ts +562 -0
- package/dist/project_class.d.ts.map +1 -0
- package/dist/project_internal.d.ts +194 -0
- package/dist/project_internal.d.ts.map +1 -0
- package/dist/project_synth.d.ts +74 -0
- package/dist/project_synth.d.ts.map +1 -0
- package/dist/project_types.d.ts +654 -0
- package/dist/project_types.d.ts.map +1 -0
- package/dist/public_types.d.ts +185 -0
- package/dist/public_types.d.ts.map +1 -0
- package/dist/public_types_acoustic.d.ts +215 -0
- package/dist/public_types_acoustic.d.ts.map +1 -0
- package/dist/public_types_mastering.d.ts +528 -0
- package/dist/public_types_mastering.d.ts.map +1 -0
- package/dist/public_types_mixing.d.ts +436 -0
- package/dist/public_types_mixing.d.ts.map +1 -0
- package/dist/public_types_music.d.ts +619 -0
- package/dist/public_types_music.d.ts.map +1 -0
- package/dist/public_types_playback.d.ts +165 -0
- package/dist/public_types_playback.d.ts.map +1 -0
- package/dist/public_types_realtime.d.ts +174 -0
- package/dist/public_types_realtime.d.ts.map +1 -0
- package/dist/public_types_repair.d.ts +424 -0
- package/dist/public_types_repair.d.ts.map +1 -0
- package/dist/public_types_spectral.d.ts +697 -0
- package/dist/public_types_spectral.d.ts.map +1 -0
- package/dist/quick_analysis.d.ts +445 -0
- package/dist/quick_analysis.d.ts.map +1 -0
- package/dist/realtime_engine.d.ts +893 -0
- package/dist/realtime_engine.d.ts.map +1 -0
- package/dist/realtime_voice_changer.d.ts +158 -0
- package/dist/realtime_voice_changer.d.ts.map +1 -0
- package/dist/repair_dereverb.d.ts +187 -0
- package/dist/repair_dereverb.d.ts.map +1 -0
- package/dist/repair_impulsive.d.ts +186 -0
- package/dist/repair_impulsive.d.ts.map +1 -0
- package/dist/repair_noise.d.ts +239 -0
- package/dist/repair_noise.d.ts.map +1 -0
- package/dist/repair_trim.d.ts +123 -0
- package/dist/repair_trim.d.ts.map +1 -0
- package/dist/sample_bank.d.ts +84 -0
- package/dist/sample_bank.d.ts.map +1 -0
- package/dist/scale.d.ts +10 -0
- package/dist/scale.d.ts.map +1 -0
- package/dist/schemas/mixer-scene.schema.json +393 -0
- package/dist/schemas/playback-renderer-config.schema.json +392 -0
- package/dist/sonare-analysis.d.ts +8 -0
- package/dist/sonare-analysis.js +2 -2
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.d.ts +3945 -0
- package/dist/sonare.js +2 -2
- package/dist/sonare.wasm +0 -0
- package/dist/stream_analyzer.d.ts +163 -0
- package/dist/stream_analyzer.d.ts.map +1 -0
- package/dist/stream_types.d.ts +214 -0
- package/dist/stream_types.d.ts.map +1 -0
- package/dist/streaming_mixing.d.ts +6 -0
- package/dist/streaming_mixing.d.ts.map +1 -0
- package/dist/streaming_processors.d.ts +340 -0
- package/dist/streaming_processors.d.ts.map +1 -0
- package/dist/transcribe.d.ts +77 -0
- package/dist/transcribe.d.ts.map +1 -0
- package/dist/validation.d.ts +140 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/web_midi.d.ts +77 -0
- package/dist/web_midi.d.ts.map +1 -0
- package/dist/worker.d.ts +5 -48
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +94 -41
- package/dist/worker.js.map +1 -1
- package/dist/worker_client.d.ts +96 -0
- package/dist/worker_client.d.ts.map +1 -0
- package/dist/worker_protocol.d.ts +43 -0
- package/dist/worker_protocol.d.ts.map +1 -0
- package/dist/worklet/audio_types.d.ts +21 -0
- package/dist/worklet/audio_types.d.ts.map +1 -0
- package/dist/worklet/engine-automation.d.ts +29 -0
- package/dist/worklet/engine-automation.d.ts.map +1 -0
- package/dist/worklet/engine-capture-facade.d.ts +35 -0
- package/dist/worklet/engine-capture-facade.d.ts.map +1 -0
- package/dist/worklet/engine-clips.d.ts +23 -0
- package/dist/worklet/engine-clips.d.ts.map +1 -0
- package/dist/worklet/engine-markers.d.ts +40 -0
- package/dist/worklet/engine-markers.d.ts.map +1 -0
- package/dist/worklet/engine-mixer-facade.d.ts +164 -0
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
- package/dist/worklet/engine-node.d.ts +83 -0
- package/dist/worklet/engine-node.d.ts.map +1 -0
- package/dist/worklet/engine-offline.d.ts +81 -0
- package/dist/worklet/engine-offline.d.ts.map +1 -0
- package/dist/worklet/engine-options.d.ts +12 -0
- package/dist/worklet/engine-options.d.ts.map +1 -0
- package/dist/worklet/engine-parameter-facade.d.ts +106 -0
- package/dist/worklet/engine-parameter-facade.d.ts.map +1 -0
- package/dist/worklet/engine-processor.d.ts +72 -0
- package/dist/worklet/engine-processor.d.ts.map +1 -0
- package/dist/worklet/engine-register.d.ts +2 -0
- package/dist/worklet/engine-register.d.ts.map +1 -0
- package/dist/worklet/engine-strips.d.ts +75 -0
- package/dist/worklet/engine-strips.d.ts.map +1 -0
- package/dist/worklet/engine-sync.d.ts +39 -0
- package/dist/worklet/engine-sync.d.ts.map +1 -0
- package/dist/worklet/engine-tempo-facade.d.ts +48 -0
- package/dist/worklet/engine-tempo-facade.d.ts.map +1 -0
- package/dist/worklet/engine.d.ts +418 -0
- package/dist/worklet/engine.d.ts.map +1 -0
- package/dist/worklet/guards.d.ts +53 -0
- package/dist/worklet/guards.d.ts.map +1 -0
- package/dist/worklet/messages.d.ts +710 -0
- package/dist/worklet/messages.d.ts.map +1 -0
- package/dist/worklet/mixer-processor.d.ts +46 -0
- package/dist/worklet/mixer-processor.d.ts.map +1 -0
- package/dist/worklet/playback-processor.d.ts +62 -0
- package/dist/worklet/playback-processor.d.ts.map +1 -0
- package/dist/worklet/protocol.d.ts +331 -0
- package/dist/worklet/protocol.d.ts.map +1 -0
- package/dist/worklet/voice-changer-processor.d.ts +41 -0
- package/dist/worklet/voice-changer-processor.d.ts.map +1 -0
- package/dist/worklet.d.ts +16 -2515
- package/dist/worklet.d.ts.map +1 -0
- package/dist/worklet.js +3200 -541
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -12
- package/src/_effects_common.ts +47 -0
- package/src/_feature_validation.ts +34 -0
- package/src/_fft_options.ts +39 -0
- package/src/align_take.ts +64 -0
- package/src/analysis.ts +56 -3
- package/src/analysis_helpers.ts +7 -0
- package/src/audio.ts +106 -3
- package/src/codes.ts +39 -2
- package/src/effects_mastering.ts +101 -22
- package/src/effects_note_ops.ts +683 -0
- package/src/effects_percussive.ts +217 -0
- package/src/effects_separation.ts +150 -0
- package/src/effects_spectral.ts +60 -0
- package/src/effects_timepitch.ts +388 -0
- package/src/errors.ts +23 -1
- package/src/feature_core.ts +127 -2
- package/src/feature_decompose.ts +633 -0
- package/src/feature_inverse.ts +454 -0
- package/src/feature_loudness.ts +125 -0
- package/src/feature_music.ts +107 -14
- package/src/feature_pitch.ts +96 -1
- package/src/feature_spectral.ts +16 -611
- package/src/feature_spectrogram.ts +63 -450
- package/src/features.ts +36 -22
- package/src/index.ts +288 -30
- package/src/instrument_types.ts +645 -0
- package/src/live_audio.ts +27 -1
- package/src/mastering_chain.ts +184 -0
- package/src/mastering_core.ts +441 -32
- package/src/mastering_dynamics.ts +22 -11
- package/src/metering.ts +67 -24
- package/src/mixer.ts +251 -22
- package/src/mixing_assistant.ts +138 -0
- package/src/mixing_oneshot.ts +10 -5
- package/src/module_state.ts +24 -2
- package/src/playback_renderer.ts +252 -0
- package/src/polyphony.ts +279 -0
- package/src/project.ts +61 -24
- package/src/project_class.ts +450 -27
- package/src/project_internal.ts +149 -42
- package/src/project_synth.ts +67 -1
- package/src/project_types.ts +271 -271
- package/src/public_types.ts +122 -3
- package/src/public_types_acoustic.ts +112 -3
- package/src/public_types_mastering.ts +275 -73
- package/src/public_types_mixing.ts +363 -1
- package/src/public_types_music.ts +312 -2
- package/src/public_types_playback.ts +196 -0
- package/src/public_types_realtime.ts +39 -7
- package/src/public_types_repair.ts +446 -0
- package/src/public_types_spectral.ts +491 -5
- package/src/quick_analysis.ts +203 -26
- package/src/realtime_engine.ts +773 -34
- package/src/realtime_voice_changer.ts +55 -1
- package/src/repair_dereverb.ts +299 -0
- package/src/repair_impulsive.ts +395 -0
- package/src/repair_noise.ts +425 -0
- package/src/repair_trim.ts +226 -0
- package/src/sample_bank.ts +113 -0
- package/src/sonare.js.d.ts +1158 -30
- package/src/stream_analyzer.ts +36 -4
- package/src/stream_types.ts +37 -0
- package/src/streaming_mixing.ts +1 -1
- package/src/streaming_processors.ts +202 -10
- package/src/transcribe.ts +89 -0
- package/src/validation.ts +285 -11
- package/src/web_midi.ts +1 -6
- package/src/worker.ts +18 -2
- package/src/worklet/audio_types.ts +37 -0
- package/src/worklet/engine-mixer-facade.ts +800 -32
- package/src/worklet/engine-node.ts +99 -29
- package/src/worklet/engine-offline.ts +14 -8
- package/src/worklet/engine-parameter-facade.ts +21 -0
- package/src/worklet/engine-processor.ts +332 -93
- package/src/worklet/engine-register.ts +32 -18
- package/src/worklet/engine-strips.ts +275 -9
- package/src/worklet/engine-sync.ts +20 -7
- package/src/worklet/engine.ts +394 -48
- package/src/worklet/guards.ts +195 -44
- package/src/worklet/messages.ts +229 -2
- package/src/worklet/mixer-processor.ts +117 -48
- package/src/worklet/playback-processor.ts +300 -0
- package/src/worklet/protocol.ts +82 -11
- package/src/worklet/voice-changer-processor.ts +17 -11
- package/src/worklet.ts +17 -0
- package/src/effects_transform.ts +0 -718
- package/src/mastering_repair.ts +0 -273
package/src/project_internal.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import { resolveEnumOrdinal } from './codes';
|
|
2
|
-
import { getSonareModule } from './module_state';
|
|
1
|
+
import { projectAutomationCurveCode, resolveEnumOrdinal } from './codes';
|
|
3
2
|
import type {
|
|
4
3
|
BuiltinSynthBinding,
|
|
4
|
+
SampleDesc,
|
|
5
|
+
SampleZoneDesc,
|
|
6
|
+
Sf2InstrumentConfig,
|
|
7
|
+
Sf2ProgramStatus,
|
|
8
|
+
SynthEnumTables,
|
|
9
|
+
SynthPatch,
|
|
10
|
+
} from './instrument_types';
|
|
11
|
+
import { getSonareModule } from './module_state';
|
|
12
|
+
import type {
|
|
13
|
+
AlignTakeToReferenceRequest,
|
|
14
|
+
AlignTakeToReferenceResult,
|
|
5
15
|
ProjectAssistSidecar,
|
|
16
|
+
ProjectAutomationCurve,
|
|
6
17
|
ProjectAutomationLaneDesc,
|
|
7
18
|
ProjectAutomationPoint,
|
|
8
19
|
ProjectAutomationTargetKind,
|
|
@@ -27,21 +38,87 @@ import type {
|
|
|
27
38
|
ProjectNotePairValidation,
|
|
28
39
|
ProjectSource,
|
|
29
40
|
ProjectTempoCandidate,
|
|
41
|
+
ProjectTempoOptions,
|
|
30
42
|
ProjectTempoSegment,
|
|
31
43
|
ProjectTimeSignatureSegment,
|
|
32
44
|
ProjectTrack,
|
|
33
45
|
ProjectTrackKind,
|
|
34
46
|
ProjectWarpMapDesc,
|
|
35
47
|
ProjectWarpMode,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
SynthEnumTables,
|
|
39
|
-
SynthPatch,
|
|
48
|
+
TranscribeOptions,
|
|
49
|
+
TranscribeResult,
|
|
40
50
|
} from './project_types';
|
|
51
|
+
// A value import, and this module's one import cycle: sample_bank.ts reaches
|
|
52
|
+
// back here for projectModule(). Both directions are read inside function
|
|
53
|
+
// bodies only, never while a module body runs, which is what makes the cycle
|
|
54
|
+
// safe. Reading SampleBank at module scope here breaks ONE import order and
|
|
55
|
+
// leaves the other working, so the property is pinned by
|
|
56
|
+
// tests/sample-bank-module-cycle.test.ts rather than left to review.
|
|
57
|
+
import { SampleBank } from './sample_bank';
|
|
58
|
+
import { assertNibble, assertU7, assertU32 } from './validation';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A synth binding as the embind layer takes it: the public `sampleBank` handle
|
|
62
|
+
* has already been resolved to the id the native registry looks the bank up by,
|
|
63
|
+
* because an embind class instance cannot travel inside a plain JS object the
|
|
64
|
+
* C++ side reads field by field.
|
|
65
|
+
*/
|
|
66
|
+
export type NativeSynthBinding = Omit<SynthPatch, 'sampleBank'> & { sampleBankId?: number };
|
|
67
|
+
|
|
68
|
+
// Embind handle for the C++ `SampleBankWasm` class, narrowed the same way as
|
|
69
|
+
// `WasmProject` below: it is registered next to the project, so a build without
|
|
70
|
+
// arrangement support has neither.
|
|
71
|
+
export interface WasmSampleBank {
|
|
72
|
+
readonly id: number;
|
|
73
|
+
addSample: (data: Float32Array, desc: SampleDesc) => number;
|
|
74
|
+
addZone: (setIndex: number, zone: Omit<SampleZoneDesc, 'setIndex'>) => void;
|
|
75
|
+
sampleCount: () => number;
|
|
76
|
+
setCount: () => number;
|
|
77
|
+
delete: () => void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Swaps a facade {@link SampleBank} in a synth patch descriptor for the id the
|
|
82
|
+
* embind layer looks the native bank up by, leaving every other field alone.
|
|
83
|
+
*
|
|
84
|
+
* Shared by the offline bounce and the realtime engine so `sampleBank` means
|
|
85
|
+
* the same thing on both. It lives in this internal module rather than beside
|
|
86
|
+
* the class because it hands out an internal identity that no caller has a use
|
|
87
|
+
* for, and the entry point must not re-export it: a facade symbol with no C
|
|
88
|
+
* counterpart is an active parity finding.
|
|
89
|
+
*
|
|
90
|
+
* The cast is the only one of its kind: `released` is private, and TypeScript's
|
|
91
|
+
* private is a compile-time rule, so reading it once here beats widening the
|
|
92
|
+
* class with a method the parity tool would then read as a facade op.
|
|
93
|
+
*/
|
|
94
|
+
export function normalizeSynthInstrument(patch: unknown): NativeSynthBinding | string {
|
|
95
|
+
if (patch === null || typeof patch !== 'object') {
|
|
96
|
+
// A preset-name string — and, at runtime, anything else — reaches the
|
|
97
|
+
// embind layer unchanged, which is where such a value is validated.
|
|
98
|
+
return patch as NativeSynthBinding | string;
|
|
99
|
+
}
|
|
100
|
+
const { sampleBank, ...rest } = patch as SynthPatch;
|
|
101
|
+
if (!sampleBank) {
|
|
102
|
+
// Omitted, and at runtime an explicit null: both mean no bank, which a
|
|
103
|
+
// sample patch renders as silence.
|
|
104
|
+
return rest;
|
|
105
|
+
}
|
|
106
|
+
if (!(sampleBank instanceof SampleBank)) {
|
|
107
|
+
throw new TypeError('sampleBank must be a SampleBank instance');
|
|
108
|
+
}
|
|
109
|
+
if ((sampleBank as unknown as { released: boolean }).released) {
|
|
110
|
+
// The id outlives the handle, so without this the native registry would be
|
|
111
|
+
// the only thing that notices — and with a different error class than Node.
|
|
112
|
+
throw new TypeError('sampleBank is destroyed');
|
|
113
|
+
}
|
|
114
|
+
return { ...rest, sampleBankId: sampleBank.nativeId };
|
|
115
|
+
}
|
|
41
116
|
|
|
42
|
-
// Embind handle for the C++ `ProjectWasm` class.
|
|
43
|
-
//
|
|
44
|
-
// module is
|
|
117
|
+
// Embind handle for the C++ `ProjectWasm` class. `SonareModule` describes the
|
|
118
|
+
// raw module's free functions and does not carry bound-class handles, so the
|
|
119
|
+
// module is narrowed through this shape here — which is also where the
|
|
120
|
+
// arrangement surface is probed for, since a build without arrangement support
|
|
121
|
+
// registers neither the class nor its free functions.
|
|
45
122
|
export interface WasmProject {
|
|
46
123
|
toJson: () => string;
|
|
47
124
|
setSampleRate: (sampleRate: number) => void;
|
|
@@ -73,9 +150,9 @@ export interface WasmProject {
|
|
|
73
150
|
events: ReadonlyArray<ProjectMidiEvent | readonly [number, number, number]>,
|
|
74
151
|
) => void;
|
|
75
152
|
importSmf: (data: Uint8Array) => number;
|
|
76
|
-
exportSmf: () => Uint8Array
|
|
153
|
+
exportSmf: () => Uint8Array<ArrayBuffer>;
|
|
77
154
|
importClipFile: (data: Uint8Array) => number;
|
|
78
|
-
exportClipFile: () => Uint8Array
|
|
155
|
+
exportClipFile: () => Uint8Array<ArrayBuffer>;
|
|
79
156
|
setProgram: (clipId: number, program: number, bank: number) => void;
|
|
80
157
|
setProgramOnChannel: (
|
|
81
158
|
clipId: number,
|
|
@@ -89,12 +166,23 @@ export interface WasmProject {
|
|
|
89
166
|
previewMidiFxCount: (clipId: number, configJson: string) => number;
|
|
90
167
|
setMidiFx: (clipId: number, configJson: string) => void;
|
|
91
168
|
validateMidiNotes: (clipId: number) => ProjectNotePairValidation;
|
|
92
|
-
|
|
169
|
+
transcribeToClip: (
|
|
170
|
+
clipId: number,
|
|
171
|
+
samples: Float32Array,
|
|
172
|
+
sampleRate: number,
|
|
173
|
+
config: TranscribeOptions,
|
|
174
|
+
) => number;
|
|
175
|
+
analyzeTempo: (
|
|
176
|
+
audio: Float32Array,
|
|
177
|
+
sampleRate: number,
|
|
178
|
+
options: ProjectTempoOptions | undefined,
|
|
179
|
+
) => ProjectTempoCandidate[];
|
|
93
180
|
autoTempo: (
|
|
94
181
|
audio: Float32Array,
|
|
95
182
|
sampleRate: number,
|
|
96
183
|
candidateIndex: number,
|
|
97
184
|
applyTimeSignatures: boolean,
|
|
185
|
+
options: ProjectTempoOptions | undefined,
|
|
98
186
|
) => number;
|
|
99
187
|
snapToGrid: (ppq: number, strength: number, division: number) => number;
|
|
100
188
|
compile: () => ProjectCompileResult;
|
|
@@ -104,7 +192,7 @@ export interface WasmProject {
|
|
|
104
192
|
options: ProjectBounceOptions,
|
|
105
193
|
) => Float32Array;
|
|
106
194
|
bounceWithSynthInstrument: (
|
|
107
|
-
bindings:
|
|
195
|
+
bindings: NativeSynthBinding | string | ReadonlyArray<NativeSynthBinding | string> | undefined,
|
|
108
196
|
options: ProjectBounceOptions,
|
|
109
197
|
) => Float32Array;
|
|
110
198
|
loadSoundFont: (data: Uint8Array) => void;
|
|
@@ -177,6 +265,8 @@ export interface WasmProject {
|
|
|
177
265
|
clipCount: () => number;
|
|
178
266
|
sourceCount: () => number;
|
|
179
267
|
tempoSegmentCount: () => number;
|
|
268
|
+
tempoSegmentByIndex: (index: number) => ProjectTempoSegment;
|
|
269
|
+
timeSignatureByIndex: (index: number) => ProjectTimeSignatureSegment;
|
|
180
270
|
timeSignatureCount: () => number;
|
|
181
271
|
setTempoSegments: (segments: ReadonlyArray<ProjectTempoSegment>) => void;
|
|
182
272
|
setTimeSignatures: (segments: ReadonlyArray<ProjectTimeSignatureSegment>) => void;
|
|
@@ -190,9 +280,14 @@ export interface ProjectModule {
|
|
|
190
280
|
fromJson: (json: string) => WasmProject;
|
|
191
281
|
fromJsonWithDiagnostics: (json: string) => { project: WasmProject; diagnostics: string };
|
|
192
282
|
};
|
|
283
|
+
SampleBank: { new (): WasmSampleBank };
|
|
193
284
|
projectAbiVersion: () => number;
|
|
194
285
|
synthPresetNames: () => string[];
|
|
195
286
|
synthPresetPatch: (name: string) => SynthPatch;
|
|
287
|
+
synthGsDrumKitName: (program: number) => string | null;
|
|
288
|
+
synthGsDrumKitIsVoicedApart: (program: number) => number;
|
|
289
|
+
synthGsVariationIsVoicedApart: (bank: number, program: number) => number;
|
|
290
|
+
controllerProfileNames: () => string[];
|
|
196
291
|
_synthEnumTables: () => SynthEnumTables;
|
|
197
292
|
_synthPatchRoundTrip: (patch: SynthPatch) => SynthPatch;
|
|
198
293
|
midiGmInstrumentName: (program: number) => string | null;
|
|
@@ -237,6 +332,21 @@ export interface ProjectModule {
|
|
|
237
332
|
group: number,
|
|
238
333
|
ppq: number,
|
|
239
334
|
) => ProjectMidiEvent | null;
|
|
335
|
+
transcribe: (
|
|
336
|
+
samples: Float32Array,
|
|
337
|
+
sampleRate: number,
|
|
338
|
+
tempoBpm: number | undefined,
|
|
339
|
+
config: TranscribeOptions,
|
|
340
|
+
) => TranscribeResult;
|
|
341
|
+
// Positional in the C ABI's own order minus the derived lengths and the out
|
|
342
|
+
// parameters. The request object is passed as `config` as well, the way
|
|
343
|
+
// `transcribe` passes its own: the reader only looks at the resolution keys.
|
|
344
|
+
alignTakeToReference: (
|
|
345
|
+
reference: Float32Array,
|
|
346
|
+
take: Float32Array,
|
|
347
|
+
sampleRate: number,
|
|
348
|
+
config: AlignTakeToReferenceRequest,
|
|
349
|
+
) => AlignTakeToReferenceResult;
|
|
240
350
|
}
|
|
241
351
|
|
|
242
352
|
export function projectModule(): ProjectModule {
|
|
@@ -247,20 +357,6 @@ export function projectModule(): ProjectModule {
|
|
|
247
357
|
return candidate as ProjectModule;
|
|
248
358
|
}
|
|
249
359
|
|
|
250
|
-
export function assertProjectU7(fnName: string, value: number, argName: string): number {
|
|
251
|
-
if (!Number.isInteger(value) || value < 0 || value > 127) {
|
|
252
|
-
throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 127]`);
|
|
253
|
-
}
|
|
254
|
-
return value;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export function assertProjectNibble(fnName: string, value: number, argName: string): number {
|
|
258
|
-
if (!Number.isInteger(value) || value < 0 || value > 15) {
|
|
259
|
-
throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 15]`);
|
|
260
|
-
}
|
|
261
|
-
return value;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
360
|
export function projectMidi1Event(
|
|
265
361
|
fnName: string,
|
|
266
362
|
ppq: number,
|
|
@@ -273,10 +369,10 @@ export function projectMidi1Event(
|
|
|
273
369
|
if (!Number.isFinite(ppq) || ppq < 0) {
|
|
274
370
|
throw new RangeError(`${fnName}: ppq must be a non-negative finite number`);
|
|
275
371
|
}
|
|
276
|
-
const g =
|
|
277
|
-
const ch =
|
|
278
|
-
const d1 =
|
|
279
|
-
const d2 =
|
|
372
|
+
const g = assertNibble(fnName, group, 'group');
|
|
373
|
+
const ch = assertNibble(fnName, channel, 'channel');
|
|
374
|
+
const d1 = assertU7(fnName, data1, 'data1');
|
|
375
|
+
const d2 = assertU7(fnName, data2, 'data2');
|
|
280
376
|
// UMP MIDI-1.0 channel-voice word (message type 0x2). Canonical layout is
|
|
281
377
|
// sonare::midi::make_midi1_* (C-ABI sonare_midi_*, which Python delegates to);
|
|
282
378
|
// this hand-written copy is locked against those words by the golden vectors
|
|
@@ -285,12 +381,6 @@ export function projectMidi1Event(
|
|
|
285
381
|
return { ppq, data0: word, data1: 0 };
|
|
286
382
|
}
|
|
287
383
|
|
|
288
|
-
export function assertProjectU32(fnName: string, value: number, argName: string): void {
|
|
289
|
-
if (!Number.isInteger(value) || value < 0 || value > 0xffffffff) {
|
|
290
|
-
throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 4294967295]`);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
384
|
export function assertProjectMidiEvents(
|
|
295
385
|
fnName: string,
|
|
296
386
|
events: ReadonlyArray<ProjectMidiEvent | readonly [number, number, number]>,
|
|
@@ -307,8 +397,8 @@ export function assertProjectMidiEvents(
|
|
|
307
397
|
if (!Number.isFinite(event[0]) || event[0] < 0) {
|
|
308
398
|
throw new RangeError(`${fnName}: ${prefix}.ppq must be a non-negative finite number`);
|
|
309
399
|
}
|
|
310
|
-
|
|
311
|
-
|
|
400
|
+
assertU32(fnName, event[1], `${prefix}.data0`);
|
|
401
|
+
assertU32(fnName, event[2], `${prefix}.data1`);
|
|
312
402
|
return;
|
|
313
403
|
}
|
|
314
404
|
if (event === null || typeof event !== 'object') {
|
|
@@ -317,9 +407,9 @@ export function assertProjectMidiEvents(
|
|
|
317
407
|
if (!Number.isFinite(event.ppq) || event.ppq < 0) {
|
|
318
408
|
throw new RangeError(`${fnName}: ${prefix}.ppq must be a non-negative finite number`);
|
|
319
409
|
}
|
|
320
|
-
|
|
410
|
+
assertU32(fnName, event.data0, `${prefix}.data0`);
|
|
321
411
|
if (event.data1 !== undefined) {
|
|
322
|
-
|
|
412
|
+
assertU32(fnName, event.data1, `${prefix}.data1`);
|
|
323
413
|
}
|
|
324
414
|
});
|
|
325
415
|
}
|
|
@@ -328,6 +418,23 @@ export function projectTrackKindValue(kind: ProjectTrackKind | undefined): numbe
|
|
|
328
418
|
return resolveEnumOrdinal(kind ?? 'audio', { audio: 0, midi: 1, aux: 2 }, 'project track kind');
|
|
329
419
|
}
|
|
330
420
|
|
|
421
|
+
/**
|
|
422
|
+
* Resolve a breakpoint's curve spelling to its ordinal before it crosses into
|
|
423
|
+
* embind, and fold the `curveToNext` alias onto `curve`.
|
|
424
|
+
*
|
|
425
|
+
* Mirrors the Node facade's `projectAutomationPointValue`: resolving here means
|
|
426
|
+
* an unknown spelling is a `RangeError` from the same table both packages
|
|
427
|
+
* declare, rather than a curve one binding renders and the other rejects.
|
|
428
|
+
*/
|
|
429
|
+
export function projectAutomationPointValue(point: ProjectAutomationPoint): ProjectAutomationPoint {
|
|
430
|
+
const curve = projectAutomationCurveCode(point.curve ?? point.curveToNext);
|
|
431
|
+
return {
|
|
432
|
+
...point,
|
|
433
|
+
curve: curve as ProjectAutomationCurve,
|
|
434
|
+
curveToNext: curve as ProjectAutomationCurve,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
331
438
|
export function projectAutomationTargetKindValue(kind: ProjectAutomationTargetKind): number {
|
|
332
439
|
return resolveEnumOrdinal(
|
|
333
440
|
kind,
|
|
@@ -339,7 +446,7 @@ export function projectAutomationTargetKindValue(kind: ProjectAutomationTargetKi
|
|
|
339
446
|
export function projectWarpModeValue(mode: ProjectWarpMode | undefined): number {
|
|
340
447
|
return resolveEnumOrdinal(
|
|
341
448
|
mode ?? 'off',
|
|
342
|
-
{ off: 0, repitch: 1, 'tempo-sync': 2 },
|
|
449
|
+
{ off: 0, repitch: 1, 'tempo-sync': 2, 'time-stretch': 3 },
|
|
343
450
|
'project warp mode',
|
|
344
451
|
);
|
|
345
452
|
}
|
package/src/project_synth.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { SynthEnumTables, SynthPatch } from './instrument_types';
|
|
1
2
|
import { projectModule } from './project_internal';
|
|
2
|
-
import type { SynthEnumTables, SynthPatch } from './project_types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Runtime ABI version of the flat project POD layout exposed by this WASM
|
|
@@ -20,6 +20,72 @@ export function synthPresetNames(): string[] {
|
|
|
20
20
|
return Array.from(projectModule().synthPresetNames());
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* GS rhythm-set name a rhythm part's `program` selects (`'Standard'`,
|
|
25
|
+
* `'Room'`, `'Jazz'`, ...), or `null` when the module's own tone map defines
|
|
26
|
+
* no set there.
|
|
27
|
+
*
|
|
28
|
+
* @remarks
|
|
29
|
+
* The answer is the module's own map, which is the newest one and reaches
|
|
30
|
+
* every set this build voices; a file selecting an older map reaches fewer.
|
|
31
|
+
*/
|
|
32
|
+
export function synthGsDrumKitName(program: number): string | null {
|
|
33
|
+
return projectModule().synthGsDrumKitName(program);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Whether the GS rhythm set at `program` is voiced apart from Standard: `true`
|
|
38
|
+
* when at least one drum note differs, `false` when the set renders exactly as
|
|
39
|
+
* Standard, `null` when no set sits at `program`.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* Derived by applying the set to every note's resolved patch and comparing, so
|
|
43
|
+
* the answer follows the voicing rather than a list that has to be kept in step
|
|
44
|
+
* with it. Four sets GS fills with one-shots share the Standard voicing
|
|
45
|
+
* deliberately, so a picker built from the set list alone offers four choices
|
|
46
|
+
* that change nothing — annotate or disable them with this.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const kits = Array.from({ length: 128 }, (_, program) => ({ program, name: synthGsDrumKitName(program) }))
|
|
51
|
+
* .filter((kit): kit is { program: number; name: string } => kit.name !== null)
|
|
52
|
+
* .map((kit) => ({ ...kit, placeholder: synthGsDrumKitIsVoicedApart(kit.program) === false }));
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export function synthGsDrumKitIsVoicedApart(program: number): boolean | null {
|
|
56
|
+
const r = projectModule().synthGsDrumKitIsVoicedApart(program);
|
|
57
|
+
return r < 0 ? null : r === 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Whether melodic Bank Select `bank` on `program` is voiced apart from the
|
|
62
|
+
* capital tone: `true` when the bank has a patch of its own, `false` when it
|
|
63
|
+
* resolves to the capital, `null` when either argument is outside `[0, 127]` —
|
|
64
|
+
* both are seven-bit MIDI values, so `128` is out of range rather than the drum
|
|
65
|
+
* bank here.
|
|
66
|
+
*
|
|
67
|
+
* @remarks
|
|
68
|
+
* Resolving an unvoiced variation to its capital is what GS specifies, so a
|
|
69
|
+
* `false` is correct behaviour rather than a gap — but only this query
|
|
70
|
+
* separates it from a bank that is voiced, which otherwise takes rendering both
|
|
71
|
+
* and comparing. Accepts the GS Bank Select MSB and the GM2 LSB alike, since
|
|
72
|
+
* both address the same variation.
|
|
73
|
+
*/
|
|
74
|
+
export function synthGsVariationIsVoicedApart(bank: number, program: number): boolean | null {
|
|
75
|
+
const r = projectModule().synthGsVariationIsVoicedApart(bank, program);
|
|
76
|
+
return r < 0 ? null : r === 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Controller-profile preset names (`'gm'`, `'breath'`, `'breath-aftertouch'`,
|
|
81
|
+
* `'mpe'`). These are the names {@link RealtimeEngine.setControllerProfile}
|
|
82
|
+
* accepts; an unknown one throws rather than resolving to a default.
|
|
83
|
+
*/
|
|
84
|
+
export function controllerProfileNames(): string[] {
|
|
85
|
+
// Array.from re-roots embind's vector as a plain, structured-cloneable Array.
|
|
86
|
+
return Array.from(projectModule().controllerProfileNames());
|
|
87
|
+
}
|
|
88
|
+
|
|
23
89
|
/**
|
|
24
90
|
* Fetch a named catalog preset as a {@link SynthPatch} (the preset name plus
|
|
25
91
|
* the wrapper-section values), so hosts can inspect a preset and tweak fields
|