@libraz/libsonare 1.4.1 → 1.5.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.
Files changed (66) hide show
  1. package/README.md +51 -20
  2. package/dist/index.d.ts +5416 -1
  3. package/dist/index.js +938 -583
  4. package/dist/index.js.map +1 -1
  5. package/dist/sonare.js +2 -2
  6. package/dist/sonare.wasm +0 -0
  7. package/dist/worklet.d.ts +1083 -5227
  8. package/dist/worklet.js +2683 -2451
  9. package/dist/worklet.js.map +1 -1
  10. package/package.json +4 -9
  11. package/src/clip_page_streamer.ts +298 -0
  12. package/src/effects_mastering.ts +85 -1089
  13. package/src/effects_transform.ts +286 -0
  14. package/src/effects_voice_change.ts +118 -0
  15. package/src/feature_music.ts +5 -2
  16. package/src/feature_spectrogram.ts +42 -2
  17. package/src/features.ts +1 -0
  18. package/src/index.ts +23 -0
  19. package/src/mastering_chain.ts +200 -0
  20. package/src/mastering_core.ts +248 -0
  21. package/src/mastering_dynamics.ts +105 -0
  22. package/src/mastering_repair.ts +161 -0
  23. package/src/mixer.ts +8 -0
  24. package/src/mixing_oneshot.ts +54 -0
  25. package/src/module_state.ts +1 -2
  26. package/src/project.ts +71 -1712
  27. package/src/project_class.ts +871 -0
  28. package/src/project_internal.ts +333 -0
  29. package/src/project_synth.ts +43 -0
  30. package/src/project_types.ts +570 -0
  31. package/src/public_types.ts +6 -1221
  32. package/src/public_types_acoustic.ts +115 -0
  33. package/src/public_types_mastering.ts +333 -0
  34. package/src/public_types_mixing.ts +97 -0
  35. package/src/public_types_music.ts +352 -0
  36. package/src/public_types_realtime.ts +163 -0
  37. package/src/public_types_spectral.ts +194 -0
  38. package/src/realtime_engine.ts +94 -0
  39. package/src/sonare.js.d.ts +117 -38
  40. package/src/stream_analyzer.ts +3 -0
  41. package/src/stream_types.ts +4 -0
  42. package/src/worklet/engine-automation.ts +73 -0
  43. package/src/worklet/engine-capture-facade.ts +80 -0
  44. package/src/worklet/engine-clips.ts +71 -0
  45. package/src/worklet/engine-markers.ts +93 -0
  46. package/src/worklet/engine-mixer-facade.ts +186 -0
  47. package/src/worklet/engine-node.ts +451 -0
  48. package/src/worklet/engine-offline.ts +162 -0
  49. package/src/worklet/engine-options.ts +13 -0
  50. package/src/worklet/engine-parameter-facade.ts +172 -0
  51. package/src/worklet/engine-processor.ts +764 -0
  52. package/src/worklet/engine-register.ts +136 -0
  53. package/src/worklet/engine-strips.ts +315 -0
  54. package/src/worklet/engine-sync.ts +94 -0
  55. package/src/worklet/engine-tempo-facade.ts +141 -0
  56. package/src/worklet/engine.ts +998 -0
  57. package/src/worklet/guards.ts +14 -1
  58. package/src/worklet/messages.ts +60 -20
  59. package/src/worklet/mixer-processor.ts +368 -0
  60. package/src/worklet/protocol.ts +3 -0
  61. package/src/worklet/voice-changer-processor.ts +246 -0
  62. package/src/worklet.ts +20 -3549
  63. package/dist/sonare-rt-module.js +0 -2
  64. package/dist/sonare-rt.js +0 -2
  65. package/dist/sonare-rt.wasm +0 -0
  66. package/src/sonare-rt.d.ts +0 -93
@@ -0,0 +1,200 @@
1
+ import { getSonareModule } from './module_state';
2
+ import type {
3
+ MasteringChainConfig,
4
+ MasteringChainResult,
5
+ MasteringPreset,
6
+ MasteringStereoChainResult,
7
+ } from './public_types';
8
+ import type { ProgressCallback } from './sonare.js';
9
+
10
+ function requireModule() {
11
+ return getSonareModule();
12
+ }
13
+
14
+ /**
15
+ * Apply a configurable mastering chain in WASM.
16
+ *
17
+ * @param samples - Audio samples (mono, float32)
18
+ * @param sampleRate - Sample rate in Hz (default: 22050)
19
+ * @param config - Chain stage configuration
20
+ * @returns Processed audio, loudness metadata, and applied stage names
21
+ */
22
+ export function masteringChain(
23
+ samples: Float32Array,
24
+ sampleRate = 22050,
25
+ config: MasteringChainConfig,
26
+ ): MasteringChainResult {
27
+ return requireModule().masteringChain(samples, sampleRate, config as Record<string, unknown>);
28
+ }
29
+
30
+ /**
31
+ * Apply a configurable stereo mastering chain in WASM.
32
+ *
33
+ * @param left - Left channel samples
34
+ * @param right - Right channel samples
35
+ * @param sampleRate - Sample rate in Hz
36
+ * @param config - Chain stage configuration
37
+ * @returns Processed stereo audio, loudness metadata, and applied stage names
38
+ */
39
+ export function masteringChainStereo(
40
+ left: Float32Array,
41
+ right: Float32Array,
42
+ sampleRate = 22050,
43
+ config: MasteringChainConfig,
44
+ ): MasteringStereoChainResult {
45
+ if (left.length !== right.length) {
46
+ throw new Error('Stereo channel lengths must match.');
47
+ }
48
+ return requireModule().masteringChainStereo(
49
+ left,
50
+ right,
51
+ sampleRate,
52
+ config as Record<string, unknown>,
53
+ );
54
+ }
55
+
56
+ /**
57
+ * Apply a configurable mastering chain in WASM with progress reporting.
58
+ *
59
+ * @param samples - Audio samples (mono, float32)
60
+ * @param sampleRate - Sample rate in Hz (default: 22050)
61
+ * @param config - Chain stage configuration
62
+ * @param onProgress - Progress callback (progress: 0-1, stage: string)
63
+ * @returns Processed audio, loudness metadata, and applied stage names
64
+ */
65
+ export function masteringChainWithProgress(
66
+ samples: Float32Array,
67
+ sampleRate = 22050,
68
+ config: MasteringChainConfig,
69
+ onProgress: ProgressCallback,
70
+ ): MasteringChainResult {
71
+ return requireModule().masteringChainWithProgress(
72
+ samples,
73
+ sampleRate,
74
+ config as Record<string, unknown>,
75
+ onProgress,
76
+ );
77
+ }
78
+
79
+ /**
80
+ * Apply a configurable stereo mastering chain in WASM with progress reporting.
81
+ *
82
+ * @param left - Left channel samples
83
+ * @param right - Right channel samples
84
+ * @param sampleRate - Sample rate in Hz
85
+ * @param config - Chain stage configuration
86
+ * @param onProgress - Progress callback (progress: 0-1, stage: string)
87
+ * @returns Processed stereo audio, loudness metadata, and applied stage names
88
+ */
89
+ export function masteringChainStereoWithProgress(
90
+ left: Float32Array,
91
+ right: Float32Array,
92
+ sampleRate = 22050,
93
+ config: MasteringChainConfig,
94
+ onProgress: ProgressCallback,
95
+ ): MasteringStereoChainResult {
96
+ if (left.length !== right.length) {
97
+ throw new Error('Stereo channel lengths must match.');
98
+ }
99
+ return requireModule().masteringChainStereoWithProgress(
100
+ left,
101
+ right,
102
+ sampleRate,
103
+ config as Record<string, unknown>,
104
+ onProgress,
105
+ );
106
+ }
107
+
108
+ /**
109
+ * List built-in mastering preset identifiers.
110
+ *
111
+ * @returns Preset names in display order (e.g. "pop", "edm", "aiMusic")
112
+ */
113
+ export function masteringPresetNames(): MasteringPreset[] {
114
+ return Array.from(requireModule().masteringPresetNames()) as MasteringPreset[];
115
+ }
116
+
117
+ /**
118
+ * Apply a named mastering preset chain to mono audio.
119
+ *
120
+ * @param samples - Audio samples (mono, float32)
121
+ * @param sampleRate - Sample rate in Hz (default: 22050)
122
+ * @param presetName - Preset identifier from {@link masteringPresetNames}
123
+ * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.
124
+ * @returns Processed audio, loudness metadata, and applied stage names
125
+ */
126
+ export function masterAudio(
127
+ samples: Float32Array,
128
+ sampleRate = 22050,
129
+ presetName: MasteringPreset = 'pop',
130
+ overrides: Record<string, number | boolean> = {},
131
+ ): MasteringChainResult {
132
+ return requireModule().masterAudio(presetName, samples, sampleRate, overrides);
133
+ }
134
+
135
+ /**
136
+ * Apply a named mastering preset chain to stereo audio.
137
+ *
138
+ * @param left - Left channel samples
139
+ * @param right - Right channel samples
140
+ * @param sampleRate - Sample rate in Hz
141
+ * @param presetName - Preset identifier from {@link masteringPresetNames}
142
+ * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.
143
+ * @returns Processed stereo audio, loudness metadata, and applied stage names
144
+ */
145
+ export function masterAudioStereo(
146
+ left: Float32Array,
147
+ right: Float32Array,
148
+ sampleRate = 22050,
149
+ presetName: MasteringPreset = 'pop',
150
+ overrides: Record<string, number | boolean> = {},
151
+ ): MasteringStereoChainResult {
152
+ if (left.length !== right.length) {
153
+ throw new Error('Stereo channel lengths must match.');
154
+ }
155
+ return requireModule().masterAudioStereo(presetName, left, right, sampleRate, overrides);
156
+ }
157
+
158
+ /**
159
+ * Mono `masterAudio` with per-stage progress reporting. `onProgress` is invoked
160
+ * with `(progress, stage)` between each chain stage (progress is in [0,1]).
161
+ */
162
+ export function masterAudioWithProgress(
163
+ samples: Float32Array,
164
+ sampleRate = 22050,
165
+ presetName: MasteringPreset,
166
+ onProgress: ProgressCallback,
167
+ overrides: Record<string, number | boolean> | null = null,
168
+ ): MasteringChainResult {
169
+ return requireModule().masterAudioWithProgress(
170
+ presetName,
171
+ samples,
172
+ sampleRate,
173
+ overrides,
174
+ onProgress,
175
+ );
176
+ }
177
+
178
+ /**
179
+ * Stereo `masterAudio` with per-stage progress reporting.
180
+ */
181
+ export function masterAudioStereoWithProgress(
182
+ left: Float32Array,
183
+ right: Float32Array,
184
+ sampleRate = 22050,
185
+ presetName: MasteringPreset,
186
+ onProgress: ProgressCallback,
187
+ overrides: Record<string, number | boolean> | null = null,
188
+ ): MasteringStereoChainResult {
189
+ if (left.length !== right.length) {
190
+ throw new Error('Stereo channel lengths must match.');
191
+ }
192
+ return requireModule().masterAudioStereoWithProgress(
193
+ presetName,
194
+ left,
195
+ right,
196
+ sampleRate,
197
+ overrides,
198
+ onProgress,
199
+ );
200
+ }
@@ -0,0 +1,248 @@
1
+ import { getSonareModule } from './module_state';
2
+ import type {
3
+ MasteringOptions,
4
+ MasteringProcessorParams,
5
+ MasteringResult,
6
+ MasteringStereoResult,
7
+ PairAnalysis,
8
+ PairProcessor,
9
+ SoloProcessor,
10
+ StereoAnalysis,
11
+ StreamingPlatform,
12
+ } from './public_types';
13
+
14
+ function requireModule() {
15
+ return getSonareModule();
16
+ }
17
+
18
+ /**
19
+ * Apply mastering loudness normalization with a true-peak ceiling.
20
+ *
21
+ * @param samples - Audio samples (mono, float32)
22
+ * @param sampleRate - Sample rate in Hz (default: 22050)
23
+ * @param options - Loudness/ceiling settings ({@link MasteringOptions})
24
+ * @returns Processed audio and loudness metadata
25
+ */
26
+ export function mastering(
27
+ samples: Float32Array,
28
+ sampleRate = 22050,
29
+ options: MasteringOptions = {},
30
+ ): MasteringResult {
31
+ return requireModule().mastering(
32
+ samples,
33
+ sampleRate,
34
+ options.targetLufs ?? -14.0,
35
+ options.ceilingDb ?? -1.0,
36
+ options.truePeakOversample ?? 4,
37
+ options.releaseMs ?? 0, // 0 => library default (50 ms)
38
+ options.applyGainAtInputRate ?? false,
39
+ );
40
+ }
41
+
42
+ export function masteringProcessorNames(): SoloProcessor[] {
43
+ // embind hands back a vector whose constructor is not this realm's Array, so the
44
+ // result is not structured-cloneable (breaks postMessage to a Worker).
45
+ // Array.from() re-roots it as a plain Array. Same for the sibling *Names() below.
46
+ return Array.from(requireModule().masteringProcessorNames()) as SoloProcessor[];
47
+ }
48
+
49
+ /**
50
+ * Names of the insert processors the mastering chain can instantiate by name
51
+ * (`mastering::api::insert_factory_names`). Mirrors the C-ABI
52
+ * `sonare_mastering_insert_names` (which joins this list) as a `string[]`.
53
+ */
54
+ export function masteringInsertNames(): string[] {
55
+ return (
56
+ requireModule() as unknown as { masteringInsertNames: () => string[] }
57
+ ).masteringInsertNames();
58
+ }
59
+
60
+ /**
61
+ * Returns the camelCase parameter names a given insert / FX processor reads, for
62
+ * tooling/validation. Any key NOT in this list is silently ignored by the
63
+ * processor (and would be reported via {@link Mixer.sceneWarnings} when a scene
64
+ * carrying it is loaded). Band/sub-band processors enumerate their indexed
65
+ * `band{i}.<field>` keys. Returns an empty array for an unknown name (or one
66
+ * whose insert needs an unavailable build feature, e.g. FX).
67
+ *
68
+ * @param name - Insert processor name (see {@link masteringInsertNames}).
69
+ */
70
+ export function masteringInsertParamNames(name: string): string[] {
71
+ return Array.from(
72
+ (
73
+ requireModule() as unknown as { masteringInsertParamNames: (name: string) => string[] }
74
+ ).masteringInsertParamNames(name),
75
+ );
76
+ }
77
+
78
+ /** One realtime-automatable parameter of an insert processor. */
79
+ export interface MasteringInsertParamInfo {
80
+ /** JSON-key parameter name, as used in scene insert params. */
81
+ name: string;
82
+ /** Integer param id for realtime automation lanes / MIDI-CC binding. */
83
+ id: number;
84
+ /** Whether the param can be changed live from the audio thread. */
85
+ rtSafe: boolean;
86
+ }
87
+
88
+ /**
89
+ * Returns the realtime-automatable parameter descriptors for an insert / FX
90
+ * processor: each entry maps a JSON-key parameter name to the integer id used by
91
+ * realtime automation and reports whether it is realtime-safe. Unlike
92
+ * {@link masteringInsertParamNames} (every construction key), this lists only the
93
+ * realtime-controllable subset — the keys accepted by
94
+ * {@link RealtimeEngine.setTrackStripInsertParamByName}. Returns an empty array
95
+ * for an unknown name or a processor with no automatable parameters.
96
+ *
97
+ * @param name - Insert processor name (see {@link masteringInsertNames}).
98
+ */
99
+ export function masteringInsertParamInfo(name: string): MasteringInsertParamInfo[] {
100
+ const json = (
101
+ requireModule() as unknown as { masteringInsertParamInfo: (name: string) => string }
102
+ ).masteringInsertParamInfo(name);
103
+ return JSON.parse(json) as MasteringInsertParamInfo[];
104
+ }
105
+
106
+ /**
107
+ * How a processor handles a buffer with more than two channels (a surround
108
+ * bed). "multichannel" processes every plane in one call; "stereoPairOnly"
109
+ * operates on the front L/R pair and passes any surround planes through dry.
110
+ * "perChannel"/"passthrough" are reserved and unused by the current catalog.
111
+ */
112
+ export type MasteringChannelPolicy =
113
+ | 'multichannel'
114
+ | 'stereoPairOnly'
115
+ | 'perChannel'
116
+ | 'passthrough';
117
+
118
+ /** One processor's realtime/offline/pair classification in the catalog. */
119
+ export interface MasteringProcessorCatalogEntry {
120
+ /** Processor id (the name used for scene inserts / named processors). */
121
+ id: string;
122
+ /**
123
+ * Primary classification, by precedence pair > realtime > offline: "pair" for
124
+ * two-input match.* processors, "realtime" for ids that build as a realtime
125
+ * scene insert, "offline" for whole-file-only processors.
126
+ */
127
+ kind: 'realtime' | 'offline' | 'pair';
128
+ /** True exactly for ids that always succeed as a realtime scene insert. */
129
+ realtimeInsertable: boolean;
130
+ /** True for processors with no mono implementation (stereo-only). */
131
+ stereoOnly: boolean;
132
+ /**
133
+ * How the mixer wraps the processor on a >2-channel (surround) bus insert:
134
+ * "multichannel" (one full-buffer call) or "stereoPairOnly" (front L/R pair,
135
+ * surround planes passed through dry).
136
+ */
137
+ channelPolicy: MasteringChannelPolicy;
138
+ }
139
+
140
+ /**
141
+ * Returns the machine-readable classification catalog for every named processor
142
+ * id, merging the offline registry, the realtime insert factory, and the pair
143
+ * registry. Lets a host filter a processor picker by realtime insertability
144
+ * instead of offering ids the realtime strip would reject.
145
+ */
146
+ export function masteringProcessorCatalog(): MasteringProcessorCatalogEntry[] {
147
+ const json = (
148
+ requireModule() as unknown as { masteringProcessorCatalog: () => string }
149
+ ).masteringProcessorCatalog();
150
+ return JSON.parse(json) as MasteringProcessorCatalogEntry[];
151
+ }
152
+
153
+ export function masteringPairProcessorNames(): PairProcessor[] {
154
+ return Array.from(requireModule().masteringPairProcessorNames()) as PairProcessor[];
155
+ }
156
+
157
+ export function masteringPairAnalysisNames(): PairAnalysis[] {
158
+ return Array.from(requireModule().masteringPairAnalysisNames()) as PairAnalysis[];
159
+ }
160
+
161
+ export function masteringStereoAnalysisNames(): StereoAnalysis[] {
162
+ return Array.from(requireModule().masteringStereoAnalysisNames()) as StereoAnalysis[];
163
+ }
164
+
165
+ export function masteringProcess(
166
+ processorName: SoloProcessor,
167
+ samples: Float32Array,
168
+ sampleRate = 22050,
169
+ params: MasteringProcessorParams = {},
170
+ ): MasteringResult {
171
+ return requireModule().masteringProcess(processorName, samples, sampleRate, params);
172
+ }
173
+
174
+ export function masteringProcessStereo(
175
+ processorName: SoloProcessor,
176
+ left: Float32Array,
177
+ right: Float32Array,
178
+ sampleRate = 22050,
179
+ params: MasteringProcessorParams = {},
180
+ ): MasteringStereoResult {
181
+ if (left.length !== right.length) {
182
+ throw new Error('Stereo channel lengths must match.');
183
+ }
184
+ return requireModule().masteringProcessStereo(processorName, left, right, sampleRate, params);
185
+ }
186
+
187
+ /**
188
+ * Apply a two-input `match.*` processor. `source` and `reference` may have
189
+ * independent lengths — the match primitives consume each buffer at its own
190
+ * length.
191
+ */
192
+ export function masteringPairProcess(
193
+ processorName: PairProcessor,
194
+ source: Float32Array,
195
+ reference: Float32Array,
196
+ sampleRate = 22050,
197
+ params: MasteringProcessorParams = {},
198
+ ): MasteringResult {
199
+ return requireModule().masteringPairProcess(processorName, source, reference, sampleRate, params);
200
+ }
201
+
202
+ /**
203
+ * Analyze a `source` against a `reference` with a two-input analysis. The two
204
+ * buffers may have independent lengths.
205
+ */
206
+ export function masteringPairAnalyze(
207
+ analysisName: PairAnalysis,
208
+ source: Float32Array,
209
+ reference: Float32Array,
210
+ sampleRate = 22050,
211
+ params: MasteringProcessorParams = {},
212
+ ): string {
213
+ return requireModule().masteringPairAnalyze(analysisName, source, reference, sampleRate, params);
214
+ }
215
+
216
+ export function masteringStereoAnalyze(
217
+ analysisName: StereoAnalysis,
218
+ left: Float32Array,
219
+ right: Float32Array,
220
+ sampleRate = 22050,
221
+ params: MasteringProcessorParams = {},
222
+ ): string {
223
+ return requireModule().masteringStereoAnalyze(analysisName, left, right, sampleRate, params);
224
+ }
225
+
226
+ export function masteringAssistantSuggest(
227
+ samples: Float32Array,
228
+ sampleRate = 22050,
229
+ params: MasteringProcessorParams = {},
230
+ ): string {
231
+ return requireModule().masteringAssistantSuggest(samples, sampleRate, params);
232
+ }
233
+
234
+ export function masteringAudioProfile(
235
+ samples: Float32Array,
236
+ sampleRate = 22050,
237
+ params: MasteringProcessorParams = {},
238
+ ): string {
239
+ return requireModule().masteringAudioProfile(samples, sampleRate, params);
240
+ }
241
+
242
+ export function masteringStreamingPreview(
243
+ samples: Float32Array,
244
+ sampleRate = 22050,
245
+ platforms: StreamingPlatform[] = [],
246
+ ): string {
247
+ return requireModule().masteringStreamingPreview(samples, sampleRate, platforms);
248
+ }
@@ -0,0 +1,105 @@
1
+ import { getSonareModule } from './module_state';
2
+ import type { ValidateOptions } from './validation';
3
+ import { assertSamples } from './validation';
4
+
5
+ function requireModule() {
6
+ return getSonareModule();
7
+ }
8
+
9
+ // ============================================================================
10
+ // Mastering — offline dynamics processors (compressor / gate / transient_shaper)
11
+ // ============================================================================
12
+
13
+ /** Compressor sidechain detector mode. */
14
+ export type CompressorDetector = 'peak' | 'rms' | 'log_rms';
15
+
16
+ /** Options for `masteringDynamicsCompressor`. */
17
+ export interface CompressorOptions extends ValidateOptions {
18
+ thresholdDb?: number;
19
+ ratio?: number;
20
+ attackMs?: number;
21
+ releaseMs?: number;
22
+ kneeDb?: number;
23
+ makeupGainDb?: number;
24
+ autoMakeup?: boolean;
25
+ detector?: CompressorDetector | number;
26
+ sidechainHpfEnabled?: boolean;
27
+ sidechainHpfHz?: number;
28
+ pdrTimeMs?: number;
29
+ pdrReleaseScale?: number;
30
+ }
31
+
32
+ /** Options for `masteringDynamicsGate`. */
33
+ export interface GateOptions extends ValidateOptions {
34
+ thresholdDb?: number;
35
+ attackMs?: number;
36
+ releaseMs?: number;
37
+ rangeDb?: number;
38
+ holdMs?: number;
39
+ closeThresholdDb?: number;
40
+ keyHpfHz?: number;
41
+ }
42
+
43
+ /** Options for `masteringDynamicsTransientShaper`. */
44
+ export interface TransientShaperOptions extends ValidateOptions {
45
+ attackGainDb?: number;
46
+ sustainGainDb?: number;
47
+ fastAttackMs?: number;
48
+ fastReleaseMs?: number;
49
+ slowAttackMs?: number;
50
+ slowReleaseMs?: number;
51
+ sensitivity?: number;
52
+ maxGainDb?: number;
53
+ gainSmoothingMs?: number;
54
+ lookaheadMs?: number;
55
+ }
56
+
57
+ /** Result envelope returned by offline mastering dynamics processors. */
58
+ export interface DynamicsResult {
59
+ samples: Float32Array;
60
+ latencySamples: number;
61
+ }
62
+
63
+ const COMPRESSOR_DETECTOR_MAP: Record<CompressorDetector, number> = {
64
+ peak: 0,
65
+ rms: 1,
66
+ log_rms: 2,
67
+ };
68
+
69
+ /** Offline feed-forward compressor (soft knee, optional auto-makeup / sidechain HPF). */
70
+ export function masteringDynamicsCompressor(
71
+ samples: Float32Array,
72
+ sampleRate: number,
73
+ options: CompressorOptions = {},
74
+ ): DynamicsResult {
75
+ assertSamples('masteringDynamicsCompressor', samples, options.validate !== false);
76
+ const detector =
77
+ typeof options.detector === 'string'
78
+ ? COMPRESSOR_DETECTOR_MAP[options.detector]
79
+ : options.detector;
80
+ const opts: Record<string, unknown> = { ...options };
81
+ if (detector !== undefined) {
82
+ opts.detector = detector;
83
+ }
84
+ return requireModule().masteringDynamicsCompressor(samples, sampleRate, opts);
85
+ }
86
+
87
+ /** Offline noise gate (hysteresis, hold, optional key HPF). */
88
+ export function masteringDynamicsGate(
89
+ samples: Float32Array,
90
+ sampleRate: number,
91
+ options: GateOptions = {},
92
+ ): DynamicsResult {
93
+ assertSamples('masteringDynamicsGate', samples, options.validate !== false);
94
+ return requireModule().masteringDynamicsGate(samples, sampleRate, options);
95
+ }
96
+
97
+ /** Offline transient shaper (envelope-difference attack/sustain control). */
98
+ export function masteringDynamicsTransientShaper(
99
+ samples: Float32Array,
100
+ sampleRate: number,
101
+ options: TransientShaperOptions = {},
102
+ ): DynamicsResult {
103
+ assertSamples('masteringDynamicsTransientShaper', samples, options.validate !== false);
104
+ return requireModule().masteringDynamicsTransientShaper(samples, sampleRate, options);
105
+ }