@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.
Files changed (303) hide show
  1. package/NOTICE +178 -0
  2. package/README.md +26 -203
  3. package/dist/_chain_config.d.ts +14 -0
  4. package/dist/_chain_config.d.ts.map +1 -0
  5. package/dist/_effects_common.d.ts +7 -0
  6. package/dist/_effects_common.d.ts.map +1 -0
  7. package/dist/_feature_validation.d.ts +8 -0
  8. package/dist/_feature_validation.d.ts.map +1 -0
  9. package/dist/_fft_options.d.ts +24 -0
  10. package/dist/_fft_options.d.ts.map +1 -0
  11. package/dist/align_take.d.ts +50 -0
  12. package/dist/align_take.d.ts.map +1 -0
  13. package/dist/analysis.d.ts +29 -5840
  14. package/dist/analysis.d.ts.map +1 -0
  15. package/dist/analysis.js +874 -722
  16. package/dist/analysis.js.map +1 -1
  17. package/dist/analysis_helpers.d.ts +9 -0
  18. package/dist/analysis_helpers.d.ts.map +1 -0
  19. package/dist/audio.d.ts +163 -0
  20. package/dist/audio.d.ts.map +1 -0
  21. package/dist/clip_page_streamer.d.ts +133 -0
  22. package/dist/clip_page_streamer.d.ts.map +1 -0
  23. package/dist/codes.d.ts +44 -0
  24. package/dist/codes.d.ts.map +1 -0
  25. package/dist/effects_mastering.d.ts +23 -0
  26. package/dist/effects_mastering.d.ts.map +1 -0
  27. package/dist/effects_note_ops.d.ts +502 -0
  28. package/dist/effects_note_ops.d.ts.map +1 -0
  29. package/dist/effects_percussive.d.ts +185 -0
  30. package/dist/effects_percussive.d.ts.map +1 -0
  31. package/dist/effects_separation.d.ts +65 -0
  32. package/dist/effects_separation.d.ts.map +1 -0
  33. package/dist/effects_spectral.d.ts +28 -0
  34. package/dist/effects_spectral.d.ts.map +1 -0
  35. package/dist/effects_timepitch.d.ts +134 -0
  36. package/dist/effects_timepitch.d.ts.map +1 -0
  37. package/dist/effects_voice_change.d.ts +53 -0
  38. package/dist/effects_voice_change.d.ts.map +1 -0
  39. package/dist/errors.d.ts +51 -0
  40. package/dist/errors.d.ts.map +1 -0
  41. package/dist/feature_core.d.ts +341 -0
  42. package/dist/feature_core.d.ts.map +1 -0
  43. package/dist/feature_decompose.d.ts +278 -0
  44. package/dist/feature_decompose.d.ts.map +1 -0
  45. package/dist/feature_inverse.d.ts +128 -0
  46. package/dist/feature_inverse.d.ts.map +1 -0
  47. package/dist/feature_loudness.d.ts +66 -0
  48. package/dist/feature_loudness.d.ts.map +1 -0
  49. package/dist/feature_music.d.ts +307 -0
  50. package/dist/feature_music.d.ts.map +1 -0
  51. package/dist/feature_pitch.d.ts +108 -0
  52. package/dist/feature_pitch.d.ts.map +1 -0
  53. package/dist/feature_resample.d.ts +16 -0
  54. package/dist/feature_resample.d.ts.map +1 -0
  55. package/dist/feature_spectral.d.ts +137 -0
  56. package/dist/feature_spectral.d.ts.map +1 -0
  57. package/dist/feature_spectrogram.d.ts +198 -0
  58. package/dist/feature_spectrogram.d.ts.map +1 -0
  59. package/dist/features.d.ts +10 -0
  60. package/dist/features.d.ts.map +1 -0
  61. package/dist/hrtf/default.shrf +0 -0
  62. package/dist/index.d.ts +74 -7431
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +4173 -1621
  65. package/dist/index.js.map +1 -1
  66. package/dist/instrument_types.d.ts +517 -0
  67. package/dist/instrument_types.d.ts.map +1 -0
  68. package/dist/live_audio.d.ts +35 -0
  69. package/dist/live_audio.d.ts.map +1 -0
  70. package/dist/mastering_chain.d.ts +213 -0
  71. package/dist/mastering_chain.d.ts.map +1 -0
  72. package/dist/mastering_core.d.ts +483 -0
  73. package/dist/mastering_core.d.ts.map +1 -0
  74. package/dist/mastering_dynamics.d.ts +80 -0
  75. package/dist/mastering_dynamics.d.ts.map +1 -0
  76. package/dist/metering.d.ts +287 -0
  77. package/dist/metering.d.ts.map +1 -0
  78. package/dist/mixer.d.ts +464 -0
  79. package/dist/mixer.d.ts.map +1 -0
  80. package/dist/mixing_assistant.d.ts +62 -0
  81. package/dist/mixing_assistant.d.ts.map +1 -0
  82. package/dist/mixing_oneshot.d.ts +40 -0
  83. package/dist/mixing_oneshot.d.ts.map +1 -0
  84. package/dist/module_state.d.ts +15 -0
  85. package/dist/module_state.d.ts.map +1 -0
  86. package/dist/opfs_clip_pages.d.ts +28 -0
  87. package/dist/opfs_clip_pages.d.ts.map +1 -0
  88. package/dist/playback_renderer.d.ts +128 -0
  89. package/dist/playback_renderer.d.ts.map +1 -0
  90. package/dist/polyphony.d.ts +202 -0
  91. package/dist/polyphony.d.ts.map +1 -0
  92. package/dist/project.d.ts +8 -0
  93. package/dist/project.d.ts.map +1 -0
  94. package/dist/project_class.d.ts +562 -0
  95. package/dist/project_class.d.ts.map +1 -0
  96. package/dist/project_internal.d.ts +194 -0
  97. package/dist/project_internal.d.ts.map +1 -0
  98. package/dist/project_synth.d.ts +74 -0
  99. package/dist/project_synth.d.ts.map +1 -0
  100. package/dist/project_types.d.ts +654 -0
  101. package/dist/project_types.d.ts.map +1 -0
  102. package/dist/public_types.d.ts +185 -0
  103. package/dist/public_types.d.ts.map +1 -0
  104. package/dist/public_types_acoustic.d.ts +215 -0
  105. package/dist/public_types_acoustic.d.ts.map +1 -0
  106. package/dist/public_types_mastering.d.ts +528 -0
  107. package/dist/public_types_mastering.d.ts.map +1 -0
  108. package/dist/public_types_mixing.d.ts +436 -0
  109. package/dist/public_types_mixing.d.ts.map +1 -0
  110. package/dist/public_types_music.d.ts +619 -0
  111. package/dist/public_types_music.d.ts.map +1 -0
  112. package/dist/public_types_playback.d.ts +165 -0
  113. package/dist/public_types_playback.d.ts.map +1 -0
  114. package/dist/public_types_realtime.d.ts +174 -0
  115. package/dist/public_types_realtime.d.ts.map +1 -0
  116. package/dist/public_types_repair.d.ts +424 -0
  117. package/dist/public_types_repair.d.ts.map +1 -0
  118. package/dist/public_types_spectral.d.ts +697 -0
  119. package/dist/public_types_spectral.d.ts.map +1 -0
  120. package/dist/quick_analysis.d.ts +445 -0
  121. package/dist/quick_analysis.d.ts.map +1 -0
  122. package/dist/realtime_engine.d.ts +893 -0
  123. package/dist/realtime_engine.d.ts.map +1 -0
  124. package/dist/realtime_voice_changer.d.ts +158 -0
  125. package/dist/realtime_voice_changer.d.ts.map +1 -0
  126. package/dist/repair_dereverb.d.ts +187 -0
  127. package/dist/repair_dereverb.d.ts.map +1 -0
  128. package/dist/repair_impulsive.d.ts +186 -0
  129. package/dist/repair_impulsive.d.ts.map +1 -0
  130. package/dist/repair_noise.d.ts +239 -0
  131. package/dist/repair_noise.d.ts.map +1 -0
  132. package/dist/repair_trim.d.ts +123 -0
  133. package/dist/repair_trim.d.ts.map +1 -0
  134. package/dist/sample_bank.d.ts +84 -0
  135. package/dist/sample_bank.d.ts.map +1 -0
  136. package/dist/scale.d.ts +10 -0
  137. package/dist/scale.d.ts.map +1 -0
  138. package/dist/schemas/mixer-scene.schema.json +393 -0
  139. package/dist/schemas/playback-renderer-config.schema.json +392 -0
  140. package/dist/sonare-analysis.d.ts +8 -0
  141. package/dist/sonare-analysis.js +2 -2
  142. package/dist/sonare-analysis.wasm +0 -0
  143. package/dist/sonare.d.ts +3945 -0
  144. package/dist/sonare.js +2 -2
  145. package/dist/sonare.wasm +0 -0
  146. package/dist/stream_analyzer.d.ts +163 -0
  147. package/dist/stream_analyzer.d.ts.map +1 -0
  148. package/dist/stream_types.d.ts +214 -0
  149. package/dist/stream_types.d.ts.map +1 -0
  150. package/dist/streaming_mixing.d.ts +6 -0
  151. package/dist/streaming_mixing.d.ts.map +1 -0
  152. package/dist/streaming_processors.d.ts +340 -0
  153. package/dist/streaming_processors.d.ts.map +1 -0
  154. package/dist/transcribe.d.ts +77 -0
  155. package/dist/transcribe.d.ts.map +1 -0
  156. package/dist/validation.d.ts +140 -0
  157. package/dist/validation.d.ts.map +1 -0
  158. package/dist/web_midi.d.ts +77 -0
  159. package/dist/web_midi.d.ts.map +1 -0
  160. package/dist/worker.d.ts +5 -48
  161. package/dist/worker.d.ts.map +1 -0
  162. package/dist/worker.js +94 -41
  163. package/dist/worker.js.map +1 -1
  164. package/dist/worker_client.d.ts +96 -0
  165. package/dist/worker_client.d.ts.map +1 -0
  166. package/dist/worker_protocol.d.ts +43 -0
  167. package/dist/worker_protocol.d.ts.map +1 -0
  168. package/dist/worklet/audio_types.d.ts +21 -0
  169. package/dist/worklet/audio_types.d.ts.map +1 -0
  170. package/dist/worklet/engine-automation.d.ts +29 -0
  171. package/dist/worklet/engine-automation.d.ts.map +1 -0
  172. package/dist/worklet/engine-capture-facade.d.ts +35 -0
  173. package/dist/worklet/engine-capture-facade.d.ts.map +1 -0
  174. package/dist/worklet/engine-clips.d.ts +23 -0
  175. package/dist/worklet/engine-clips.d.ts.map +1 -0
  176. package/dist/worklet/engine-markers.d.ts +40 -0
  177. package/dist/worklet/engine-markers.d.ts.map +1 -0
  178. package/dist/worklet/engine-mixer-facade.d.ts +164 -0
  179. package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
  180. package/dist/worklet/engine-node.d.ts +83 -0
  181. package/dist/worklet/engine-node.d.ts.map +1 -0
  182. package/dist/worklet/engine-offline.d.ts +81 -0
  183. package/dist/worklet/engine-offline.d.ts.map +1 -0
  184. package/dist/worklet/engine-options.d.ts +12 -0
  185. package/dist/worklet/engine-options.d.ts.map +1 -0
  186. package/dist/worklet/engine-parameter-facade.d.ts +106 -0
  187. package/dist/worklet/engine-parameter-facade.d.ts.map +1 -0
  188. package/dist/worklet/engine-processor.d.ts +72 -0
  189. package/dist/worklet/engine-processor.d.ts.map +1 -0
  190. package/dist/worklet/engine-register.d.ts +2 -0
  191. package/dist/worklet/engine-register.d.ts.map +1 -0
  192. package/dist/worklet/engine-strips.d.ts +75 -0
  193. package/dist/worklet/engine-strips.d.ts.map +1 -0
  194. package/dist/worklet/engine-sync.d.ts +39 -0
  195. package/dist/worklet/engine-sync.d.ts.map +1 -0
  196. package/dist/worklet/engine-tempo-facade.d.ts +48 -0
  197. package/dist/worklet/engine-tempo-facade.d.ts.map +1 -0
  198. package/dist/worklet/engine.d.ts +418 -0
  199. package/dist/worklet/engine.d.ts.map +1 -0
  200. package/dist/worklet/guards.d.ts +53 -0
  201. package/dist/worklet/guards.d.ts.map +1 -0
  202. package/dist/worklet/messages.d.ts +710 -0
  203. package/dist/worklet/messages.d.ts.map +1 -0
  204. package/dist/worklet/mixer-processor.d.ts +46 -0
  205. package/dist/worklet/mixer-processor.d.ts.map +1 -0
  206. package/dist/worklet/playback-processor.d.ts +62 -0
  207. package/dist/worklet/playback-processor.d.ts.map +1 -0
  208. package/dist/worklet/protocol.d.ts +331 -0
  209. package/dist/worklet/protocol.d.ts.map +1 -0
  210. package/dist/worklet/voice-changer-processor.d.ts +41 -0
  211. package/dist/worklet/voice-changer-processor.d.ts.map +1 -0
  212. package/dist/worklet.d.ts +16 -2515
  213. package/dist/worklet.d.ts.map +1 -0
  214. package/dist/worklet.js +3200 -541
  215. package/dist/worklet.js.map +1 -1
  216. package/package.json +23 -12
  217. package/src/_effects_common.ts +47 -0
  218. package/src/_feature_validation.ts +34 -0
  219. package/src/_fft_options.ts +39 -0
  220. package/src/align_take.ts +64 -0
  221. package/src/analysis.ts +56 -3
  222. package/src/analysis_helpers.ts +7 -0
  223. package/src/audio.ts +106 -3
  224. package/src/codes.ts +39 -2
  225. package/src/effects_mastering.ts +101 -22
  226. package/src/effects_note_ops.ts +683 -0
  227. package/src/effects_percussive.ts +217 -0
  228. package/src/effects_separation.ts +150 -0
  229. package/src/effects_spectral.ts +60 -0
  230. package/src/effects_timepitch.ts +388 -0
  231. package/src/errors.ts +23 -1
  232. package/src/feature_core.ts +127 -2
  233. package/src/feature_decompose.ts +633 -0
  234. package/src/feature_inverse.ts +454 -0
  235. package/src/feature_loudness.ts +125 -0
  236. package/src/feature_music.ts +107 -14
  237. package/src/feature_pitch.ts +96 -1
  238. package/src/feature_spectral.ts +16 -611
  239. package/src/feature_spectrogram.ts +63 -450
  240. package/src/features.ts +36 -22
  241. package/src/index.ts +288 -30
  242. package/src/instrument_types.ts +645 -0
  243. package/src/live_audio.ts +27 -1
  244. package/src/mastering_chain.ts +184 -0
  245. package/src/mastering_core.ts +441 -32
  246. package/src/mastering_dynamics.ts +22 -11
  247. package/src/metering.ts +67 -24
  248. package/src/mixer.ts +251 -22
  249. package/src/mixing_assistant.ts +138 -0
  250. package/src/mixing_oneshot.ts +10 -5
  251. package/src/module_state.ts +24 -2
  252. package/src/playback_renderer.ts +252 -0
  253. package/src/polyphony.ts +279 -0
  254. package/src/project.ts +61 -24
  255. package/src/project_class.ts +450 -27
  256. package/src/project_internal.ts +149 -42
  257. package/src/project_synth.ts +67 -1
  258. package/src/project_types.ts +271 -271
  259. package/src/public_types.ts +122 -3
  260. package/src/public_types_acoustic.ts +112 -3
  261. package/src/public_types_mastering.ts +275 -73
  262. package/src/public_types_mixing.ts +363 -1
  263. package/src/public_types_music.ts +312 -2
  264. package/src/public_types_playback.ts +196 -0
  265. package/src/public_types_realtime.ts +39 -7
  266. package/src/public_types_repair.ts +446 -0
  267. package/src/public_types_spectral.ts +491 -5
  268. package/src/quick_analysis.ts +203 -26
  269. package/src/realtime_engine.ts +773 -34
  270. package/src/realtime_voice_changer.ts +55 -1
  271. package/src/repair_dereverb.ts +299 -0
  272. package/src/repair_impulsive.ts +395 -0
  273. package/src/repair_noise.ts +425 -0
  274. package/src/repair_trim.ts +226 -0
  275. package/src/sample_bank.ts +113 -0
  276. package/src/sonare.js.d.ts +1158 -30
  277. package/src/stream_analyzer.ts +36 -4
  278. package/src/stream_types.ts +37 -0
  279. package/src/streaming_mixing.ts +1 -1
  280. package/src/streaming_processors.ts +202 -10
  281. package/src/transcribe.ts +89 -0
  282. package/src/validation.ts +285 -11
  283. package/src/web_midi.ts +1 -6
  284. package/src/worker.ts +18 -2
  285. package/src/worklet/audio_types.ts +37 -0
  286. package/src/worklet/engine-mixer-facade.ts +800 -32
  287. package/src/worklet/engine-node.ts +99 -29
  288. package/src/worklet/engine-offline.ts +14 -8
  289. package/src/worklet/engine-parameter-facade.ts +21 -0
  290. package/src/worklet/engine-processor.ts +332 -93
  291. package/src/worklet/engine-register.ts +32 -18
  292. package/src/worklet/engine-strips.ts +275 -9
  293. package/src/worklet/engine-sync.ts +20 -7
  294. package/src/worklet/engine.ts +394 -48
  295. package/src/worklet/guards.ts +195 -44
  296. package/src/worklet/messages.ts +229 -2
  297. package/src/worklet/mixer-processor.ts +117 -48
  298. package/src/worklet/playback-processor.ts +300 -0
  299. package/src/worklet/protocol.ts +82 -11
  300. package/src/worklet/voice-changer-processor.ts +17 -11
  301. package/src/worklet.ts +17 -0
  302. package/src/effects_transform.ts +0 -718
  303. package/src/mastering_repair.ts +0 -273
@@ -48,6 +48,7 @@ export interface RealtimeVoiceChangerPlanarBuffer {
48
48
 
49
49
  export class RealtimeVoiceChanger {
50
50
  private changer: import('./sonare.js').WasmRealtimeVoiceChanger;
51
+ private released = false;
51
52
 
52
53
  /**
53
54
  * Creates a voice changer. Supplying `sampleRate` prepares it immediately,
@@ -63,7 +64,21 @@ export class RealtimeVoiceChanger {
63
64
  const module = getSonareModule();
64
65
  this.changer = module.createRealtimeVoiceChanger(config as Record<string, unknown> | string);
65
66
  if (sampleRate !== undefined) {
66
- this.changer.prepare(sampleRate, maxBlockSize, channels);
67
+ // `prepare` rejects a non-positive sample rate, a negative block size and
68
+ // a channel count outside [1, 2]. The handle is already allocated by
69
+ // then, and a throwing constructor leaves `this` unreachable, so release
70
+ // it here — embind has no GC finalizer, and a device-change handler that
71
+ // retries on failure would otherwise leak one whole DSP chain per attempt
72
+ // (retune ring, ISP limiter, reverb, scratch).
73
+ let prepared = false;
74
+ try {
75
+ this.changer.prepare(sampleRate, maxBlockSize, channels);
76
+ prepared = true;
77
+ } finally {
78
+ if (!prepared) {
79
+ this.changer.delete();
80
+ }
81
+ }
67
82
  }
68
83
  }
69
84
 
@@ -98,6 +113,35 @@ export class RealtimeVoiceChanger {
98
113
  return this.changer.latencySamples();
99
114
  }
100
115
 
116
+ /**
117
+ * Channel-blocks in which the chain discarded its own state because a
118
+ * non-finite value had reached it.
119
+ *
120
+ * Advisory telemetry, and the only thing that separates a degraded stream
121
+ * from a clean one. Every stage of this chain leaves an in-domain finite
122
+ * value where a non-finite one was — the input scrub and the
123
+ * inter-sample-peak limiter substitute silence, the sample-domain limiter
124
+ * folds an infinity onto its ceiling — so the output stays finite, in range
125
+ * and free of any error while carrying samples unrelated to the input. A
126
+ * non-zero count is what says the samples in between were not computed from
127
+ * what you supplied.
128
+ *
129
+ * Monotonic for the lifetime of the instance. The unit is one processed
130
+ * block, never a channel, so a stereo block that discards on both channels
131
+ * adds one and the number does not depend on a dimension you did not choose.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * changer.processInterleaved(block, 2);
136
+ * if (changer.nonFiniteDiscardCount() > 0) {
137
+ * // the audio just produced is not a function of `block`
138
+ * }
139
+ * ```
140
+ */
141
+ nonFiniteDiscardCount(): number {
142
+ return this.changer.nonFiniteDiscardCount();
143
+ }
144
+
101
145
  /**
102
146
  * Monotonically increases whenever {@link prepare} can replace the native
103
147
  * scratch buffers. Cached WASM heap views must be reacquired after it changes.
@@ -303,9 +347,19 @@ export class RealtimeVoiceChanger {
303
347
  };
304
348
  }
305
349
 
350
+ /** Releases the native handle. Idempotent, as the Node facade is. */
306
351
  delete(): void {
352
+ if (this.released) {
353
+ return;
354
+ }
355
+ this.released = true;
307
356
  this.changer.delete();
308
357
  }
358
+
359
+ /** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */
360
+ destroy(): void {
361
+ this.delete();
362
+ }
309
363
  }
310
364
 
311
365
  export function realtimeVoiceChangerPresetNames(): VoicePresetId[] {
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Reverberation repair, with its detector and the room-driven configuration.
3
+ */
4
+
5
+ import { getSonareModule } from './module_state';
6
+ import type { RoomEstimateResult } from './public_types_acoustic';
7
+ import type {
8
+ MasteringRepairDereverbClassicalLinkedResult,
9
+ MasteringRepairDereverbClassicalStereoResult,
10
+ ReverbDetection,
11
+ } from './public_types_repair';
12
+
13
+ function requireModule() {
14
+ return getSonareModule();
15
+ }
16
+
17
+ /** Options for `masteringRepairDereverbClassical`. */
18
+ export interface DereverbClassicalOptions {
19
+ threshold?: number;
20
+ attenuation?: number;
21
+ nFft?: number;
22
+ hopLength?: number;
23
+ t60Sec?: number;
24
+ lateDelayMs?: number;
25
+ overSubtraction?: number;
26
+ spectralFloor?: number;
27
+ wpeEnabled?: boolean;
28
+ wpeIterations?: number;
29
+ wpeTaps?: number;
30
+ wpeStrength?: number;
31
+ }
32
+
33
+ export interface MasteringRepairDereverbClassicalRequest extends DereverbClassicalOptions {
34
+ samples: Float32Array;
35
+ sampleRate: number;
36
+ }
37
+
38
+ /** Request form of `masteringRepairDereverbClassicalStereo`. */
39
+ export interface MasteringRepairDereverbClassicalStereoRequest extends DereverbClassicalOptions {
40
+ left: Float32Array;
41
+ right: Float32Array;
42
+ sampleRate?: number;
43
+ }
44
+
45
+ /** Request form of `masteringRepairDereverbClassicalLinked`. */
46
+ export interface MasteringRepairDereverbClassicalLinkedRequest extends DereverbClassicalOptions {
47
+ /** At least one channel; all the same length. */
48
+ channels: Float32Array[];
49
+ sampleRate?: number;
50
+ }
51
+
52
+ /** Request form of `masteringRepairDereverbConfigForRoom`. */
53
+ export interface MasteringRepairDereverbConfigForRoomRequest extends DereverbClassicalOptions {
54
+ /** The measured room, from `estimateRoom`. Only `volume` and `rt60Bands` are read. */
55
+ estimate: RoomEstimateResult;
56
+ }
57
+
58
+ /** Offline classical dereverberator (spectral subtraction + optional WPE). */
59
+ export function masteringRepairDereverbClassical(
60
+ request: MasteringRepairDereverbClassicalRequest,
61
+ ): Float32Array;
62
+ export function masteringRepairDereverbClassical(
63
+ samples: Float32Array,
64
+ sampleRate: number,
65
+ options?: DereverbClassicalOptions,
66
+ ): Float32Array;
67
+ export function masteringRepairDereverbClassical(
68
+ samples: Float32Array | MasteringRepairDereverbClassicalRequest,
69
+ sampleRate?: number,
70
+ options: DereverbClassicalOptions = {},
71
+ ): Float32Array {
72
+ const request =
73
+ samples instanceof Float32Array
74
+ ? { samples, sampleRate: sampleRate as number, ...options }
75
+ : samples;
76
+ return requireModule().masteringRepairDereverbClassical(
77
+ request.samples,
78
+ request.sampleRate,
79
+ request,
80
+ );
81
+ }
82
+
83
+ /**
84
+ * Offline classical dereverberator for a stereo pair (spectral subtraction plus an optional
85
+ * WPE pre-stage), driven by one channel-linked mask.
86
+ *
87
+ * The mask is built from the channel-summed power, and the WPE stage accumulates over both
88
+ * channels and applies one predictor set to each, so neither stage can move an interchannel
89
+ * level or phase difference. That is also why the result carries a single `report` rather than
90
+ * one per channel.
91
+ *
92
+ * Every field of that report is a ratio or a fraction, so unlike the denoise pair nothing in
93
+ * it shifts with the channel count: a stereo figure here is comparable against a mono one.
94
+ *
95
+ * An input shorter than `nFft` is PADDED for analysis rather than rejected, the opposite of
96
+ * {@link masteringRepairDenoiseClassicalStereo}.
97
+ *
98
+ * Two report fields are gated on the WPE stage, which is off unless `wpeEnabled` is set:
99
+ * `detected.latePredictability` and `wpePredictorNorm` are then both exactly 0, which is the
100
+ * measurement rather than an unset field. `detected.lateDecayRatioDb` runs the other way from
101
+ * what its name suggests — less negative means the material sustains across the module's late
102
+ * lag, so a reverberant input reads *higher* than the same material dry.
103
+ *
104
+ * `threshold` and `attenuation` are both validated to `[0, 1]`, so the strongest gate this
105
+ * accepts is `threshold: 0.99`, not an arbitrarily large number.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * const { left, right, report } = masteringRepairDereverbClassicalStereo({
110
+ * left: leftSamples,
111
+ * right: rightSamples,
112
+ * sampleRate: 48000,
113
+ * wpeEnabled: true,
114
+ * });
115
+ * console.log(report.detected.lateDecayRatioDb, report.wpePredictorNorm);
116
+ * ```
117
+ */
118
+ export function masteringRepairDereverbClassicalStereo(
119
+ request: MasteringRepairDereverbClassicalStereoRequest,
120
+ ): MasteringRepairDereverbClassicalStereoResult;
121
+ export function masteringRepairDereverbClassicalStereo(
122
+ left: Float32Array,
123
+ right: Float32Array,
124
+ sampleRate: number,
125
+ config?: DereverbClassicalOptions,
126
+ ): MasteringRepairDereverbClassicalStereoResult;
127
+ export function masteringRepairDereverbClassicalStereo(
128
+ left: Float32Array | MasteringRepairDereverbClassicalStereoRequest,
129
+ right?: Float32Array,
130
+ sampleRate?: number,
131
+ config: DereverbClassicalOptions = {},
132
+ ): MasteringRepairDereverbClassicalStereoResult {
133
+ const request: MasteringRepairDereverbClassicalStereoRequest =
134
+ left instanceof Float32Array
135
+ ? { left, right: right as Float32Array, sampleRate, ...config }
136
+ : left;
137
+ const { left: leftSamples, right: rightSamples, sampleRate: rate, ...options } = request;
138
+ return requireModule().masteringRepairDereverbClassicalStereo(
139
+ leftSamples,
140
+ rightSamples,
141
+ rate ?? 22050,
142
+ options,
143
+ );
144
+ }
145
+
146
+ /**
147
+ * Offline classical dereverberator for any number of channels (spectral subtraction plus an
148
+ * optional WPE pre-stage), driven by one channel-linked mask.
149
+ *
150
+ * The N-channel form of {@link masteringRepairDereverbClassicalStereo}: the mask is built from
151
+ * the channel-summed power and the WPE stage accumulates over every channel and applies one
152
+ * predictor set to each, so neither stage can move an interchannel level or phase difference
153
+ * however many channels there are. One `report` for the set, and one output per input channel in
154
+ * input order.
155
+ *
156
+ * A single channel reproduces {@link masteringRepairDereverbClassical} bit for bit, and two
157
+ * reproduce {@link masteringRepairDereverbClassicalStereo} plane for plane — `channels[0]` is the
158
+ * left plane and `channels[1]` the right.
159
+ *
160
+ * Every field of the report is a ratio or a fraction, so nothing in it shifts with the channel
161
+ * count: a figure measured over a set is comparable against a mono one. That is the opposite of
162
+ * {@link masteringRepairDenoiseClassicalLinked}, whose `detected` levels are absolute and move by
163
+ * `10*log10(N)`.
164
+ *
165
+ * An input shorter than `nFft` is PADDED for analysis rather than rejected — again the opposite
166
+ * of that entry, which refuses one.
167
+ *
168
+ * Two report fields are gated on the WPE stage, which is off unless `wpeEnabled` is set:
169
+ * `detected.latePredictability` and `wpePredictorNorm` are then both exactly 0, which is the
170
+ * measurement rather than an unset field.
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * const { channels, report } = masteringRepairDereverbClassicalLinked({
175
+ * channels: [frontLeft, frontRight, centre],
176
+ * sampleRate: 48000,
177
+ * wpeEnabled: true,
178
+ * });
179
+ * console.log(channels.length, report.detected.lateDecayRatioDb);
180
+ * ```
181
+ */
182
+ export function masteringRepairDereverbClassicalLinked(
183
+ request: MasteringRepairDereverbClassicalLinkedRequest,
184
+ ): MasteringRepairDereverbClassicalLinkedResult;
185
+ export function masteringRepairDereverbClassicalLinked(
186
+ channels: Float32Array[],
187
+ sampleRate: number,
188
+ config?: DereverbClassicalOptions,
189
+ ): MasteringRepairDereverbClassicalLinkedResult;
190
+ export function masteringRepairDereverbClassicalLinked(
191
+ channels: Float32Array[] | MasteringRepairDereverbClassicalLinkedRequest,
192
+ sampleRate?: number,
193
+ config: DereverbClassicalOptions = {},
194
+ ): MasteringRepairDereverbClassicalLinkedResult {
195
+ const request: MasteringRepairDereverbClassicalLinkedRequest = Array.isArray(channels)
196
+ ? { channels, sampleRate, ...config }
197
+ : channels;
198
+ const { channels: input, sampleRate: rate, ...options } = request;
199
+ return requireModule().masteringRepairDereverbClassicalLinked(input, rate ?? 22050, options);
200
+ }
201
+
202
+ /**
203
+ * Point a dereverb config at a measured room.
204
+ *
205
+ * The pair to {@link estimateRoom}, which measures a recording blind. Returns a complete
206
+ * config for {@link masteringRepairDereverbClassical}, so the caller does not have to know
207
+ * which reverberation-time band to use or how the late delay relates to room size.
208
+ *
209
+ * What the room decides is *where* the tail is. Exactly two fields come back changed from
210
+ * what was passed in:
211
+ *
212
+ * - `t60Sec` — the mid-frequency reverberation time, the average of the 500 Hz and 1 kHz
213
+ * octaves an ISO 3382 room is quoted by.
214
+ * - `lateDelayMs` — Polack's mixing time, sqrt(volume) in milliseconds, past which the
215
+ * response is a diffuse tail rather than separable early reflections.
216
+ *
217
+ * How *much* to remove is taste rather than measurement, so `attenuation`, `threshold`,
218
+ * `overSubtraction` and `spectralFloor` are never written. A measurement that did not
219
+ * converge leaves its own field alone, so a partial estimate still configures the half it
220
+ * measured; a low-`confidence` estimate is still applied, because whether to trust it is
221
+ * the caller's call.
222
+ *
223
+ * Every field of `config` that is omitted falls back to the library's own dereverb default,
224
+ * matching {@link masteringRepairDereverbClassical}, so calling this with only an estimate
225
+ * returns a config that is ready to run. The C ABI underneath reads and writes the whole
226
+ * config and takes every field literally — it has no "zero means default" rule — which is
227
+ * why an omitted field resolves to its default here rather than to zero.
228
+ *
229
+ * @param estimate - The measured room, from {@link estimateRoom}. Only `volume` and
230
+ * `rt60Bands` are read. The request form carries it as `estimate` alongside the config
231
+ * fields.
232
+ * @param config - The config to point at the room; omitted fields take the library default.
233
+ * @returns A complete dereverb config.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * const estimate = estimateRoom(samples, sampleRate);
238
+ * const config = masteringRepairDereverbConfigForRoom(estimate);
239
+ * const clean = masteringRepairDereverbClassical(samples, sampleRate, config);
240
+ * ```
241
+ *
242
+ * When NEITHER mid band converged, `t60Sec` falls back to the average of whatever
243
+ * bands did, so a low-band-only estimate configures something rather than nothing --
244
+ * that value is no longer a mid-frequency figure. Only `volume`, `rt60Bands` and the
245
+ * band count are read; the rest of the estimate is ignored.
246
+ */
247
+ export function masteringRepairDereverbConfigForRoom(
248
+ request: MasteringRepairDereverbConfigForRoomRequest,
249
+ ): Required<DereverbClassicalOptions>;
250
+ export function masteringRepairDereverbConfigForRoom(
251
+ estimate: RoomEstimateResult,
252
+ config?: DereverbClassicalOptions,
253
+ ): Required<DereverbClassicalOptions>;
254
+ export function masteringRepairDereverbConfigForRoom(
255
+ estimate: RoomEstimateResult | MasteringRepairDereverbConfigForRoomRequest,
256
+ config: DereverbClassicalOptions = {},
257
+ ): Required<DereverbClassicalOptions> {
258
+ const request = 'estimate' in estimate ? estimate : { estimate, ...config };
259
+ return requireModule().masteringRepairDereverbConfigForRoom(request.estimate, request);
260
+ }
261
+
262
+ /** Request form of `masteringRepairDetectReverb`. */
263
+ export interface MasteringRepairDetectReverbRequest extends DereverbClassicalOptions {
264
+ samples: Float32Array;
265
+ sampleRate: number;
266
+ }
267
+
268
+ /**
269
+ * Measures reverberation without dereverberating.
270
+ *
271
+ * NOT an ISO 3382 reverberation time — use `estimateRoom` for a graded RT60. This reports what
272
+ * {@link masteringRepairDereverbClassical} itself measures while deciding how much to subtract.
273
+ *
274
+ * A buffer shorter than `nFft` is PADDED for analysis, as the repair pads it, which is the
275
+ * opposite of {@link masteringRepairDetectNoiseFloor}.
276
+ *
277
+ * `latePredictability` comes from the WPE stage, which runs only under `wpeEnabled` — clear by
278
+ * default — and then only its covariance and solve; the prediction is never subtracted. A
279
+ * default-config call therefore reports exactly 0 there as its measurement.
280
+ */
281
+ export function masteringRepairDetectReverb(
282
+ request: MasteringRepairDetectReverbRequest,
283
+ ): ReverbDetection;
284
+ export function masteringRepairDetectReverb(
285
+ samples: Float32Array,
286
+ sampleRate: number,
287
+ options?: DereverbClassicalOptions,
288
+ ): ReverbDetection;
289
+ export function masteringRepairDetectReverb(
290
+ samples: Float32Array | MasteringRepairDetectReverbRequest,
291
+ sampleRate?: number,
292
+ options: DereverbClassicalOptions = {},
293
+ ): ReverbDetection {
294
+ const request =
295
+ samples instanceof Float32Array
296
+ ? { samples, sampleRate: sampleRate as number, ...options }
297
+ : samples;
298
+ return requireModule().masteringRepairDetectReverb(request.samples, request.sampleRate, request);
299
+ }