@libraz/libsonare 1.7.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +6 -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 +873 -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 +477 -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 +129 -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 +3758 -1362
- 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 +457 -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 +652 -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 +510 -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 +164 -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 +850 -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 +3909 -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 +335 -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 +128 -0
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
- package/dist/worklet/engine-node.d.ts +81 -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 +68 -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 +73 -0
- package/dist/worklet/engine-strips.d.ts.map +1 -0
- package/dist/worklet/engine-sync.d.ts +37 -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 +397 -0
- package/dist/worklet/engine.d.ts.map +1 -0
- package/dist/worklet/guards.d.ts +47 -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 +323 -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 +2763 -501
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -12
- package/src/_effects_common.ts +17 -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 +97 -22
- package/src/effects_note_ops.ts +635 -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 +377 -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 +282 -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 +346 -32
- package/src/mastering_dynamics.ts +22 -11
- package/src/metering.ts +67 -24
- package/src/mixer.ts +212 -3
- 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 +268 -270
- package/src/public_types.ts +122 -3
- package/src/public_types_acoustic.ts +112 -3
- package/src/public_types_mastering.ts +254 -73
- package/src/public_types_mixing.ts +363 -1
- package/src/public_types_music.ts +312 -2
- package/src/public_types_playback.ts +195 -0
- package/src/public_types_realtime.ts +39 -7
- package/src/public_types_repair.ts +446 -0
- package/src/public_types_spectral.ts +487 -1
- package/src/quick_analysis.ts +203 -26
- package/src/realtime_engine.ts +711 -28
- 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 +1122 -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 +194 -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 +444 -10
- package/src/worklet/engine-node.ts +78 -26
- package/src/worklet/engine-offline.ts +14 -8
- package/src/worklet/engine-parameter-facade.ts +21 -0
- package/src/worklet/engine-processor.ts +272 -83
- package/src/worklet/engine-register.ts +32 -18
- package/src/worklet/engine-strips.ts +280 -9
- package/src/worklet/engine-sync.ts +14 -6
- package/src/worklet/engine.ts +365 -31
- package/src/worklet/guards.ts +140 -44
- package/src/worklet/messages.ts +227 -2
- package/src/worklet/mixer-processor.ts +109 -47
- package/src/worklet/playback-processor.ts +300 -0
- package/src/worklet/protocol.ts +53 -3
- 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/mastering_chain.ts
CHANGED
|
@@ -7,11 +7,170 @@ import type {
|
|
|
7
7
|
MasteringPreset,
|
|
8
8
|
} from './public_types';
|
|
9
9
|
import type { ProgressCallback } from './sonare.js';
|
|
10
|
+
import type { ValidateOptions } from './validation';
|
|
11
|
+
import { assertSamples } from './validation';
|
|
10
12
|
|
|
11
13
|
function requireModule() {
|
|
12
14
|
return getSonareModule();
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
export type NormalizeMode = 'peak' | 'rms';
|
|
18
|
+
|
|
19
|
+
// `context` is the calling entry point's name: the refusal is about that
|
|
20
|
+
// caller's argument, so naming a fixed one would send a normalizeStereo user
|
|
21
|
+
// looking at normalize.
|
|
22
|
+
function resolveNormalizeMode(value: unknown, context = 'normalize'): NormalizeMode {
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
return 'peak';
|
|
25
|
+
}
|
|
26
|
+
if (typeof value !== 'string') {
|
|
27
|
+
throw new TypeError(`${context}: mode must be the string 'peak' or 'rms'`);
|
|
28
|
+
}
|
|
29
|
+
if (value !== 'peak' && value !== 'rms') {
|
|
30
|
+
throw new RangeError(`${context}: mode must be the string 'peak' or 'rms'`);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface NormalizeRequest extends ValidateOptions {
|
|
36
|
+
samples: Float32Array;
|
|
37
|
+
sampleRate?: number;
|
|
38
|
+
targetDb?: number;
|
|
39
|
+
mode?: NormalizeMode;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Normalize audio to a target peak or RMS level.
|
|
44
|
+
*
|
|
45
|
+
* @param samples - Audio samples (mono, float32)
|
|
46
|
+
* @param sampleRate - Sample rate in Hz (default: 22050)
|
|
47
|
+
* @param targetDb - Finite target at or below 0 dBFS (default: 0 dB = full scale).
|
|
48
|
+
* For `mode: 'peak'`, this is the peak target; for `mode: 'rms'`, this is the RMS target.
|
|
49
|
+
* @param mode - Normalization mode: `'peak'` (default) or `'rms'`.
|
|
50
|
+
* @returns Normalized audio
|
|
51
|
+
*/
|
|
52
|
+
export function normalize(request: NormalizeRequest): Float32Array;
|
|
53
|
+
export function normalize(
|
|
54
|
+
samples: Float32Array,
|
|
55
|
+
sampleRate: number,
|
|
56
|
+
targetDb?: number,
|
|
57
|
+
options?: ValidateOptions,
|
|
58
|
+
): Float32Array;
|
|
59
|
+
export function normalize(
|
|
60
|
+
samples: Float32Array,
|
|
61
|
+
sampleRate: number,
|
|
62
|
+
targetDb?: number,
|
|
63
|
+
mode?: NormalizeMode,
|
|
64
|
+
options?: ValidateOptions,
|
|
65
|
+
): Float32Array;
|
|
66
|
+
export function normalize(
|
|
67
|
+
samples: Float32Array | NormalizeRequest,
|
|
68
|
+
sampleRate?: number,
|
|
69
|
+
targetDb = 0.0,
|
|
70
|
+
modeOrOptions: NormalizeMode | ValidateOptions = 'peak',
|
|
71
|
+
options: ValidateOptions = {},
|
|
72
|
+
): Float32Array {
|
|
73
|
+
if (
|
|
74
|
+
modeOrOptions !== undefined &&
|
|
75
|
+
modeOrOptions !== null &&
|
|
76
|
+
typeof modeOrOptions !== 'string' &&
|
|
77
|
+
typeof modeOrOptions !== 'object'
|
|
78
|
+
) {
|
|
79
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
80
|
+
}
|
|
81
|
+
if (modeOrOptions === null) {
|
|
82
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
83
|
+
}
|
|
84
|
+
const positionalOptions =
|
|
85
|
+
typeof modeOrOptions === 'object' && modeOrOptions !== null ? modeOrOptions : options;
|
|
86
|
+
const positionalMode = typeof modeOrOptions === 'string' ? modeOrOptions : undefined;
|
|
87
|
+
const request: NormalizeRequest =
|
|
88
|
+
samples instanceof Float32Array
|
|
89
|
+
? { samples, sampleRate, targetDb, mode: positionalMode, ...positionalOptions }
|
|
90
|
+
: samples;
|
|
91
|
+
assertSamples('normalize', request.samples, request.validate !== false);
|
|
92
|
+
const mode = resolveNormalizeMode(request.mode);
|
|
93
|
+
return requireModule().normalizeEx(
|
|
94
|
+
request.samples,
|
|
95
|
+
request.sampleRate ?? 22050,
|
|
96
|
+
request.targetDb ?? 0.0,
|
|
97
|
+
mode,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface NormalizeStereoRequest extends ValidateOptions {
|
|
102
|
+
left: Float32Array;
|
|
103
|
+
right: Float32Array;
|
|
104
|
+
sampleRate?: number;
|
|
105
|
+
targetDb?: number;
|
|
106
|
+
mode?: NormalizeMode;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** A normalized channel pair and the gain both channels were moved by. */
|
|
110
|
+
export interface NormalizeStereoResult {
|
|
111
|
+
left: Float32Array;
|
|
112
|
+
right: Float32Array;
|
|
113
|
+
/**
|
|
114
|
+
* One figure rather than a pair: the gain is one decision shared by both
|
|
115
|
+
* channels. Silence leaves the pair untouched and reports 0.
|
|
116
|
+
*/
|
|
117
|
+
appliedGainDb: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Normalize a stereo pair on a gain measured across both channels.
|
|
122
|
+
*
|
|
123
|
+
* Normalizing the two channels separately lifts the quieter one until the peaks
|
|
124
|
+
* match, which changes the balance rather than the level. The level here is read
|
|
125
|
+
* from the pair and the resulting gain goes to both channels, so the image is
|
|
126
|
+
* preserved: for `mode: 'peak'` the louder channel reaches `targetDb` and the
|
|
127
|
+
* other keeps its distance from it; for `mode: 'rms'` the quantity driven to
|
|
128
|
+
* `targetDb` is the root mean square over both channels' samples together — the
|
|
129
|
+
* quadratic mean of the per-channel figures, not their average — and the output
|
|
130
|
+
* is hard-clipped to [-1, 1].
|
|
131
|
+
*
|
|
132
|
+
* @param request.left - Left channel samples (float32)
|
|
133
|
+
* @param request.right - Right channel samples, same length as `left`
|
|
134
|
+
* @param request.sampleRate - Sample rate in Hz (default: 22050)
|
|
135
|
+
* @param request.targetDb - Finite target at or below 0 dBFS. Defaults to 0 for
|
|
136
|
+
* `mode: 'peak'` and -20 for `mode: 'rms'`, matching the library and the other
|
|
137
|
+
* language surfaces.
|
|
138
|
+
* @param request.mode - `'peak'` (default) or `'rms'`
|
|
139
|
+
* @returns The normalized pair and the shared gain in dB
|
|
140
|
+
* @throws RangeError when the two channels differ in length
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const { left, right, appliedGainDb } = normalizeStereo({
|
|
145
|
+
* left: leftSamples,
|
|
146
|
+
* right: rightSamples,
|
|
147
|
+
* sampleRate: 44100,
|
|
148
|
+
* targetDb: -1,
|
|
149
|
+
* });
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
export function normalizeStereo(request: NormalizeStereoRequest): NormalizeStereoResult {
|
|
153
|
+
assertSamples('normalizeStereo', request.left, request.validate !== false);
|
|
154
|
+
assertSamples('normalizeStereo', request.right, request.validate !== false);
|
|
155
|
+
if (request.left.length !== request.right.length) {
|
|
156
|
+
throw new RangeError('Stereo channel lengths must match.');
|
|
157
|
+
}
|
|
158
|
+
const mode = resolveNormalizeMode(request.mode, 'normalizeStereo');
|
|
159
|
+
// Mode-dependent, unlike the mono `normalize` on this surface, which defaults
|
|
160
|
+
// to 0 dB in both modes. 0 dBFS RMS is not a usable default -- the peaks sit
|
|
161
|
+
// well above the RMS, so every one of them clips -- and the library and the
|
|
162
|
+
// other surfaces all default RMS to -20. A new entry point takes the shared
|
|
163
|
+
// default rather than inheriting a surface-local one.
|
|
164
|
+
const targetDb = request.targetDb ?? (mode === 'rms' ? -20.0 : 0.0);
|
|
165
|
+
return requireModule().normalizeStereo(
|
|
166
|
+
request.left,
|
|
167
|
+
request.right,
|
|
168
|
+
request.sampleRate ?? 22050,
|
|
169
|
+
targetDb,
|
|
170
|
+
mode,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
15
174
|
/** Internal envelope selecting the core dotted-param parser in the embind layer. */
|
|
16
175
|
function canonicalChainConfig(config: MasteringChainConfig): Record<string, unknown> {
|
|
17
176
|
return { __flatParams: flattenChainConfig(config) };
|
|
@@ -279,6 +438,31 @@ export function masteringPresetNames(): MasteringPreset[] {
|
|
|
279
438
|
return Array.from(requireModule().masteringPresetNames()) as MasteringPreset[];
|
|
280
439
|
}
|
|
281
440
|
|
|
441
|
+
/**
|
|
442
|
+
* The flat `{key: number|boolean}` params of preset `preset`'s built-in chain
|
|
443
|
+
* configuration, in the same key space {@link masteringAssistantSuggestChain}
|
|
444
|
+
* returns. Passing this straight through as `overrides` to {@link masterAudio}
|
|
445
|
+
* reproduces the preset unchanged, bit for bit in the C++ core.
|
|
446
|
+
*
|
|
447
|
+
* @param preset - Preset identifier from {@link masteringPresetNames}.
|
|
448
|
+
* @throws For an unknown `preset`.
|
|
449
|
+
*/
|
|
450
|
+
export function masteringPresetParams(preset: MasteringPreset): Record<string, number | boolean> {
|
|
451
|
+
return requireModule().masteringPresetParams(preset);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* List the delivery targets the mastering assistant accepts as `targetPlatform`.
|
|
456
|
+
*
|
|
457
|
+
* Read from the library rather than from a list kept here, so a target added in
|
|
458
|
+
* the core is discoverable without a binding change.
|
|
459
|
+
*
|
|
460
|
+
* @returns Target names in index order (e.g. "streaming", "broadcast", "club")
|
|
461
|
+
*/
|
|
462
|
+
export function masteringPlatformNames(): string[] {
|
|
463
|
+
return Array.from(requireModule().masteringPlatformNames());
|
|
464
|
+
}
|
|
465
|
+
|
|
282
466
|
/**
|
|
283
467
|
* Apply a named mastering preset chain to mono audio.
|
|
284
468
|
*
|
package/src/mastering_core.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import { ErrorCode, SonareError } from './errors';
|
|
1
2
|
import { getSonareModule } from './module_state';
|
|
2
3
|
import type {
|
|
4
|
+
LoudnessMatchResult,
|
|
5
|
+
MasteringAssistantParams,
|
|
6
|
+
MasteringInsertParamChoice,
|
|
7
|
+
MasteringInsertSlot,
|
|
3
8
|
MasteringOptions,
|
|
4
9
|
MasteringProcessorParams,
|
|
5
10
|
MasteringResult,
|
|
@@ -11,6 +16,8 @@ import type {
|
|
|
11
16
|
StreamingPlatform,
|
|
12
17
|
} from './public_types';
|
|
13
18
|
|
|
19
|
+
export type { MasteringInsertParamChoice, MasteringInsertSlot };
|
|
20
|
+
|
|
14
21
|
function requireModule() {
|
|
15
22
|
return getSonareModule();
|
|
16
23
|
}
|
|
@@ -45,6 +52,15 @@ export interface MasteringPairProcessRequest {
|
|
|
45
52
|
params?: MasteringProcessorParams;
|
|
46
53
|
}
|
|
47
54
|
|
|
55
|
+
/** Canonical request form for {@link masteringAbMatchLoudness}. */
|
|
56
|
+
export interface MasteringAbMatchLoudnessRequest {
|
|
57
|
+
/** The take to gain-match. */
|
|
58
|
+
source: Float32Array;
|
|
59
|
+
/** The take whose loudness `source` is matched to; returned untouched. */
|
|
60
|
+
reference: Float32Array;
|
|
61
|
+
sampleRate?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
/** Canonical request form for a two-input match analysis. */
|
|
49
65
|
export interface MasteringPairAnalyzeRequest {
|
|
50
66
|
analysisName: PairAnalysis;
|
|
@@ -70,6 +86,13 @@ export interface MasteringSamplesParamsRequest {
|
|
|
70
86
|
params?: MasteringProcessorParams;
|
|
71
87
|
}
|
|
72
88
|
|
|
89
|
+
/** Canonical request form for the assistant, whose params carry a target platform. */
|
|
90
|
+
export interface MasteringAssistantParamsRequest {
|
|
91
|
+
samples: Float32Array;
|
|
92
|
+
sampleRate?: number;
|
|
93
|
+
params?: MasteringAssistantParams;
|
|
94
|
+
}
|
|
95
|
+
|
|
73
96
|
/** Canonical request form for streaming-platform preview. */
|
|
74
97
|
export interface MasteringStreamingPreviewRequest {
|
|
75
98
|
samples: Float32Array;
|
|
@@ -85,6 +108,14 @@ export interface MasteringStereoParamsRequest {
|
|
|
85
108
|
params?: MasteringProcessorParams;
|
|
86
109
|
}
|
|
87
110
|
|
|
111
|
+
/** Stereo counterpart of {@link MasteringAssistantParamsRequest}. */
|
|
112
|
+
export interface MasteringAssistantStereoParamsRequest {
|
|
113
|
+
left: Float32Array;
|
|
114
|
+
right: Float32Array;
|
|
115
|
+
sampleRate?: number;
|
|
116
|
+
params?: MasteringAssistantParams;
|
|
117
|
+
}
|
|
118
|
+
|
|
88
119
|
/** Canonical request form for the stereo streaming-platform preview. */
|
|
89
120
|
export interface MasteringStreamingPreviewStereoRequest {
|
|
90
121
|
left: Float32Array;
|
|
@@ -137,9 +168,7 @@ export function masteringProcessorNames(): SoloProcessor[] {
|
|
|
137
168
|
* `sonare_mastering_insert_names` (which joins this list) as a `string[]`.
|
|
138
169
|
*/
|
|
139
170
|
export function masteringInsertNames(): string[] {
|
|
140
|
-
return (
|
|
141
|
-
requireModule() as unknown as { masteringInsertNames: () => string[] }
|
|
142
|
-
).masteringInsertNames();
|
|
171
|
+
return requireModule().masteringInsertNames();
|
|
143
172
|
}
|
|
144
173
|
|
|
145
174
|
/**
|
|
@@ -153,43 +182,165 @@ export function masteringInsertNames(): string[] {
|
|
|
153
182
|
* @param name - Insert processor name (see {@link masteringInsertNames}).
|
|
154
183
|
*/
|
|
155
184
|
export function masteringInsertParamNames(name: string): string[] {
|
|
156
|
-
return Array.from(
|
|
157
|
-
(
|
|
158
|
-
requireModule() as unknown as { masteringInsertParamNames: (name: string) => string[] }
|
|
159
|
-
).masteringInsertParamNames(name),
|
|
160
|
-
);
|
|
185
|
+
return Array.from(requireModule().masteringInsertParamNames(name));
|
|
161
186
|
}
|
|
162
187
|
|
|
163
|
-
/**
|
|
188
|
+
/**
|
|
189
|
+
* One parameter an insert processor's construction reads, whether or not it
|
|
190
|
+
* is realtime-automatable.
|
|
191
|
+
*/
|
|
164
192
|
export interface MasteringInsertParamInfo {
|
|
165
193
|
/** JSON-key parameter name, as used in scene insert params. */
|
|
166
194
|
name: string;
|
|
167
|
-
/**
|
|
168
|
-
|
|
169
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Integer param id for realtime automation lanes / MIDI-CC binding, or null
|
|
197
|
+
* for a construction-only key with no automation target.
|
|
198
|
+
*/
|
|
199
|
+
id: number | null;
|
|
200
|
+
/** Whether the param can be changed live from the audio thread; false when `id` is null. */
|
|
170
201
|
rtSafe: boolean;
|
|
171
|
-
/**
|
|
172
|
-
|
|
202
|
+
/**
|
|
203
|
+
* The C++ type the processor's config builder reads the key as. `"enum"` is
|
|
204
|
+
* sent as the number in its `choices` entry; `"string"` / `"array"` (an
|
|
205
|
+
* embedded impulse response, a per-band list) is construction-only and
|
|
206
|
+
* reports null for `min`, `max`, `default` and `choices`.
|
|
207
|
+
*/
|
|
208
|
+
type: 'boolean' | 'number' | 'enum' | 'string' | 'array';
|
|
209
|
+
/**
|
|
210
|
+
* Smallest value construction accepts, or null when the catalog states no
|
|
211
|
+
* limit or `choices` is non-null. Measured, so it is a hard constraint
|
|
212
|
+
* rather than a UI range; see {@link CapabilityCatalogParameter} for what a
|
|
213
|
+
* measured bound does and does not promise.
|
|
214
|
+
*/
|
|
215
|
+
min: number | null;
|
|
216
|
+
/** Largest value construction accepts, or null when the catalog states no limit or `choices` is non-null. */
|
|
217
|
+
max: number | null;
|
|
218
|
+
/**
|
|
219
|
+
* Value the processor uses when the key is absent — the config struct's own
|
|
220
|
+
* field initializer, an enum as its number. Null for a param id with no
|
|
221
|
+
* construction key, a `"string"` / `"array"` key, or a construction key with
|
|
222
|
+
* no fallback.
|
|
223
|
+
*/
|
|
224
|
+
default: boolean | number | null;
|
|
225
|
+
/** Physical unit, or null when the parameter is unitless. */
|
|
226
|
+
unit: string | null;
|
|
227
|
+
/**
|
|
228
|
+
* The closed set of values construction accepts, in value order, or null
|
|
229
|
+
* when the accepted values are not a closed set. Non-null only for `"enum"`
|
|
230
|
+
* (every declared enumerator construction accepts) or a `"number"` key
|
|
231
|
+
* whose accepted integers have holes; `min` / `max` are then both null.
|
|
232
|
+
*/
|
|
233
|
+
choices: MasteringInsertParamChoice[] | null;
|
|
234
|
+
/**
|
|
235
|
+
* The {@link MasteringInsertSlot} this key belongs to, or null for a key that
|
|
236
|
+
* always exists.
|
|
237
|
+
*/
|
|
238
|
+
slot: string | null;
|
|
173
239
|
}
|
|
174
240
|
|
|
175
241
|
/**
|
|
176
|
-
* Returns
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
242
|
+
* Returns every parameter an insert / FX processor's construction reads,
|
|
243
|
+
* including construction-time-only keys with no realtime automation target.
|
|
244
|
+
* Entries come in two runs: first the processor's realtime automation
|
|
245
|
+
* targets in id order (the keys accepted by
|
|
246
|
+
* {@link RealtimeEngine.setTrackStripInsertParamByName}, `id` non-null); then,
|
|
247
|
+
* sorted by name, every other construction key with `id` null and `rtSafe`
|
|
248
|
+
* false. The name set matches {@link masteringInsertParamNames} plus any
|
|
249
|
+
* automation target construction does not read. Returns an empty array for an
|
|
250
|
+
* unknown name.
|
|
183
251
|
*
|
|
184
252
|
* @param name - Insert processor name (see {@link masteringInsertNames}).
|
|
185
253
|
*/
|
|
186
254
|
export function masteringInsertParamInfo(name: string): MasteringInsertParamInfo[] {
|
|
187
|
-
const json = (
|
|
188
|
-
requireModule() as unknown as { masteringInsertParamInfo: (name: string) => string }
|
|
189
|
-
).masteringInsertParamInfo(name);
|
|
255
|
+
const json = requireModule().masteringInsertParamInfo(name);
|
|
190
256
|
return JSON.parse(json) as MasteringInsertParamInfo[];
|
|
191
257
|
}
|
|
192
258
|
|
|
259
|
+
/** Latency and tail of one insert instance, in samples. */
|
|
260
|
+
export interface MasteringInsertTiming {
|
|
261
|
+
/** Latency in samples at the queried sample rate. */
|
|
262
|
+
latencySamples: number;
|
|
263
|
+
/** Audible decay tail in samples at the queried sample rate. */
|
|
264
|
+
tailSamples: number;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** One built-in amp-sim rig with its resolved starting configuration. */
|
|
268
|
+
export interface MasteringAmpPresetCatalogEntry {
|
|
269
|
+
/** Stable index used by the amp-sim `presetIndex` parameter. */
|
|
270
|
+
index: number;
|
|
271
|
+
/** Canonical preset identifier accepted by the amp-sim insert. */
|
|
272
|
+
name: string;
|
|
273
|
+
/** Effective values from the core preset, before sparse user overrides. */
|
|
274
|
+
params: Record<string, number | boolean>;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Returns the built-in amp-sim rigs and their resolved control values.
|
|
279
|
+
*
|
|
280
|
+
* The catalog is read-only metadata for hosts such as Studio. Persist only the
|
|
281
|
+
* preset index and explicit overrides in a project so future core updates can
|
|
282
|
+
* continue to define the canonical DSP configuration.
|
|
283
|
+
*/
|
|
284
|
+
export function masteringAmpPresetCatalog(): MasteringAmpPresetCatalogEntry[] {
|
|
285
|
+
const json = requireModule().masteringAmpPresetCatalog();
|
|
286
|
+
return JSON.parse(json) as MasteringAmpPresetCatalogEntry[];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Reject a `params` value {@link masteringInsertTiming} cannot serialize:
|
|
291
|
+
* anything other than a finite number or a boolean, naming the offending key.
|
|
292
|
+
* Booleans serialize as JSON booleans, not 0/1, since the C++ reader accepts
|
|
293
|
+
* `is_bool` alongside a number.
|
|
294
|
+
*/
|
|
295
|
+
function insertTimingParamsToJson(fnName: string, params: Record<string, number | boolean>) {
|
|
296
|
+
const out: Record<string, number | boolean> = {};
|
|
297
|
+
for (const [key, value] of Object.entries(params)) {
|
|
298
|
+
if (typeof value === 'boolean') {
|
|
299
|
+
out[key] = value;
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
303
|
+
throw new SonareError(
|
|
304
|
+
ErrorCode.InvalidParameter,
|
|
305
|
+
'InvalidParameter',
|
|
306
|
+
`${fnName}: params.${key} must be a finite number or boolean`,
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
out[key] = value;
|
|
310
|
+
}
|
|
311
|
+
return JSON.stringify(out);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Latency and tail of insert `name` built from `params` and prepared at
|
|
316
|
+
* `sampleRate` (`mastering::api::insert_timing`). Answers for the exact
|
|
317
|
+
* instance a scene or strip would build — an oversampled saturation path, a
|
|
318
|
+
* linear-phase crossover, a lookahead all change the reported latency. The
|
|
319
|
+
* capability catalog's `latencySamples` / `tailSamples` are this query at
|
|
320
|
+
* default parameters and 48 kHz. `effects.reverb.convolution` answers for its
|
|
321
|
+
* configuration without an impulse response: its latency is its fixed
|
|
322
|
+
* partition size and does not depend on one.
|
|
323
|
+
*
|
|
324
|
+
* A key `name`'s construction does not read is refused rather than ignored,
|
|
325
|
+
* because an ignored key would answer for a configuration the caller did not
|
|
326
|
+
* ask for.
|
|
327
|
+
*
|
|
328
|
+
* @param name - Insert processor name (see {@link masteringInsertNames}).
|
|
329
|
+
* @param params - Flat parameter values, keyed as in {@link masteringInsertParamInfo}.
|
|
330
|
+
* @param sampleRate - Rate the insert is prepared at.
|
|
331
|
+
* @throws For an unknown `name`, a key the insert does not read, a value its
|
|
332
|
+
* construction or `prepare` refuses, or a `params` value that is not a
|
|
333
|
+
* finite number or boolean.
|
|
334
|
+
*/
|
|
335
|
+
export function masteringInsertTiming(
|
|
336
|
+
name: string,
|
|
337
|
+
params: Record<string, number | boolean>,
|
|
338
|
+
sampleRate: number,
|
|
339
|
+
): MasteringInsertTiming {
|
|
340
|
+
const json = insertTimingParamsToJson('masteringInsertTiming', params);
|
|
341
|
+
return requireModule().masteringInsertTiming(name, json, sampleRate);
|
|
342
|
+
}
|
|
343
|
+
|
|
193
344
|
/**
|
|
194
345
|
* How a processor handles a buffer with more than two channels (a surround
|
|
195
346
|
* bed). "multichannel" processes every plane in one call; "stereoPairOnly"
|
|
@@ -205,6 +356,25 @@ export type MasteringChannelPolicy =
|
|
|
205
356
|
/** Coarse algorithmic work estimate for a realtime insert; not a benchmark. */
|
|
206
357
|
export type MasteringRealtimeCost = 'low' | 'moderate' | 'high';
|
|
207
358
|
|
|
359
|
+
/**
|
|
360
|
+
* Catalog grouping for a processor picker, derived from the id's prefix
|
|
361
|
+
* ("eq.*" -> "eq", "match.*" -> "reference"); anything unprefixed is "other".
|
|
362
|
+
*/
|
|
363
|
+
export type MasteringProcessorCategory =
|
|
364
|
+
| 'dynamics'
|
|
365
|
+
| 'effects'
|
|
366
|
+
| 'eq'
|
|
367
|
+
| 'final'
|
|
368
|
+
| 'maximizer'
|
|
369
|
+
| 'multiband'
|
|
370
|
+
| 'other'
|
|
371
|
+
| 'reference'
|
|
372
|
+
| 'repair'
|
|
373
|
+
| 'saturation'
|
|
374
|
+
| 'spectral'
|
|
375
|
+
| 'stereo'
|
|
376
|
+
| 'utility';
|
|
377
|
+
|
|
208
378
|
/** One processor's realtime/offline/pair classification in the catalog. */
|
|
209
379
|
export interface MasteringProcessorCatalogEntry {
|
|
210
380
|
/** Processor id (the name used for scene inserts / named processors). */
|
|
@@ -237,6 +407,19 @@ export interface MasteringProcessorCatalogEntry {
|
|
|
237
407
|
* surround planes passed through dry).
|
|
238
408
|
*/
|
|
239
409
|
channelPolicy: MasteringChannelPolicy;
|
|
410
|
+
/** Grouping for a processor picker; see {@link MasteringProcessorCategory}. */
|
|
411
|
+
category: MasteringProcessorCategory;
|
|
412
|
+
/**
|
|
413
|
+
* The processor's construction parameters, the same list
|
|
414
|
+
* {@link masteringInsertParamInfo} returns. Empty for entries that are not
|
|
415
|
+
* realtime-insertable.
|
|
416
|
+
*/
|
|
417
|
+
params: MasteringInsertParamInfo[];
|
|
418
|
+
/**
|
|
419
|
+
* The insert's conditional key groups in declaration order, named by each
|
|
420
|
+
* parameter's `slot`. Empty for entries that are not realtime-insertable.
|
|
421
|
+
*/
|
|
422
|
+
slots: MasteringInsertSlot[];
|
|
240
423
|
}
|
|
241
424
|
|
|
242
425
|
/**
|
|
@@ -246,9 +429,7 @@ export interface MasteringProcessorCatalogEntry {
|
|
|
246
429
|
* instead of offering ids the realtime strip would reject.
|
|
247
430
|
*/
|
|
248
431
|
export function masteringProcessorCatalog(): MasteringProcessorCatalogEntry[] {
|
|
249
|
-
const json = (
|
|
250
|
-
requireModule() as unknown as { masteringProcessorCatalog: () => string }
|
|
251
|
-
).masteringProcessorCatalog();
|
|
432
|
+
const json = requireModule().masteringProcessorCatalog();
|
|
252
433
|
return JSON.parse(json) as MasteringProcessorCatalogEntry[];
|
|
253
434
|
}
|
|
254
435
|
|
|
@@ -405,6 +586,36 @@ export function masteringPairAnalyze(
|
|
|
405
586
|
);
|
|
406
587
|
}
|
|
407
588
|
|
|
589
|
+
/**
|
|
590
|
+
* Gain-match `source` to `reference`'s integrated loudness, so an A/B between
|
|
591
|
+
* the two is not decided by level. `source` and `reference` may have
|
|
592
|
+
* independent lengths.
|
|
593
|
+
*
|
|
594
|
+
* The gain is applied with no upper bound and `matchedTruePeakDbtp` reports
|
|
595
|
+
* where that left the peak, rather than the call capping it: a headroom clamp
|
|
596
|
+
* would return `source` at its own loudness whenever it started near full
|
|
597
|
+
* scale. Both loudness values are non-finite for a silent or below-gate take,
|
|
598
|
+
* and `appliedGainDb` is then 0.
|
|
599
|
+
*
|
|
600
|
+
* @example
|
|
601
|
+
* ```ts
|
|
602
|
+
* const { samples, appliedGainDb, matchedTruePeakDbtp } = masteringAbMatchLoudness({
|
|
603
|
+
* source: take,
|
|
604
|
+
* reference: master,
|
|
605
|
+
* sampleRate: 48000,
|
|
606
|
+
* });
|
|
607
|
+
* ```
|
|
608
|
+
*/
|
|
609
|
+
export function masteringAbMatchLoudness(
|
|
610
|
+
request: MasteringAbMatchLoudnessRequest,
|
|
611
|
+
): LoudnessMatchResult {
|
|
612
|
+
return requireModule().masteringAbMatchLoudness(
|
|
613
|
+
request.source,
|
|
614
|
+
request.reference,
|
|
615
|
+
request.sampleRate ?? 22050,
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
|
|
408
619
|
export function masteringStereoAnalyze(request: MasteringStereoAnalyzeRequest): string;
|
|
409
620
|
export function masteringStereoAnalyze(
|
|
410
621
|
analysisName: StereoAnalysis,
|
|
@@ -439,16 +650,16 @@ export function masteringStereoAnalyze(
|
|
|
439
650
|
);
|
|
440
651
|
}
|
|
441
652
|
|
|
442
|
-
export function masteringAssistantSuggest(request:
|
|
653
|
+
export function masteringAssistantSuggest(request: MasteringAssistantParamsRequest): string;
|
|
443
654
|
export function masteringAssistantSuggest(
|
|
444
655
|
samples: Float32Array,
|
|
445
656
|
sampleRate?: number,
|
|
446
|
-
params?:
|
|
657
|
+
params?: MasteringAssistantParams,
|
|
447
658
|
): string;
|
|
448
659
|
export function masteringAssistantSuggest(
|
|
449
|
-
samples: Float32Array |
|
|
660
|
+
samples: Float32Array | MasteringAssistantParamsRequest,
|
|
450
661
|
sampleRate = 22050,
|
|
451
|
-
params:
|
|
662
|
+
params: MasteringAssistantParams = {},
|
|
452
663
|
): string {
|
|
453
664
|
const request = samples instanceof Float32Array ? { samples, sampleRate, params } : samples;
|
|
454
665
|
return requireModule().masteringAssistantSuggest(
|
|
@@ -458,6 +669,91 @@ export function masteringAssistantSuggest(
|
|
|
458
669
|
);
|
|
459
670
|
}
|
|
460
671
|
|
|
672
|
+
/**
|
|
673
|
+
* Suggest a mastering chain, as the flat `{key: number|boolean}` params map
|
|
674
|
+
* {@link masteringAssistantSuggest}'s `chainConfig` carries, without needing to
|
|
675
|
+
* pull it out of the full assistant document. The returned map can be passed
|
|
676
|
+
* straight through as `overrides` to {@link mastering} / {@link masterAudio}.
|
|
677
|
+
*/
|
|
678
|
+
export function masteringAssistantSuggestChain(
|
|
679
|
+
request: MasteringAssistantParamsRequest,
|
|
680
|
+
): Record<string, number | boolean> {
|
|
681
|
+
return requireModule().masteringAssistantSuggestChain(
|
|
682
|
+
request.samples,
|
|
683
|
+
request.sampleRate ?? 22050,
|
|
684
|
+
request.params ?? {},
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* The shape {@link masteringAudioProfile}'s JSON parses to.
|
|
690
|
+
*
|
|
691
|
+
* The profile crosses as a string, so nothing type-checks it on arrival; this
|
|
692
|
+
* declaration is what a conformance check compares against the paths the C++
|
|
693
|
+
* writer publishes, so a field added on one side and not the other fails there
|
|
694
|
+
* rather than reaching a caller as `undefined`.
|
|
695
|
+
*/
|
|
696
|
+
export interface MasteringAudioProfile {
|
|
697
|
+
durationSec: number;
|
|
698
|
+
bpm: number;
|
|
699
|
+
bpmConfidence: number;
|
|
700
|
+
loudness: {
|
|
701
|
+
integratedLufs: number;
|
|
702
|
+
lraLu: number;
|
|
703
|
+
truePeakDb: number;
|
|
704
|
+
crestFactorDb: number;
|
|
705
|
+
};
|
|
706
|
+
spectral: {
|
|
707
|
+
subRmsDb: number;
|
|
708
|
+
lowRmsDb: number;
|
|
709
|
+
lowMidRmsDb: number;
|
|
710
|
+
midRmsDb: number;
|
|
711
|
+
highMidRmsDb: number;
|
|
712
|
+
highRmsDb: number;
|
|
713
|
+
airRmsDb: number;
|
|
714
|
+
centroidHz: number;
|
|
715
|
+
flatness: number;
|
|
716
|
+
rolloffHz: number;
|
|
717
|
+
};
|
|
718
|
+
dynamics: {
|
|
719
|
+
shortTermLufsStd: number;
|
|
720
|
+
attackDensity: number;
|
|
721
|
+
sustainRatio: number;
|
|
722
|
+
};
|
|
723
|
+
/**
|
|
724
|
+
* What the repair detectors measured. `measured` is false when nothing ran —
|
|
725
|
+
* either `detectDefects` was not asked for or the input was too short — and
|
|
726
|
+
* every other field is then at its default rather than a reading.
|
|
727
|
+
*/
|
|
728
|
+
defects: {
|
|
729
|
+
measured: boolean;
|
|
730
|
+
clickCount: number;
|
|
731
|
+
clickRejected: number;
|
|
732
|
+
clickLongestRunSamples: number;
|
|
733
|
+
clickPerSecond: number;
|
|
734
|
+
crackleSampleCount: number;
|
|
735
|
+
crackleSampleFraction: number;
|
|
736
|
+
cracklePerSecond: number;
|
|
737
|
+
clipSampleCount: number;
|
|
738
|
+
clipRunCount: number;
|
|
739
|
+
clipLongestRunSamples: number;
|
|
740
|
+
clipSampleFraction: number;
|
|
741
|
+
clipFlatRunCount: number;
|
|
742
|
+
clipFlatSampleCount: number;
|
|
743
|
+
clipLongestFlatRunSamples: number;
|
|
744
|
+
clipFlatLevel: number;
|
|
745
|
+
noiseFloorDbfs: number;
|
|
746
|
+
noiseBandPeakDbfs: number;
|
|
747
|
+
noiseBandPeakIndex: number;
|
|
748
|
+
humFundamentalHz: number;
|
|
749
|
+
humFundamentalProminence: number;
|
|
750
|
+
humHarmonics: number;
|
|
751
|
+
humFundamentalDbfs: number;
|
|
752
|
+
humPeakHarmonicDbfs: number;
|
|
753
|
+
lateDecayRatioDb: number;
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
|
|
461
757
|
export function masteringAudioProfile(request: MasteringSamplesParamsRequest): string;
|
|
462
758
|
export function masteringAudioProfile(
|
|
463
759
|
samples: Float32Array,
|
|
@@ -503,7 +799,9 @@ export function masteringStreamingPreview(
|
|
|
503
799
|
* of the suggestion is built on the channel-summed program rather than a
|
|
504
800
|
* downmix that reads roughly 6 dB low.
|
|
505
801
|
*/
|
|
506
|
-
export function masteringAssistantSuggestStereo(
|
|
802
|
+
export function masteringAssistantSuggestStereo(
|
|
803
|
+
request: MasteringAssistantStereoParamsRequest,
|
|
804
|
+
): string {
|
|
507
805
|
return requireModule().masteringAssistantSuggestStereo(
|
|
508
806
|
request.left,
|
|
509
807
|
request.right,
|
|
@@ -512,6 +810,22 @@ export function masteringAssistantSuggestStereo(request: MasteringStereoParamsRe
|
|
|
512
810
|
);
|
|
513
811
|
}
|
|
514
812
|
|
|
813
|
+
/**
|
|
814
|
+
* Stereo counterpart of {@link masteringAssistantSuggestChain}: the flat
|
|
815
|
+
* `{key: number|boolean}` params map without the surrounding assistant
|
|
816
|
+
* document, ready to pass through as `overrides` to {@link masterAudioStereo}.
|
|
817
|
+
*/
|
|
818
|
+
export function masteringAssistantSuggestChainStereo(
|
|
819
|
+
request: MasteringAssistantStereoParamsRequest,
|
|
820
|
+
): Record<string, number | boolean> {
|
|
821
|
+
return requireModule().masteringAssistantSuggestChainStereo(
|
|
822
|
+
request.left,
|
|
823
|
+
request.right,
|
|
824
|
+
request.sampleRate ?? 22050,
|
|
825
|
+
request.params ?? {},
|
|
826
|
+
);
|
|
827
|
+
}
|
|
828
|
+
|
|
515
829
|
/**
|
|
516
830
|
* Mastering assistant profile of a stereo pair, as shared JSON.
|
|
517
831
|
*
|