@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
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/module_state.ts","../src/feature_core.ts","../src/validation.ts","../src/feature_music.ts","../src/feature_pitch.ts","../src/feature_resample.ts","../src/feature_spectral.ts","../src/feature_spectrogram.ts","../src/metering.ts","../src/public_types_music.ts","../src/codes.ts","../src/analysis_helpers.ts","../src/quick_analysis.ts","../src/analysis.ts"],"sourcesContent":["/**\n * Numeric error codes carried by a {@link SonareError}. Mirrors the C ABI\n * `SonareError` enum (and the Node / Python surfaces), so the same failure\n * reports the same numeric code on every binding.\n */\nexport enum ErrorCode {\n Ok = 0,\n FileNotFound = 1,\n InvalidFormat = 2,\n DecodeFailed = 3,\n InvalidParameter = 4,\n OutOfMemory = 5,\n NotSupported = 6,\n InvalidState = 7,\n Cancelled = 8,\n Unknown = 99,\n}\n\n/**\n * Error thrown by libsonare on a native (C++) failure. Carries a numeric\n * {@link ErrorCode} `code` plus its canonical `codeName`, so callers can branch\n * on the cause instead of matching message text.\n */\nexport class SonareError extends Error {\n /** Numeric error code, equal to an {@link ErrorCode} value. */\n readonly code: number;\n /** Canonical name of `code`, e.g. `'InvalidParameter'`. */\n readonly codeName: string;\n\n constructor(code: number, codeName: string, message: string) {\n super(message);\n this.name = 'SonareError';\n this.code = code;\n this.codeName = codeName;\n }\n}\n\n/** Type guard: whether a caught value is a libsonare {@link SonareError}. */\nexport function isSonareError(value: unknown): value is SonareError {\n return (\n value instanceof Error &&\n (value as { name?: unknown }).name === 'SonareError' &&\n typeof (value as { code?: unknown }).code === 'number'\n );\n}\n","import { ErrorCode, SonareError } from './errors';\nimport type { SonareModule } from './sonare.js';\n\nlet wrappedModule: SonareModule | null = null;\n\n/**\n * Shape of the structured info the native `sonareExceptionInfo(ptr)` returns.\n */\ninterface NativeExceptionInfo {\n code: number;\n codeName: string;\n message: string;\n}\n\n/**\n * Recover the native exception-object pointer from a value thrown across the\n * WASM boundary. emscripten surfaces a C++ throw in two shapes depending on the\n * toolchain/exception mode:\n * - a raw pointer number (older / classic surfacing), or\n * - a `CppException` object exposing the pointer as `excPtr` (emscripten with\n * `-fexceptions`).\n * Returns null when the thrown value is neither (a genuine JS error), so the\n * caller rethrows it unchanged.\n */\nfunction nativeExceptionPtr(error: unknown): number | null {\n if (typeof error === 'number') {\n return error;\n }\n if (error !== null && typeof error === 'object') {\n const ptr = (error as { excPtr?: unknown }).excPtr;\n if (typeof ptr === 'number') {\n return ptr;\n }\n }\n return null;\n}\n\n/**\n * Turn a thrown native exception pointer into a {@link SonareError}. The bound\n * `sonareExceptionInfo` decodes the pointer back into { code, codeName,\n * message }.\n */\nfunction makeSonareError(raw: SonareModule, thrown: number): SonareError {\n let code: number = ErrorCode.Unknown;\n let codeName = 'Unknown';\n let message = `libsonare native exception (${thrown})`;\n try {\n const info = (\n raw as unknown as { sonareExceptionInfo?: (ptr: number) => NativeExceptionInfo }\n ).sonareExceptionInfo?.(thrown);\n if (info) {\n code = info.code ?? code;\n codeName = info.codeName ?? codeName;\n message = info.message || message;\n }\n } catch {\n // Fall back to the generic message if decoding fails.\n }\n return new SonareError(code, codeName, message);\n}\n\n/**\n * Wrap the embind module so a native C++ exception (which surfaces as a raw\n * pointer number or a `CppException` carrying one) is rethrown as a\n * {@link SonareError}. Only function-valued\n * members are wrapped, and the wrapper is cached per member so repeated access\n * stays cheap; non-function members (typed-array heap views, etc.) pass through\n * unchanged.\n */\nfunction wrapModuleErrors(raw: SonareModule): SonareModule {\n const cache = new Map<PropertyKey, unknown>();\n const objectCache = new WeakMap<object, unknown>();\n const convert = (error: unknown): never => {\n const ptr = nativeExceptionPtr(error);\n if (ptr !== null) {\n throw makeSonareError(raw, ptr);\n }\n throw error;\n };\n\n const wrapNativeObject = (value: unknown): unknown => {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof Promise) {\n return value;\n }\n const objectValue = value as object;\n const cached = objectCache.get(objectValue);\n if (cached) {\n return cached;\n }\n const methodCache = new Map<PropertyKey, unknown>();\n const wrapped = new Proxy(objectValue, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMethod = methodCache.get(prop);\n if (cachedMethod) {\n return cachedMethod;\n }\n const method = member as (...a: unknown[]) => unknown;\n const wrappedMethod = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(method, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n methodCache.set(prop, wrappedMethod);\n return wrappedMethod;\n },\n });\n objectCache.set(objectValue, wrapped);\n return wrapped;\n };\n\n const wrapFunction = (value: (...a: unknown[]) => unknown): unknown => {\n const fnCache = new Map<PropertyKey, unknown>();\n return new Proxy(value, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMember = fnCache.get(prop);\n if (cachedMember) {\n return cachedMember;\n }\n const fn = member as (...a: unknown[]) => unknown;\n const wrappedMember = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(fn, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n fnCache.set(prop, wrappedMember);\n return wrappedMember;\n },\n apply(t, thisArg, args) {\n try {\n return wrapNativeObject(Reflect.apply(t, thisArg, args as unknown[]));\n } catch (error) {\n return convert(error);\n }\n },\n construct(t, args, newTarget) {\n try {\n return wrapNativeObject(Reflect.construct(t, args as unknown[], newTarget)) as object;\n } catch (error) {\n return convert(error) as object;\n }\n },\n });\n };\n\n return new Proxy(raw, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n const cached = cache.get(prop);\n if (cached) {\n return cached;\n }\n // Wrap as a Proxy (not a plain function) so embind class constructors\n // invoked via `new module.Foo(...)` keep their `[[Construct]]` behaviour\n // and prototype while still converting thrown native pointers.\n const wrapped = wrapFunction(value as (...a: unknown[]) => unknown);\n cache.set(prop, wrapped);\n return wrapped;\n },\n }) as SonareModule;\n}\n\nexport function setSonareModule(module: SonareModule): void {\n wrappedModule = wrapModuleErrors(module);\n}\n\nexport function getSonareModule(): SonareModule {\n if (!wrappedModule) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return wrappedModule;\n}\n","import { getSonareModule } from './module_state';\nimport type { TempogramMode } from './public_types';\nimport type {\n WasmCyclicTempogramResult,\n WasmFrameResult,\n WasmTempogramResult,\n WasmTrimResult,\n} from './sonare.js';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nexport function tone(request?: ToneRequest): Float32Array;\nexport function tone(\n frequency?: number,\n sampleRate?: number,\n duration?: number,\n phase?: number,\n amplitude?: number,\n): Float32Array;\nexport function tone(\n frequency: number | ToneRequest = 440,\n sampleRate = 22050,\n duration = 1,\n phase = 0,\n amplitude = 1,\n): Float32Array {\n const request =\n typeof frequency === 'number'\n ? { frequency, sampleRate, duration, phase, amplitude }\n : frequency;\n return requireModule().tone(\n request.frequency ?? 440,\n request.sampleRate ?? 22050,\n request.duration ?? 1,\n request.phase ?? 0,\n request.amplitude ?? 1,\n );\n}\n\nexport function chirp(request?: ChirpRequest): Float32Array;\nexport function chirp(\n fmin?: number,\n fmax?: number,\n sampleRate?: number,\n duration?: number,\n linear?: boolean,\n): Float32Array;\nexport function chirp(\n fmin: number | ChirpRequest = 440,\n fmax = 880,\n sampleRate = 22050,\n duration = 1,\n linear = true,\n): Float32Array {\n const request = typeof fmin === 'number' ? { fmin, fmax, sampleRate, duration, linear } : fmin;\n return requireModule().chirp(\n request.fmin ?? 440,\n request.fmax ?? 880,\n request.sampleRate ?? 22050,\n request.duration ?? 1,\n request.linear ?? true,\n );\n}\n\nexport function clicks(request: ClicksRequest): Float32Array;\nexport function clicks(\n times: Float32Array,\n sampleRate?: number,\n length?: number,\n frequency?: number,\n clickDuration?: number,\n): Float32Array;\nexport function clicks(\n times: Float32Array | ClicksRequest,\n sampleRate = 22050,\n length = 0,\n frequency = 1000,\n clickDuration = 0.1,\n): Float32Array {\n const request =\n times instanceof Float32Array ? { times, sampleRate, length, frequency, clickDuration } : times;\n return requireModule().clicks(\n request.times,\n request.sampleRate ?? 22050,\n request.length ?? 0,\n request.frequency ?? 1000,\n request.clickDuration ?? 0.1,\n );\n}\n\nexport interface DbConversionRequest {\n values: Float32Array;\n ref?: number;\n amin?: number;\n topDb?: number;\n}\n\nexport interface SilenceRequest {\n samples: Float32Array;\n topDb?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\nexport interface FrameSignalRequest {\n samples: Float32Array;\n frameLength: number;\n hopLength: number;\n}\nexport interface ToneRequest {\n frequency?: number;\n sampleRate?: number;\n duration?: number;\n phase?: number;\n amplitude?: number;\n}\nexport interface ChirpRequest {\n fmin?: number;\n fmax?: number;\n sampleRate?: number;\n duration?: number;\n linear?: boolean;\n}\nexport interface ClicksRequest {\n times: Float32Array;\n sampleRate?: number;\n length?: number;\n frequency?: number;\n clickDuration?: number;\n}\n/** Canonical request form for pre/de-emphasis filters. */\nexport interface EmphasisRequest {\n samples: Float32Array;\n coef?: number;\n zi?: number;\n}\n/** Canonical request form for centering or extending a vector. */\nexport interface PadCenterRequest {\n values: Float32Array;\n targetSize: number;\n padValue?: number;\n}\n/** Canonical request form for resizing a vector. */\nexport interface FixLengthRequest {\n values: Float32Array;\n targetSize: number;\n padValue?: number;\n}\n/** Canonical request form for bounding a frame-index vector. */\nexport interface FixFramesRequest {\n frames: Int32Array;\n xMin?: number;\n xMax?: number;\n pad?: boolean;\n}\nexport interface OnsetBacktrackRequest {\n events: Int32Array;\n energy: Float32Array;\n}\n/** Canonical request form for peak selection. */\nexport interface PeakPickRequest {\n values: Float32Array;\n preMax: number;\n postMax: number;\n preAvg: number;\n postAvg: number;\n delta: number;\n wait: number;\n}\n/** Canonical request form for vector normalization. */\nexport interface VectorNormalizeRequest {\n values: Float32Array;\n normType?: number;\n threshold?: number;\n}\n/** Canonical request form for tonal centroid projection. */\nexport interface TonnetzRequest {\n chromagram: Float32Array;\n nChroma: number;\n nFrames: number;\n}\nexport interface PcenRequest {\n values: Float32Array;\n nBins: number;\n nFrames: number;\n sampleRate?: number;\n hopLength?: number;\n timeConstant?: number;\n gain?: number;\n bias?: number;\n power?: number;\n eps?: number;\n /** @deprecated Put PCEN fields directly on the request object. */\n options?: Record<string, number>;\n}\nexport interface TempogramRequest {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n winLength?: number;\n mode?: TempogramMode;\n center?: boolean;\n norm?: boolean;\n}\nexport interface CyclicTempogramRequest {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n winLength?: number;\n bpmMin?: number;\n nBins?: number;\n}\nexport interface PlpRequest {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n tempoMin?: number;\n tempoMax?: number;\n winLength?: number;\n}\n\n// ============================================================================\n// Core - Unit Conversion\n// ============================================================================\n\n/**\n * Convert frequency in Hz to Mel scale.\n *\n * @param hz - Frequency in Hz\n * @returns Mel frequency\n */\nexport function hzToMel(hz: number): number {\n return requireModule().hzToMel(hz);\n}\n\n/**\n * Convert Mel scale to frequency in Hz.\n *\n * @param mel - Mel frequency\n * @returns Frequency in Hz\n */\nexport function melToHz(mel: number): number {\n return requireModule().melToHz(mel);\n}\n\n/**\n * Convert frequency in Hz to MIDI note number.\n *\n * @param hz - Frequency in Hz\n * @returns MIDI note number (A4 = 440 Hz = 69)\n */\nexport function hzToMidi(hz: number): number {\n return requireModule().hzToMidi(hz);\n}\n\n/**\n * Convert MIDI note number to frequency in Hz.\n *\n * @param midi - MIDI note number\n * @returns Frequency in Hz\n */\nexport function midiToHz(midi: number): number {\n return requireModule().midiToHz(midi);\n}\n\n/**\n * Convert frequency in Hz to note name.\n *\n * @param hz - Frequency in Hz\n * @returns Note name (e.g., \"A4\", \"C#5\")\n */\nexport function hzToNote(hz: number): string {\n return requireModule().hzToNote(hz);\n}\n\n/**\n * Convert note name to frequency in Hz.\n *\n * @param note - Note name (e.g., \"A4\", \"C#5\")\n * @returns Frequency in Hz\n */\nexport function noteToHz(note: string): number {\n return requireModule().noteToHz(note);\n}\n\n/**\n * Convert frame index to time in seconds.\n *\n * @param frames - Frame index\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Time in seconds\n */\nexport function framesToTime(frames: number, sr = 22050, hopLength = 512): number {\n return requireModule().framesToTime(frames, sr, hopLength);\n}\n\n/**\n * Convert time in seconds to frame index.\n *\n * @param time - Time in seconds\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Frame index\n */\nexport function timeToFrames(time: number, sr = 22050, hopLength = 512): number {\n return requireModule().timeToFrames(time, sr, hopLength);\n}\n\nexport function framesToSamples(frames: number, hopLength = 512, nFft = 0): number {\n return requireModule().framesToSamples(frames, hopLength, nFft);\n}\n\nexport function samplesToFrames(samples: number, hopLength = 512, nFft = 0): number {\n return requireModule().samplesToFrames(samples, hopLength, nFft);\n}\n\nexport function powerToDb(request: DbConversionRequest): Float32Array;\nexport function powerToDb(\n values: Float32Array,\n ref?: number,\n amin?: number,\n topDb?: number,\n): Float32Array;\nexport function powerToDb(\n values: Float32Array | DbConversionRequest,\n ref = 1.0,\n amin = 1e-10,\n topDb = 80.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return powerToDb(values.values, values.ref, values.amin, values.topDb);\n }\n return requireModule().powerToDb(values, ref, amin, topDb);\n}\n\nexport function amplitudeToDb(request: DbConversionRequest): Float32Array;\nexport function amplitudeToDb(\n values: Float32Array,\n ref?: number,\n amin?: number,\n topDb?: number,\n): Float32Array;\nexport function amplitudeToDb(\n values: Float32Array | DbConversionRequest,\n ref = 1.0,\n amin = 1e-5,\n topDb = 80.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return amplitudeToDb(values.values, values.ref, values.amin, values.topDb);\n }\n return requireModule().amplitudeToDb(values, ref, amin, topDb);\n}\n\nexport function dbToPower(values: Float32Array, ref = 1.0): Float32Array {\n return requireModule().dbToPower(values, ref);\n}\n\nexport function dbToAmplitude(values: Float32Array, ref = 1.0): Float32Array {\n return requireModule().dbToAmplitude(values, ref);\n}\n\nexport function preemphasis(request: EmphasisRequest): Float32Array;\nexport function preemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array;\nexport function preemphasis(\n samples: Float32Array | EmphasisRequest,\n coef = 0.97,\n zi?: number,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return preemphasis(samples.samples, samples.coef, samples.zi);\n }\n return requireModule().preemphasis(samples, coef, zi ?? null);\n}\n\nexport function deemphasis(request: EmphasisRequest): Float32Array;\nexport function deemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array;\nexport function deemphasis(\n samples: Float32Array | EmphasisRequest,\n coef = 0.97,\n zi?: number,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return deemphasis(samples.samples, samples.coef, samples.zi);\n }\n return requireModule().deemphasis(samples, coef, zi ?? null);\n}\n\nexport function trimSilence(request: SilenceRequest): WasmTrimResult;\nexport function trimSilence(\n samples: Float32Array,\n topDb?: number,\n frameLength?: number,\n hopLength?: number,\n): WasmTrimResult;\nexport function trimSilence(\n samples: Float32Array | SilenceRequest,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): WasmTrimResult {\n if (!(samples instanceof Float32Array)) {\n return trimSilence(samples.samples, samples.topDb, samples.frameLength, samples.hopLength);\n }\n return requireModule().trimSilence(samples, topDb, frameLength, hopLength);\n}\n\nexport function splitSilence(request: SilenceRequest): Int32Array;\nexport function splitSilence(\n samples: Float32Array,\n topDb?: number,\n frameLength?: number,\n hopLength?: number,\n): Int32Array;\nexport function splitSilence(\n samples: Float32Array | SilenceRequest,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): Int32Array {\n if (!(samples instanceof Float32Array)) {\n return splitSilence(samples.samples, samples.topDb, samples.frameLength, samples.hopLength);\n }\n return requireModule().splitSilence(samples, topDb, frameLength, hopLength);\n}\n\nexport function frameSignal(request: FrameSignalRequest): WasmFrameResult;\nexport function frameSignal(\n samples: Float32Array,\n frameLength: number,\n hopLength: number,\n): WasmFrameResult;\nexport function frameSignal(\n samples: Float32Array | FrameSignalRequest,\n frameLength?: number,\n hopLength?: number,\n): WasmFrameResult {\n if (!(samples instanceof Float32Array)) {\n return frameSignal(samples.samples, samples.frameLength, samples.hopLength);\n }\n return requireModule().frameSignal(samples, frameLength as number, hopLength as number);\n}\n\nexport function padCenter(request: PadCenterRequest): Float32Array;\nexport function padCenter(\n values: Float32Array,\n targetSize: number,\n padValue?: number,\n): Float32Array;\nexport function padCenter(\n values: Float32Array | PadCenterRequest,\n targetSize?: number,\n padValue = 0.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return padCenter(values.values, values.targetSize, values.padValue);\n }\n return requireModule().padCenter(values, targetSize as number, padValue);\n}\n\nexport function fixLength(request: FixLengthRequest): Float32Array;\nexport function fixLength(\n values: Float32Array,\n targetSize: number,\n padValue?: number,\n): Float32Array;\nexport function fixLength(\n values: Float32Array | FixLengthRequest,\n targetSize?: number,\n padValue = 0.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return fixLength(values.values, values.targetSize, values.padValue);\n }\n return requireModule().fixLength(values, targetSize as number, padValue);\n}\n\nexport function fixFrames(request: FixFramesRequest): Int32Array;\nexport function fixFrames(\n frames: Int32Array,\n xMin?: number,\n xMax?: number,\n pad?: boolean,\n): Int32Array;\nexport function fixFrames(\n frames: Int32Array | FixFramesRequest,\n xMin = 0,\n xMax = -1,\n pad = true,\n): Int32Array {\n if (!(frames instanceof Int32Array)) {\n return fixFrames(frames.frames, frames.xMin, frames.xMax, frames.pad);\n }\n return requireModule().fixFrames(frames, xMin, xMax, pad);\n}\n\nexport function onsetBacktrack(request: OnsetBacktrackRequest): Int32Array;\nexport function onsetBacktrack(events: Int32Array, energy: Float32Array): Int32Array;\nexport function onsetBacktrack(\n events: Int32Array | OnsetBacktrackRequest,\n energy?: Float32Array,\n): Int32Array {\n if (!(events instanceof Int32Array)) {\n return onsetBacktrack(events.events, events.energy);\n }\n return requireModule().onsetBacktrack(events, energy as Float32Array);\n}\n\nexport function peakPick(request: PeakPickRequest): Int32Array;\nexport function peakPick(\n values: Float32Array,\n preMax: number,\n postMax: number,\n preAvg: number,\n postAvg: number,\n delta: number,\n wait: number,\n): Int32Array;\nexport function peakPick(\n values: Float32Array | PeakPickRequest,\n preMax?: number,\n postMax?: number,\n preAvg?: number,\n postAvg?: number,\n delta?: number,\n wait?: number,\n): Int32Array {\n if (!(values instanceof Float32Array)) {\n const r = values;\n return peakPick(r.values, r.preMax, r.postMax, r.preAvg, r.postAvg, r.delta, r.wait);\n }\n return requireModule().peakPick(\n values,\n preMax as number,\n postMax as number,\n preAvg as number,\n postAvg as number,\n delta as number,\n wait as number,\n );\n}\n\nexport function vectorNormalize(request: VectorNormalizeRequest): Float32Array;\nexport function vectorNormalize(\n values: Float32Array,\n normType?: number,\n threshold?: number,\n): Float32Array;\nexport function vectorNormalize(\n values: Float32Array | VectorNormalizeRequest,\n normType = 0,\n threshold = 0.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return vectorNormalize(values.values, values.normType, values.threshold);\n }\n return requireModule().vectorNormalize(values, normType, threshold);\n}\n\nexport function pcen(request: PcenRequest): Float32Array;\nexport function pcen(\n values: Float32Array,\n nBins: number,\n nFrames: number,\n options?: Record<string, number>,\n): Float32Array;\nexport function pcen(\n values: Float32Array | PcenRequest,\n nBins = 0,\n nFrames = 0,\n options: Record<string, number> = {},\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n const r = values;\n const {\n values: requestValues,\n nBins: requestBins,\n nFrames: requestFrames,\n options: legacyOptions,\n ...flatOptions\n } = r;\n return pcen(requestValues, requestBins, requestFrames, {\n ...legacyOptions,\n ...flatOptions,\n });\n }\n return requireModule().pcen(values, nBins, nFrames, options);\n}\n\nexport function tonnetz(request: TonnetzRequest): Float32Array;\nexport function tonnetz(chromagram: Float32Array, nChroma: number, nFrames: number): Float32Array;\nexport function tonnetz(\n chromagram: Float32Array | TonnetzRequest,\n nChroma?: number,\n nFrames?: number,\n): Float32Array {\n if (!(chromagram instanceof Float32Array)) {\n return tonnetz(chromagram.chromagram, chromagram.nChroma, chromagram.nFrames);\n }\n return requireModule().tonnetz(chromagram, nChroma as number, nFrames as number);\n}\n\nexport function tempogram(request: TempogramRequest): WasmTempogramResult;\nexport function tempogram(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n winLength?: number,\n mode?: TempogramMode,\n center?: boolean,\n norm?: boolean,\n): WasmTempogramResult;\nexport function tempogram(\n onsetEnvelope: Float32Array | TempogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n mode: TempogramMode = 'autocorrelation',\n center = true,\n norm = true,\n): WasmTempogramResult {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const r = onsetEnvelope;\n return tempogram(\n r.onsetEnvelope,\n r.sampleRate,\n r.hopLength,\n r.winLength,\n r.mode,\n r.center,\n r.norm,\n );\n }\n return requireModule().tempogram(\n onsetEnvelope,\n sampleRate,\n hopLength,\n winLength,\n mode,\n center,\n norm,\n );\n}\n\nexport function cyclicTempogram(request: CyclicTempogramRequest): WasmCyclicTempogramResult;\nexport function cyclicTempogram(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n winLength?: number,\n bpmMin?: number,\n nBins?: number,\n): WasmCyclicTempogramResult;\nexport function cyclicTempogram(\n onsetEnvelope: Float32Array | CyclicTempogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n bpmMin = 60.0,\n nBins = 60,\n): WasmCyclicTempogramResult {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const r = onsetEnvelope;\n return cyclicTempogram(\n r.onsetEnvelope,\n r.sampleRate,\n r.hopLength,\n r.winLength,\n r.bpmMin,\n r.nBins,\n );\n }\n return requireModule().cyclicTempogram(\n onsetEnvelope,\n sampleRate,\n hopLength,\n winLength,\n bpmMin,\n nBins,\n );\n}\n\nexport function plp(request: PlpRequest): Float32Array;\nexport function plp(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n tempoMin?: number,\n tempoMax?: number,\n winLength?: number,\n): Float32Array;\nexport function plp(\n onsetEnvelope: Float32Array | PlpRequest,\n sampleRate = 22050,\n hopLength = 512,\n tempoMin = 30.0,\n tempoMax = 300.0,\n winLength = 384,\n): Float32Array {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const r = onsetEnvelope;\n return plp(r.onsetEnvelope, r.sampleRate, r.hopLength, r.tempoMin, r.tempoMax, r.winLength);\n }\n return requireModule().plp(onsetEnvelope, sampleRate, hopLength, tempoMin, tempoMax, winLength);\n}\n","/**\n * Per-call validation options accepted by guarded wrappers. Empty-buffer\n * checks are always performed; pass `{ validate: false }` to opt out of the\n * O(n) NaN/Inf scan on hot paths.\n *\n * `{ validate: false }` only skips this JS-side pre-scan (which raises a\n * `RangeError` naming the exact offending index). It is NOT a way to push\n * non-finite samples into the core: the native layer always re-validates the\n * buffer (see `validate_offline_audio_input` in the C++ core), matching the C\n * ABI / Node / Python surfaces, so an NaN/Inf buffer still throws — just with a\n * generic native message instead of the indexed JS one.\n */\nexport interface ValidateOptions {\n validate?: boolean;\n}\n\n/**\n * Offline-analysis sample-rate bounds, mirroring the C++ core limits\n * (`sonare::kMinAudioSampleRate` / `kMaxAudioSampleRate` in `core/audio.h`).\n * Every guarded WASM entry point rejects the same out-of-range rates the C ABI,\n * Node, and Python surfaces do.\n */\nexport const MIN_AUDIO_SAMPLE_RATE = 8000;\nexport const MAX_AUDIO_SAMPLE_RATE = 384000;\n\nfunction assertNonEmptySamples(\n fnName: string,\n samples: ArrayLike<number>,\n argName = 'samples',\n): void {\n if (samples.length === 0) {\n throw new RangeError(`${fnName}: ${argName} must not be empty`);\n }\n}\n\nfunction assertFiniteSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n if (!validate) {\n return;\n }\n for (let i = 0; i < samples.length; i++) {\n const v = samples[i] as number;\n if (!Number.isFinite(v)) {\n throw new RangeError(`${fnName}: ${argName} contains NaN or Inf at index ${i}`);\n }\n }\n}\n\nexport function assertSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n assertNonEmptySamples(fnName, samples, argName);\n assertFiniteSamples(fnName, samples, validate, argName);\n}\n\nexport function assertFiniteScalar(fnName: string, value: number, argName: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${fnName}: ${argName} must be a finite number`);\n }\n}\n\nexport function assertSampleRate(fnName: string, sampleRate: number): void {\n if (\n !Number.isInteger(sampleRate) ||\n sampleRate < MIN_AUDIO_SAMPLE_RATE ||\n sampleRate > MAX_AUDIO_SAMPLE_RATE\n ) {\n throw new RangeError(\n `${fnName}: sampleRate out of supported range [${MIN_AUDIO_SAMPLE_RATE}, ${MAX_AUDIO_SAMPLE_RATE}]`,\n );\n }\n}\n\n/** Validate and retain the public Audio.fromBuffer construction contract. */\nexport function validateAudioBuffer(samples: Float32Array, sampleRate: number): void {\n assertSamples('Audio.fromBuffer', samples, true);\n assertSampleRate('Audio.fromBuffer', sampleRate);\n}\n\nexport function assertNonNegativeInteger(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new RangeError(`${fnName}: ${argName} must be a non-negative integer`);\n }\n}\n\nexport function assertPositiveInteger(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new RangeError(`${fnName}: ${argName} must be a positive integer`);\n }\n}\n\nexport function assertInterleavedSamples(\n fnName: string,\n samples: ArrayLike<number>,\n channels: number,\n validate: boolean,\n): void {\n assertSamples(fnName, samples, validate);\n assertPositiveInteger(fnName, channels, 'channels');\n if (samples.length % channels !== 0) {\n throw new RangeError(`${fnName}: samples length must be a multiple of channels`);\n }\n}\n","import { ErrorCode, SonareError } from './errors';\nimport { getSonareModule } from './module_state';\nimport type {\n AnalyzeSectionsOptions,\n CqtResult,\n LufsResult,\n MelodyResult,\n OnsetStrengthMultiResult,\n Section,\n SectionType,\n} from './public_types';\nimport type { WasmFourierTempogramResult, WasmNnlsChromaResult } from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport {\n assertFiniteScalar,\n assertPositiveInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\ntype AnalyzeSectionsGuardedOptions = AnalyzeSectionsOptions & ValidateOptions;\ntype MelodyGuardedOptions = MelodyOptions & ValidateOptions;\n\n/** Canonical request form shared by the Constant-Q transform variants. */\nexport interface CqtRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n fmin?: number;\n nBins?: number;\n binsPerOctave?: number;\n}\n\n/** Canonical request form for {@link vqt}. */\nexport interface VqtRequest extends CqtRequest {\n gamma?: number;\n}\n\nexport interface OnsetEnvelopeRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n nMels?: number;\n}\n\nexport interface OnsetStrengthMultiRequest extends OnsetEnvelopeRequest {\n nBands?: number;\n}\n\nexport interface FourierTempogramRequest extends GuardedOptions {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n winLength?: number;\n center?: boolean;\n norm?: boolean;\n}\n\nexport interface TempogramRatioRequest extends GuardedOptions {\n tempogramData: Float32Array;\n winLength?: number;\n sampleRate?: number;\n hopLength?: number;\n factors?: Float32Array | number[];\n}\n\nexport interface CqtToAudioRequest extends GuardedOptions {\n magnitude: Float32Array;\n nBins: number;\n nFrames: number;\n sampleRate?: number;\n hopLength?: number;\n fmin?: number;\n binsPerOctave?: number;\n nIter?: number;\n}\n\nexport interface VqtToAudioRequest extends CqtToAudioRequest {\n gamma?: number;\n}\n\nexport interface AnalyzeSectionsRequest extends AnalyzeSectionsGuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\nexport interface AnalyzeMelodyRequest extends MelodyGuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\nexport interface LufsRequest extends ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\nexport interface NnlsChromaRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n enableStftBlend?: boolean;\n stftBlendWeight?: number;\n stftBlendNFft?: number;\n hopLength?: number;\n}\n\nfunction validateMusicSamples(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\nfunction validatePositiveIntegers(fnName: string, values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n assertPositiveInteger(fnName, value, name);\n }\n}\n\nfunction validateFrequencyBounds(fnName: string, fmin: number, fmax?: number): void {\n assertFiniteScalar(fnName, fmin, 'fmin');\n if (fmin < 0) {\n throw new RangeError(`${fnName}: fmin must be non-negative`);\n }\n if (fmax !== undefined) {\n assertFiniteScalar(fnName, fmax, 'fmax');\n if (fmax <= fmin) {\n throw new RangeError(`${fnName}: fmax must be greater than fmin`);\n }\n }\n}\n\n/**\n * Compute NNLS (non-negative least squares) chromagram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns NNLS chroma result\n */\nexport function nnlsChroma(request: NnlsChromaRequest): WasmNnlsChromaResult;\nexport function nnlsChroma(\n samples: Float32Array,\n sampleRate?: number,\n options?: Omit<NnlsChromaRequest, 'samples' | 'sampleRate'>,\n): WasmNnlsChromaResult;\nexport function nnlsChroma(\n samples: Float32Array | NnlsChromaRequest,\n sampleRate = 22050,\n options: Omit<NnlsChromaRequest, 'samples' | 'sampleRate'> = {},\n): WasmNnlsChromaResult {\n if (!(samples instanceof Float32Array)) {\n return nnlsChroma(samples.samples, samples.sampleRate, samples);\n }\n validateMusicSamples('nnlsChroma', samples, sampleRate, options);\n const hopLength = options.hopLength === undefined ? 512 : options.hopLength;\n assertPositiveInteger('nnlsChroma', hopLength, 'hopLength');\n if (hopLength > 2 ** 31 - 1) {\n throw new RangeError('nnlsChroma: hopLength must fit in a signed 32-bit integer');\n }\n return requireModule().nnlsChromaEx(\n samples,\n sampleRate,\n options.enableStftBlend ?? true,\n options.stftBlendWeight ?? 0.55,\n options.stftBlendNFft ?? 4096,\n hopLength,\n );\n}\n\n/**\n * Compute the Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function cqt(request: CqtRequest): CqtResult;\nexport function cqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function cqt(\n samples: Float32Array | CqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return cqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request,\n );\n }\n validateMusicSamples('cqt', samples, sampleRate, options);\n validatePositiveIntegers('cqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('cqt', fmin);\n return requireModule().cqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the pseudo Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function pseudoCqt(request: CqtRequest): CqtResult;\nexport function pseudoCqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function pseudoCqt(\n samples: Float32Array | CqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return pseudoCqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request,\n );\n }\n validateMusicSamples('pseudoCqt', samples, sampleRate, options);\n validatePositiveIntegers('pseudoCqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('pseudoCqt', fmin);\n return requireModule().pseudoCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the hybrid Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function hybridCqt(request: CqtRequest): CqtResult;\nexport function hybridCqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function hybridCqt(\n samples: Float32Array | CqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return hybridCqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request,\n );\n }\n validateMusicSamples('hybridCqt', samples, sampleRate, options);\n validatePositiveIntegers('hybridCqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('hybridCqt', fmin);\n return requireModule().hybridCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the Variable-Q Transform magnitude (gamma controls Q).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @param gamma - Bandwidth offset; negative selects the automatic ERB-derived\n * value, while 0 is equivalent to CQT (default: -1)\n * @returns VQT magnitude result (same shape as CQT)\n */\nexport function vqt(request: VqtRequest): CqtResult;\nexport function vqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n gamma?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function vqt(\n samples: Float32Array | VqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n gamma = -1,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return vqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request.gamma,\n request,\n );\n }\n validateMusicSamples('vqt', samples, sampleRate, options);\n validatePositiveIntegers('vqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('vqt', fmin);\n assertFiniteScalar('vqt', gamma, 'gamma');\n return requireModule().vqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave, gamma);\n}\n\nfunction validateCqtInverse(\n fnName: string,\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate: number,\n hopLength: number,\n fmin: number,\n binsPerOctave: number,\n nIter: number,\n options: GuardedOptions,\n): void {\n assertSampleRate(fnName, sampleRate);\n validatePositiveIntegers(fnName, { nBins, nFrames, hopLength, binsPerOctave, nIter });\n if (nIter > 256) {\n throw new RangeError(`${fnName}: nIter must be at most 256`);\n }\n validateFrequencyBounds(fnName, fmin);\n if (fmin === 0) {\n throw new RangeError(`${fnName}: fmin must be positive`);\n }\n if (magnitude.length !== nBins * nFrames) {\n throw new RangeError(`${fnName}: magnitude length must equal nBins * nFrames`);\n }\n assertSamples(fnName, magnitude, options.validate !== false);\n}\n\n/** Reconstruct mono audio from row-major CQT magnitude via Griffin-Lim. */\nexport function cqtToAudio(request: CqtToAudioRequest): Float32Array;\nexport function cqtToAudio(\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n binsPerOctave?: number,\n nIter?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function cqtToAudio(\n magnitude: Float32Array | CqtToAudioRequest,\n nBins = 0,\n nFrames = 0,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n binsPerOctave = 12,\n nIter = 32,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(magnitude instanceof Float32Array)) {\n const request = magnitude;\n return cqtToAudio(\n request.magnitude,\n request.nBins,\n request.nFrames,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.binsPerOctave,\n request.nIter,\n request,\n );\n }\n validateCqtInverse(\n 'cqtToAudio',\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n nIter,\n options,\n );\n return requireModule().cqtToAudio(\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n nIter,\n );\n}\n\n/** Reconstruct mono audio from row-major VQT magnitude via Griffin-Lim. */\nexport function vqtToAudio(request: VqtToAudioRequest): Float32Array;\nexport function vqtToAudio(\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n binsPerOctave?: number,\n gamma?: number,\n nIter?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function vqtToAudio(\n magnitude: Float32Array | VqtToAudioRequest,\n nBins = 0,\n nFrames = 0,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n binsPerOctave = 12,\n gamma = -1,\n nIter = 32,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(magnitude instanceof Float32Array)) {\n const request = magnitude;\n return vqtToAudio(\n request.magnitude,\n request.nBins,\n request.nFrames,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.binsPerOctave,\n request.gamma,\n request.nIter,\n request,\n );\n }\n validateCqtInverse(\n 'vqtToAudio',\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n nIter,\n options,\n );\n assertFiniteScalar('vqtToAudio', gamma, 'gamma');\n return requireModule().vqtToAudio(\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n gamma,\n nIter,\n );\n}\n\n/**\n * Detect song-structure sections (intro/verse/chorus/...).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param minSectionSec - Minimum section duration in seconds (default: 4.0)\n * @returns Array of detected sections\n */\nexport function analyzeSections(request: AnalyzeSectionsRequest): Section[];\nexport function analyzeSections(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeSectionsGuardedOptions,\n): Section[];\nexport function analyzeSections(\n samples: Float32Array | AnalyzeSectionsRequest,\n sampleRate = 22050,\n options: AnalyzeSectionsGuardedOptions = {},\n): Section[] {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return analyzeSections(r.samples, r.sampleRate, r);\n }\n validateMusicSamples('analyzeSections', samples, sampleRate, options);\n validatePositiveIntegers('analyzeSections', {\n nFft: options.nFft ?? 2048,\n hopLength: options.hopLength ?? 512,\n });\n assertFiniteScalar('analyzeSections', options.minSectionSec ?? 4.0, 'minSectionSec');\n if ((options.minSectionSec ?? 4.0) < 0) {\n throw new RangeError('analyzeSections: minSectionSec must be non-negative');\n }\n // The embind value marshalling returns an array whose constructor is not this\n // realm's Array; chaining .map() onto it propagates that constructor via\n // Symbol.species, leaving a result that structuredClone (and so postMessage to\n // a Worker) rejects with \"could not be cloned\". Array.from() re-roots it as a\n // plain Array before mapping.\n const sections = requireModule().analyzeSections(\n samples,\n sampleRate,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.minSectionSec ?? 4.0,\n );\n return Array.from(sections, (s) => ({ ...s, type: s.type as SectionType }));\n}\n\n/** Options for {@link analyzeMelody}. All fields are optional. */\nexport interface MelodyOptions {\n /** Lowest f0 (Hz) the tracker will consider. Default 65 (≈ C2). */\n fmin?: number;\n /** Highest f0 (Hz) the tracker will consider. Default 2093 (≈ C7). */\n fmax?: number;\n /** Analysis frame length in samples. Default 2048. */\n frameLength?: number;\n /** Hop length between frames in samples. Default 256. */\n hopLength?: number;\n /** Voicing confidence threshold in [0,1]; frames below are unvoiced. Default 0.1. */\n threshold?: number;\n /**\n * Use the pYIN tracker (Viterbi-smoothed) instead of plain per-frame YIN.\n * Produces a less octave-jumpy contour. Defaults to `false`.\n */\n usePyin?: boolean;\n /**\n * When {@link usePyin} is `true`, zero-pad by `frameLength / 2` so frame\n * `i` is centered at `i * hopLength` (matches `librosa.pyin(center=True)`).\n * Ignored by the plain-YIN path. Defaults to `true`.\n */\n center?: boolean;\n}\n\n/**\n * Extract the melody contour from monophonic audio via YIN (or pYIN).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Tracker + tuning options ({@link MelodyOptions})\n * @returns Melody contour with per-frame pitch points and summary stats\n */\nexport function analyzeMelody(request: AnalyzeMelodyRequest): MelodyResult;\nexport function analyzeMelody(\n samples: Float32Array,\n sampleRate?: number,\n options?: MelodyGuardedOptions,\n): MelodyResult;\nexport function analyzeMelody(\n samples: Float32Array | AnalyzeMelodyRequest,\n sampleRate = 22050,\n options: MelodyGuardedOptions = {},\n): MelodyResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return analyzeMelody(r.samples, r.sampleRate, r);\n }\n validateMusicSamples('analyzeMelody', samples, sampleRate, options);\n const fmin = options.fmin ?? 65.0;\n const fmax = options.fmax ?? 2093.0;\n validateFrequencyBounds('analyzeMelody', fmin, fmax);\n // The melody tracker's fmin is a YIN pitch floor: 0 is meaningless, and the\n // flat C ABI (sonare_analyze_melody) rejects it with InvalidParameter.\n // validateFrequencyBounds only guards fmin >= 0, so enforce strict positivity\n // here and report the same branded error the Node/Python surfaces raise.\n if (fmin <= 0) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n 'analyzeMelody: fmin must be positive',\n );\n }\n validatePositiveIntegers('analyzeMelody', {\n frameLength: options.frameLength ?? 2048,\n hopLength: options.hopLength ?? 256,\n });\n const threshold = options.threshold ?? 0.1;\n assertFiniteScalar('analyzeMelody', threshold, 'threshold');\n if (threshold <= 0) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n 'analyzeMelody: threshold must be positive',\n );\n }\n return requireModule().analyzeMelody(\n samples,\n sampleRate,\n options.fmin ?? 65.0,\n options.fmax ?? 2093.0,\n options.frameLength ?? 2048,\n options.hopLength ?? 256,\n options.threshold ?? 0.1,\n options.usePyin ?? false,\n options.center ?? true,\n );\n}\n\n/**\n * Compute the onset strength envelope.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @returns Onset envelope for each frame\n */\nexport function onsetEnvelope(request: OnsetEnvelopeRequest): Float32Array;\nexport function onsetEnvelope(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function onsetEnvelope(\n samples: Float32Array | OnsetEnvelopeRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return onsetEnvelope(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request,\n );\n }\n validateMusicSamples('onsetEnvelope', samples, sampleRate, options);\n validatePositiveIntegers('onsetEnvelope', { nFft, hopLength, nMels });\n return requireModule().onsetEnvelope(samples, sampleRate, nFft, hopLength, nMels);\n}\n\n/**\n * Compute multi-band onset strength envelopes.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param nBands - Number of onset bands (default: 3)\n * @returns Multi-band onset matrix\n */\nexport function onsetStrengthMulti(request: OnsetStrengthMultiRequest): OnsetStrengthMultiResult;\nexport function onsetStrengthMulti(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n nBands?: number,\n options?: GuardedOptions,\n): OnsetStrengthMultiResult;\nexport function onsetStrengthMulti(\n samples: Float32Array | OnsetStrengthMultiRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nBands = 3,\n options: GuardedOptions = {},\n): OnsetStrengthMultiResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return onsetStrengthMulti(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request.nBands,\n request,\n );\n }\n validateMusicSamples('onsetStrengthMulti', samples, sampleRate, options);\n validatePositiveIntegers('onsetStrengthMulti', { nFft, hopLength, nMels, nBands });\n return requireModule().onsetStrengthMulti(samples, sampleRate, nFft, hopLength, nMels, nBands);\n}\n\n/**\n * Compute the Fourier tempogram from an onset envelope.\n *\n * @param onsetEnvelope - Onset strength envelope (float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param winLength - Window length in frames (default: 384)\n * @returns Fourier tempogram result\n */\nexport function fourierTempogram(request: FourierTempogramRequest): WasmFourierTempogramResult;\nexport function fourierTempogram(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n winLength?: number,\n center?: boolean,\n norm?: boolean,\n options?: GuardedOptions,\n): WasmFourierTempogramResult;\nexport function fourierTempogram(\n onsetEnvelope: Float32Array | FourierTempogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n center = true,\n norm = true,\n options: GuardedOptions = {},\n): WasmFourierTempogramResult {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const request = onsetEnvelope;\n return fourierTempogram(\n request.onsetEnvelope,\n request.sampleRate,\n request.hopLength,\n request.winLength,\n request.center,\n request.norm,\n request,\n );\n }\n assertSampleRate('fourierTempogram', sampleRate);\n assertSamples('fourierTempogram', onsetEnvelope, options.validate !== false, 'onsetEnvelope');\n validatePositiveIntegers('fourierTempogram', { hopLength, winLength });\n return requireModule().fourierTempogram(\n onsetEnvelope,\n sampleRate,\n hopLength,\n winLength,\n center,\n norm,\n );\n}\n\n/**\n * Compute tempogram ratio features.\n *\n * @param tempogramData - Tempogram data (float32)\n * @param winLength - Window length in frames (default: 384)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param factors - Lag ratios to evaluate. When omitted or empty, the library\n * default {0.5, 1, 2, 3, 4} is used.\n * @returns Tempogram ratio features (one value per factor)\n */\nexport function tempogramRatio(request: TempogramRatioRequest): Float32Array;\nexport function tempogramRatio(\n tempogramData: Float32Array,\n winLength?: number,\n sampleRate?: number,\n hopLength?: number,\n factors?: Float32Array | number[],\n options?: GuardedOptions,\n): Float32Array;\nexport function tempogramRatio(\n tempogramData: Float32Array | TempogramRatioRequest,\n winLength = 384,\n sampleRate = 22050,\n hopLength = 512,\n factors?: Float32Array | number[],\n options: GuardedOptions = {},\n): Float32Array {\n if (!(tempogramData instanceof Float32Array)) {\n const request = tempogramData;\n return tempogramRatio(\n request.tempogramData,\n request.winLength,\n request.sampleRate,\n request.hopLength,\n request.factors,\n request,\n );\n }\n assertSampleRate('tempogramRatio', sampleRate);\n assertSamples('tempogramRatio', tempogramData, options.validate !== false, 'tempogramData');\n validatePositiveIntegers('tempogramRatio', { winLength, hopLength });\n return requireModule().tempogramRatio(tempogramData, winLength, sampleRate, hopLength, factors);\n}\n\n/**\n * Measure loudness (EBU R128 / ITU-R BS.1770).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz. The default (22050) is non-standard for\n * audio; pass the buffer's actual rate, as K-weighting is sample-rate\n * dependent and a wrong rate yields wrong loudness.\n * @returns Loudness measurement result\n */\nexport function lufs(request: LufsRequest): LufsResult;\nexport function lufs(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): LufsResult;\nexport function lufs(\n samples: Float32Array | LufsRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): LufsResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return lufs(r.samples, r.sampleRate, r);\n }\n assertSampleRate('lufs', sampleRate);\n assertSamples('lufs', samples, options.validate !== false);\n return requireModule().lufs(samples, sampleRate);\n}\n\n/**\n * Compute the momentary loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz. The default (22050) is non-standard and\n * K-weighting is sample-rate dependent; pass the buffer's actual rate.\n * @returns Momentary LUFS values over time\n */\nexport function momentaryLufs(request: LufsRequest): Float32Array;\nexport function momentaryLufs(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): Float32Array;\nexport function momentaryLufs(\n samples: Float32Array | LufsRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return momentaryLufs(r.samples, r.sampleRate, r);\n }\n assertSampleRate('momentaryLufs', sampleRate);\n assertSamples('momentaryLufs', samples, options.validate !== false);\n return requireModule().momentaryLufs(samples, sampleRate);\n}\n\n/**\n * Compute the short-term loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz. The default (22050) is non-standard and\n * K-weighting is sample-rate dependent; pass the buffer's actual rate.\n * @returns Short-term LUFS values over time\n */\nexport function shortTermLufs(request: LufsRequest): Float32Array;\nexport function shortTermLufs(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): Float32Array;\nexport function shortTermLufs(\n samples: Float32Array | LufsRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return shortTermLufs(r.samples, r.sampleRate, r);\n }\n assertSampleRate('shortTermLufs', sampleRate);\n assertSamples('shortTermLufs', samples, options.validate !== false);\n return requireModule().shortTermLufs(samples, sampleRate);\n}\n","import { getSonareModule } from './module_state';\nimport type { NoteSegment, PiptrackResult, PitchResult } from './public_types';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Features - Pitch\n// ============================================================================\n\n/**\n * Detect pitch using YIN algorithm.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.1)\n * @param fillNa - Retained for compatibility; YIN always returns a finite per-frame estimate.\n * @returns Pitch detection result\n */\nexport interface PitchYinRequest {\n samples: Float32Array;\n sampleRate?: number;\n frameLength?: number;\n hopLength?: number;\n fmin?: number;\n fmax?: number;\n threshold?: number;\n fillNa?: boolean;\n}\n\nexport interface PiptrackRequest {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n fmin?: number;\n fmax?: number;\n threshold?: number;\n}\n\n/** Per-bin spectral pitch candidates and peak magnitudes (librosa.piptrack). */\nexport function piptrack(request: PiptrackRequest): PiptrackResult;\nexport function piptrack(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n threshold?: number,\n): PiptrackResult;\nexport function piptrack(\n samples: Float32Array | PiptrackRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 150,\n fmax = 4000,\n threshold = 0.1,\n): PiptrackResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return piptrack(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.threshold,\n );\n }\n return requireModule().piptrack(samples, sampleRate, nFft, hopLength, fmin, fmax, threshold);\n}\n\nexport function pitchYin(request: PitchYinRequest): PitchResult;\nexport function pitchYin(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n threshold?: number,\n fillNa?: boolean,\n): PitchResult;\nexport function pitchYin(\n samples: Float32Array | PitchYinRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.1,\n fillNa = false,\n): PitchResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return pitchYin(\n request.samples,\n request.sampleRate,\n request.frameLength,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.threshold,\n request.fillNa,\n );\n }\n return requireModule().pitchYin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n\n/**\n * Detect pitch using pYIN algorithm (probabilistic YIN with HMM smoothing).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.1)\n * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)\n * @returns Pitch detection result\n */\nexport interface PitchPyinRequest extends PitchYinRequest {}\n\nexport function pitchPyin(request: PitchPyinRequest): PitchResult;\nexport function pitchPyin(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n threshold?: number,\n fillNa?: boolean,\n): PitchResult;\nexport function pitchPyin(\n samples: Float32Array | PitchPyinRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.1,\n fillNa = false,\n): PitchResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return pitchPyin(\n request.samples,\n request.sampleRate,\n request.frameLength,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.threshold,\n request.fillNa,\n );\n }\n return requireModule().pitchPyin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n\n/** Parameters for segmenting an F0 track into stable monophonic notes. */\nexport interface NoteSegmentsRequest {\n f0Hz: Float32Array;\n voicedProb: Float32Array;\n frameRate: number;\n segmentationThresholdCents?: number;\n minNoteMs?: number;\n referenceHz?: number;\n}\n\n/**\n * Segment a caller-supplied monophonic F0 track into stable note regions.\n *\n * `f0Hz` and `voicedProb` must have the same non-zero length. Zero-Hz frames\n * and probabilities below 0.5 are treated as unvoiced.\n */\nexport function noteSegments(request: NoteSegmentsRequest): NoteSegment[] {\n return requireModule().noteSegments(request.f0Hz, request.voicedProb, request.frameRate, {\n segmentationThresholdCents: request.segmentationThresholdCents,\n minNoteMs: request.minNoteMs,\n referenceHz: request.referenceHz,\n });\n}\n","import { getSonareModule } from './module_state';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Core - Resample\n// ============================================================================\n\n/**\n * Resample audio to a different sample rate.\n *\n * @param samples - Audio samples (mono, float32)\n * @param srcSr - Source sample rate in Hz\n * @param targetSr - Target sample rate in Hz\n * @returns Resampled audio\n */\nexport interface ResampleRequest {\n samples: Float32Array;\n srcSr: number;\n targetSr: number;\n}\n\nexport function resample(request: ResampleRequest): Float32Array;\nexport function resample(samples: Float32Array, srcSr: number, targetSr: number): Float32Array;\nexport function resample(\n samples: Float32Array | ResampleRequest,\n srcSr?: number,\n targetSr?: number,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return resample(samples.samples, samples.srcSr, samples.targetSr);\n }\n return requireModule().resample(samples, srcSr as number, targetSr as number);\n}\n","import { getSonareModule } from './module_state';\nimport type { SegmentMatrix } from './public_types';\nimport type {\n WasmDecomposeResult,\n WasmHpssWithResidualResult,\n WasmLufsResult,\n WasmMatrix2dResult,\n} from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport {\n assertInterleavedSamples,\n assertNonNegativeInteger,\n assertPositiveInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nfunction resolveEffectFftOptions(\n fnName: string,\n nFft: unknown,\n hopLength: unknown,\n): { nFft: number; hopLength: number } {\n const resolvedNFft = nFft === undefined ? 2048 : nFft;\n const resolvedHopLength = hopLength === undefined ? 512 : hopLength;\n if (typeof resolvedNFft !== 'number' || !Number.isInteger(resolvedNFft)) {\n throw new TypeError(`${fnName}: nFft must be an integer`);\n }\n if (resolvedNFft < 2 || resolvedNFft > 2 ** 30) {\n throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);\n }\n if ((resolvedNFft & (resolvedNFft - 1)) !== 0) {\n throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);\n }\n if (typeof resolvedHopLength !== 'number' || !Number.isInteger(resolvedHopLength)) {\n throw new TypeError(`${fnName}: hopLength must be an integer`);\n }\n if (resolvedHopLength <= 0 || resolvedHopLength > 2 ** 31 - 1) {\n throw new RangeError(`${fnName}: hopLength must be a positive integer`);\n }\n return { nFft: resolvedNFft, hopLength: resolvedHopLength };\n}\n\nfunction resolveHardMask(fnName: string, value: unknown): boolean {\n if (value === undefined) {\n return false;\n }\n if (typeof value !== 'boolean') {\n throw new TypeError(`${fnName}: hardMask must be a boolean`);\n }\n return value;\n}\n\n/** Canonical request form for frame-based spectral feature extraction. */\nexport interface SpectralFrameRequest {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n}\n\nexport interface SpectralRolloffRequest extends SpectralFrameRequest {\n rollPercent?: number;\n}\n\nexport interface ZeroCrossingRateRequest {\n samples: Float32Array;\n sampleRate?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\nexport interface DecomposeRequest {\n s: Float32Array;\n nFeatures: number;\n nFrames: number;\n nComponents: number;\n nIter?: number;\n beta?: number;\n}\n\nexport interface DecomposeWithInitRequest extends DecomposeRequest {\n init?: 'random' | 'nndsvd';\n}\n\nexport interface SpectralContrastRequest extends SpectralFrameRequest {\n nBands?: number;\n fmin?: number;\n quantile?: number;\n}\nexport interface PolyFeaturesRequest extends SpectralFrameRequest {\n order?: number;\n}\nexport interface ZeroCrossingsRequest {\n samples: Float32Array;\n threshold?: number;\n refMagnitude?: boolean;\n pad?: boolean;\n zeroPos?: boolean;\n}\nexport interface PitchTuningRequest {\n frequencies: Float32Array;\n resolution?: number;\n binsPerOctave?: number;\n}\nexport interface EstimateTuningRequest extends SpectralFrameRequest {\n resolution?: number;\n binsPerOctave?: number;\n}\nexport interface NnFilterRequest {\n s: Float32Array;\n nFeatures: number;\n nFrames: number;\n aggregate?: string;\n k?: number;\n width?: number;\n}\nexport interface SegmentCrossSimilarityRequest {\n x: Float32Array;\n xRows: number;\n xCols: number;\n y: Float32Array;\n yRows: number;\n yCols: number;\n k?: number;\n metric?: 'cosine' | 'euclidean';\n mode?: 'connectivity' | 'affinity';\n}\nexport interface SegmentRecurrenceMatrixRequest {\n data: Float32Array;\n rows: number;\n cols: number;\n k?: number;\n width?: number;\n sym?: boolean;\n metric?: 'cosine' | 'euclidean';\n mode?: 'connectivity' | 'affinity';\n}\nexport interface SegmentRecurrenceToLagRequest {\n recurrence: Float32Array;\n n: number;\n pad?: boolean;\n}\nexport interface SegmentLagToRecurrenceRequest {\n lag: Float32Array;\n rows: number;\n lags: number;\n}\nexport interface SegmentSubsegmentRequest {\n data: Float32Array;\n rows: number;\n cols: number;\n boundaries: Int32Array;\n nSegments?: number;\n}\nexport interface SegmentAgglomerativeRequest {\n data: Float32Array;\n rows: number;\n cols: number;\n k: number;\n linkage?: 'average' | 'single' | 'complete' | 'ward';\n}\nexport interface SegmentPathEnhanceRequest {\n recurrence: Float32Array;\n n: number;\n win: number;\n maxRatio?: number;\n minRatio?: number;\n nFilters?: number;\n}\n\nfunction validateSegmentMatrix(\n fnName: string,\n data: Float32Array,\n rows: number,\n cols: number,\n dataName: string,\n): void {\n assertPositiveInteger(fnName, rows, 'rows');\n assertPositiveInteger(fnName, cols, 'cols');\n assertSamples(fnName, data, true, dataName);\n const expected = rows * cols;\n if (!Number.isSafeInteger(expected) || data.length !== expected) {\n throw new RangeError(`${fnName}: ${dataName} length must equal rows * cols`);\n }\n}\nexport interface RemixRequest {\n samples: Float32Array;\n intervals: Int32Array | ArrayLike<number>;\n sampleRate?: number;\n alignZeros?: boolean;\n}\nexport interface PhaseVocoderRequest extends SpectralFrameRequest {\n rate: number;\n}\nexport interface HpssWithResidualRequest {\n samples: Float32Array;\n sampleRate?: number;\n kernelHarmonic?: number;\n kernelPercussive?: number;\n nFft?: number;\n hopLength?: number;\n hardMask?: boolean;\n}\nexport interface LufsInterleavedRequest extends ValidateOptions {\n samples: Float32Array;\n channels: number;\n sampleRate?: number;\n}\nexport interface Ebur128LoudnessRangeRequest extends ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n// ============================================================================\n// Features - Spectral\n// ============================================================================\n\n/**\n * Compute spectral centroid (center of mass of spectrum).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral centroid in Hz for each frame\n */\nexport function spectralCentroid(request: SpectralFrameRequest): Float32Array;\nexport function spectralCentroid(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n): Float32Array;\nexport function spectralCentroid(\n samples: Float32Array | SpectralFrameRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralCentroid(samples.samples, samples.sampleRate, samples.nFft, samples.hopLength);\n }\n return requireModule().spectralCentroid(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute spectral contrast (librosa.feature.spectral_contrast).\n *\n * @returns Matrix2d of shape (nBands + 1) x nFrames.\n */\nexport function spectralContrast(request: SpectralContrastRequest): WasmMatrix2dResult;\nexport function spectralContrast(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nBands?: number,\n fmin?: number,\n quantile?: number,\n): WasmMatrix2dResult;\nexport function spectralContrast(\n samples: Float32Array | SpectralContrastRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nBands = 6,\n fmin = 200.0,\n quantile = 0.02,\n): WasmMatrix2dResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return spectralContrast(\n r.samples,\n r.sampleRate,\n r.nFft,\n r.hopLength,\n r.nBands,\n r.fmin,\n r.quantile,\n );\n }\n return requireModule().spectralContrast(\n samples,\n sampleRate,\n nFft,\n hopLength,\n nBands,\n fmin,\n quantile,\n );\n}\n\n/**\n * Fit per-frame polynomial coefficients (librosa.feature.poly_features).\n *\n * @returns Matrix2d of shape (order + 1) x nFrames.\n */\nexport function polyFeatures(request: PolyFeaturesRequest): WasmMatrix2dResult;\nexport function polyFeatures(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n order?: number,\n): WasmMatrix2dResult;\nexport function polyFeatures(\n samples: Float32Array | PolyFeaturesRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n order = 1,\n): WasmMatrix2dResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return polyFeatures(r.samples, r.sampleRate, r.nFft, r.hopLength, r.order);\n }\n return requireModule().polyFeatures(samples, sampleRate, nFft, hopLength, order);\n}\n\n/**\n * Locate zero-crossing indices of a signal (librosa.zero_crossings).\n */\nexport function zeroCrossings(request: ZeroCrossingsRequest): Int32Array;\nexport function zeroCrossings(\n samples: Float32Array,\n threshold?: number,\n refMagnitude?: boolean,\n pad?: boolean,\n zeroPos?: boolean,\n): Int32Array;\nexport function zeroCrossings(\n samples: Float32Array | ZeroCrossingsRequest,\n threshold = 1e-10,\n refMagnitude = false,\n pad = true,\n zeroPos = true,\n): Int32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return zeroCrossings(r.samples, r.threshold, r.refMagnitude, r.pad, r.zeroPos);\n }\n return requireModule().zeroCrossings(samples, threshold, refMagnitude, pad, zeroPos);\n}\n\n/**\n * Estimate the global tuning offset from a set of frequencies\n * (librosa.pitch_tuning). Returns a deviation in fractions of a bin.\n */\nexport function pitchTuning(request: PitchTuningRequest): number;\nexport function pitchTuning(\n frequencies: Float32Array,\n resolution?: number,\n binsPerOctave?: number,\n): number;\nexport function pitchTuning(\n frequencies: Float32Array | PitchTuningRequest,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n if (!(frequencies instanceof Float32Array)) {\n const r = frequencies;\n return pitchTuning(r.frequencies, r.resolution, r.binsPerOctave);\n }\n return requireModule().pitchTuning(frequencies, resolution, binsPerOctave);\n}\n\n/**\n * Estimate the tuning offset of an audio signal (librosa.estimate_tuning).\n */\nexport function estimateTuning(request: EstimateTuningRequest): number;\nexport function estimateTuning(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n resolution?: number,\n binsPerOctave?: number,\n): number;\nexport function estimateTuning(\n samples: Float32Array | EstimateTuningRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return estimateTuning(\n r.samples,\n r.sampleRate,\n r.nFft,\n r.hopLength,\n r.resolution,\n r.binsPerOctave,\n );\n }\n return requireModule().estimateTuning(\n samples,\n sampleRate,\n nFft,\n hopLength,\n resolution,\n binsPerOctave,\n );\n}\n\n/**\n * Non-negative matrix factorisation of a flattened [nFeatures x nFrames]\n * spectrogram (librosa.decompose.decompose). Returns the W and H factors.\n */\nexport function decompose(request: DecomposeRequest): WasmDecomposeResult;\nexport function decompose(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n nComponents: number,\n nIter?: number,\n beta?: number,\n): WasmDecomposeResult;\nexport function decompose(\n s: Float32Array | DecomposeRequest,\n nFeatures = 0,\n nFrames = 0,\n nComponents = 0,\n nIter = 50,\n beta = 2.0,\n): WasmDecomposeResult {\n if (!(s instanceof Float32Array)) {\n const request = s;\n return decompose(\n request.s,\n request.nFeatures,\n request.nFrames,\n request.nComponents,\n request.nIter,\n request.beta,\n );\n }\n return requireModule().decompose(s, nFeatures, nFrames, nComponents, nIter, beta);\n}\n\n/**\n * Non-negative matrix factorisation with a selectable initialiser\n * (librosa.decompose.decompose, `init`). Identical to {@link decompose} but\n * exposes the initialisation strategy: `'random'` (default, deterministic seed)\n * or `'nndsvd'` (SVD-based warm start, which tends to converge in fewer\n * iterations). Returns the W and H factors.\n */\nexport function decomposeWithInit(request: DecomposeWithInitRequest): WasmDecomposeResult;\nexport function decomposeWithInit(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n nComponents: number,\n nIter?: number,\n beta?: number,\n init?: 'random' | 'nndsvd',\n): WasmDecomposeResult;\nexport function decomposeWithInit(\n s: Float32Array | DecomposeWithInitRequest,\n nFeatures = 0,\n nFrames = 0,\n nComponents = 0,\n nIter = 50,\n beta = 2.0,\n init: 'random' | 'nndsvd' = 'random',\n): WasmDecomposeResult {\n if (!(s instanceof Float32Array)) {\n const request = s;\n return decomposeWithInit(\n request.s,\n request.nFeatures,\n request.nFrames,\n request.nComponents,\n request.nIter,\n request.beta,\n request.init,\n );\n }\n return requireModule().decomposeWithInit(s, nFeatures, nFrames, nComponents, nIter, beta, init);\n}\n\n/**\n * Nearest-neighbour filtering of a flattened [nFeatures x nFrames] spectrogram\n * (librosa.decompose.nn_filter).\n */\nexport function nnFilter(request: NnFilterRequest): WasmMatrix2dResult;\nexport function nnFilter(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n aggregate?: string,\n k?: number,\n width?: number,\n): WasmMatrix2dResult;\nexport function nnFilter(\n s: Float32Array | NnFilterRequest,\n nFeatures = 0,\n nFrames = 0,\n aggregate = 'mean',\n k = 7,\n width = 1,\n): WasmMatrix2dResult {\n if (!(s instanceof Float32Array)) {\n const r = s;\n return nnFilter(r.s, r.nFeatures, r.nFrames, r.aggregate, r.k, r.width);\n }\n return requireModule().nnFilter(s, nFeatures, nFrames, aggregate, k, width);\n}\n\n/**\n * Reorder/concatenate a signal by interval slices (librosa.effects.remix).\n *\n * @param intervals - Flat (start, end) sample pairs (even length).\n */\nexport function remix(request: RemixRequest): Float32Array;\nexport function remix(\n samples: Float32Array,\n intervals: Int32Array | ArrayLike<number>,\n sampleRate?: number,\n alignZeros?: boolean,\n): Float32Array;\nexport function remix(\n samples: Float32Array | RemixRequest,\n intervals?: Int32Array | ArrayLike<number>,\n sampleRate = 22050,\n alignZeros = false,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return remix(r.samples, r.intervals, r.sampleRate, r.alignZeros);\n }\n // Sample indices must reach the native side as exact 32-bit integers. Passing\n // a Float32Array (or a number[] holding fractional/large values) would round\n // boundaries above 2^24 and misalign the slice. Coerce to an Int32Array,\n // truncating toward zero, so callers can hand us any numeric array safely.\n const intervalsI32 =\n intervals instanceof Int32Array\n ? intervals\n : Int32Array.from(intervals as ArrayLike<number>, (v) => Math.trunc(v));\n return requireModule().remix(samples, intervalsI32, sampleRate, alignZeros);\n}\n\n/**\n * Phase-vocoder time-scale modification (rate > 1 faster, < 1 slower).\n */\nexport function phaseVocoder(request: PhaseVocoderRequest): Float32Array;\nexport function phaseVocoder(\n samples: Float32Array,\n sampleRate: number,\n rate: number,\n nFft?: number,\n hopLength?: number,\n): Float32Array;\nexport function phaseVocoder(\n samples: Float32Array | PhaseVocoderRequest,\n sampleRate = 22050,\n rate = 1,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return phaseVocoder(r.samples, r.sampleRate ?? 22050, r.rate, r.nFft, r.hopLength);\n }\n return requireModule().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);\n}\n\n/**\n * HPSS into harmonic / percussive / residual signals.\n */\nexport function hpssWithResidual(request: HpssWithResidualRequest): WasmHpssWithResidualResult;\nexport function hpssWithResidual(\n samples: Float32Array,\n sampleRate?: number,\n kernelHarmonic?: number,\n kernelPercussive?: number,\n nFft?: number,\n hopLength?: number,\n hardMask?: boolean,\n): WasmHpssWithResidualResult;\nexport function hpssWithResidual(\n samples: Float32Array | HpssWithResidualRequest,\n sampleRate = 22050,\n kernelHarmonic = 31,\n kernelPercussive = 31,\n nFft?: number,\n hopLength?: number,\n hardMask?: boolean,\n): WasmHpssWithResidualResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return hpssWithResidual(\n r.samples,\n r.sampleRate,\n r.kernelHarmonic,\n r.kernelPercussive,\n r.nFft,\n r.hopLength,\n r.hardMask,\n );\n }\n const fftOptions = resolveEffectFftOptions('hpssWithResidual', nFft, hopLength);\n const resolvedHardMask = resolveHardMask('hpssWithResidual', hardMask);\n return requireModule().hpssWithResidualEx(\n samples,\n sampleRate,\n kernelHarmonic,\n kernelPercussive,\n fftOptions.nFft,\n fftOptions.hopLength,\n resolvedHardMask,\n );\n}\n\n/**\n * Channel-weighted multichannel integrated loudness + LRA (ITU-R BS.1770 /\n * EBU R128) from an interleaved buffer of `frames * channels` samples. The\n * per-channel frame count is derived from the buffer length and `channels`.\n *\n * Pass the buffer's actual `sampleRate`: the default (22050) is non-standard for\n * audio, and K-weighting is sample-rate dependent, so a wrong rate yields wrong\n * loudness.\n */\nexport function lufsInterleaved(request: LufsInterleavedRequest): WasmLufsResult;\nexport function lufsInterleaved(\n samples: Float32Array,\n channels: number,\n sampleRate?: number,\n options?: ValidateOptions,\n): WasmLufsResult;\nexport function lufsInterleaved(\n samples: Float32Array | LufsInterleavedRequest,\n channels = 0,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): WasmLufsResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return lufsInterleaved(r.samples, r.channels, r.sampleRate, r);\n }\n assertSampleRate('lufsInterleaved', sampleRate);\n assertInterleavedSamples('lufsInterleaved', samples, channels, options.validate !== false);\n return requireModule().lufsInterleaved(samples, channels, sampleRate);\n}\n\n/**\n * Standards-compliant EBU R128 loudness range (LRA) in LU. Pass the buffer's\n * actual `sampleRate`: the default (22050) is non-standard and K-weighting is\n * sample-rate dependent.\n */\nexport function ebur128LoudnessRange(request: Ebur128LoudnessRangeRequest): number;\nexport function ebur128LoudnessRange(samples: Float32Array, sampleRate?: number): number;\nexport function ebur128LoudnessRange(\n samples: Float32Array | Ebur128LoudnessRangeRequest,\n sampleRate = 22050,\n): number {\n if (!(samples instanceof Float32Array)) {\n return ebur128LoudnessRange(samples.samples, samples.sampleRate);\n }\n return requireModule().ebur128LoudnessRange(samples, sampleRate);\n}\n\n/**\n * Compute spectral bandwidth.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral bandwidth in Hz for each frame\n */\nexport function spectralBandwidth(request: SpectralFrameRequest & { p?: number }): Float32Array;\nexport function spectralBandwidth(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n p?: number,\n): Float32Array;\nexport function spectralBandwidth(\n samples: Float32Array | (SpectralFrameRequest & { p?: number }),\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n p = 2,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralBandwidth(\n samples.samples,\n samples.sampleRate,\n samples.nFft,\n samples.hopLength,\n samples.p,\n );\n }\n return requireModule().spectralBandwidth(samples, sampleRate, nFft, hopLength, p);\n}\n\n/**\n * Compute spectral rolloff frequency.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param rollPercent - Percentage threshold (default: 0.85)\n * @returns Rolloff frequency in Hz for each frame\n */\nexport function spectralRolloff(request: SpectralRolloffRequest): Float32Array;\nexport function spectralRolloff(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n rollPercent?: number,\n): Float32Array;\nexport function spectralRolloff(\n samples: Float32Array | SpectralRolloffRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n rollPercent = 0.85,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralRolloff(\n samples.samples,\n samples.sampleRate,\n samples.nFft,\n samples.hopLength,\n samples.rollPercent,\n );\n }\n return requireModule().spectralRolloff(samples, sampleRate, nFft, hopLength, rollPercent);\n}\n\n/**\n * Compute spectral flatness.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral flatness for each frame (0 = tonal, 1 = noise-like)\n */\nexport function spectralFlatness(request: SpectralFrameRequest): Float32Array;\nexport function spectralFlatness(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n): Float32Array;\nexport function spectralFlatness(\n samples: Float32Array | SpectralFrameRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralFlatness(samples.samples, samples.sampleRate, samples.nFft, samples.hopLength);\n }\n return requireModule().spectralFlatness(samples, sampleRate, nFft, hopLength);\n}\n\nexport function spectralFlux(request: SpectralFrameRequest & { lag?: number }): Float32Array;\nexport function spectralFlux(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n lag?: number,\n): Float32Array;\nexport function spectralFlux(\n samples: Float32Array | (SpectralFrameRequest & { lag?: number }),\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n lag = 1,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralFlux(\n samples.samples,\n samples.sampleRate,\n samples.nFft,\n samples.hopLength,\n samples.lag,\n );\n }\n return requireModule().spectralFlux(samples, sampleRate, nFft, hopLength, lag);\n}\n\n/**\n * Compute zero crossing rate.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Zero crossing rate for each frame\n */\nexport function zeroCrossingRate(request: ZeroCrossingRateRequest): Float32Array;\nexport function zeroCrossingRate(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n): Float32Array;\nexport function zeroCrossingRate(\n samples: Float32Array | ZeroCrossingRateRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return zeroCrossingRate(\n samples.samples,\n samples.sampleRate,\n samples.frameLength,\n samples.hopLength,\n );\n }\n return requireModule().zeroCrossingRate(samples, sampleRate, frameLength, hopLength);\n}\n\n/**\n * Compute RMS energy.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns RMS energy for each frame\n */\nexport function rmsEnergy(request: ZeroCrossingRateRequest): Float32Array;\nexport function rmsEnergy(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n): Float32Array;\nexport function rmsEnergy(\n samples: Float32Array | ZeroCrossingRateRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return rmsEnergy(samples.samples, samples.sampleRate, samples.frameLength, samples.hopLength);\n }\n return requireModule().rmsEnergy(samples, sampleRate, frameLength, hopLength);\n}\n\n/** Column-wise cross-similarity (librosa.segment.cross_similarity). */\nexport function segmentCrossSimilarity(request: SegmentCrossSimilarityRequest): SegmentMatrix {\n validateSegmentMatrix('segmentCrossSimilarity', request.x, request.xRows, request.xCols, 'x');\n validateSegmentMatrix('segmentCrossSimilarity', request.y, request.yRows, request.yCols, 'y');\n if (request.xRows !== request.yRows) {\n throw new RangeError('segmentCrossSimilarity: feature dimensions must match');\n }\n assertNonNegativeInteger('segmentCrossSimilarity', request.k ?? 0, 'k');\n return requireModule().segmentCrossSimilarity(\n request.x,\n request.xRows,\n request.xCols,\n request.y,\n request.yRows,\n request.yCols,\n request.k ?? 0,\n request.metric ?? 'cosine',\n request.mode ?? 'connectivity',\n );\n}\n\n/** Self-similarity recurrence matrix (librosa.segment.recurrence_matrix). */\nexport function segmentRecurrenceMatrix(request: SegmentRecurrenceMatrixRequest): SegmentMatrix {\n validateSegmentMatrix(\n 'segmentRecurrenceMatrix',\n request.data,\n request.rows,\n request.cols,\n 'data',\n );\n assertNonNegativeInteger('segmentRecurrenceMatrix', request.k ?? 0, 'k');\n assertNonNegativeInteger('segmentRecurrenceMatrix', request.width ?? 1, 'width');\n return requireModule().segmentRecurrenceMatrix(\n request.data,\n request.rows,\n request.cols,\n request.k ?? 0,\n request.width ?? 1,\n request.sym ?? false,\n request.metric ?? 'euclidean',\n request.mode ?? 'connectivity',\n );\n}\n\n/** Convert an `n × n` recurrence matrix to a lag matrix. */\nexport function segmentRecurrenceToLag(request: SegmentRecurrenceToLagRequest): SegmentMatrix {\n validateSegmentMatrix(\n 'segmentRecurrenceToLag',\n request.recurrence,\n request.n,\n request.n,\n 'recurrence',\n );\n return requireModule().segmentRecurrenceToLag(\n request.recurrence,\n request.n,\n request.pad ?? false,\n );\n}\n\n/** Convert a lag matrix back to an `n × n` recurrence matrix. */\nexport function segmentLagToRecurrence(request: SegmentLagToRecurrenceRequest): SegmentMatrix {\n validateSegmentMatrix('segmentLagToRecurrence', request.lag, request.rows, request.lags, 'lag');\n return requireModule().segmentLagToRecurrence(request.lag, request.rows, request.lags);\n}\n\n/** Refine frame boundaries by clustering within each parent segment. */\nexport function segmentSubsegment(request: SegmentSubsegmentRequest): Int32Array {\n validateSegmentMatrix('segmentSubsegment', request.data, request.rows, request.cols, 'data');\n assertPositiveInteger('segmentSubsegment', request.nSegments ?? 4, 'nSegments');\n return requireModule().segmentSubsegment(\n request.data,\n request.rows,\n request.cols,\n request.boundaries,\n request.nSegments ?? 4,\n );\n}\n\n/** Cluster feature columns and return one label per column. */\nexport function segmentAgglomerative(request: SegmentAgglomerativeRequest): Int32Array {\n validateSegmentMatrix('segmentAgglomerative', request.data, request.rows, request.cols, 'data');\n assertPositiveInteger('segmentAgglomerative', request.k, 'k');\n return requireModule().segmentAgglomerative(\n request.data,\n request.rows,\n request.cols,\n request.k,\n request.linkage ?? 'average',\n );\n}\n\n/** Enhance diagonal paths in an `n × n` recurrence matrix. */\nexport function segmentPathEnhance(request: SegmentPathEnhanceRequest): SegmentMatrix {\n validateSegmentMatrix(\n 'segmentPathEnhance',\n request.recurrence,\n request.n,\n request.n,\n 'recurrence',\n );\n assertPositiveInteger('segmentPathEnhance', request.win, 'win');\n assertPositiveInteger('segmentPathEnhance', request.maxRatio ?? 2, 'maxRatio');\n assertNonNegativeInteger('segmentPathEnhance', request.minRatio ?? 0, 'minRatio');\n assertPositiveInteger('segmentPathEnhance', request.nFilters ?? 7, 'nFilters');\n return requireModule().segmentPathEnhance(\n request.recurrence,\n request.n,\n request.win,\n request.maxRatio ?? 2,\n request.minRatio ?? 0,\n request.nFilters ?? 7,\n );\n}\n","import { getSonareModule } from './module_state';\nimport type {\n ChromaResult,\n MelPowerResult,\n MelSpectrogramResult,\n MfccResult,\n ReassignedSpectrogramResult,\n StftPowerResult,\n StftResult,\n} from './public_types';\nimport type { ValidateOptions } from './validation';\nimport {\n assertFiniteScalar,\n assertPositiveInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\n\n/** Canonical request form for basic frame-based spectrogram features. */\nexport interface SpectrogramRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n}\n\nexport interface ChromaSpectrogramRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n nChroma?: number;\n binsPerOctave?: number;\n}\n\nexport interface MelSpectrogramRequest extends SpectrogramRequest {\n nMels?: number;\n fmin?: number;\n fmax?: number;\n htk?: boolean;\n}\n\nexport interface MfccRequest extends MelSpectrogramRequest {\n nMfcc?: number;\n lifter?: number;\n}\n\nexport interface MelDeltaRequest extends GuardedOptions {\n features: Float32Array;\n nFeatures: number;\n nFrames: number;\n width?: number;\n}\nexport interface ReassignedSpectrogramRequest extends SpectrogramRequest {\n refPower?: number;\n fillNan?: boolean;\n}\n\nexport interface MfccToMelRequest extends GuardedOptions {\n mfccCoefficients: Float32Array;\n nMfcc: number;\n nFrames: number;\n nMels?: number;\n /** Lifter used by the forward MFCC transform; zero means no liftering. */\n lifter?: number;\n}\n\n/** Canonical request form for reconstruction from a Mel power spectrogram. */\nexport interface MelToStftRequest extends GuardedOptions {\n melPower: Float32Array;\n nMels: number;\n nFrames: number;\n sampleRate?: number;\n nFft?: number;\n fmin?: number;\n fmax?: number;\n htk?: boolean;\n}\n\n/** Canonical request form for Griffin-Lim reconstruction from Mel power. */\nexport interface MelToAudioRequest extends MelToStftRequest {\n hopLength?: number;\n nIter?: number;\n}\nexport interface GriffinLimRequest extends GuardedOptions {\n magnitude: Float32Array;\n nBins: number;\n nFrames: number;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n nIter?: number;\n momentum?: number;\n}\n\n/** Canonical request form for Griffin-Lim reconstruction from MFCCs. */\nexport interface MfccToAudioRequest extends MfccToMelRequest {\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n fmin?: number;\n fmax?: number;\n nIter?: number;\n htk?: boolean;\n}\n\nexport interface TrimRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate: number;\n thresholdDb?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\nfunction validateSpectrogramSamples(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\nfunction validatePositiveIntegers(fnName: string, values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n assertPositiveInteger(fnName, value, name);\n }\n}\n\nfunction validateMelFrequencyRange(\n fnName: string,\n fmin: number,\n fmax: number,\n sampleRate: number,\n): void {\n assertFiniteScalar(fnName, fmin, 'fmin');\n assertFiniteScalar(fnName, fmax, 'fmax');\n if (fmin < 0) {\n throw new RangeError(`${fnName}: fmin must be non-negative`);\n }\n if (fmax < 0) {\n throw new RangeError(`${fnName}: fmax must be non-negative`);\n }\n const effectiveFmax = fmax === 0 ? sampleRate / 2 : fmax;\n if (effectiveFmax <= fmin) {\n throw new RangeError(`${fnName}: fmax must be greater than fmin`);\n }\n}\n\nfunction validateMatrix(\n fnName: string,\n data: Float32Array,\n rows: number,\n frames: number,\n dataName: string,\n rowName: string,\n options: GuardedOptions = {},\n): void {\n validatePositiveIntegers(fnName, { [rowName]: rows, nFrames: frames });\n assertSamples(fnName, data, options.validate !== false, dataName);\n const expectedLength = rows * frames;\n if (!Number.isSafeInteger(expectedLength) || data.length !== expectedLength) {\n throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);\n }\n}\n\n/**\n * Trim silence from beginning and end of audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param thresholdDb - Silence threshold in dB (default: -60 dB)\n * @returns Trimmed audio\n */\nexport function trim(request: TrimRequest): Float32Array;\nexport function trim(\n samples: Float32Array,\n sampleRate: number,\n thresholdDb?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function trim(\n samples: Float32Array,\n sampleRate: number,\n thresholdDb?: number,\n frameLength?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function trim(\n samples: Float32Array | TrimRequest,\n sampleRate = 22050,\n thresholdDb = -60.0,\n frameLengthOrOptions?: number | GuardedOptions,\n hopLength?: number,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return trim(r.samples, r.sampleRate, r.thresholdDb, r.frameLength, r.hopLength, r);\n }\n if (frameLengthOrOptions === null) {\n throw new TypeError('trim: frameLength must be an integer or options object');\n }\n if (\n frameLengthOrOptions !== undefined &&\n typeof frameLengthOrOptions !== 'number' &&\n typeof frameLengthOrOptions !== 'object'\n ) {\n throw new TypeError('trim: frameLength must be an integer or options object');\n }\n const positionalOptions =\n typeof frameLengthOrOptions === 'object' && frameLengthOrOptions !== null\n ? frameLengthOrOptions\n : options;\n const positionalFrameLength =\n typeof frameLengthOrOptions === 'number' ? frameLengthOrOptions : undefined;\n const resolvedFrameLength = positionalFrameLength ?? 2048;\n const resolvedHopLength = hopLength === undefined ? 512 : hopLength;\n validateSpectrogramSamples('trim', samples, sampleRate, positionalOptions);\n assertFiniteScalar('trim', thresholdDb, 'thresholdDb');\n assertPositiveInteger('trim', resolvedFrameLength, 'frameLength');\n assertPositiveInteger('trim', resolvedHopLength, 'hopLength');\n if (resolvedFrameLength > 2 ** 31 - 1 || resolvedHopLength > 2 ** 31 - 1) {\n throw new RangeError('trim: frameLength and hopLength must fit in a signed 32-bit integer');\n }\n return requireModule().trimEx(\n samples,\n sampleRate,\n thresholdDb,\n resolvedFrameLength,\n resolvedHopLength,\n );\n}\n\n// ============================================================================\n// Features - Spectrogram\n// ============================================================================\n\n/**\n * Compute Short-Time Fourier Transform (STFT).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with magnitude and power spectrograms\n */\nexport function stft(request: SpectrogramRequest): StftResult;\nexport function stft(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): StftResult;\nexport function stft(\n samples: Float32Array | SpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): StftResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return stft(request.samples, request.sampleRate, request.nFft, request.hopLength, request);\n }\n validateSpectrogramSamples('stft', samples, sampleRate, options);\n validatePositiveIntegers('stft', { nFft, hopLength });\n return requireModule().stft(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute STFT and return magnitude in decibels.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with dB values\n */\nexport function stftDb(request: SpectrogramRequest): {\n nBins: number;\n nFrames: number;\n db: Float32Array;\n};\nexport function stftDb(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): { nBins: number; nFrames: number; db: Float32Array };\nexport function stftDb(\n samples: Float32Array | SpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): { nBins: number; nFrames: number; db: Float32Array } {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return stftDb(request.samples, request.sampleRate, request.nFft, request.hopLength, request);\n }\n validateSpectrogramSamples('stftDb', samples, sampleRate, options);\n validatePositiveIntegers('stftDb', { nFft, hopLength });\n return requireModule().stftDb(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute Chroma Energy Normalized Statistics.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function chromaCens(request: ChromaSpectrogramRequest): ChromaResult;\nexport function chromaCens(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n nChroma?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function chromaCens(\n samples: Float32Array | ChromaSpectrogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n binsPerOctave = 36,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return chromaCens(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.nChroma,\n request.binsPerOctave,\n request,\n );\n }\n validateSpectrogramSamples('chromaCens', samples, sampleRate, options);\n validatePositiveIntegers('chromaCens', { hopLength, nChroma, binsPerOctave });\n if (binsPerOctave % nChroma !== 0) {\n throw new RangeError('chromaCens: binsPerOctave must be a multiple of nChroma');\n }\n return requireModule().chromaCens(samples, sampleRate, hopLength, nChroma, binsPerOctave);\n}\n\n/**\n * Compute a constant-Q chromagram (librosa.feature.chroma_cqt).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function chromaCqt(request: ChromaSpectrogramRequest): ChromaResult;\nexport function chromaCqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n nChroma?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function chromaCqt(\n samples: Float32Array | ChromaSpectrogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n binsPerOctave = 36,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return chromaCqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.nChroma,\n request.binsPerOctave,\n request,\n );\n }\n validateSpectrogramSamples('chromaCqt', samples, sampleRate, options);\n validatePositiveIntegers('chromaCqt', { hopLength, nChroma, binsPerOctave });\n if (binsPerOctave % nChroma !== 0) {\n throw new RangeError('chromaCqt: binsPerOctave must be a multiple of nChroma');\n }\n return requireModule().chromaCqt(samples, sampleRate, hopLength, nChroma, binsPerOctave);\n}\n\n/**\n * Compute low-frequency bass chroma.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function bassChroma(request: ChromaSpectrogramRequest): ChromaResult;\nexport function bassChroma(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n nChroma?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function bassChroma(\n samples: Float32Array | ChromaSpectrogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return bassChroma(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.nChroma,\n request,\n );\n }\n validateSpectrogramSamples('bassChroma', samples, sampleRate, options);\n validatePositiveIntegers('bassChroma', { hopLength, nChroma });\n return requireModule().bassChroma(samples, sampleRate, hopLength, nChroma);\n}\n\n// ============================================================================\n// Features - Mel Spectrogram\n// ============================================================================\n\n/**\n * Compute Mel spectrogram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default).\n * Set with `fmax` to round-trip with `melToStft` / `melToAudio`.\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Mel spectrogram result\n */\nexport function melSpectrogram(request: MelSpectrogramRequest): MelSpectrogramResult;\nexport function melSpectrogram(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n fmin?: number,\n fmax?: number,\n htk?: boolean,\n options?: GuardedOptions,\n): MelSpectrogramResult;\nexport function melSpectrogram(\n samples: Float32Array | MelSpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n fmin = 0,\n fmax = 0,\n htk = false,\n options: GuardedOptions = {},\n): MelSpectrogramResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return melSpectrogram(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request.fmin,\n request.fmax,\n request.htk,\n request,\n );\n }\n validateSpectrogramSamples('melSpectrogram', samples, sampleRate, options);\n validatePositiveIntegers('melSpectrogram', { nFft, hopLength, nMels });\n validateMelFrequencyRange('melSpectrogram', fmin, fmax, sampleRate);\n return requireModule().melSpectrogram(\n samples,\n sampleRate,\n nFft,\n hopLength,\n nMels,\n fmin,\n fmax,\n htk,\n );\n}\n\n/**\n * Compute MFCC (Mel-Frequency Cepstral Coefficients).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param nMfcc - Number of MFCC coefficients (default: 20)\n * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @param lifter - Cepstral liftering coefficient (default: 0 = no liftering)\n * @returns MFCC result\n */\nexport function mfcc(request: MfccRequest): MfccResult;\nexport function mfcc(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n nMfcc?: number,\n fmin?: number,\n fmax?: number,\n htk?: boolean,\n lifter?: number,\n options?: GuardedOptions,\n): MfccResult;\nexport function mfcc(\n samples: Float32Array | MfccRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nMfcc = 20,\n fmin = 0,\n fmax = 0,\n htk = false,\n lifter = 0,\n options: GuardedOptions = {},\n): MfccResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return mfcc(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request.nMfcc,\n request.fmin,\n request.fmax,\n request.htk,\n request.lifter,\n request,\n );\n }\n validateSpectrogramSamples('mfcc', samples, sampleRate, options);\n validatePositiveIntegers('mfcc', { nFft, hopLength, nMels, nMfcc });\n validateMelFrequencyRange('mfcc', fmin, fmax, sampleRate);\n return requireModule().mfcc(\n samples,\n sampleRate,\n nFft,\n hopLength,\n nMels,\n nMfcc,\n fmin,\n fmax,\n htk,\n lifter,\n );\n}\n\n/** First-order regression delta of a row-major feature matrix. */\nexport function melDelta(request: MelDeltaRequest): Float32Array;\nexport function melDelta(\n features: Float32Array,\n nFeatures: number,\n nFrames: number,\n width?: number,\n): Float32Array;\nexport function melDelta(\n features: Float32Array | MelDeltaRequest,\n nFeatures?: number,\n nFrames?: number,\n width = 9,\n): Float32Array {\n const request: MelDeltaRequest =\n features instanceof Float32Array\n ? { features, nFeatures: nFeatures ?? 0, nFrames: nFrames ?? 0, width }\n : features;\n assertPositiveInteger('melDelta', request.nFeatures, 'nFeatures');\n assertPositiveInteger('melDelta', request.nFrames, 'nFrames');\n assertPositiveInteger('melDelta', request.width ?? 9, 'width');\n if ((request.width ?? 9) < 3 || (request.width ?? 9) % 2 === 0) {\n throw new RangeError('melDelta: width must be an odd integer of at least 3');\n }\n if (request.features.length !== request.nFeatures * request.nFrames) {\n throw new RangeError('melDelta: feature matrix length must equal nFeatures * nFrames');\n }\n return requireModule().melDelta(\n request.features,\n request.nFeatures,\n request.nFrames,\n request.width ?? 9,\n );\n}\n\n/** Auger-Flandrin reassigned spectrogram (row-major [nBins x nFrames] arrays). */\nexport function reassignedSpectrogram(\n request: ReassignedSpectrogramRequest,\n): ReassignedSpectrogramResult;\nexport function reassignedSpectrogram(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n refPower?: number,\n fillNan?: boolean,\n): ReassignedSpectrogramResult;\nexport function reassignedSpectrogram(\n samples: Float32Array | ReassignedSpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n refPower = 1e-6,\n fillNan = false,\n): ReassignedSpectrogramResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return reassignedSpectrogram(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.refPower,\n request.fillNan,\n );\n }\n assertSamples('reassignedSpectrogram', samples, true);\n assertSampleRate('reassignedSpectrogram', sampleRate);\n assertPositiveInteger('reassignedSpectrogram', nFft, 'nFft');\n assertPositiveInteger('reassignedSpectrogram', hopLength, 'hopLength');\n assertFiniteScalar('reassignedSpectrogram', refPower, 'refPower');\n if (refPower < 0) {\n throw new RangeError('reassignedSpectrogram: refPower must be non-negative');\n }\n return requireModule().reassignedSpectrogram(\n samples,\n sampleRate,\n nFft,\n hopLength,\n refPower,\n fillNan,\n );\n}\n\n// ============================================================================\n// Features - Inverse reconstruction\n// ============================================================================\n\n/**\n * Approximate inverse of a Mel filterbank: Mel power spectrogram -> STFT power\n * spectrogram. Mirrors `feature::mel_to_stft`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param fmin - Lower Mel band edge in Hz (default: 0)\n * @param fmax - Upper Mel band edge in Hz (default: sr/2 when 0)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns STFT power spectrogram result\n */\nexport function melToStft(request: MelToStftRequest): StftPowerResult;\nexport function melToStft(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate?: number,\n nFft?: number,\n fmin?: number,\n fmax?: number,\n htk?: boolean,\n options?: GuardedOptions,\n): StftPowerResult;\nexport function melToStft(\n melPower: Float32Array | MelToStftRequest,\n nMels = 0,\n nFrames = 0,\n sampleRate = 22050,\n nFft = 2048,\n fmin = 0,\n fmax = 0,\n htk = false,\n options: GuardedOptions = {},\n): StftPowerResult {\n if (!(melPower instanceof Float32Array)) {\n const request = melPower;\n return melToStft(\n request.melPower,\n request.nMels,\n request.nFrames,\n request.sampleRate,\n request.nFft,\n request.fmin,\n request.fmax,\n request.htk,\n request,\n );\n }\n assertSampleRate('melToStft', sampleRate);\n validateMatrix('melToStft', melPower, nMels, nFrames, 'melPower', 'nMels', options);\n validatePositiveIntegers('melToStft', { nFft });\n validateMelFrequencyRange('melToStft', fmin, fmax, sampleRate);\n return requireModule().melToStft(melPower, nMels, nFrames, sampleRate, nFft, fmin, fmax, htk);\n}\n\n/**\n * Reconstruct audio from a Mel power spectrogram via Griffin-Lim. Mirrors\n * `feature::mel_to_audio`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function melToAudio(request: MelToAudioRequest): Float32Array;\nexport function melToAudio(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n nIter?: number,\n htk?: boolean,\n options?: GuardedOptions,\n): Float32Array;\nexport function melToAudio(\n melPower: Float32Array | MelToAudioRequest,\n nMels = 0,\n nFrames = 0,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n htk = false,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(melPower instanceof Float32Array)) {\n const request = melPower;\n return melToAudio(\n request.melPower,\n request.nMels,\n request.nFrames,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.nIter,\n request.htk,\n request,\n );\n }\n assertSampleRate('melToAudio', sampleRate);\n validateMatrix('melToAudio', melPower, nMels, nFrames, 'melPower', 'nMels', options);\n validatePositiveIntegers('melToAudio', { nFft, hopLength, nIter });\n validateMelFrequencyRange('melToAudio', fmin, fmax, sampleRate);\n return requireModule().melToAudio(\n melPower,\n nMels,\n nFrames,\n sampleRate,\n nFft,\n hopLength,\n fmin,\n fmax,\n nIter,\n htk,\n );\n}\n\n/** Reconstruct audio from an STFT magnitude matrix via Griffin-Lim. */\nexport function griffinLim(request: GriffinLimRequest): Float32Array;\nexport function griffinLim(\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nIter?: number,\n momentum?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function griffinLim(\n magnitude: Float32Array | GriffinLimRequest,\n nBins = 0,\n nFrames = 0,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nIter = 32,\n momentum = 0.99,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(magnitude instanceof Float32Array)) {\n const request = magnitude;\n return griffinLim(\n request.magnitude,\n request.nBins,\n request.nFrames,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nIter,\n request.momentum,\n request,\n );\n }\n assertSampleRate('griffinLim', sampleRate);\n validateMatrix('griffinLim', magnitude, nBins, nFrames, 'magnitude', 'nBins', options);\n validatePositiveIntegers('griffinLim', { nFft, hopLength, nIter });\n return requireModule().griffinLim(\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n nFft,\n hopLength,\n nIter,\n momentum,\n );\n}\n\n/**\n * Invert MFCC coefficients back to a Mel power spectrogram. Mirrors\n * `feature::mfcc_to_mel`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins to reconstruct (default: 128)\n * @returns Mel power spectrogram result\n */\nexport function mfccToMel(request: MfccToMelRequest): MelPowerResult;\nexport function mfccToMel(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels?: number,\n lifter?: number,\n options?: GuardedOptions,\n): MelPowerResult;\nexport function mfccToMel(\n mfccCoefficients: Float32Array | MfccToMelRequest,\n nMfcc = 0,\n nFrames = 0,\n nMels = 128,\n lifter = 0,\n options: GuardedOptions = {},\n): MelPowerResult {\n if (!(mfccCoefficients instanceof Float32Array)) {\n const request = mfccCoefficients;\n return mfccToMel(\n request.mfccCoefficients,\n request.nMfcc,\n request.nFrames,\n request.nMels,\n request.lifter,\n request,\n );\n }\n validateMatrix(\n 'mfccToMel',\n mfccCoefficients,\n nMfcc,\n nFrames,\n 'mfccCoefficients',\n 'nMfcc',\n options,\n );\n validatePositiveIntegers('mfccToMel', { nMels });\n return requireModule().mfccToMel(mfccCoefficients, nMfcc, nFrames, nMels, lifter);\n}\n\n/**\n * Reconstruct audio directly from MFCC coefficients via Griffin-Lim. Mirrors\n * `feature::mfcc_to_audio`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins (default: 128)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function mfccToAudio(request: MfccToAudioRequest): Float32Array;\nexport function mfccToAudio(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels?: number,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n nIter?: number,\n htk?: boolean,\n lifter?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function mfccToAudio(\n mfccCoefficients: Float32Array | MfccToAudioRequest,\n nMfcc = 0,\n nFrames = 0,\n nMels = 128,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n htk = false,\n lifter = 0,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(mfccCoefficients instanceof Float32Array)) {\n const request = mfccCoefficients;\n return mfccToAudio(\n request.mfccCoefficients,\n request.nMfcc,\n request.nFrames,\n request.nMels,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.nIter,\n request.htk,\n request.lifter,\n request,\n );\n }\n assertSampleRate('mfccToAudio', sampleRate);\n validateMatrix(\n 'mfccToAudio',\n mfccCoefficients,\n nMfcc,\n nFrames,\n 'mfccCoefficients',\n 'nMfcc',\n options,\n );\n validatePositiveIntegers('mfccToAudio', { nMels, nFft, hopLength, nIter });\n validateMelFrequencyRange('mfccToAudio', fmin, fmax, sampleRate);\n return requireModule().mfccToAudio(\n mfccCoefficients,\n nMfcc,\n nFrames,\n nMels,\n sampleRate,\n nFft,\n hopLength,\n fmin,\n fmax,\n nIter,\n htk,\n lifter,\n );\n}\n\n// ============================================================================\n// Features - Chroma\n// ============================================================================\n\n/**\n * Compute STFT chromagram (librosa.feature.chroma_stft).\n *\n * The chroma filterbank uses a fixed tuning of 0 (concert A440). Unlike\n * librosa.feature.chroma_stft — which estimates tuning from the signal when none\n * is given — this does NOT auto-estimate and exposes no tuning argument, so\n * sharp/flat (non-A440) recordings smear across pitch classes. Estimate tuning\n * separately via {@link estimateTuning} if a non-A440 reference matters.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Chroma features result\n */\nexport function chroma(request: SpectrogramRequest): ChromaResult;\nexport function chroma(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function chroma(\n samples: Float32Array | SpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return chroma(request.samples, request.sampleRate, request.nFft, request.hopLength, request);\n }\n validateSpectrogramSamples('chroma', samples, sampleRate, options);\n validatePositiveIntegers('chroma', { nFft, hopLength });\n return requireModule().chroma(samples, sampleRate, nFft, hopLength);\n}\n","import { ErrorCode, SonareError } from './errors';\nimport { getSonareModule } from './module_state';\nimport type { ValidateOptions } from './validation';\nimport { assertSamples } from './validation';\n\n/**\n * Validates a true-peak oversample factor: `0` (meaning \"use the default 4\") or\n * a power of two in `[1, 16]`. The native layer applies the same `0 -> 4`\n * normalization (see `metering::true_peak_db`), so the raw factor can be passed\n * through unchanged after this check. Kept module-local (not exported) so it does\n * not surface as a WASM-only symbol with no C-API counterpart.\n */\nfunction assertOversampleFactor(fnName: string, factor: number): void {\n const normalized = factor === 0 ? 4 : factor;\n if (\n !Number.isInteger(normalized) ||\n normalized < 1 ||\n normalized > 16 ||\n (normalized & (normalized - 1)) !== 0\n ) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n `${fnName}: oversampleFactor must be 0 or a power of two from 1 to 16`,\n );\n }\n}\n\n// ============================================================================\n// Metering — basic / true-peak / clipping / dynamic range\n// ============================================================================\n\n/** One contiguous run of clipped samples reported by `meteringDetectClipping`. */\nexport interface ClippingRegion {\n startSample: number;\n endSample: number;\n length: number;\n peak: number;\n}\n\n/** Aggregated clipping report. */\nexport interface ClippingReport {\n clippedSamples: number;\n clippingRatio: number;\n maxClippedPeak: number;\n regions: ClippingRegion[];\n}\n\n/** Sliding-window dynamic range report. */\nexport interface DynamicRangeReport {\n dynamicRangeDb: number;\n lowPercentileDb: number;\n highPercentileDb: number;\n windowRmsDb: Float32Array;\n}\n\n/** Options for {@link meteringDetectClipping}. All fields are optional. */\nexport interface MeteringDetectClippingOptions extends ValidateOptions {\n /** Linear absolute threshold. Default 0.999. */\n threshold?: number;\n /** Minimum run length to report. Default 1. */\n minRegionSamples?: number;\n}\n\n/** Options for {@link meteringDynamicRange}. All fields are optional. */\nexport interface MeteringDynamicRangeOptions extends ValidateOptions {\n /** Window length in seconds (0 = library default, 3 s). Default 0. */\n windowSec?: number;\n /** Hop length in seconds (0 = library default, 1 s). Default 0. */\n hopSec?: number;\n /** Low percentile in [0,1] (negative = library default, 0.10). Default -1. */\n lowPercentile?: number;\n /** High percentile in [0,1] (negative = library default, 0.95). Default -1. */\n highPercentile?: number;\n}\n\n/** Canonical request form for single-channel meter readings. */\nexport interface MeteringSamplesRequest extends ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for true-peak analysis. */\nexport interface MeteringTruePeakRequest extends MeteringSamplesRequest {\n oversampleFactor?: number;\n}\n\n/** Canonical request form for clipping analysis. */\nexport interface MeteringDetectClippingRequest extends MeteringDetectClippingOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for dynamic-range analysis. */\nexport interface MeteringDynamicRangeRequest extends MeteringDynamicRangeOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nexport function meteringPeakDb(request: MeteringSamplesRequest): number;\nexport function meteringPeakDb(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringPeakDb(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringPeakDb', request.samples, request.validate !== false);\n return requireModule().meteringPeakDb(request.samples, request.sampleRate ?? 22050);\n}\n\nexport function meteringRmsDb(request: MeteringSamplesRequest): number;\nexport function meteringRmsDb(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringRmsDb(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringRmsDb', request.samples, request.validate !== false);\n return requireModule().meteringRmsDb(request.samples, request.sampleRate ?? 22050);\n}\n\nexport interface MeteringSilenceRatioRequest extends MeteringSamplesRequest {\n thresholdDb?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\nexport function meteringSilenceRatio(request: MeteringSilenceRatioRequest): number;\nexport function meteringSilenceRatio(\n samples: Float32Array,\n sampleRate?: number,\n thresholdDb?: number,\n frameLength?: number,\n hopLength?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringSilenceRatio(\n samples: Float32Array | MeteringSilenceRatioRequest,\n sampleRate = 22050,\n thresholdDb = -45,\n frameLength = 1024,\n hopLength = 256,\n options: ValidateOptions = {},\n): number {\n const request =\n samples instanceof Float32Array\n ? { samples, sampleRate, thresholdDb, frameLength, hopLength, ...options }\n : samples;\n assertSamples('meteringSilenceRatio', request.samples, request.validate !== false);\n return requireModule().meteringSilenceRatio(\n request.samples,\n request.sampleRate ?? 22050,\n request.thresholdDb ?? -45,\n request.frameLength ?? 1024,\n request.hopLength ?? 256,\n );\n}\n\nexport function meteringCrestFactorDb(request: MeteringSamplesRequest): number;\nexport function meteringCrestFactorDb(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringCrestFactorDb(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringCrestFactorDb', request.samples, request.validate !== false);\n return requireModule().meteringCrestFactorDb(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Crest factor in dB across both channels of a stereo pair.\n *\n * Takes the peak across both channels and the RMS over both together. An\n * out-of-phase pair cancels in the `0.5 * (left + right)` downmix\n * {@link meteringCrestFactorDb} would need, which understates its RMS and so\n * overstates the crest factor.\n */\nexport function meteringCrestFactorDbStereo(request: MeteringStereoRequest): number {\n assertSamples('meteringCrestFactorDbStereo', request.left, request.validate !== false);\n assertSamples('meteringCrestFactorDbStereo', request.right, request.validate !== false);\n return requireModule().meteringCrestFactorDbStereo(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n );\n}\n\nexport function meteringDcOffset(request: MeteringSamplesRequest): number;\nexport function meteringDcOffset(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringDcOffset(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringDcOffset', request.samples, request.validate !== false);\n return requireModule().meteringDcOffset(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Inter-sample (true) peak in dBFS. `oversampleFactor` must be a power of two\n * in [1, 16]; pass 0 to use the library default (4).\n */\nexport function meteringTruePeakDb(request: MeteringTruePeakRequest): number;\nexport function meteringTruePeakDb(\n samples: Float32Array,\n sampleRate?: number,\n oversampleFactor?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringTruePeakDb(\n samples: Float32Array | MeteringTruePeakRequest,\n sampleRate = 22050,\n oversampleFactor = 4,\n options: ValidateOptions = {},\n): number {\n const request =\n samples instanceof Float32Array\n ? { samples, sampleRate, oversampleFactor, ...options }\n : samples;\n assertSamples('meteringTruePeakDb', request.samples, request.validate !== false);\n const factor = request.oversampleFactor ?? 4;\n assertOversampleFactor('meteringTruePeakDb', factor);\n return requireModule().meteringTruePeakDb(request.samples, request.sampleRate ?? 22050, factor);\n}\n\n/**\n * Detect contiguous runs of clipped samples.\n *\n * @param threshold Linear absolute threshold (default 0.999).\n * @param minRegionSamples Minimum run length to report (default 1).\n */\nexport function meteringDetectClipping(request: MeteringDetectClippingRequest): ClippingReport;\nexport function meteringDetectClipping(\n samples: Float32Array,\n sampleRate?: number,\n options?: MeteringDetectClippingOptions,\n): ClippingReport;\nexport function meteringDetectClipping(\n samples: Float32Array | MeteringDetectClippingRequest,\n sampleRate = 22050,\n options: MeteringDetectClippingOptions = {},\n): ClippingReport {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringDetectClipping', request.samples, request.validate !== false);\n const minRegionSamples = request.minRegionSamples ?? 1;\n if (!Number.isInteger(minRegionSamples) || minRegionSamples < 0) {\n throw new RangeError('meteringDetectClipping: minRegionSamples must be a non-negative integer');\n }\n return requireModule().meteringDetectClipping(\n request.samples,\n request.sampleRate ?? 22050,\n request.threshold ?? 0.999,\n minRegionSamples,\n );\n}\n\n/**\n * Sliding-window dynamic range for mono audio. Pass 0 for window/hop to use the library\n * default (window=3 s, hop=1 s). The percentiles use a NEGATIVE sentinel for\n * \"use the library default\" (low=0.10, high=0.95) because 0 is a literal 0th\n * percentile; omitted percentiles therefore default to -1.\n */\nexport function meteringDynamicRange(request: MeteringDynamicRangeRequest): DynamicRangeReport;\nexport function meteringDynamicRange(\n samples: Float32Array,\n sampleRate?: number,\n options?: MeteringDynamicRangeOptions,\n): DynamicRangeReport;\nexport function meteringDynamicRange(\n samples: Float32Array | MeteringDynamicRangeRequest,\n sampleRate = 22050,\n options: MeteringDynamicRangeOptions = {},\n): DynamicRangeReport {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringDynamicRange', request.samples, request.validate !== false);\n return requireModule().meteringDynamicRange(\n request.samples,\n request.sampleRate ?? 22050,\n request.windowSec ?? 0,\n request.hopSec ?? 0,\n request.lowPercentile ?? -1,\n request.highPercentile ?? -1,\n );\n}\n\n// ============================================================================\n// Metering — stereo / phase-scope / spectrum\n// ============================================================================\n\n/** Mid/side vectorscope point series for a (left, right) stereo pair. */\nexport interface VectorscopeReport {\n mid: Float32Array;\n side: Float32Array;\n}\n\n/** Phase-scope (Lissajous) point series plus summary stats. */\nexport interface PhaseScopeReport {\n mid: Float32Array;\n side: Float32Array;\n radius: Float32Array;\n angleRad: Float32Array;\n correlation: number;\n averageAbsAngleRad: number;\n maxRadius: number;\n}\n\n/** Options for `meteringSpectrum`. */\nexport interface SpectrumOptions {\n /** FFT size. Pass 0 / omit for the library default (2048). */\n nFft?: number;\n /** Apply fractional-octave smoothing to magnitude. */\n applyOctaveSmoothing?: boolean;\n /** Smoothing fraction (e.g. 3 = 1/3-octave). 0 / omit = library default (3). */\n octaveFraction?: number;\n /** Linear reference for the dB conversion. 0 / omit = 1.0. */\n dbRef?: number;\n /** Linear floor used to avoid log(0). 0 / omit = library default. */\n dbAmin?: number;\n}\n\n/** Single-frame magnitude / power / dB spectrum returned by `meteringSpectrum`. */\nexport interface SpectrumReport {\n frequencies: Float32Array;\n magnitude: Float32Array;\n power: Float32Array;\n db: Float32Array;\n nFft: number;\n sampleRate: number;\n}\n\n/** Options for {@link waveformPeaks}. All fields are optional. */\nexport interface WaveformPeaksOptions extends ValidateOptions {\n /** Bucket width in frames. Default 512. */\n samplesPerBucket?: number;\n}\n\n/** Options for {@link waveformPeakPyramid}. All fields are optional. */\nexport interface WaveformPeakPyramidOptions extends ValidateOptions {\n /** Bucket widths in frames, one per zoom level. Default [512, 1024, 2048, 4096]. */\n samplesPerBucketLevels?: number[];\n}\n\n/** Canonical request form for stereo meter readings. */\nexport interface MeteringStereoRequest extends ValidateOptions {\n left: Float32Array;\n right: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for display-decimated stereo scopes. */\nexport interface MeteringStereoDecimatedRequest extends MeteringStereoRequest {\n maxPoints?: number;\n}\n\n/** Options for the scope functions (mirrors the Node `ScopeOptions`). */\nexport interface ScopeOptions extends ValidateOptions {\n /**\n * Upper bound on the returned point count. Omit / `0` (or a value `>= length`)\n * yields one point per input sample; otherwise the point cloud is\n * deterministically decimated to at most `maxPoints` points for display.\n */\n maxPoints?: number;\n}\n\n/** Canonical request form for whole-signal spectrum analysis. */\nexport interface MeteringSpectrumRequest extends SpectrumOptions, ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for a single spectrum frame. */\nexport interface MeteringSpectrumFrameRequest extends MeteringSpectrumRequest {\n frameOffset?: number;\n}\n\n/** Canonical request form for waveform bucket generation. */\nexport interface WaveformPeaksRequest extends WaveformPeaksOptions {\n samples: Float32Array;\n channels: number;\n}\n\n/** Canonical request form for multi-resolution waveform bucket generation. */\nexport interface WaveformPeakPyramidRequest extends WaveformPeakPyramidOptions {\n samples: Float32Array;\n channels: number;\n}\n\n/** Per-channel min/max waveform buckets. Arrays are channel-major. */\nexport interface WaveformPeaksReport {\n min: Float32Array;\n max: Float32Array;\n channels: number;\n bucketCount: number;\n samplesPerBucket: number;\n}\n\n/** Uncentered correlation (cosine similarity) in [-1, 1] between equal-length channels. */\nexport function meteringStereoCorrelation(request: MeteringStereoRequest): number;\nexport function meteringStereoCorrelation(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringStereoCorrelation(\n left: Float32Array | MeteringStereoRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringStereoCorrelation', request.left, validate, 'left');\n assertSamples('meteringStereoCorrelation', request.right, validate, 'right');\n return requireModule().meteringStereoCorrelation(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n );\n}\n\n/**\n * Side / mid energy ratio in `[0, +Infinity)`: 0 = pure mono, ~1 = wide stereo,\n * larger = increasingly decorrelated / out-of-phase. The value is unbounded and\n * returns `Infinity` when the mid channel is silent (a mono-collapsed / fully\n * out-of-phase signal).\n */\nexport function meteringStereoWidth(request: MeteringStereoRequest): number;\nexport function meteringStereoWidth(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringStereoWidth(\n left: Float32Array | MeteringStereoRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringStereoWidth', request.left, validate, 'left');\n assertSamples('meteringStereoWidth', request.right, validate, 'right');\n return requireModule().meteringStereoWidth(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n );\n}\n\n/**\n * Mid/side vectorscope point series. By default emits one point per input\n * sample; pass `maxPoints` to get a display-sized decimated point set (matching\n * the Node `meteringVectorscope` shape).\n */\nexport function meteringVectorscope(request: MeteringStereoDecimatedRequest): VectorscopeReport;\nexport function meteringVectorscope(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ScopeOptions,\n): VectorscopeReport;\nexport function meteringVectorscope(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ScopeOptions = {},\n): VectorscopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringVectorscope', request.left, validate, 'left');\n assertSamples('meteringVectorscope', request.right, validate, 'right');\n return requireModule().meteringVectorscopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Display-sized mid/side vectorscope.\n *\n * @deprecated Pass `maxPoints` to {@link meteringVectorscope} instead; it now\n * folds `maxPoints` into the request, matching the Node surface. This alias is\n * kept for backward compatibility and simply delegates.\n */\nexport function meteringVectorscopeDecimated(\n request: MeteringStereoDecimatedRequest,\n): VectorscopeReport;\nexport function meteringVectorscopeDecimated(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n maxPoints?: number,\n options?: ValidateOptions,\n): VectorscopeReport;\nexport function meteringVectorscopeDecimated(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n maxPoints = 0,\n options: ValidateOptions = {},\n): VectorscopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, maxPoints, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringVectorscopeDecimated', request.left, validate, 'left');\n assertSamples('meteringVectorscopeDecimated', request.right, validate, 'right');\n return requireModule().meteringVectorscopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Phase-scope point series plus summary stats. By default emits one point per\n * input sample; pass `maxPoints` to decimate the point cloud for display\n * (matching the Node `meteringPhaseScope` shape). The summary stats are always\n * computed over the full-resolution signal.\n */\nexport function meteringPhaseScope(request: MeteringStereoDecimatedRequest): PhaseScopeReport;\nexport function meteringPhaseScope(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ScopeOptions,\n): PhaseScopeReport;\nexport function meteringPhaseScope(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ScopeOptions = {},\n): PhaseScopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringPhaseScope', request.left, validate, 'left');\n assertSamples('meteringPhaseScope', request.right, validate, 'right');\n return requireModule().meteringPhaseScopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Display-sized phase scope.\n *\n * @deprecated Pass `maxPoints` to {@link meteringPhaseScope} instead; it now\n * folds `maxPoints` into the request, matching the Node surface. This alias is\n * kept for backward compatibility and simply delegates.\n */\nexport function meteringPhaseScopeDecimated(\n request: MeteringStereoDecimatedRequest,\n): PhaseScopeReport;\nexport function meteringPhaseScopeDecimated(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n maxPoints?: number,\n options?: ValidateOptions,\n): PhaseScopeReport;\nexport function meteringPhaseScopeDecimated(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n maxPoints = 0,\n options: ValidateOptions = {},\n): PhaseScopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, maxPoints, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringPhaseScopeDecimated', request.left, validate, 'left');\n assertSamples('meteringPhaseScopeDecimated', request.right, validate, 'right');\n return requireModule().meteringPhaseScopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Welch-averaged magnitude / power / dB spectrum over the WHOLE mono signal (split\n * into Hann-windowed, 50%-overlapping `nFft`-length frames whose power spectra\n * are averaged). For a true single-frame snapshot, use\n * {@link meteringSpectrumFrame}.\n */\nexport function meteringSpectrum(request: MeteringSpectrumRequest): SpectrumReport;\nexport function meteringSpectrum(\n samples: Float32Array,\n sampleRate?: number,\n options?: SpectrumOptions & ValidateOptions,\n): SpectrumReport;\nexport function meteringSpectrum(\n samples: Float32Array | MeteringSpectrumRequest,\n sampleRate = 22050,\n options: SpectrumOptions & ValidateOptions = {},\n): SpectrumReport {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringSpectrum', request.samples, request.validate !== false);\n return requireModule().meteringSpectrum(request.samples, request.sampleRate ?? 22050, request);\n}\n\n/**\n * True single-frame magnitude / power / dB spectrum (one Hann-windowed\n * `nFft`-length FFT), for spectrum-analyzer \"moment\" snapshots that must not be\n * time-averaged like {@link meteringSpectrum}. The analysis frame spans\n * `[frameOffset, frameOffset + nFft)`; samples past the end are zero-padded.\n */\nexport function meteringSpectrumFrame(request: MeteringSpectrumFrameRequest): SpectrumReport;\nexport function meteringSpectrumFrame(\n samples: Float32Array,\n sampleRate?: number,\n frameOffset?: number,\n options?: SpectrumOptions & ValidateOptions,\n): SpectrumReport;\nexport function meteringSpectrumFrame(\n samples: Float32Array | MeteringSpectrumFrameRequest,\n sampleRate = 22050,\n frameOffset = 0,\n options: SpectrumOptions & ValidateOptions = {},\n): SpectrumReport {\n const request =\n samples instanceof Float32Array ? { samples, sampleRate, frameOffset, ...options } : samples;\n assertSamples('meteringSpectrumFrame', request.samples, request.validate !== false);\n return requireModule().meteringSpectrumFrame(\n request.samples,\n request.sampleRate ?? 22050,\n request.frameOffset ?? 0,\n request,\n );\n}\n\n/** Compute per-channel min/max waveform buckets from interleaved audio. */\nexport function waveformPeaks(request: WaveformPeaksRequest): WaveformPeaksReport;\nexport function waveformPeaks(\n samples: Float32Array,\n channels: number,\n options?: WaveformPeaksOptions,\n): WaveformPeaksReport;\nexport function waveformPeaks(\n samples: Float32Array | WaveformPeaksRequest,\n channels?: number,\n options: WaveformPeaksOptions = {},\n): WaveformPeaksReport {\n const request =\n samples instanceof Float32Array\n ? { samples, channels: channels as number, ...options }\n : samples;\n assertSamples('waveformPeaks', request.samples, request.validate !== false);\n if (request.channels <= 0 || request.samples.length % request.channels !== 0) {\n throw new RangeError('waveformPeaks: samples length must be a multiple of channels');\n }\n const samplesPerBucket = request.samplesPerBucket ?? 512;\n if (samplesPerBucket <= 0) {\n throw new RangeError('waveformPeaks: samplesPerBucket must be > 0');\n }\n return requireModule().waveformPeaks(request.samples, request.channels, samplesPerBucket);\n}\n\n/** Compute waveform peak buckets for several zoom levels. */\nexport function waveformPeakPyramid(request: WaveformPeakPyramidRequest): WaveformPeaksReport[];\nexport function waveformPeakPyramid(\n samples: Float32Array,\n channels: number,\n options?: WaveformPeakPyramidOptions,\n): WaveformPeaksReport[];\nexport function waveformPeakPyramid(\n samples: Float32Array | WaveformPeakPyramidRequest,\n channels?: number,\n options: WaveformPeakPyramidOptions = {},\n): WaveformPeaksReport[] {\n const request =\n samples instanceof Float32Array\n ? { samples, channels: channels as number, ...options }\n : samples;\n assertSamples('waveformPeakPyramid', request.samples, request.validate !== false);\n if (request.channels <= 0 || request.samples.length % request.channels !== 0) {\n throw new RangeError('waveformPeakPyramid: samples length must be a multiple of channels');\n }\n const levels = request.samplesPerBucketLevels ?? [512, 1024, 2048, 4096];\n if (levels.length === 0 || levels.some((level) => level <= 0)) {\n throw new RangeError('waveformPeakPyramid: samplesPerBucketLevels must be non-empty and > 0');\n }\n return requireModule().waveformPeakPyramid(request.samples, request.channels, levels);\n}\n","import type { ValidateOptions } from './validation';\n\n/**\n * Pitch class enum (C=0, C#=1, ..., B=11)\n */\nexport const PitchClass = {\n C: 0,\n Cs: 1,\n D: 2,\n Ds: 3,\n E: 4,\n F: 5,\n Fs: 6,\n G: 7,\n Gs: 8,\n A: 9,\n As: 10,\n B: 11,\n} as const;\n\nexport type PitchClass = (typeof PitchClass)[keyof typeof PitchClass];\n\n/**\n * Musical mode\n */\nexport const Mode = {\n Major: 0,\n Minor: 1,\n Dorian: 2,\n Phrygian: 3,\n Lydian: 4,\n Mixolydian: 5,\n Locrian: 6,\n} as const;\n\nexport type Mode = (typeof Mode)[keyof typeof Mode];\n\nexport type TempogramMode = 'autocorrelation' | 'auto' | 'ac' | 'cosine' | 0 | 1;\n\nexport const KeyProfile = {\n KrumhanslSchmuckler: 0,\n Temperley: 1,\n Shaath: 2,\n FaraldoEDMT: 3,\n FaraldoEDMA: 4,\n FaraldoEDMM: 5,\n BellmanBudge: 6,\n} as const;\n\nexport type KeyProfile = (typeof KeyProfile)[keyof typeof KeyProfile];\n\nexport type KeyProfileName =\n | 'ks'\n | 'krumhansl'\n | 'temperley'\n | 'shaath'\n | 'keyfinder'\n | 'faraldo-edmt'\n | 'edmt'\n | 'faraldo-edma'\n | 'edma'\n | 'faraldo-edmm'\n | 'edmm'\n | 'bellman-budge'\n | 'bellman';\n\n/**\n * Chord quality\n */\nexport const ChordQuality = {\n Major: 0,\n Minor: 1,\n Diminished: 2,\n Augmented: 3,\n Dominant7: 4,\n Major7: 5,\n Minor7: 6,\n Sus2: 7,\n Sus4: 8,\n Unknown: 9,\n Add9: 10,\n MinorAdd9: 11,\n Dim7: 12,\n HalfDim7: 13,\n Major9: 14,\n Dominant9: 15,\n Sus2Add4: 16,\n} as const;\n\nexport type ChordQuality = (typeof ChordQuality)[keyof typeof ChordQuality];\n\n/**\n * Section type\n */\nexport const SectionType = {\n Intro: 0,\n Verse: 1,\n PreChorus: 2,\n Chorus: 3,\n Bridge: 4,\n Instrumental: 5,\n Outro: 6,\n Unknown: 7,\n} as const;\n\nexport type SectionType = (typeof SectionType)[keyof typeof SectionType];\n\n/**\n * Detected musical key\n */\nexport interface Key {\n root: PitchClass;\n mode: Mode;\n confidence: number;\n name: string;\n shortName: string;\n}\n\nexport interface KeyDetectionOptions extends ValidateOptions {\n nFft?: number;\n hopLength?: number;\n useHpss?: boolean;\n loudnessWeighted?: boolean;\n highPassHz?: number;\n modes?:\n | Mode[]\n | ('major' | 'minor' | 'dorian' | 'phrygian' | 'lydian' | 'mixolydian' | 'locrian')[]\n | 'major-minor'\n | 'all'\n | 'modal';\n profile?: KeyProfile | KeyProfileName;\n genreHint?: 'auto' | 'edm' | 'electronic' | 'dance' | 'pop' | 'classical' | 'jazz' | string;\n}\n\nexport interface KeyCandidate {\n key: Key;\n correlation: number;\n}\n\nexport interface ChordDetectionOptions extends ValidateOptions {\n minDuration?: number;\n smoothingWindow?: number;\n /** Final-template correlation threshold in [0, 1]; below it emits Unknown / N.C. */\n threshold?: number;\n useTriadsOnly?: boolean;\n nFft?: number;\n hopLength?: number;\n useBeatSync?: boolean;\n useHmm?: boolean;\n hmmBeamWidth?: number;\n useKeyContext?: boolean;\n keyRoot?: PitchClass;\n keyMode?: Mode;\n detectInversions?: boolean;\n chromaMethod?: 'stft' | 'nnls';\n}\n\n/** Options for `analyzeBpm`. All fields are optional. */\nexport interface AnalyzeBpmOptions extends ValidateOptions {\n /** Lowest BPM to consider. Default 30. */\n bpmMin?: number;\n /** Highest BPM to consider. Default 300. */\n bpmMax?: number;\n /** Tempo prior the tracker is biased toward. Default 120. */\n startBpm?: number;\n /** FFT size for the onset envelope. Default 2048. */\n nFft?: number;\n /** Hop length for the onset envelope. Default 512. */\n hopLength?: number;\n /** Number of tempo candidates to return. Default 5. */\n maxCandidates?: number;\n}\n\n/** Options for `analyzeRhythm`. All fields are optional. */\nexport interface AnalyzeRhythmOptions extends ValidateOptions {\n /** Lowest BPM to consider. Default 60. */\n bpmMin?: number;\n /** Highest BPM to consider. Default 200. */\n bpmMax?: number;\n /** Tempo prior the tracker is biased toward. Default 120. */\n startBpm?: number;\n /** FFT size for the onset envelope. Default 2048. */\n nFft?: number;\n /** Hop length for the onset envelope. Default 512. */\n hopLength?: number;\n}\n\n/** Options for `analyzeDynamics`. All fields are optional. */\nexport interface AnalyzeDynamicsOptions extends ValidateOptions {\n /** Loudness-curve window length in seconds. Default 0.4. */\n windowSec?: number;\n /** Hop length for the loudness curve. Default 512. */\n hopLength?: number;\n /** Crest-factor (dB) below which the signal is flagged as compressed. Default 6. */\n compressionThreshold?: number;\n}\n\n/** Options for `analyzeTimbre`. All fields are optional. */\nexport interface AnalyzeTimbreOptions extends ValidateOptions {\n /** FFT size. Default 2048. */\n nFft?: number;\n /** Hop length. Default 512. */\n hopLength?: number;\n /** Number of Mel bands. Default 128. */\n nMels?: number;\n /** Number of MFCCs. Default 13. */\n nMfcc?: number;\n /** Per-window analysis length in seconds. Default 0.5. */\n windowSec?: number;\n}\n\n/** Options for `analyzeSections`. All fields are optional. */\nexport interface AnalyzeSectionsOptions {\n /** FFT size. Default 2048. */\n nFft?: number;\n /** Hop length. Default 512. */\n hopLength?: number;\n /** Minimum section duration in seconds. Default 4. */\n minSectionSec?: number;\n}\n\n/**\n * Detected beat\n */\nexport interface Beat {\n time: number;\n strength: number;\n}\n\n/**\n * Detected chord\n */\nexport interface Chord {\n root: PitchClass;\n bass: PitchClass;\n /** Canonical core spelling; stable across all language bindings. */\n rootName: string;\n /** Canonical core spelling; stable across all language bindings. */\n bassName: string;\n quality: ChordQuality;\n start: number;\n end: number;\n confidence: number;\n name: string;\n}\n\nexport interface ChordAnalysisResult {\n chords: Chord[];\n}\n\n/**\n * Detected section\n */\nexport interface Section {\n type: SectionType;\n start: number;\n end: number;\n energyLevel: number;\n confidence: number;\n name: string;\n}\n\n/**\n * A single melody contour point (mirrors the C `SonareMelodyPoint`).\n */\nexport interface MelodyPoint {\n /** Frame time in seconds. */\n time: number;\n /** Estimated fundamental frequency in Hz (0 when unvoiced). */\n frequency: number;\n /** Voicing confidence in `[0, 1]`. */\n confidence: number;\n}\n\n/**\n * Melody analysis result (mirrors the C `SonareMelodyResult`).\n */\nexport interface MelodyResult {\n points: MelodyPoint[];\n pitchRangeOctaves: number;\n pitchStability: number;\n meanFrequency: number;\n vibratoRate: number;\n}\n\n/**\n * Timbre characteristics\n */\nexport interface Timbre {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\n/**\n * Dynamics characteristics\n */\nexport interface Dynamics {\n dynamicRangeDb: number;\n peakDb: number;\n rmsDb: number;\n loudnessRangeDb: number;\n crestFactor: number;\n isCompressed: boolean;\n}\n\n/**\n * Time signature\n */\nexport interface TimeSignature {\n numerator: number;\n denominator: number;\n confidence: number;\n}\n\n/** Existing tempo-estimator hypothesis retained by unified analysis. */\nexport interface BpmHypothesis {\n value: number;\n confidence: number;\n relation: 'primary' | 'half' | 'double' | 'other';\n}\n\n/**\n * Rhythm features\n */\nexport interface RhythmFeatures {\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n tempoStability: number;\n timeSignature: TimeSignature;\n}\n\n/**\n * Melody contour from the unified analysis (pitch trajectory + summary stats).\n */\nexport interface MelodyContour {\n pitchRangeOctaves: number;\n pitchStability: number;\n meanFrequency: number;\n vibratoRate: number;\n pitches: MelodyPoint[];\n}\n\n/**\n * Complete analysis result\n */\nexport interface AnalysisResult {\n bpm: number;\n bpmConfidence: number;\n bpmCandidates: BpmHypothesis[];\n key: Key;\n timeSignature: TimeSignature;\n timeSignatureCandidates: TimeSignature[];\n beatTimes: Float32Array;\n beats: Beat[];\n chords: Chord[];\n sections: Section[];\n timbre: Timbre;\n dynamics: Dynamics;\n rhythm: RhythmFeatures;\n melody: MelodyContour;\n form: string;\n}\n","import type { AutomationCurve, MeterTap, PanLawInput, PanMode, SendTiming } from './public_types';\n\n/** Resolve a numeric ordinal in an inclusive range without coercion. */\nexport function resolveOrdinalInRange(\n value: unknown,\n min: number,\n max: number,\n enumName: string,\n): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < min || value > max) {\n throw new RangeError(`Invalid ${enumName}: ${String(value)}`);\n }\n return value;\n}\n\n/** Resolve a public enum spelling or ordinal without permitting unknown values. */\nexport function resolveEnumOrdinal(\n value: unknown,\n values: Readonly<Record<string, number>>,\n enumName: string,\n): number {\n if (typeof value === 'number') {\n const ordinals = Object.values(values);\n const ordinal = resolveOrdinalInRange(\n value,\n Math.min(...ordinals),\n Math.max(...ordinals),\n enumName,\n );\n if (!ordinals.includes(ordinal)) {\n throw new RangeError(`Invalid ${enumName}: ${String(value)}`);\n }\n return ordinal;\n }\n if (typeof value === 'string') {\n const ordinal = values[value];\n if (ordinal !== undefined) {\n return ordinal;\n }\n }\n throw new RangeError(`Invalid ${enumName}: ${String(value)}`);\n}\n\nconst AUTOMATION_CURVE_VALUES = {\n linear: 0,\n exponential: 1,\n hold: 2,\n 's-curve': 3,\n} as const;\nconst PAN_LAW_VALUES: Readonly<Record<string, number>> = {\n const3db: 0,\n 'const-3db': 0,\n '-3db': 0,\n 'const4.5db': 1,\n 'const-4.5db': 1,\n '-4.5db': 1,\n const6db: 2,\n 'const-6db': 2,\n '-6db': 2,\n linear0db: 3,\n 'linear-0db': 3,\n linear: 3,\n '0db': 3,\n} as const;\nconst PAN_MODE_VALUES = {\n balance: 0,\n pan: 1,\n stereopan: 1,\n 'stereo-pan': 1,\n dualpan: 2,\n 'dual-pan': 2,\n} as const;\nconst METER_TAP_VALUES = { preFader: 0, postFader: 1 } as const;\nconst SEND_TIMING_VALUES = { postFader: 0, preFader: 1 } as const;\nconst TRACK_MONITOR_MODE_VALUES = { off: 0, pfl: 1, afl: 2 } as const;\n\nexport function automationCurveCode(curve: AutomationCurve): number {\n return resolveEnumOrdinal(curve, AUTOMATION_CURVE_VALUES, 'automation curve');\n}\n\nexport function panLawCode(panLaw: PanLawInput): number {\n const normalized = typeof panLaw === 'string' ? panLaw.toLowerCase().replace(/_/g, '-') : panLaw;\n return resolveEnumOrdinal(normalized, PAN_LAW_VALUES, 'pan law');\n}\n\nexport function panModeCode(panMode: PanMode | number): number {\n const normalized =\n typeof panMode === 'string' ? panMode.replace(/_/g, '-').toLowerCase() : panMode;\n return resolveEnumOrdinal(normalized, PAN_MODE_VALUES, 'pan mode');\n}\n\nexport function meterTapCode(tap: MeterTap | number): number {\n return resolveEnumOrdinal(tap, METER_TAP_VALUES, 'meter tap');\n}\n\nexport function sendTimingCode(timing: SendTiming | number): number {\n // Mirrors SonareSendTiming: post-fader is 0 (so an omitted/zeroed value is\n // post-fader), pre-fader is 1. A raw number is passed through as the C ABI int.\n // An unknown string is rejected rather than silently routed to post-fader,\n // matching the sibling enum-code helpers and Node's sendTimingValue.\n return resolveEnumOrdinal(timing, SEND_TIMING_VALUES, 'send timing');\n}\n\n/** Resolve a per-track PFL/AFL monitor mode to its C-ABI ordinal. */\nexport function trackMonitorModeCode(mode: unknown): number {\n return resolveEnumOrdinal(mode, TRACK_MONITOR_MODE_VALUES, 'track monitor mode');\n}\n","import { resolveEnumOrdinal } from './codes';\nimport type {\n AnalysisResult,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChordQuality,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n PitchClass,\n SectionType,\n} from './public_types';\nimport { KeyProfile as KeyProfileValues, Mode } from './public_types';\nimport type {\n WasmAnalysisResult,\n WasmChordAnalysisResult,\n WasmKeyCandidateResult,\n} from './sonare.js';\n\nconst PITCH_CLASS_NAMES = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n] as const;\n\nfunction pitchClassName(value: number): string {\n return PITCH_CLASS_NAMES[value] ?? 'C';\n}\n\nexport function convertKeyCandidate(wasm: WasmKeyCandidateResult): KeyCandidate {\n return {\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n correlation: wasm.correlation,\n };\n}\n\n// Consolidated spelling -> ordinal tables, resolved through the same\n// resolveEnumOrdinal() primitive as panModeCode/panLawCode/etc. in ./codes.\n// An unmapped string or an out-of-range numeric ordinal throws RangeError\n// instead of silently resolving to `undefined` (which used to reach the WASM\n// layer as a mistyped argument) or passing an unvalidated raw number through.\nconst KEY_MODE_VALUES: Readonly<Record<string, number>> = {\n major: Mode.Major,\n minor: Mode.Minor,\n dorian: Mode.Dorian,\n phrygian: Mode.Phrygian,\n lydian: Mode.Lydian,\n mixolydian: Mode.Mixolydian,\n locrian: Mode.Locrian,\n};\n\nconst KEY_PROFILE_VALUES: Readonly<Record<KeyProfileName, number>> = {\n ks: KeyProfileValues.KrumhanslSchmuckler,\n krumhansl: KeyProfileValues.KrumhanslSchmuckler,\n temperley: KeyProfileValues.Temperley,\n shaath: KeyProfileValues.Shaath,\n keyfinder: KeyProfileValues.Shaath,\n 'faraldo-edmt': KeyProfileValues.FaraldoEDMT,\n edmt: KeyProfileValues.FaraldoEDMT,\n 'faraldo-edma': KeyProfileValues.FaraldoEDMA,\n edma: KeyProfileValues.FaraldoEDMA,\n 'faraldo-edmm': KeyProfileValues.FaraldoEDMM,\n edmm: KeyProfileValues.FaraldoEDMM,\n 'bellman-budge': KeyProfileValues.BellmanBudge,\n bellman: KeyProfileValues.BellmanBudge,\n};\n\nexport function keyModeValues(modes: KeyDetectionOptions['modes'] | undefined): number[] {\n if (!modes) {\n return [];\n }\n if (modes === 'major-minor') {\n return [Mode.Major, Mode.Minor];\n }\n if (modes === 'all' || modes === 'modal') {\n return [\n Mode.Major,\n Mode.Minor,\n Mode.Dorian,\n Mode.Phrygian,\n Mode.Lydian,\n Mode.Mixolydian,\n Mode.Locrian,\n ];\n }\n return modes.map((mode) => resolveEnumOrdinal(mode, KEY_MODE_VALUES, 'key mode'));\n}\n\nexport function keyProfileValue(profile: KeyDetectionOptions['profile'] | undefined): number {\n if (profile === undefined) {\n return -1;\n }\n return resolveEnumOrdinal(profile, KEY_PROFILE_VALUES, 'key profile');\n}\n\nexport function convertChordAnalysisResult(wasm: WasmChordAnalysisResult): ChordAnalysisResult {\n return {\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n rootName: pitchClassName(c.root),\n bassName: pitchClassName(c.bass),\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n confidence: c.confidence,\n name: c.name,\n })),\n };\n}\n\nexport function chordChromaMethodValue(method: ChordDetectionOptions['chromaMethod']): number {\n if (method === 'stft') {\n return 0;\n }\n if (method === 'nnls') {\n return 1;\n }\n throw new Error(`Invalid chord chroma method: ${method}`);\n}\n\nexport function convertAnalysisResult(wasm: WasmAnalysisResult): AnalysisResult {\n const beatTimes = new Float32Array(wasm.beats.length);\n for (let i = 0; i < wasm.beats.length; i++) {\n beatTimes[i] = wasm.beats[i].time;\n }\n return {\n bpm: wasm.bpm,\n bpmConfidence: wasm.bpmConfidence,\n bpmCandidates: wasm.bpmCandidates.map((candidate) => ({\n value: candidate.value,\n confidence: candidate.confidence,\n relation: candidate.relation,\n })),\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n timeSignature: wasm.timeSignature,\n timeSignatureCandidates: wasm.timeSignatureCandidates,\n beatTimes,\n beats: wasm.beats,\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n rootName: pitchClassName(c.root),\n bassName: pitchClassName(c.bass),\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n confidence: c.confidence,\n name: c.name,\n })),\n sections: wasm.sections.map((s) => ({\n type: s.type as SectionType,\n start: s.start,\n end: s.end,\n energyLevel: s.energyLevel,\n confidence: s.confidence,\n name: s.name,\n })),\n timbre: wasm.timbre,\n dynamics: wasm.dynamics,\n rhythm: wasm.rhythm,\n melody: wasm.melody,\n form: wasm.form,\n };\n}\n","import {\n chordChromaMethodValue,\n convertAnalysisResult,\n convertChordAnalysisResult,\n convertKeyCandidate,\n keyModeValues,\n keyProfileValue,\n} from './analysis_helpers';\nimport { getSonareModule } from './module_state';\nimport type {\n AcousticOptions,\n AcousticResult,\n AnalysisResult,\n AnalyzeBpmOptions,\n AnalyzeDynamicsOptions,\n AnalyzeRhythmOptions,\n AnalyzeTimbreOptions,\n ChordAnalysisResult,\n ChordDetectionOptions,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomMorphOptions,\n} from './public_types';\nimport { Mode, PitchClass } from './public_types';\nimport type { ProgressCallback, WasmAcousticResult } from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport {\n assertFiniteScalar,\n assertNonNegativeInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\n\n/** Canonical request form for one-shot analysis functions. */\nexport interface SamplesRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Peak-picking configuration for {@link detectOnsets}. */\nexport interface OnsetDetectOptions {\n nFft?: number;\n hopLength?: number;\n threshold?: number;\n preMax?: number;\n postMax?: number;\n preAvg?: number;\n postAvg?: number;\n delta?: number;\n wait?: number;\n backtrack?: boolean;\n backtrackRange?: number;\n}\nexport interface DetectOnsetsRequest extends SamplesRequest, OnsetDetectOptions {}\n\n/** Canonical request form for key detection functions. */\nexport interface DetectKeyRequest extends KeyDetectionOptions, SamplesRequest {}\n\n/** Canonical request form for analysis with synchronous progress reporting. */\nexport interface AnalyzeWithProgressRequest extends SamplesRequest {\n onProgress?: ProgressCallback;\n cancel?: () => boolean;\n}\n\n/** Canonical request form for chord detection. */\nexport interface DetectChordsRequest extends ChordDetectionOptions, SamplesRequest {}\n\n/** Canonical request form for functional chord analysis. */\nexport interface ChordFunctionalAnalysisRequest extends DetectChordsRequest {\n keyRoot: PitchClass;\n /** Musical mode; defaults to {@link Mode.Major}. */\n keyMode?: Mode;\n}\n\n/** Canonical request form for impulse-response analysis. */\nexport interface AnalyzeImpulseResponseRequest extends SamplesRequest {\n nOctaveBands?: number;\n minDecayDb?: number;\n}\n\n/** Canonical request form for acoustic analysis. */\nexport interface DetectAcousticRequest extends AcousticOptions, SamplesRequest {}\n\n/** Canonical request form for equivalent-room estimation. */\nexport interface EstimateRoomRequest extends RoomEstimateOptions, SamplesRequest {}\n\n/** Canonical request form for room-reverb morphing. */\nexport interface RoomMorphRequest extends RoomMorphOptions, GuardedOptions {\n samples: Float32Array;\n sampleRate: number;\n}\n\n/** Canonical request forms for detailed music-analysis APIs. */\nexport interface AnalyzeBpmRequest extends AnalyzeBpmOptions, SamplesRequest {}\nexport interface AnalyzeRhythmRequest extends AnalyzeRhythmOptions, SamplesRequest {}\nexport interface AnalyzeDynamicsRequest extends AnalyzeDynamicsOptions, SamplesRequest {}\nexport interface AnalyzeTimbreRequest extends AnalyzeTimbreOptions, SamplesRequest {}\n\nfunction validateAnalysisInput(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\n// ============================================================================\n// Quick API (High-level Analysis)\n// ============================================================================\n\n/**\n * Detect BPM from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected BPM\n */\nexport function detectBpm(request: SamplesRequest): number;\nexport function detectBpm(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions,\n): number;\nexport function detectBpm(\n samples: Float32Array | SamplesRequest,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectBpm', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectBpm(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Detect musical key from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected key\n */\nexport function detectKey(request: DetectKeyRequest): Key;\nexport function detectKey(\n samples: Float32Array,\n sampleRate?: number,\n options?: KeyDetectionOptions,\n): Key;\nexport function detectKey(\n samples: Float32Array | DetectKeyRequest,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): Key {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectKey', request.samples, request.sampleRate ?? 22050, request);\n const result = requireModule()._detectKeyWithOptions(\n request.samples,\n request.sampleRate ?? 22050,\n request.nFft ?? 4096,\n request.hopLength ?? 512,\n request.useHpss ?? false,\n request.loudnessWeighted ?? false,\n request.highPassHz ?? 0,\n keyModeValues(request.modes),\n keyProfileValue(request.profile),\n request.genreHint ?? '',\n );\n return {\n root: result.root as PitchClass,\n mode: result.mode as Mode,\n confidence: result.confidence,\n name: result.name,\n shortName: result.shortName,\n };\n}\n\nexport function detectKeyCandidates(request: DetectKeyRequest): KeyCandidate[];\nexport function detectKeyCandidates(\n samples: Float32Array,\n sampleRate?: number,\n options?: KeyDetectionOptions,\n): KeyCandidate[];\nexport function detectKeyCandidates(\n samples: Float32Array | DetectKeyRequest,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): KeyCandidate[] {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput(\n 'detectKeyCandidates',\n request.samples,\n request.sampleRate ?? 22050,\n request,\n );\n // The embind value marshalling returns an array whose constructor is not this\n // realm's Array; chaining .map() onto it propagates that constructor via\n // Symbol.species, leaving a result that structuredClone (and so postMessage to\n // a Worker) rejects with \"could not be cloned\". Array.from() re-roots it as a\n // plain Array before mapping.\n const candidates = requireModule()._detectKeyCandidates(\n request.samples,\n request.sampleRate ?? 22050,\n request.nFft ?? 4096,\n request.hopLength ?? 512,\n request.useHpss ?? false,\n request.loudnessWeighted ?? false,\n request.highPassHz ?? 0,\n keyModeValues(request.modes),\n keyProfileValue(request.profile),\n request.genreHint ?? '',\n );\n return Array.from(candidates, convertKeyCandidate);\n}\n\n/**\n * Detect onset times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of onset times in seconds\n */\nexport function detectOnsets(request: DetectOnsetsRequest): Float32Array;\nexport function detectOnsets(\n samples: Float32Array,\n sampleRate?: number,\n options?: OnsetDetectOptions & GuardedOptions,\n): Float32Array;\nexport function detectOnsets(\n samples: Float32Array | DetectOnsetsRequest,\n sampleRate = 22050,\n options: OnsetDetectOptions & GuardedOptions = {},\n): Float32Array {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectOnsets', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectOnsets(request.samples, request.sampleRate ?? 22050, request);\n}\n\n/**\n * Detect beat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of beat times in seconds\n */\nexport function detectBeats(request: SamplesRequest): Float32Array;\nexport function detectBeats(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function detectBeats(\n samples: Float32Array | SamplesRequest,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): Float32Array {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectBeats', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectBeats(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Detect downbeat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of downbeat times in seconds\n */\nexport function detectDownbeats(request: SamplesRequest): Float32Array;\nexport function detectDownbeats(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function detectDownbeats(\n samples: Float32Array | SamplesRequest,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): Float32Array {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectDownbeats', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectDownbeats(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Detect chords from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Optional chord detection settings\n * @returns Detected chord segments\n */\nexport function detectChords(request: DetectChordsRequest): ChordAnalysisResult;\nexport function detectChords(\n samples: Float32Array,\n sampleRate?: number,\n options?: ChordDetectionOptions,\n): ChordAnalysisResult;\nexport function detectChords(\n samples: Float32Array | DetectChordsRequest,\n sampleRate = 22050,\n options: ChordDetectionOptions = {},\n): ChordAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectChords', request.samples, request.sampleRate ?? 22050, request);\n const result = requireModule().detectChords(\n request.samples,\n request.sampleRate ?? 22050,\n request.minDuration ?? 0.3,\n request.smoothingWindow ?? 2.0,\n request.threshold ?? 0.5,\n request.useTriadsOnly ?? false,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.useBeatSync ?? true,\n request.useHmm ?? false,\n request.hmmBeamWidth ?? 24,\n request.useKeyContext ?? false,\n request.keyRoot ?? PitchClass.C,\n request.keyMode ?? Mode.Major,\n request.detectInversions ?? false,\n chordChromaMethodValue(request.chromaMethod ?? 'stft'),\n );\n return convertChordAnalysisResult(result);\n}\n\n/**\n * Functional (Roman-numeral) harmonic analysis of the detected chord\n * progression, relative to the given key. Mirrors the C-ABI\n * `sonare_chord_functional_analysis` and the Node/Python `chordFunctionalAnalysis`.\n *\n * @returns One Roman-numeral label (e.g. \"I\", \"IV\", \"V\", \"vi\") per detected chord\n */\nexport function chordFunctionalAnalysis(request: ChordFunctionalAnalysisRequest): string[];\nexport function chordFunctionalAnalysis(\n samples: Float32Array,\n keyRoot: PitchClass,\n keyMode?: Mode,\n sampleRate?: number,\n options?: ChordDetectionOptions,\n): string[];\nexport function chordFunctionalAnalysis(\n samples: Float32Array | ChordFunctionalAnalysisRequest,\n keyRoot?: PitchClass,\n keyMode?: Mode,\n sampleRate = 22050,\n options: ChordDetectionOptions = {},\n): string[] {\n const request =\n samples instanceof Float32Array\n ? { samples, keyRoot, keyMode, sampleRate, ...options }\n : samples;\n validateAnalysisInput(\n 'chordFunctionalAnalysis',\n request.samples,\n request.sampleRate ?? 22050,\n request,\n );\n return requireModule().chordFunctionalAnalysis(\n request.samples,\n request.keyRoot as PitchClass,\n request.keyMode ?? Mode.Major,\n request.sampleRate ?? 22050,\n request.minDuration ?? 0.3,\n request.smoothingWindow ?? 2.0,\n request.threshold ?? 0.5,\n request.useTriadsOnly ?? false,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.useBeatSync ?? true,\n request.useHmm ?? false,\n request.hmmBeamWidth ?? 24,\n request.useKeyContext ?? false,\n request.detectInversions ?? false,\n chordChromaMethodValue(request.chromaMethod ?? 'stft'),\n );\n}\n\n/**\n * Perform complete music analysis.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Complete analysis result\n *\n * @remarks\n * This call is synchronous and blocks until analysis completes. Unlike the\n * Node binding (which offers `analyzeAsync` on a libuv worker thread), the\n * WASM build runs on a single thread, so there is no non-blocking variant —\n * the DSP pipeline always runs to completion on the calling thread. To keep\n * the UI responsive for long inputs, drive this from a Web Worker and use\n * {@link analyzeWithProgress} to report progress.\n */\nexport interface MusicAnalyzeOptions {\n nFft?: number;\n hopLength?: number;\n bpmMin?: number;\n bpmMax?: number;\n startBpm?: number;\n useTriadsOnly?: boolean;\n useHpss?: boolean;\n chromaHighpassHz?: number;\n useBassWeighted?: boolean;\n chromaHopMultiplier?: number;\n useChordHmm?: boolean;\n useChordKeyContext?: boolean;\n chordHmmBeamWidth?: number;\n detectChordInversions?: boolean;\n}\nexport interface MusicAnalyzeRequest extends SamplesRequest, MusicAnalyzeOptions {}\n\nexport function analyze(request: MusicAnalyzeRequest): AnalysisResult;\nexport function analyze(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions & MusicAnalyzeOptions,\n): AnalysisResult;\nexport function analyze(\n samples: Float32Array | MusicAnalyzeRequest,\n sampleRate = 22050,\n options: GuardedOptions & MusicAnalyzeOptions = {},\n): AnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyze', request.samples, request.sampleRate ?? 22050, request);\n const result = requireModule().analyze(request.samples, request.sampleRate ?? 22050, request);\n return convertAnalysisResult(result);\n}\n\nexport function analyzeImpulseResponse(request: AnalyzeImpulseResponseRequest): AcousticResult;\nexport function analyzeImpulseResponse(\n samples: Float32Array,\n sampleRate?: number,\n nOctaveBands?: number,\n minDecayDb?: number,\n): AcousticResult;\nexport function analyzeImpulseResponse(\n samples: Float32Array | AnalyzeImpulseResponseRequest,\n sampleRate = 48000,\n nOctaveBands = 6,\n minDecayDb?: number,\n): AcousticResult {\n const request =\n samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands, minDecayDb } : samples;\n if (request.minDecayDb === null) {\n throw new TypeError('analyzeImpulseResponse: minDecayDb must be a finite number');\n }\n const resolvedMinDecayDb = request.minDecayDb === undefined ? 30.0 : request.minDecayDb;\n assertFiniteScalar('analyzeImpulseResponse', resolvedMinDecayDb, 'minDecayDb');\n if (resolvedMinDecayDb <= 0) {\n throw new RangeError('analyzeImpulseResponse: minDecayDb must be greater than zero');\n }\n validateAnalysisInput(\n 'analyzeImpulseResponse',\n request.samples,\n request.sampleRate ?? 48000,\n request,\n );\n const result: WasmAcousticResult = requireModule().analyzeImpulseResponseEx(\n request.samples,\n request.sampleRate ?? 48000,\n request.nOctaveBands ?? 6,\n resolvedMinDecayDb,\n );\n return result;\n}\n\nexport function detectAcoustic(request: DetectAcousticRequest): AcousticResult;\nexport function detectAcoustic(\n samples: Float32Array,\n sampleRate?: number,\n options?: AcousticOptions,\n): AcousticResult;\nexport function detectAcoustic(\n samples: Float32Array | DetectAcousticRequest,\n sampleRate = 48000,\n options: AcousticOptions = {},\n): AcousticResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectAcoustic', request.samples, request.sampleRate ?? 48000, request);\n const result: WasmAcousticResult = requireModule().detectAcoustic(\n request.samples,\n request.sampleRate ?? 48000,\n request.nOctaveBands ?? 6,\n request.nThirdOctaveSubbands ?? 24,\n request.minDecayDb ?? 30.0,\n request.noiseFloorMarginDb ?? 10.0,\n );\n return result;\n}\n\n/**\n * Synthesize a room impulse response from shoebox geometry. `hasError` is true\n * when the source/listener falls outside the room (the RIR is then empty).\n */\nexport function synthesizeRir(options: RirSynthOptions = {}): RirResult {\n const module = requireModule();\n if (typeof module.synthesizeRir !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n return module.synthesizeRir(options);\n}\n\n/**\n * Estimate an equivalent room (volume/dimensions/absorption/DRR) from a\n * recording or impulse response.\n */\nexport function estimateRoom(request: EstimateRoomRequest): RoomEstimateResult;\nexport function estimateRoom(\n samples: Float32Array,\n sampleRate?: number,\n options?: RoomEstimateOptions,\n): RoomEstimateResult;\nexport function estimateRoom(\n samples: Float32Array | EstimateRoomRequest,\n sampleRate = 48000,\n options: RoomEstimateOptions = {},\n): RoomEstimateResult {\n const module = requireModule();\n if (typeof module.estimateRoom !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('estimateRoom', request.samples, request.sampleRate ?? 48000, request);\n return module.estimateRoom(request.samples, request.sampleRate ?? 48000, request);\n}\n\n/**\n * Morph a recording's reverberation toward a target room (creative FX, not\n * dereverberation). Returns the morphed samples (input length plus the target\n * room's reverb tail).\n */\nexport function roomMorph(request: RoomMorphRequest): Float32Array;\nexport function roomMorph(\n samples: Float32Array,\n sampleRate: number,\n options?: RoomMorphOptions,\n): Float32Array;\nexport function roomMorph(\n samples: Float32Array | RoomMorphRequest,\n sampleRate?: number,\n options: RoomMorphOptions = {},\n): Float32Array {\n const module = requireModule();\n if (typeof module.roomMorph !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n const request =\n samples instanceof Float32Array\n ? { samples, sampleRate: sampleRate as number, ...options }\n : samples;\n validateAnalysisInput('roomMorph', request.samples, request.sampleRate, request);\n return module.roomMorph(request.samples, request.sampleRate, request);\n}\n\n/**\n * Perform complete music analysis with progress reporting.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Complete analysis result\n */\nexport function analyzeWithProgress(request: AnalyzeWithProgressRequest): AnalysisResult;\nexport function analyzeWithProgress(\n samples: Float32Array,\n sampleRate: number | undefined,\n onProgress: ProgressCallback,\n): AnalysisResult;\nexport function analyzeWithProgress(\n samples: Float32Array | AnalyzeWithProgressRequest,\n sampleRate = 22050,\n onProgress?: ProgressCallback,\n): AnalysisResult {\n const request: AnalyzeWithProgressRequest =\n samples instanceof Float32Array\n ? { samples, sampleRate, onProgress: onProgress as ProgressCallback }\n : samples;\n validateAnalysisInput(\n 'analyzeWithProgress',\n request.samples,\n request.sampleRate ?? 22050,\n request,\n );\n const result = requireModule().analyzeWithProgress(\n request.samples,\n request.sampleRate ?? 22050,\n request.onProgress ?? (() => {}),\n request.cancel ?? (() => false),\n );\n return convertAnalysisResult(result);\n}\n\nexport interface BpmCandidate {\n bpm: number;\n confidence: number;\n}\n\nexport interface BpmAnalysisResult {\n bpm: number;\n confidence: number;\n candidates: BpmCandidate[];\n autocorrelation: Float32Array;\n tempogram: Float32Array;\n}\n\nexport interface RhythmAnalysisResult {\n timeSignature: { numerator: number; denominator: number; confidence: number };\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n tempoStability: number;\n bpm: number;\n beatIntervals: Float32Array;\n}\n\nexport interface DynamicsAnalysisResult {\n dynamicRangeDb: number;\n peakDb: number;\n rmsDb: number;\n crestFactor: number;\n loudnessRangeDb: number;\n isCompressed: boolean;\n /** Loudness curve timestamps (seconds), parallel to {@link loudnessRmsDb}. */\n loudnessTimes: Float32Array;\n /** Loudness curve RMS values (dB), parallel to {@link loudnessTimes}. */\n loudnessRmsDb: Float32Array;\n}\n\n/** Timbre metrics for one analysis window. Entries are ordered by time in `timbreOverTime`. */\nexport interface TimbreFrame {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\nexport interface TimbreAnalysisResult extends TimbreFrame {\n spectralCentroid: Float32Array;\n spectralFlatness: Float32Array;\n spectralRolloff: Float32Array;\n /** Time-varying timbre metrics, one entry per analysis window. */\n timbreOverTime: TimbreFrame[];\n}\n\n/**\n * Detailed BPM analysis (BPM, confidence, alternate candidates, autocorrelation,\n * tempogram). Matches the Node `analyzeBpm` / Python `analyze_bpm` surface.\n */\nexport function analyzeBpm(request: AnalyzeBpmRequest): BpmAnalysisResult;\nexport function analyzeBpm(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeBpmOptions,\n): BpmAnalysisResult;\nexport function analyzeBpm(\n samples: Float32Array | AnalyzeBpmRequest,\n sampleRate = 22050,\n options: AnalyzeBpmOptions = {},\n): BpmAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeBpm', request.samples, request.sampleRate ?? 22050, request);\n assertNonNegativeInteger('analyzeBpm', request.maxCandidates ?? 5, 'maxCandidates');\n return requireModule().analyzeBpm(\n request.samples,\n request.sampleRate ?? 22050,\n request.bpmMin ?? 30.0,\n request.bpmMax ?? 300.0,\n request.startBpm ?? 120.0,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.maxCandidates ?? 5,\n );\n}\n\n/**\n * Detailed rhythm analysis (time signature, groove, syncopation, beat intervals).\n */\nexport function analyzeRhythm(request: AnalyzeRhythmRequest): RhythmAnalysisResult;\nexport function analyzeRhythm(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeRhythmOptions,\n): RhythmAnalysisResult;\nexport function analyzeRhythm(\n samples: Float32Array | AnalyzeRhythmRequest,\n sampleRate = 22050,\n options: AnalyzeRhythmOptions = {},\n): RhythmAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeRhythm', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().analyzeRhythm(\n request.samples,\n request.sampleRate ?? 22050,\n request.bpmMin ?? 60.0,\n request.bpmMax ?? 200.0,\n request.startBpm ?? 120.0,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n );\n}\n\n/**\n * Dynamics analysis (RMS, peak, crest factor, LRA, loudness curve).\n */\nexport function analyzeDynamics(request: AnalyzeDynamicsRequest): DynamicsAnalysisResult;\nexport function analyzeDynamics(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeDynamicsOptions,\n): DynamicsAnalysisResult;\nexport function analyzeDynamics(\n samples: Float32Array | AnalyzeDynamicsRequest,\n sampleRate = 22050,\n options: AnalyzeDynamicsOptions = {},\n): DynamicsAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeDynamics', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().analyzeDynamics(\n request.samples,\n request.sampleRate ?? 22050,\n request.windowSec ?? 0.4,\n request.hopLength ?? 512,\n request.compressionThreshold ?? 6.0,\n );\n}\n\n/**\n * Timbre analysis (brightness/warmth/density/roughness/complexity plus spectral\n * features and per-window timbre frames).\n */\nexport function analyzeTimbre(request: AnalyzeTimbreRequest): TimbreAnalysisResult;\nexport function analyzeTimbre(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeTimbreOptions,\n): TimbreAnalysisResult;\nexport function analyzeTimbre(\n samples: Float32Array | AnalyzeTimbreRequest,\n sampleRate = 22050,\n options: AnalyzeTimbreOptions = {},\n): TimbreAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeTimbre', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().analyzeTimbre(\n request.samples,\n request.sampleRate ?? 22050,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.nMels ?? 128,\n request.nMfcc ?? 13,\n request.windowSec ?? 0.5,\n );\n}\n\n/**\n * Whether this WASM build was compiled with FFmpeg support. Mirrors Node /\n * Python `hasFfmpegSupport`. In the published WASM binding this currently\n * always returns `false` (FFmpeg is not bundled into the .wasm), but the API\n * exists so caller code can branch on capabilities portably.\n */\nexport function hasFfmpegSupport(): boolean {\n return requireModule().hasFfmpegSupport();\n}\n","/**\n * Analysis and feature-extraction entry point for the smaller WASM binary.\n *\n * This entry intentionally omits mastering, mixing, realtime engines, Project,\n * and other native-handle APIs. Import the package root when those surfaces are\n * required.\n */\n\nimport { setSonareModule } from './module_state';\nimport type { SonareCapabilities } from './public_types';\nimport type { SonareModule } from './sonare.js';\n\nexport { ErrorCode, isSonareError, SonareError } from './errors';\nexport * from './feature_core';\nexport * from './feature_music';\nexport * from './feature_pitch';\nexport * from './feature_resample';\nexport * from './feature_spectral';\nexport * from './feature_spectrogram';\nexport * from './metering';\nexport * from './public_types';\nexport type {\n AnalyzeBpmRequest,\n AnalyzeDynamicsRequest,\n AnalyzeImpulseResponseRequest,\n AnalyzeRhythmRequest,\n AnalyzeTimbreRequest,\n AnalyzeWithProgressRequest,\n BpmAnalysisResult,\n BpmCandidate,\n ChordFunctionalAnalysisRequest,\n DetectAcousticRequest,\n DetectChordsRequest,\n DetectKeyRequest,\n DynamicsAnalysisResult,\n MusicAnalyzeOptions,\n MusicAnalyzeRequest,\n RhythmAnalysisResult,\n SamplesRequest,\n TimbreAnalysisResult,\n TimbreFrame,\n} from './quick_analysis';\nexport {\n analyze,\n analyzeBpm,\n analyzeDynamics,\n analyzeImpulseResponse,\n analyzeRhythm,\n analyzeTimbre,\n analyzeWithProgress,\n chordFunctionalAnalysis,\n detectAcoustic,\n detectBeats,\n detectBpm,\n detectChords,\n detectDownbeats,\n detectKey,\n detectKeyCandidates,\n detectOnsets,\n hasFfmpegSupport,\n} from './quick_analysis';\n\nlet module: SonareModule | null = null;\nlet initPromise: Promise<void> | null = null;\n\n/** Initialize the analysis-only WASM module. */\nexport async function init(options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n moduleFactory?: (options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n }) => Promise<SonareModule>;\n}): Promise<void> {\n if (module) {\n return;\n }\n if (initPromise) {\n return initPromise;\n }\n initPromise = (async () => {\n try {\n const createModule = options?.moduleFactory ?? (await import('./sonare-analysis.js')).default;\n module = await createModule(options);\n setSonareModule(module);\n } catch (error) {\n initPromise = null;\n throw error;\n }\n })();\n return initPromise;\n}\n\n/** Whether this analysis entry has loaded its WASM module. */\nexport function isInitialized(): boolean {\n return module !== null;\n}\n\n/** Version reported by the loaded analysis WASM module. */\nexport function version(): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.version();\n}\n\n/** Build capabilities for the loaded analysis-only module. */\nexport function capabilities(): SonareCapabilities {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.capabilities();\n}\n\n/** Packed C-ABI version for compatibility checks. */\nexport function abiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.abiVersion();\n}\n\n/** Realtime command-queue ABI version shared with the full entry. */\nexport function engineAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.engineAbiVersion();\n}\n\n/** Voice-changer ABI version retained for cross-entry compatibility checks. */\nexport function voiceChangerAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceChangerAbiVersion();\n}\n"],"mappings":"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","names":["ErrorCode","module","onsetEnvelope","requireModule","onsetEnvelope","requireModule","requireModule","requireModule","init","requireModule","validatePositiveIntegers","requireModule","requireModule","requireModule"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/module_state.ts","../src/feature_core.ts","../src/validation.ts","../src/_fft_options.ts","../src/feature_decompose.ts","../src/_feature_validation.ts","../src/feature_inverse.ts","../src/feature_loudness.ts","../src/feature_music.ts","../src/feature_pitch.ts","../src/feature_spectral.ts","../src/feature_spectrogram.ts","../src/metering.ts","../src/public_types_mastering.ts","../src/public_types_music.ts","../src/codes.ts","../src/analysis_helpers.ts","../src/quick_analysis.ts","../src/analysis.ts"],"sourcesContent":["/**\n * Numeric error codes carried by a {@link SonareError}. Mirrors the C ABI\n * `SonareError` enum (and the Node / Python surfaces), so the same failure\n * reports the same numeric code on every binding.\n */\nexport enum ErrorCode {\n Ok = 0,\n FileNotFound = 1,\n InvalidFormat = 2,\n DecodeFailed = 3,\n InvalidParameter = 4,\n OutOfMemory = 5,\n NotSupported = 6,\n InvalidState = 7,\n Cancelled = 8,\n EncodeFailed = 9,\n Unknown = 99,\n}\n\n/**\n * Error thrown by libsonare on a native (C++) failure. Carries a numeric\n * {@link ErrorCode} `code` plus its canonical `codeName`, so callers can branch\n * on the cause instead of matching message text.\n *\n * Narrow a caught value with {@link isSonareError} or with `instanceof`; both\n * accept the same values. The Node package exports the same class under the\n * same name.\n */\nexport class SonareError extends Error {\n /** Numeric error code, equal to an {@link ErrorCode} value. */\n readonly code: number;\n /** Canonical name of `code`, e.g. `'InvalidParameter'`. */\n readonly codeName: string;\n\n constructor(code: number, codeName: string, message: string) {\n super(message);\n this.name = 'SonareError';\n this.code = code;\n this.codeName = codeName;\n }\n\n /**\n * Brand-based `instanceof`: an error that carries the shape narrows here even\n * when it is not literally an instance of this class. That is not a\n * hypothetical — an error posted from the analysis worker arrives as a\n * structured clone with its prototype gone, which a prototype-based\n * `instanceof` would silently miss. Delegates to {@link isSonareError} so the\n * two never disagree.\n */\n static [Symbol.hasInstance](value: unknown): value is SonareError {\n return isSonareError(value);\n }\n}\n\n/**\n * Type guard: whether a caught value is a libsonare {@link SonareError}.\n *\n * Duck-typed on purpose: a value that crossed a worker boundary has lost its\n * prototype, so a prototype check would miss it.\n */\nexport function isSonareError(value: unknown): value is SonareError {\n return (\n value instanceof Error &&\n (value as { name?: unknown }).name === 'SonareError' &&\n typeof (value as { code?: unknown }).code === 'number'\n );\n}\n","import { ErrorCode, SonareError } from './errors';\nimport type { SonareModule } from './sonare.js';\n\nlet wrappedModule: SonareModule | null = null;\n\n/**\n * Shape of the structured info the native `sonareExceptionInfo(ptr)` returns.\n */\ninterface NativeExceptionInfo {\n code: number;\n codeName: string;\n message: string;\n}\n\n/**\n * Recover the native exception-object pointer from a value thrown across the\n * WASM boundary. emscripten surfaces a C++ throw in two shapes depending on the\n * toolchain/exception mode:\n * - a raw pointer number (older / classic surfacing), or\n * - a `CppException` object exposing the pointer as `excPtr` (emscripten with\n * `-fexceptions`).\n * Returns null when the thrown value is neither (a genuine JS error), so the\n * caller rethrows it unchanged.\n */\nexport function nativeExceptionPtr(error: unknown): number | null {\n if (typeof error === 'number') {\n return error;\n }\n if (error !== null && typeof error === 'object') {\n const ptr = (error as { excPtr?: unknown }).excPtr;\n if (typeof ptr === 'number') {\n return ptr;\n }\n }\n return null;\n}\n\n/**\n * Turn a thrown native exception pointer into a {@link SonareError}. The bound\n * `sonareExceptionInfo` decodes the pointer back into { code, codeName,\n * message }, then `sonareReleaseException` drops the reference emscripten's\n * `__cxa_throw` took before rethrowing the pointer into JS.\n *\n * The release is mandatory, not an optimization: no C++ frame catches the\n * exception, so that reference is the only one and nothing else ever drops it.\n * Every rejected input would otherwise leak its exception object for the\n * lifetime of the module — and rejection-as-control-flow (re-validating markers\n * or clips on each edit, a scrub handle seeking every pointer move) is a\n * documented usage of this API. It runs in a `finally` so a decode failure\n * still frees, and after decoding because freeing invalidates the message.\n */\nfunction makeSonareError(raw: SonareModule, thrown: number): SonareError {\n let code: number = ErrorCode.Unknown;\n let codeName = 'Unknown';\n let message = `libsonare native exception (${thrown})`;\n try {\n const info = (\n raw as unknown as { sonareExceptionInfo?: (ptr: number) => NativeExceptionInfo }\n ).sonareExceptionInfo?.(thrown);\n if (info) {\n code = info.code ?? code;\n codeName = info.codeName ?? codeName;\n message = info.message || message;\n }\n } catch {\n // Fall back to the generic message if decoding fails.\n } finally {\n try {\n raw.sonareReleaseException(thrown);\n } catch {\n // A module built before the release binding existed still yields an error\n // object; it just keeps leaking, which is what this replaces.\n }\n }\n return new SonareError(code, codeName, message);\n}\n\n/**\n * Wrap the embind module so a native C++ exception (which surfaces as a raw\n * pointer number or a `CppException` carrying one) is rethrown as a\n * {@link SonareError}. Only function-valued\n * members are wrapped, and the wrapper is cached per member so repeated access\n * stays cheap; non-function members (typed-array heap views, etc.) pass through\n * unchanged.\n */\nfunction wrapModuleErrors(raw: SonareModule): SonareModule {\n const cache = new Map<PropertyKey, unknown>();\n const objectCache = new WeakMap<object, unknown>();\n const convert = (error: unknown): never => {\n const ptr = nativeExceptionPtr(error);\n if (ptr !== null) {\n throw makeSonareError(raw, ptr);\n }\n throw error;\n };\n\n const wrapNativeObject = (value: unknown): unknown => {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof Promise) {\n return value;\n }\n // Plain result data carries no native methods, and a Proxy cannot be\n // structured-cloned, so wrapping it would block postMessage to a worker.\n const proto = Object.getPrototypeOf(value);\n if (Array.isArray(value) || proto === Object.prototype || proto === null) {\n return value;\n }\n const objectValue = value as object;\n const cached = objectCache.get(objectValue);\n if (cached) {\n return cached;\n }\n const methodCache = new Map<PropertyKey, unknown>();\n const wrapped = new Proxy(objectValue, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMethod = methodCache.get(prop);\n if (cachedMethod) {\n return cachedMethod;\n }\n const method = member as (...a: unknown[]) => unknown;\n const wrappedMethod = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(method, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n methodCache.set(prop, wrappedMethod);\n return wrappedMethod;\n },\n });\n objectCache.set(objectValue, wrapped);\n return wrapped;\n };\n\n const wrapFunction = (value: (...a: unknown[]) => unknown): unknown => {\n const fnCache = new Map<PropertyKey, unknown>();\n return new Proxy(value, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMember = fnCache.get(prop);\n if (cachedMember) {\n return cachedMember;\n }\n const fn = member as (...a: unknown[]) => unknown;\n const wrappedMember = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(fn, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n fnCache.set(prop, wrappedMember);\n return wrappedMember;\n },\n apply(t, thisArg, args) {\n try {\n return wrapNativeObject(Reflect.apply(t, thisArg, args as unknown[]));\n } catch (error) {\n return convert(error);\n }\n },\n construct(t, args, newTarget) {\n try {\n return wrapNativeObject(Reflect.construct(t, args as unknown[], newTarget)) as object;\n } catch (error) {\n return convert(error) as object;\n }\n },\n });\n };\n\n return new Proxy(raw, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n const cached = cache.get(prop);\n if (cached) {\n return cached;\n }\n // Wrap as a Proxy (not a plain function) so embind class constructors\n // invoked via `new module.Foo(...)` keep their `[[Construct]]` behaviour\n // and prototype while still converting thrown native pointers.\n const wrapped = wrapFunction(value as (...a: unknown[]) => unknown);\n cache.set(prop, wrapped);\n return wrapped;\n },\n }) as SonareModule;\n}\n\nexport function setSonareModule(module: SonareModule): void {\n wrappedModule = wrapModuleErrors(module);\n}\n\nexport function getSonareModule(): SonareModule {\n if (!wrappedModule) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return wrappedModule;\n}\n","import { getSonareModule } from './module_state';\nimport type { TempogramMode } from './public_types';\nimport type {\n WasmCyclicTempogramResult,\n WasmFrameResult,\n WasmTempogramResult,\n WasmTrimResult,\n} from './sonare.js';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nexport function tone(request?: ToneRequest): Float32Array;\nexport function tone(\n frequency?: number,\n sampleRate?: number,\n duration?: number,\n phase?: number,\n amplitude?: number,\n): Float32Array;\nexport function tone(\n frequency: number | ToneRequest = 440,\n sampleRate = 22050,\n duration = 1,\n phase = 0,\n amplitude = 1,\n): Float32Array {\n const request =\n typeof frequency === 'number'\n ? { frequency, sampleRate, duration, phase, amplitude }\n : frequency;\n return requireModule().tone(\n request.frequency ?? 440,\n request.sampleRate ?? 22050,\n request.duration ?? 1,\n request.phase ?? 0,\n request.amplitude ?? 1,\n );\n}\n\nexport function chirp(request?: ChirpRequest): Float32Array;\nexport function chirp(\n fmin?: number,\n fmax?: number,\n sampleRate?: number,\n duration?: number,\n linear?: boolean,\n): Float32Array;\nexport function chirp(\n fmin: number | ChirpRequest = 440,\n fmax = 880,\n sampleRate = 22050,\n duration = 1,\n linear = true,\n): Float32Array {\n const request = typeof fmin === 'number' ? { fmin, fmax, sampleRate, duration, linear } : fmin;\n return requireModule().chirp(\n request.fmin ?? 440,\n request.fmax ?? 880,\n request.sampleRate ?? 22050,\n request.duration ?? 1,\n request.linear ?? true,\n );\n}\n\nexport function clicks(request: ClicksRequest): Float32Array;\nexport function clicks(\n times: Float32Array,\n sampleRate?: number,\n length?: number,\n frequency?: number,\n clickDuration?: number,\n): Float32Array;\nexport function clicks(\n times: Float32Array | ClicksRequest,\n sampleRate = 22050,\n length = 0,\n frequency = 1000,\n clickDuration = 0.1,\n): Float32Array {\n const request =\n times instanceof Float32Array ? { times, sampleRate, length, frequency, clickDuration } : times;\n return requireModule().clicks(\n request.times,\n request.sampleRate ?? 22050,\n request.length ?? 0,\n request.frequency ?? 1000,\n request.clickDuration ?? 0.1,\n );\n}\n\nexport interface DbConversionRequest {\n values: Float32Array;\n ref?: number;\n amin?: number;\n topDb?: number;\n}\n\nexport interface SilenceRequest {\n samples: Float32Array;\n topDb?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\n/** Canonical request form for the common-silence union of several signals. */\nexport interface SplitSilenceCommonRequest {\n signals: Float32Array[];\n topDb?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\n/**\n * Why {@link splitSilenceCommonWithReport} found the gaps it did.\n *\n * One interval covering everything is the answer to three different situations\n * and the interval list cannot separate them: no take has a quiet moment at all,\n * the takes each have one but not in the same place, or `topDb` was set too loose\n * to see the ones they have.\n *\n * **Read {@link silenceCeilingDb} against the `topDb` that was passed**, which is\n * the whole decision:\n *\n * - ceiling near 0 — a take is sounding continuously. No threshold helps, and a\n * cut point has to come from somewhere other than silence.\n * - ceiling below `topDb` — the threshold was too loose to see the quiet these\n * takes do have. A `topDb` under the reported ceiling finds it.\n * - ceiling at or above `topDb`, and still one interval — every take shows silence\n * at this setting and they do not share any of it. That is the alignment case,\n * and it is what {@link alignTakeToReference} is for.\n *\n * The figures come from the same RMS pass the intervals do, so they can never\n * describe a different measurement.\n */\nexport interface SilenceCommonReport {\n /**\n * The largest `topDb` at which EVERY signal still shows silence.\n *\n * A frame counts as silent when it sits at least `topDb` under its own signal's\n * peak RMS, so each signal's deepest dip decides whether any threshold can find\n * silence in it, and the union needs all of them quiet at once — hence the\n * minimum across the signals. 0 for an all-silent signal, where the peak is 0\n * and the ratio has no value; 120 is the floor the dB conversion clamps at,\n * reported for a signal holding a zero-valued frame.\n */\n silenceCeilingDb: number;\n /**\n * How many intervals the most fragmented signal produced alone, counted before\n * the union merges anything.\n *\n * A measure of shape rather than of cause: 1 is a take that sounds once and\n * stops, so a take that is loud then silent counts 1 exactly as a take with no\n * silence does. Use {@link silenceCeilingDb} to tell those apart; use these two\n * to see whether any take has an interior gap at all (`>= 2`) and whether the\n * takes differ in how broken up they are (`maxSignalIntervals !==\n * minSignalIntervals`).\n */\n maxSignalIntervals: number;\n /** How many intervals the least fragmented signal produced alone. */\n minSignalIntervals: number;\n}\n\n/** Result of {@link splitSilenceCommonWithReport}. */\nexport interface SplitSilenceCommonWithReportResult {\n /** Exactly what {@link splitSilenceCommon} returns for the same arguments. */\n intervals: Int32Array;\n /** Why those are the intervals. */\n report: SilenceCommonReport;\n}\n\nexport interface FrameSignalRequest {\n samples: Float32Array;\n frameLength: number;\n hopLength: number;\n}\nexport interface ToneRequest {\n frequency?: number;\n sampleRate?: number;\n duration?: number;\n phase?: number;\n amplitude?: number;\n}\nexport interface ChirpRequest {\n fmin?: number;\n fmax?: number;\n sampleRate?: number;\n duration?: number;\n linear?: boolean;\n}\nexport interface ClicksRequest {\n times: Float32Array;\n sampleRate?: number;\n length?: number;\n frequency?: number;\n clickDuration?: number;\n}\n/** Canonical request form for pre/de-emphasis filters. */\nexport interface EmphasisRequest {\n samples: Float32Array;\n coef?: number;\n zi?: number;\n}\n/** Canonical request form for centering or extending a vector. */\nexport interface PadCenterRequest {\n values: Float32Array;\n targetSize: number;\n padValue?: number;\n}\n/** Canonical request form for resizing a vector. */\nexport interface FixLengthRequest {\n values: Float32Array;\n targetSize: number;\n padValue?: number;\n}\n/** Canonical request form for bounding a frame-index vector. */\nexport interface FixFramesRequest {\n frames: Int32Array;\n xMin?: number;\n xMax?: number;\n pad?: boolean;\n}\nexport interface OnsetBacktrackRequest {\n events: Int32Array;\n energy: Float32Array;\n}\n/** Canonical request form for peak selection. */\nexport interface PeakPickRequest {\n values: Float32Array;\n preMax: number;\n postMax: number;\n preAvg: number;\n postAvg: number;\n delta: number;\n wait: number;\n}\n/** Canonical request form for vector normalization. */\nexport interface VectorNormalizeRequest {\n values: Float32Array;\n normType?: number;\n threshold?: number;\n}\n/** Canonical request form for tonal centroid projection. */\nexport interface TonnetzRequest {\n chromagram: Float32Array;\n nChroma: number;\n nFrames: number;\n}\nexport interface PcenRequest {\n values: Float32Array;\n nBins: number;\n nFrames: number;\n sampleRate?: number;\n hopLength?: number;\n timeConstant?: number;\n gain?: number;\n bias?: number;\n power?: number;\n eps?: number;\n /** @deprecated Put PCEN fields directly on the request object. */\n options?: Record<string, number>;\n}\nexport interface TempogramRequest {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n winLength?: number;\n mode?: TempogramMode;\n center?: boolean;\n norm?: boolean;\n}\nexport interface CyclicTempogramRequest {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n winLength?: number;\n bpmMin?: number;\n nBins?: number;\n}\nexport interface PlpRequest {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n tempoMin?: number;\n tempoMax?: number;\n winLength?: number;\n}\n\n// ============================================================================\n// Core - Unit Conversion\n// ============================================================================\n\n/**\n * Convert frequency in Hz to Mel scale.\n *\n * A total function, matching the C ABI and librosa: a non-finite `hz`\n * propagates rather than throwing, and a magnitude past the 32-bit float range\n * saturates to an infinity the same way the C conversion does. Out-of-audio\n * frequencies are not refused either — the mapping is defined over the whole\n * real line.\n *\n * @param hz - Frequency in Hz\n * @returns Mel frequency\n */\nexport function hzToMel(hz: number): number {\n return requireModule().hzToMel(hz);\n}\n\n/**\n * Convert Mel scale to frequency in Hz. Total over the same domain as\n * {@link hzToMel}.\n *\n * @param mel - Mel frequency\n * @returns Frequency in Hz\n */\nexport function melToHz(mel: number): number {\n return requireModule().melToHz(mel);\n}\n\n/**\n * Convert frequency in Hz to MIDI note number.\n *\n * Total, like {@link hzToMel}. A non-positive `hz` returns `-Infinity`, the log2\n * limit, and {@link midiToHz} maps that back to 0. A NaN propagates, which is\n * what makes a default `pitchPyin` track — whose unvoiced frames are NaN — safe\n * to map through.\n *\n * @param hz - Frequency in Hz\n * @returns MIDI note number (A4 = 440 Hz = 69)\n */\nexport function hzToMidi(hz: number): number {\n return requireModule().hzToMidi(hz);\n}\n\n/**\n * Convert MIDI note number to frequency in Hz. Total, like {@link hzToMel};\n * `-Infinity` bottoms out at 0 rather than propagating its sign.\n *\n * @param midi - MIDI note number\n * @returns Frequency in Hz\n */\nexport function midiToHz(midi: number): number {\n return requireModule().midiToHz(midi);\n}\n\n/**\n * Convert frequency in Hz to note name.\n *\n * Every frequency with no note answers `\"?\"` rather than throwing: zero,\n * negative, past the representable MIDI range, and non-finite alike. A default\n * `pitchPyin` track fills unvoiced frames with NaN, so mapping one through this\n * yields `\"?\"` at those frames.\n *\n * @param hz - Frequency in Hz\n * @returns Note name (e.g., \"A4\", \"C#5\")\n */\nexport function hzToNote(hz: number): string {\n return requireModule().hzToNote(hz);\n}\n\n/**\n * Convert note name to frequency in Hz.\n *\n * @param note - Note name (e.g., \"A4\", \"C#5\")\n * @returns Frequency in Hz\n */\nexport function noteToHz(note: string): number {\n return requireModule().noteToHz(note);\n}\n\n/**\n * Convert frame index to time in seconds.\n *\n * @param frames - Frame index\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Time in seconds\n */\nexport function framesToTime(frames: number, sr = 22050, hopLength = 512): number {\n return requireModule().framesToTime(frames, sr, hopLength);\n}\n\n/**\n * Convert time in seconds to frame index.\n *\n * @param time - Time in seconds\n * @param sr - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length in samples (default: 512)\n * @returns Frame index\n */\nexport function timeToFrames(time: number, sr = 22050, hopLength = 512): number {\n return requireModule().timeToFrames(time, sr, hopLength);\n}\n\nexport function framesToSamples(frames: number, hopLength = 512, nFft = 0): number {\n return requireModule().framesToSamples(frames, hopLength, nFft);\n}\n\nexport function samplesToFrames(samples: number, hopLength = 512, nFft = 0): number {\n return requireModule().samplesToFrames(samples, hopLength, nFft);\n}\n\nexport function powerToDb(request: DbConversionRequest): Float32Array;\nexport function powerToDb(\n values: Float32Array,\n ref?: number,\n amin?: number,\n topDb?: number,\n): Float32Array;\nexport function powerToDb(\n values: Float32Array | DbConversionRequest,\n ref = 1.0,\n amin = 1e-10,\n topDb = 80.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return powerToDb(values.values, values.ref, values.amin, values.topDb);\n }\n return requireModule().powerToDb(values, ref, amin, topDb);\n}\n\nexport function amplitudeToDb(request: DbConversionRequest): Float32Array;\nexport function amplitudeToDb(\n values: Float32Array,\n ref?: number,\n amin?: number,\n topDb?: number,\n): Float32Array;\nexport function amplitudeToDb(\n values: Float32Array | DbConversionRequest,\n ref = 1.0,\n amin = 1e-5,\n topDb = 80.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return amplitudeToDb(values.values, values.ref, values.amin, values.topDb);\n }\n return requireModule().amplitudeToDb(values, ref, amin, topDb);\n}\n\nexport function dbToPower(values: Float32Array, ref = 1.0): Float32Array {\n return requireModule().dbToPower(values, ref);\n}\n\nexport function dbToAmplitude(values: Float32Array, ref = 1.0): Float32Array {\n return requireModule().dbToAmplitude(values, ref);\n}\n\nexport function preemphasis(request: EmphasisRequest): Float32Array;\nexport function preemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array;\nexport function preemphasis(\n samples: Float32Array | EmphasisRequest,\n coef = 0.97,\n zi?: number,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return preemphasis(samples.samples, samples.coef, samples.zi);\n }\n return requireModule().preemphasis(samples, coef, zi ?? null);\n}\n\nexport function deemphasis(request: EmphasisRequest): Float32Array;\nexport function deemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array;\nexport function deemphasis(\n samples: Float32Array | EmphasisRequest,\n coef = 0.97,\n zi?: number,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return deemphasis(samples.samples, samples.coef, samples.zi);\n }\n return requireModule().deemphasis(samples, coef, zi ?? null);\n}\n\nexport function trimSilence(request: SilenceRequest): WasmTrimResult;\nexport function trimSilence(\n samples: Float32Array,\n topDb?: number,\n frameLength?: number,\n hopLength?: number,\n): WasmTrimResult;\nexport function trimSilence(\n samples: Float32Array | SilenceRequest,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): WasmTrimResult {\n if (!(samples instanceof Float32Array)) {\n return trimSilence(samples.samples, samples.topDb, samples.frameLength, samples.hopLength);\n }\n return requireModule().trimSilence(samples, topDb, frameLength, hopLength);\n}\n\nexport function splitSilence(request: SilenceRequest): Int32Array;\nexport function splitSilence(\n samples: Float32Array,\n topDb?: number,\n frameLength?: number,\n hopLength?: number,\n): Int32Array;\nexport function splitSilence(\n samples: Float32Array | SilenceRequest,\n topDb = 60.0,\n frameLength = 2048,\n hopLength = 512,\n): Int32Array {\n if (!(samples instanceof Float32Array)) {\n return splitSilence(samples.samples, samples.topDb, samples.frameLength, samples.hopLength);\n }\n return requireModule().splitSilence(samples, topDb, frameLength, hopLength);\n}\n\n/**\n * Lists the intervals where ANY of `signals` is sounding, so every gap\n * between them is silent in all of them -- what several takes of one part\n * share is their silence, not their sound.\n *\n * @returns The union of {@link splitSilence}'s per-signal intervals, merged\n * where they touch. A single signal returns exactly what `splitSilence`\n * does for it.\n */\nexport function splitSilenceCommon(request: SplitSilenceCommonRequest): Int32Array {\n return requireModule().splitSilenceCommon(\n request.signals,\n request.topDb ?? 60.0,\n request.frameLength ?? 2048,\n request.hopLength ?? 512,\n );\n}\n\n/**\n * {@link splitSilenceCommon} plus the report that says why those are the\n * intervals.\n *\n * Identical intervals, identical refusals, identical defaults; the only\n * difference is the second field. The plain entry point stays because a caller\n * cutting takes has no use for the diagnosis, and one interval covering\n * everything is the answer to three different situations the interval list cannot\n * separate — see {@link SilenceCommonReport} for reading them apart.\n *\n * @returns The union intervals and the report measured on the same RMS pass\n */\nexport function splitSilenceCommonWithReport(\n request: SplitSilenceCommonRequest,\n): SplitSilenceCommonWithReportResult {\n return requireModule().splitSilenceCommonWithReport(\n request.signals,\n request.topDb ?? 60.0,\n request.frameLength ?? 2048,\n request.hopLength ?? 512,\n );\n}\n\nexport function frameSignal(request: FrameSignalRequest): WasmFrameResult;\nexport function frameSignal(\n samples: Float32Array,\n frameLength: number,\n hopLength: number,\n): WasmFrameResult;\nexport function frameSignal(\n samples: Float32Array | FrameSignalRequest,\n frameLength?: number,\n hopLength?: number,\n): WasmFrameResult {\n if (!(samples instanceof Float32Array)) {\n return frameSignal(samples.samples, samples.frameLength, samples.hopLength);\n }\n return requireModule().frameSignal(samples, frameLength as number, hopLength as number);\n}\n\nexport function padCenter(request: PadCenterRequest): Float32Array;\nexport function padCenter(\n values: Float32Array,\n targetSize: number,\n padValue?: number,\n): Float32Array;\nexport function padCenter(\n values: Float32Array | PadCenterRequest,\n targetSize?: number,\n padValue = 0.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return padCenter(values.values, values.targetSize, values.padValue);\n }\n return requireModule().padCenter(values, targetSize as number, padValue);\n}\n\nexport function fixLength(request: FixLengthRequest): Float32Array;\nexport function fixLength(\n values: Float32Array,\n targetSize: number,\n padValue?: number,\n): Float32Array;\nexport function fixLength(\n values: Float32Array | FixLengthRequest,\n targetSize?: number,\n padValue = 0.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return fixLength(values.values, values.targetSize, values.padValue);\n }\n return requireModule().fixLength(values, targetSize as number, padValue);\n}\n\nexport function fixFrames(request: FixFramesRequest): Int32Array;\nexport function fixFrames(\n frames: Int32Array,\n xMin?: number,\n xMax?: number,\n pad?: boolean,\n): Int32Array;\nexport function fixFrames(\n frames: Int32Array | FixFramesRequest,\n xMin = 0,\n xMax = -1,\n pad = true,\n): Int32Array {\n if (!(frames instanceof Int32Array)) {\n return fixFrames(frames.frames, frames.xMin, frames.xMax, frames.pad);\n }\n return requireModule().fixFrames(frames, xMin, xMax, pad);\n}\n\nexport function onsetBacktrack(request: OnsetBacktrackRequest): Int32Array;\nexport function onsetBacktrack(events: Int32Array, energy: Float32Array): Int32Array;\nexport function onsetBacktrack(\n events: Int32Array | OnsetBacktrackRequest,\n energy?: Float32Array,\n): Int32Array {\n if (!(events instanceof Int32Array)) {\n return onsetBacktrack(events.events, events.energy);\n }\n return requireModule().onsetBacktrack(events, energy as Float32Array);\n}\n\nexport function peakPick(request: PeakPickRequest): Int32Array;\nexport function peakPick(\n values: Float32Array,\n preMax: number,\n postMax: number,\n preAvg: number,\n postAvg: number,\n delta: number,\n wait: number,\n): Int32Array;\nexport function peakPick(\n values: Float32Array | PeakPickRequest,\n preMax?: number,\n postMax?: number,\n preAvg?: number,\n postAvg?: number,\n delta?: number,\n wait?: number,\n): Int32Array {\n if (!(values instanceof Float32Array)) {\n const r = values;\n return peakPick(r.values, r.preMax, r.postMax, r.preAvg, r.postAvg, r.delta, r.wait);\n }\n return requireModule().peakPick(\n values,\n preMax as number,\n postMax as number,\n preAvg as number,\n postAvg as number,\n delta as number,\n wait as number,\n );\n}\n\nexport function vectorNormalize(request: VectorNormalizeRequest): Float32Array;\nexport function vectorNormalize(\n values: Float32Array,\n normType?: number,\n threshold?: number,\n): Float32Array;\nexport function vectorNormalize(\n values: Float32Array | VectorNormalizeRequest,\n normType = 0,\n threshold = 0.0,\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n return vectorNormalize(values.values, values.normType, values.threshold);\n }\n return requireModule().vectorNormalize(values, normType, threshold);\n}\n\nexport function pcen(request: PcenRequest): Float32Array;\nexport function pcen(\n values: Float32Array,\n nBins: number,\n nFrames: number,\n options?: Record<string, number>,\n): Float32Array;\nexport function pcen(\n values: Float32Array | PcenRequest,\n nBins = 0,\n nFrames = 0,\n options: Record<string, number> = {},\n): Float32Array {\n if (!(values instanceof Float32Array)) {\n const r = values;\n const {\n values: requestValues,\n nBins: requestBins,\n nFrames: requestFrames,\n options: legacyOptions,\n ...flatOptions\n } = r;\n return pcen(requestValues, requestBins, requestFrames, {\n ...legacyOptions,\n ...flatOptions,\n });\n }\n return requireModule().pcen(values, nBins, nFrames, options);\n}\n\nexport function tonnetz(request: TonnetzRequest): Float32Array;\nexport function tonnetz(chromagram: Float32Array, nChroma: number, nFrames: number): Float32Array;\nexport function tonnetz(\n chromagram: Float32Array | TonnetzRequest,\n nChroma?: number,\n nFrames?: number,\n): Float32Array {\n if (!(chromagram instanceof Float32Array)) {\n return tonnetz(chromagram.chromagram, chromagram.nChroma, chromagram.nFrames);\n }\n return requireModule().tonnetz(chromagram, nChroma as number, nFrames as number);\n}\n\nexport function tempogram(request: TempogramRequest): WasmTempogramResult;\nexport function tempogram(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n winLength?: number,\n mode?: TempogramMode,\n center?: boolean,\n norm?: boolean,\n): WasmTempogramResult;\nexport function tempogram(\n onsetEnvelope: Float32Array | TempogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n mode: TempogramMode = 'autocorrelation',\n center = true,\n norm = true,\n): WasmTempogramResult {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const r = onsetEnvelope;\n return tempogram(\n r.onsetEnvelope,\n r.sampleRate,\n r.hopLength,\n r.winLength,\n r.mode,\n r.center,\n r.norm,\n );\n }\n return requireModule().tempogram(\n onsetEnvelope,\n sampleRate,\n hopLength,\n winLength,\n mode,\n center,\n norm,\n );\n}\n\nexport function cyclicTempogram(request: CyclicTempogramRequest): WasmCyclicTempogramResult;\nexport function cyclicTempogram(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n winLength?: number,\n bpmMin?: number,\n nBins?: number,\n): WasmCyclicTempogramResult;\nexport function cyclicTempogram(\n onsetEnvelope: Float32Array | CyclicTempogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n bpmMin = 60.0,\n nBins = 60,\n): WasmCyclicTempogramResult {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const r = onsetEnvelope;\n return cyclicTempogram(\n r.onsetEnvelope,\n r.sampleRate,\n r.hopLength,\n r.winLength,\n r.bpmMin,\n r.nBins,\n );\n }\n return requireModule().cyclicTempogram(\n onsetEnvelope,\n sampleRate,\n hopLength,\n winLength,\n bpmMin,\n nBins,\n );\n}\n\nexport function plp(request: PlpRequest): Float32Array;\nexport function plp(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n tempoMin?: number,\n tempoMax?: number,\n winLength?: number,\n): Float32Array;\nexport function plp(\n onsetEnvelope: Float32Array | PlpRequest,\n sampleRate = 22050,\n hopLength = 512,\n tempoMin = 30.0,\n tempoMax = 300.0,\n winLength = 384,\n): Float32Array {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const r = onsetEnvelope;\n return plp(r.onsetEnvelope, r.sampleRate, r.hopLength, r.tempoMin, r.tempoMax, r.winLength);\n }\n return requireModule().plp(onsetEnvelope, sampleRate, hopLength, tempoMin, tempoMax, winLength);\n}\n","import { ErrorCode, SonareError } from './errors';\n\n/**\n * Per-call validation options accepted by guarded wrappers. Empty-buffer\n * checks are always performed; pass `{ validate: false }` to opt out of the\n * O(n) NaN/Inf scan on hot paths.\n *\n * `{ validate: false }` only skips this JS-side pre-scan (which raises a\n * `RangeError` naming the exact offending index). It is NOT a way to push\n * non-finite samples into the core: the native layer always re-validates the\n * buffer — through `validate_offline_audio_input` for the offline-analysis\n * entry points, and through the computation's own per-sample guard where a call\n * takes no sample rate to validate against (the waveform bucket kernels) —\n * matching the C ABI / Node / Python surfaces, so an NaN/Inf buffer still\n * throws, just with a generic native message instead of the indexed JS one.\n */\nexport interface ValidateOptions {\n validate?: boolean;\n}\n\n/**\n * Offline-analysis sample-rate bounds, mirroring the C++ core limits\n * (`sonare::kMinAudioSampleRate` / `kMaxAudioSampleRate` in `core/audio.h`).\n * Every guarded WASM entry point rejects the same out-of-range rates the C ABI,\n * Node, and Python surfaces do.\n */\nexport const MIN_AUDIO_SAMPLE_RATE = 8000;\nexport const MAX_AUDIO_SAMPLE_RATE = 384000;\n\nfunction assertNonEmptySamples(\n fnName: string,\n samples: ArrayLike<number>,\n argName = 'samples',\n): void {\n if (samples.length === 0) {\n throw new RangeError(`${fnName}: ${argName} must not be empty`);\n }\n}\n\nfunction assertFiniteSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n if (!validate) {\n return;\n }\n for (let i = 0; i < samples.length; i++) {\n const v = samples[i] as number;\n if (!Number.isFinite(v)) {\n throw new RangeError(`${fnName}: ${argName} contains NaN or Inf at index ${i}`);\n }\n }\n}\n\nexport function assertSamples(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n argName = 'samples',\n): void {\n assertNonEmptySamples(fnName, samples, argName);\n assertFiniteSamples(fnName, samples, validate, argName);\n}\n\n/**\n * `assertSamples` restricted to the span a windowed entry point actually reads.\n *\n * The emptiness check still covers the whole buffer, and the reported index is\n * the absolute one, so the message keeps naming the sample the caller passed.\n * What narrows is the scan: a windowed call refuses a non-finite sample inside\n * its frame and is indifferent to one outside it, which is the contract the C\n * ABI states and the cost model it promises -- per call the scan is bounded by\n * the frame, not by the length of the buffer being polled.\n */\nexport function assertSamplesInWindow(\n fnName: string,\n samples: ArrayLike<number>,\n validate: boolean,\n windowStart: number,\n windowLength: number,\n argName = 'samples',\n): void {\n assertNonEmptySamples(fnName, samples, argName);\n if (!validate) {\n return;\n }\n // Floored and ceiled before use: a fractional offset is refused by the layer\n // that owns it, but an index of 100.5 reads `undefined` out of the buffer and\n // would be reported here as a non-finite sample that is not there.\n const start = Math.min(Math.max(Math.floor(windowStart), 0), samples.length);\n const stop = Math.min(start + Math.max(Math.ceil(windowLength), 0), samples.length);\n for (let i = start; i < stop; i++) {\n const v = samples[i] as number;\n if (!Number.isFinite(v)) {\n throw new RangeError(`${fnName}: ${argName} contains NaN or Inf at index ${i}`);\n }\n }\n}\n\nexport function assertFiniteScalar(fnName: string, value: number, argName: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${fnName}: ${argName} must be a finite number`);\n }\n}\n\n/**\n * A NaN gamma is the automatic-bandwidth sentinel the variable-Q transform\n * documents, alongside a negative value, so only an infinity is out of domain.\n */\nexport function assertVqtGamma(fnName: string, gamma: number): void {\n if (gamma === Number.POSITIVE_INFINITY || gamma === Number.NEGATIVE_INFINITY) {\n throw new RangeError(`${fnName}: gamma must not be infinite`);\n }\n}\n\nexport function assertSampleRate(fnName: string, sampleRate: number, argName = 'sampleRate'): void {\n // Two refusals, not one: 22050.7 sits inside the range, so reporting it as\n // out of range names an argument that is not the one at fault. `argName` is\n // the same point for a rate the caller spelled something else, such as a\n // resampler's source and target.\n if (!Number.isInteger(sampleRate)) {\n throw new RangeError(`${fnName}: ${argName} must be an integer`);\n }\n if (sampleRate < MIN_AUDIO_SAMPLE_RATE || sampleRate > MAX_AUDIO_SAMPLE_RATE) {\n throw new RangeError(\n `${fnName}: ${argName} out of supported range [${MIN_AUDIO_SAMPLE_RATE}, ${MAX_AUDIO_SAMPLE_RATE}]`,\n );\n }\n}\n\n/** Validate and retain the public Audio.fromBuffer construction contract. */\nexport function validateAudioBuffer(samples: Float32Array, sampleRate: number): void {\n assertSamples('Audio.fromBuffer', samples, true);\n assertSampleRate('Audio.fromBuffer', sampleRate);\n}\n\n/** Bounds of the native `int` every embind argument below is narrowed into. */\nexport const C_INT_MIN = -2147483648;\nexport const C_INT_MAX = 2147483647;\n\n/**\n * Reject an argument embind's declared-`int` narrowing would wrap.\n *\n * A positional embind parameter declared `int` WRAPS rather than saturates, so\n * a kernel of `2 ** 32` arrives as 0 and `2 ** 32 + 1` as 1 — both values the\n * native guards accept, so the call succeeds having separated on a setting the\n * caller never asked for. (The options-object path narrows through\n * `checkedIntFromVal`, which refuses the same inputs in the module; this is the\n * positional path's equivalent.)\n *\n * Reported as the branded `SonareError` carrying `InvalidParameter` rather than\n * a `RangeError`, because the class follows what the rejection stands in for: a\n * `RangeError` is this surface refusing an argument on its own authority, while\n * this one pre-empts a native refusal the caller would have received under that\n * code had the narrowing not wrapped the value into the accepted domain first.\n * The agreement with the Node and Python surfaces is asserted by the Node\n * package's `tests/narrowing-code-parity.test.ts`, which drives one value\n * through all three — weakening this check turns that red.\n */\nexport function assertInt32(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value < C_INT_MIN || value > C_INT_MAX) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n `${fnName}: ${argName} must be an integer within the signed 32-bit range`,\n );\n }\n}\n\n/**\n * Check both HPSS kernels before embind narrows them.\n *\n * Parity, positivity and the ceiling stay the core's to enforce, and it names\n * the median filter that rejected the value. What cannot be deferred is the\n * narrowing itself: a wrapped kernel arrives as a legal one and separates on it.\n *\n * These two arrive POSITIONALLY, so they never pass through the options-bag\n * reader and inherit none of its checks. That is what separates this from\n * {@link assertPercussiveSeparation}, which duplicates a reader check to improve\n * a message; here there is no reader to duplicate.\n */\nexport function assertHpssKernels(\n fnName: string,\n kernelHarmonic: number,\n kernelPercussive: number,\n): void {\n assertInt32(fnName, kernelHarmonic, 'kernelHarmonic');\n assertInt32(fnName, kernelPercussive, 'kernelPercussive');\n}\n\nfunction assertIntegralField(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value)) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n `${fnName}: ${argName} must be an integer`,\n );\n }\n}\n\n/**\n * Percussive-event separation fields, as the request objects carry them.\n */\nexport interface PercussiveSeparationFields {\n nFft?: number;\n hopLength?: number;\n hpssKernelHarmonic?: number;\n hpssKernelPercussive?: number;\n}\n\n/**\n * Check the percussive-event separation's framing and kernels for integrality.\n *\n * All four fields reach the module through one options-bag reader, which now\n * refuses a fractional value itself, so this is the diagnostic rather than the\n * guarantee: it fires first and names the function, where the reader can only\n * name the field. Both reject the same set, so they cannot disagree about an\n * input — only about how the message reads. Do not narrow this to fields the\n * reader misses; there are none, and a check scoped to a gap that no longer\n * exists is how a stale justification outlives its divergence.\n *\n * The fields are iterated rather than named at each call site so a new one is\n * visible here. Absence means the default, so an omitted field is not resolved.\n */\nexport function assertPercussiveSeparation(\n fnName: string,\n options: PercussiveSeparationFields,\n): void {\n const fields = ['nFft', 'hopLength', 'hpssKernelHarmonic', 'hpssKernelPercussive'] as const;\n for (const field of fields) {\n const value = options[field];\n if (value !== undefined) {\n assertIntegralField(fnName, value, field);\n }\n }\n}\n\nexport function assertNonNegativeInteger(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new RangeError(`${fnName}: ${argName} must be a non-negative integer`);\n }\n}\n\n/** Integer strictly greater than zero, up to the native `int` ceiling. */\nexport function assertPositiveInteger(fnName: string, value: number, argName: string): void {\n // Two refusals, not one: 512.7 is positive, so reporting it as non-positive\n // names a property it has. The ceiling travels with the sign rather than with\n // integrality, because both describe a value the native `int` can carry.\n if (!Number.isInteger(value)) {\n throw new RangeError(`${fnName}: ${argName} must be an integer`);\n }\n if (value <= 0 || value > C_INT_MAX) {\n throw new RangeError(`${fnName}: ${argName} must be a positive integer`);\n }\n}\n\n/**\n * Split \"not an integer\" into the two mistakes it can be: `TypeError` when the\n * value is not a `number` at all, `RangeError` when it is a number but not\n * integral -- the right-type, wrong-domain half of the same message.\n *\n * `Number.isInteger` alone answers both, which is why a single check reads as\n * sufficient; what it cannot do is say which one happened, and a caller can act\n * only on the mistake they made. The classes are the contract on this surface,\n * so a sibling argument in the same call must not report a fraction differently\n * from this one.\n */\nexport function assertIntegerValue(\n fnName: string,\n value: unknown,\n argName: string,\n): asserts value is number {\n if (typeof value !== 'number') {\n throw new TypeError(`${fnName}: ${argName} must be an integer`);\n }\n if (!Number.isInteger(value)) {\n throw new RangeError(`${fnName}: ${argName} must be an integer`);\n }\n}\n\n/** Even integer in `[min, max]`, for an FFT-style size where only parity matters. */\nexport function assertEvenIntegerAtLeast(\n fnName: string,\n value: number,\n argName: string,\n min: number,\n max: number,\n): void {\n // Range and parity are separate refusals: 2 ** 31 is already even, so telling\n // its caller the value must be even names a property it has.\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [${min}, ${max}]`);\n }\n if (value % 2 !== 0) {\n throw new RangeError(`${fnName}: ${argName} must be an even integer`);\n }\n}\n\n/** General integer-in-`[min, max]` check, for a bound {@link assertU7}/{@link assertNibble} don't cover. */\nexport function assertBoundedInteger(\n fnName: string,\n value: number,\n argName: string,\n min: number,\n max: number,\n): void {\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [${min}, ${max}]`);\n }\n}\n\nexport function assertU7(fnName: string, value: number, argName: string): number {\n if (!Number.isInteger(value) || value < 0 || value > 127) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 127]`);\n }\n return value;\n}\n\nexport function assertNibble(fnName: string, value: number, argName: string): number {\n if (!Number.isInteger(value) || value < 0 || value > 15) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 15]`);\n }\n return value;\n}\n\nexport function assertU32(fnName: string, value: number, argName: string): void {\n if (!Number.isInteger(value) || value < 0 || value > 0xffffffff) {\n throw new RangeError(`${fnName}: ${argName} must be an integer in [0, 4294967295]`);\n }\n}\n\n/**\n * Convert a caller-supplied index array to `Int32Array`, refusing any element\n * the conversion would change rather than folding it.\n *\n * `Int32Array.from(values, Math.trunc)` turns the sample index `1000.7` into\n * `1000` and `2 ** 31` into `-2 ** 31`. The C ABI takes `const int*`, so both\n * arrive as values nothing downstream can separate from ones the caller chose.\n * An `Int32Array` is returned as-is: its elements are already exact.\n */\nexport function toInt32Array(\n fnName: string,\n values: Int32Array | ArrayLike<number>,\n argName: string,\n): Int32Array {\n if (values instanceof Int32Array) {\n return values;\n }\n const out = new Int32Array(values.length);\n for (let i = 0; i < values.length; i++) {\n const element = values[i];\n // The element shape of `assertIntegerValue`, and it splits the same way: the\n // class says whether the entry was the wrong type or the wrong domain, and a\n // sibling element in the same array must not report a fraction differently.\n if (typeof element !== 'number') {\n throw new TypeError(`${fnName}: ${argName}[${i}] must be an integer`);\n }\n if (!Number.isInteger(element)) {\n throw new RangeError(`${fnName}: ${argName}[${i}] must be an integer`);\n }\n if (element < C_INT_MIN || element > C_INT_MAX) {\n throw new RangeError(\n `${fnName}: ${argName}[${i}] must be an integer in [${C_INT_MIN}, ${C_INT_MAX}]`,\n );\n }\n out[i] = element;\n }\n return out;\n}\n\nexport function assertInterleavedSamples(\n fnName: string,\n samples: ArrayLike<number>,\n channels: number,\n validate: boolean,\n): void {\n assertSamples(fnName, samples, validate);\n assertPositiveInteger(fnName, channels, 'channels');\n if (samples.length % channels !== 0) {\n throw new RangeError(`${fnName}: samples length must be a multiple of channels`);\n }\n}\n","import {\n assertEvenIntegerAtLeast,\n assertIntegerValue,\n assertPositiveInteger,\n} from './validation.js';\n\n/**\n * The facade's single FFT-size/hop domain.\n *\n * This module is deliberately internal: sibling facade modules import it, but\n * nothing re-exports it, so it stays out of the package entry point and out of\n * the C-ABI parity surface (which is defined by the index's re-export closure).\n */\n\n/**\n * Resolves and validates the `nFft` / `hopLength` pair every STFT-backed entry\n * point takes.\n *\n * The core FFT is mixed-radix, so any even size transforms exactly; only the\n * real one-sided spectrum's `n_fft / 2 + 1` bin layout needs the evenness. A\n * power-of-two restriction rejects sizes the C ABI and the native CLI accept,\n * which is what a second copy of this rule used to do: `hpss({ nFft: 1536 })`\n * worked while `hpssWithResidual({ nFft: 1536 })` threw, with the message\n * asserting a constraint this project had explicitly written down as untrue.\n * One implementation, so the two cannot disagree again.\n */\nexport function resolveFftOptions(\n fnName: string,\n nFft: unknown,\n hopLength: unknown,\n): { nFft: number; hopLength: number } {\n const resolvedNFft = nFft === undefined ? 2048 : nFft;\n const resolvedHopLength = hopLength === undefined ? 512 : hopLength;\n assertIntegerValue(fnName, resolvedNFft, 'nFft');\n assertEvenIntegerAtLeast(fnName, resolvedNFft, 'nFft', 2, 2 ** 30);\n assertIntegerValue(fnName, resolvedHopLength, 'hopLength');\n assertPositiveInteger(fnName, resolvedHopLength, 'hopLength');\n return { nFft: resolvedNFft, hopLength: resolvedHopLength };\n}\n","/**\n * Source decomposition and self-similarity segmentation: NMF factorisation and\n * the masks built over it, and the recurrence structure of a track.\n */\n\nimport { resolveFftOptions } from './_fft_options';\nimport { getSonareModule } from './module_state';\nimport type { SegmentMatrix } from './public_types';\nimport type {\n WasmDecomposeResult,\n WasmHpssWithResidualResult,\n WasmMatrix2dResult,\n} from './sonare.js';\nimport {\n assertHpssKernels,\n assertNonNegativeInteger,\n assertPositiveInteger,\n assertSamples,\n toInt32Array,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nfunction resolveHardMask(fnName: string, value: unknown): boolean {\n if (value === undefined) {\n return false;\n }\n if (typeof value !== 'boolean') {\n throw new TypeError(`${fnName}: hardMask must be a boolean`);\n }\n return value;\n}\n\nexport interface DecomposeRequest {\n s: Float32Array;\n nFeatures: number;\n nFrames: number;\n nComponents: number;\n nIter?: number;\n beta?: number;\n}\n\nexport interface DecomposeWithInitRequest extends DecomposeRequest {\n init?: 'random' | 'nndsvd';\n}\n\nexport interface NnFilterRequest {\n s: Float32Array;\n nFeatures: number;\n nFrames: number;\n aggregate?: string;\n k?: number;\n width?: number;\n}\n\nexport interface SegmentCrossSimilarityRequest {\n x: Float32Array;\n xRows: number;\n xCols: number;\n y: Float32Array;\n yRows: number;\n yCols: number;\n k?: number;\n metric?: 'cosine' | 'euclidean';\n mode?: 'connectivity' | 'affinity';\n}\n\nexport interface SegmentRecurrenceMatrixRequest {\n data: Float32Array;\n rows: number;\n cols: number;\n k?: number;\n width?: number;\n sym?: boolean;\n metric?: 'cosine' | 'euclidean';\n mode?: 'connectivity' | 'affinity';\n}\n\nexport interface SegmentRecurrenceToLagRequest {\n recurrence: Float32Array;\n n: number;\n pad?: boolean;\n}\n\nexport interface SegmentLagToRecurrenceRequest {\n lag: Float32Array;\n rows: number;\n lags: number;\n}\n\nexport interface SegmentSubsegmentRequest {\n data: Float32Array;\n rows: number;\n cols: number;\n boundaries: Int32Array;\n nSegments?: number;\n}\n\nexport interface SegmentAgglomerativeRequest {\n data: Float32Array;\n rows: number;\n cols: number;\n k: number;\n linkage?: 'average' | 'single' | 'complete' | 'ward';\n}\n\nexport interface SegmentPathEnhanceRequest {\n recurrence: Float32Array;\n n: number;\n win: number;\n maxRatio?: number;\n minRatio?: number;\n nFilters?: number;\n}\n\nfunction validateSegmentMatrix(\n fnName: string,\n data: Float32Array,\n rows: number,\n cols: number,\n dataName: string,\n): void {\n assertPositiveInteger(fnName, rows, 'rows');\n assertPositiveInteger(fnName, cols, 'cols');\n assertSamples(fnName, data, true, dataName);\n const expected = rows * cols;\n if (!Number.isSafeInteger(expected) || data.length !== expected) {\n throw new RangeError(`${fnName}: ${dataName} length must equal rows * cols`);\n }\n}\n\nexport interface RemixRequest {\n samples: Float32Array;\n intervals: Int32Array | ArrayLike<number>;\n sampleRate?: number;\n alignZeros?: boolean;\n}\n\nexport interface HpssWithResidualRequest {\n samples: Float32Array;\n sampleRate?: number;\n /**\n * Horizontal median filter size, in STFT frames: a positive odd integer at\n * most 524287. Default 31. The ceiling is 524288 and an even kernel is\n * refused, so 524287 is the largest legal value.\n */\n kernelHarmonic?: number;\n /** Vertical median filter size, in STFT bins, under the same rule. Default 31. */\n kernelPercussive?: number;\n nFft?: number;\n hopLength?: number;\n hardMask?: boolean;\n}\n\n/**\n * Non-negative matrix factorisation of a flattened [nFeatures x nFrames]\n * spectrogram (librosa.decompose.decompose). Returns the W and H factors.\n */\nexport function decompose(request: DecomposeRequest): WasmDecomposeResult;\nexport function decompose(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n nComponents: number,\n nIter?: number,\n beta?: number,\n): WasmDecomposeResult;\nexport function decompose(\n s: Float32Array | DecomposeRequest,\n nFeatures = 0,\n nFrames = 0,\n nComponents = 0,\n nIter = 50,\n beta = 2.0,\n): WasmDecomposeResult {\n if (!(s instanceof Float32Array)) {\n const request = s;\n return decompose(\n request.s,\n request.nFeatures,\n request.nFrames,\n request.nComponents,\n request.nIter,\n request.beta,\n );\n }\n return requireModule().decompose(s, nFeatures, nFrames, nComponents, nIter, beta);\n}\n\n/**\n * Non-negative matrix factorisation with a selectable initialiser\n * (librosa.decompose.decompose, `init`). Identical to {@link decompose} but\n * exposes the initialisation strategy: `'random'` (default, deterministic seed)\n * or `'nndsvd'` (SVD-based warm start, which tends to converge in fewer\n * iterations). Returns the W and H factors.\n */\nexport function decomposeWithInit(request: DecomposeWithInitRequest): WasmDecomposeResult;\nexport function decomposeWithInit(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n nComponents: number,\n nIter?: number,\n beta?: number,\n init?: 'random' | 'nndsvd',\n): WasmDecomposeResult;\nexport function decomposeWithInit(\n s: Float32Array | DecomposeWithInitRequest,\n nFeatures = 0,\n nFrames = 0,\n nComponents = 0,\n nIter = 50,\n beta = 2.0,\n init: 'random' | 'nndsvd' = 'random',\n): WasmDecomposeResult {\n if (!(s instanceof Float32Array)) {\n const request = s;\n return decomposeWithInit(\n request.s,\n request.nFeatures,\n request.nFrames,\n request.nComponents,\n request.nIter,\n request.beta,\n request.init,\n );\n }\n return requireModule().decomposeWithInit(s, nFeatures, nFrames, nComponents, nIter, beta, init);\n}\n\n/** Options for {@link decomposeStems}. */\nexport interface DecomposeStemsRequest {\n samples: Float32Array;\n sampleRate?: number;\n /** Number of NMF components (default 4). */\n nComponents?: number;\n /** STFT size (default 2048). */\n nFft?: number;\n /** STFT hop (default 512). */\n hopLength?: number;\n /** NMF multiplicative-update iterations (default 100). */\n nIter?: number;\n /** Beta divergence: 2 = Frobenius (default), 1 = Kullback-Leibler. */\n beta?: number;\n /** NMF initialisation (default `'random'`). */\n init?: 'random' | 'nndsvd';\n /**\n * Soft-mask exponent (default 1). 1 keeps the magnitude ratio; 2 is the\n * Wiener-style power ratio, which separates harder at the cost of more\n * artefacts on overlapping partials. Must be >= 1.\n */\n maskPower?: number;\n}\n\n/** One time-domain signal per NMF component, plus the factorisation. */\nexport interface DecomposeStemsResult {\n /** Component signals, each the length of the input. */\n components: Float32Array[];\n /** Component matrix [nBins x nComponents], row-major. */\n w: Float32Array;\n /** Activation matrix [nComponents x nFrames], row-major. */\n h: Float32Array;\n sampleRate: number;\n}\n\n/**\n * NMF separation that **carries the original phase**, so each component is\n * directly listenable.\n *\n * {@link decompose} returns the W/H factors of a magnitude spectrogram, which\n * have no phase; reconstructing from them needs a phase estimator\n * ({@link griffinLim}), and an estimated phase does not hold up as a stem. This\n * instead builds a per-component soft mask from the factorisation and applies\n * it to the original complex spectrogram. The masks sum to one wherever the\n * model has energy and the inverse STFT is linear, so the components sum back\n * to the input.\n */\nexport function decomposeStems(request: DecomposeStemsRequest): DecomposeStemsResult {\n return requireModule().decomposeStems(request.samples, request.sampleRate ?? 22050, {\n nComponents: request.nComponents,\n nFft: request.nFft,\n hopLength: request.hopLength,\n nIter: request.nIter,\n beta: request.beta,\n init: request.init,\n maskPower: request.maskPower,\n });\n}\n\n/** Request form of {@link decomposeStemsLinked}. */\nexport interface DecomposeStemsLinkedRequest {\n /** At least one channel; all the same length. */\n channels: Float32Array[];\n sampleRate?: number;\n /** Number of NMF components (default 4). */\n nComponents?: number;\n /** STFT size (default 2048). */\n nFft?: number;\n /** STFT hop (default 512). */\n hopLength?: number;\n /** NMF multiplicative-update iterations (default 100). */\n nIter?: number;\n /** Beta divergence: 2 = Frobenius (default), 1 = Kullback-Leibler. */\n beta?: number;\n /** NMF initialisation (default `'random'`). */\n init?: 'random' | 'nndsvd';\n /** Soft-mask exponent (default 1); see {@link DecomposeStemsRequest.maskPower}. */\n maskPower?: number;\n}\n\n/** One time-domain signal per (component, channel), plus the factorisation. */\nexport interface DecomposeStemsLinkedResult {\n /**\n * Component signals: `components[k][c]` is component `k`'s signal on\n * channel `c`, each the length of the input.\n */\n components: Float32Array[][];\n /** Component matrix [nBins x nComponents], row-major. */\n w: Float32Array;\n /** Activation matrix [nComponents x nFrames], row-major. */\n h: Float32Array;\n sampleRate: number;\n}\n\n/**\n * Multi-channel form of {@link decomposeStems}: one NMF model and one soft\n * mask shared across every channel, built from the channels' averaged\n * magnitude spectrogram and applied UNCHANGED to each channel's own complex\n * spectrum, so no interchannel level or phase difference moves. A single\n * channel reproduces {@link decomposeStems} bit for bit.\n *\n * @throws On a null/empty channel set, mismatched channel lengths, a channel\n * count above the core's ceiling, or an invalid option.\n */\nexport function decomposeStemsLinked(\n request: DecomposeStemsLinkedRequest,\n): DecomposeStemsLinkedResult {\n return requireModule().decomposeStemsLinked(request.channels, request.sampleRate ?? 22050, {\n nComponents: request.nComponents,\n nFft: request.nFft,\n hopLength: request.hopLength,\n nIter: request.nIter,\n beta: request.beta,\n init: request.init,\n maskPower: request.maskPower,\n });\n}\n\n/**\n * Nearest-neighbour filtering of a flattened [nFeatures x nFrames] spectrogram\n * (librosa.decompose.nn_filter).\n */\nexport function nnFilter(request: NnFilterRequest): WasmMatrix2dResult;\nexport function nnFilter(\n s: Float32Array,\n nFeatures: number,\n nFrames: number,\n aggregate?: string,\n k?: number,\n width?: number,\n): WasmMatrix2dResult;\nexport function nnFilter(\n s: Float32Array | NnFilterRequest,\n nFeatures = 0,\n nFrames = 0,\n aggregate = 'mean',\n k = 7,\n width = 1,\n): WasmMatrix2dResult {\n if (!(s instanceof Float32Array)) {\n const r = s;\n return nnFilter(r.s, r.nFeatures, r.nFrames, r.aggregate, r.k, r.width);\n }\n return requireModule().nnFilter(s, nFeatures, nFrames, aggregate, k, width);\n}\n\n/**\n * Reorder/concatenate a signal by interval slices (librosa.effects.remix).\n *\n * With `alignZeros` the boundaries snap to the signal's zero-crossings. That is\n * a per-signal decision, so calling this per channel snaps each channel to a\n * different frame and drifts a stereo take apart; resolve one cut set with\n * {@link remixAlignedIntervals} and apply it to every channel instead.\n *\n * @param intervals - Flat (start, end) sample pairs (even length).\n */\nexport function remix(request: RemixRequest): Float32Array;\nexport function remix(\n samples: Float32Array,\n intervals: Int32Array | ArrayLike<number>,\n sampleRate?: number,\n alignZeros?: boolean,\n): Float32Array;\nexport function remix(\n samples: Float32Array | RemixRequest,\n intervals?: Int32Array | ArrayLike<number>,\n sampleRate = 22050,\n alignZeros = false,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return remix(r.samples, r.intervals, r.sampleRate, r.alignZeros);\n }\n // Sample indices must reach the native side as exact 32-bit integers, and a\n // boundary the conversion changed would cut the slice somewhere the caller\n // never named.\n const intervalsI32 = toInt32Array('remix', intervals as ArrayLike<number>, 'intervals');\n return requireModule().remix(samples, intervalsI32, sampleRate, alignZeros);\n}\n\n/**\n * Resolve the cut points {@link remix} would use, without cutting.\n *\n * Returns a flat `Int32Array` of one clamped `(start, end)` pair per input\n * interval. With `alignZeros` each boundary snaps to the nearest zero-crossing,\n * with two guards that stop a slice from vanishing: a signal with no sign\n * change at all (silence, a DC offset, any constant) is not snapped, and a\n * slice that had content but collapses to empty after snapping keeps its\n * unsnapped boundaries.\n *\n * Use this to cut a multichannel take on one common frame set: resolve once\n * from one channel, then slice every channel with the returned pairs.\n *\n * @param intervals - Flat (start, end) sample pairs (even length).\n */\nexport function remixAlignedIntervals(request: RemixRequest): Int32Array;\nexport function remixAlignedIntervals(\n samples: Float32Array,\n intervals: Int32Array | ArrayLike<number>,\n sampleRate?: number,\n alignZeros?: boolean,\n): Int32Array;\nexport function remixAlignedIntervals(\n samples: Float32Array | RemixRequest,\n intervals?: Int32Array | ArrayLike<number>,\n sampleRate = 22050,\n alignZeros = true,\n): Int32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return remixAlignedIntervals(r.samples, r.intervals, r.sampleRate, r.alignZeros ?? true);\n }\n const intervalsI32 = toInt32Array(\n 'remixAlignedIntervals',\n intervals as ArrayLike<number>,\n 'intervals',\n );\n return requireModule().remixAlignedIntervals(samples, intervalsI32, sampleRate, alignZeros);\n}\n\n/**\n * HPSS into harmonic / percussive / residual signals.\n *\n * The three outputs always add back up to the input. `residual` is silent under\n * the default soft mask, whose two masks sum to one, so `harmonic` and\n * `percussive` already carry everything; it is returned anyway so the result\n * shape does not change with the mask. Pass `hardMask: true` for a residual that\n * holds signal — its thresholded masks leave the band where neither component\n * dominates, measured at 3 % of the input energy on a voice-plus-kick signal.\n *\n * @example\n * ```ts\n * const soft = hpssWithResidual({ samples, sampleRate });\n * // soft.residual is silence\n * const hard = hpssWithResidual({ samples, sampleRate, hardMask: true });\n * // hard.residual carries what neither component claimed\n * ```\n *\n * @throws SonareError (`InvalidParameter`) on a kernel that is not an integer\n * within the signed 32-bit range, or one the core rejects as even,\n * non-positive or above its ceiling\n */\nexport function hpssWithResidual(request: HpssWithResidualRequest): WasmHpssWithResidualResult;\nexport function hpssWithResidual(\n samples: Float32Array,\n sampleRate?: number,\n kernelHarmonic?: number,\n kernelPercussive?: number,\n nFft?: number,\n hopLength?: number,\n hardMask?: boolean,\n): WasmHpssWithResidualResult;\nexport function hpssWithResidual(\n samples: Float32Array | HpssWithResidualRequest,\n sampleRate = 22050,\n kernelHarmonic = 31,\n kernelPercussive = 31,\n nFft?: number,\n hopLength?: number,\n hardMask?: boolean,\n): WasmHpssWithResidualResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return hpssWithResidual(\n r.samples,\n r.sampleRate,\n r.kernelHarmonic,\n r.kernelPercussive,\n r.nFft,\n r.hopLength,\n r.hardMask,\n );\n }\n const fftOptions = resolveFftOptions('hpssWithResidual', nFft, hopLength);\n const resolvedHardMask = resolveHardMask('hpssWithResidual', hardMask);\n assertHpssKernels('hpssWithResidual', kernelHarmonic, kernelPercussive);\n return requireModule().hpssWithResidualEx(\n samples,\n sampleRate,\n kernelHarmonic,\n kernelPercussive,\n fftOptions.nFft,\n fftOptions.hopLength,\n resolvedHardMask,\n );\n}\n\n/** Column-wise cross-similarity (librosa.segment.cross_similarity). */\nexport function segmentCrossSimilarity(request: SegmentCrossSimilarityRequest): SegmentMatrix {\n validateSegmentMatrix('segmentCrossSimilarity', request.x, request.xRows, request.xCols, 'x');\n validateSegmentMatrix('segmentCrossSimilarity', request.y, request.yRows, request.yCols, 'y');\n if (request.xRows !== request.yRows) {\n throw new RangeError('segmentCrossSimilarity: feature dimensions must match');\n }\n assertNonNegativeInteger('segmentCrossSimilarity', request.k ?? 0, 'k');\n return requireModule().segmentCrossSimilarity(\n request.x,\n request.xRows,\n request.xCols,\n request.y,\n request.yRows,\n request.yCols,\n request.k ?? 0,\n request.metric ?? 'cosine',\n request.mode ?? 'connectivity',\n );\n}\n\n/** Self-similarity recurrence matrix (librosa.segment.recurrence_matrix). */\nexport function segmentRecurrenceMatrix(request: SegmentRecurrenceMatrixRequest): SegmentMatrix {\n validateSegmentMatrix(\n 'segmentRecurrenceMatrix',\n request.data,\n request.rows,\n request.cols,\n 'data',\n );\n assertNonNegativeInteger('segmentRecurrenceMatrix', request.k ?? 0, 'k');\n assertNonNegativeInteger('segmentRecurrenceMatrix', request.width ?? 1, 'width');\n return requireModule().segmentRecurrenceMatrix(\n request.data,\n request.rows,\n request.cols,\n request.k ?? 0,\n request.width ?? 1,\n request.sym ?? false,\n request.metric ?? 'euclidean',\n request.mode ?? 'connectivity',\n );\n}\n\n/** Convert an `n × n` recurrence matrix to a lag matrix. */\nexport function segmentRecurrenceToLag(request: SegmentRecurrenceToLagRequest): SegmentMatrix {\n validateSegmentMatrix(\n 'segmentRecurrenceToLag',\n request.recurrence,\n request.n,\n request.n,\n 'recurrence',\n );\n return requireModule().segmentRecurrenceToLag(\n request.recurrence,\n request.n,\n request.pad ?? false,\n );\n}\n\n/** Convert a lag matrix back to an `n × n` recurrence matrix. */\nexport function segmentLagToRecurrence(request: SegmentLagToRecurrenceRequest): SegmentMatrix {\n validateSegmentMatrix('segmentLagToRecurrence', request.lag, request.rows, request.lags, 'lag');\n return requireModule().segmentLagToRecurrence(request.lag, request.rows, request.lags);\n}\n\n/** Refine frame boundaries by clustering within each parent segment. */\nexport function segmentSubsegment(request: SegmentSubsegmentRequest): Int32Array {\n validateSegmentMatrix('segmentSubsegment', request.data, request.rows, request.cols, 'data');\n assertPositiveInteger('segmentSubsegment', request.nSegments ?? 4, 'nSegments');\n return requireModule().segmentSubsegment(\n request.data,\n request.rows,\n request.cols,\n request.boundaries,\n request.nSegments ?? 4,\n );\n}\n\n/** Cluster feature columns and return one label per column. */\nexport function segmentAgglomerative(request: SegmentAgglomerativeRequest): Int32Array {\n validateSegmentMatrix('segmentAgglomerative', request.data, request.rows, request.cols, 'data');\n assertPositiveInteger('segmentAgglomerative', request.k, 'k');\n return requireModule().segmentAgglomerative(\n request.data,\n request.rows,\n request.cols,\n request.k,\n request.linkage ?? 'average',\n );\n}\n\n/** Enhance diagonal paths in an `n × n` recurrence matrix. */\nexport function segmentPathEnhance(request: SegmentPathEnhanceRequest): SegmentMatrix {\n validateSegmentMatrix(\n 'segmentPathEnhance',\n request.recurrence,\n request.n,\n request.n,\n 'recurrence',\n );\n assertPositiveInteger('segmentPathEnhance', request.win, 'win');\n assertPositiveInteger('segmentPathEnhance', request.maxRatio ?? 2, 'maxRatio');\n assertNonNegativeInteger('segmentPathEnhance', request.minRatio ?? 0, 'minRatio');\n assertPositiveInteger('segmentPathEnhance', request.nFilters ?? 7, 'nFilters');\n return requireModule().segmentPathEnhance(\n request.recurrence,\n request.n,\n request.win,\n request.maxRatio ?? 2,\n request.minRatio ?? 0,\n request.nFilters ?? 7,\n );\n}\n","/**\n * Input checks the spectrogram and inverse-transform entries share.\n */\n\nimport type { ValidateOptions } from './validation';\nimport { assertFiniteScalar, assertPositiveInteger } from './validation';\n\nexport type GuardedOptions = ValidateOptions;\n\nexport function validatePositiveIntegers(fnName: string, values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n assertPositiveInteger(fnName, value, name);\n }\n}\n\nexport function validateMelFrequencyRange(\n fnName: string,\n fmin: number,\n fmax: number,\n sampleRate: number,\n): void {\n assertFiniteScalar(fnName, fmin, 'fmin');\n assertFiniteScalar(fnName, fmax, 'fmax');\n if (fmin < 0) {\n throw new RangeError(`${fnName}: fmin must be non-negative`);\n }\n if (fmax < 0) {\n throw new RangeError(`${fnName}: fmax must be non-negative`);\n }\n const effectiveFmax = fmax === 0 ? sampleRate / 2 : fmax;\n if (effectiveFmax <= fmin) {\n throw new RangeError(`${fnName}: fmax must be greater than fmin`);\n }\n}\n","/**\n * Inverse transforms: reconstructing a linear spectrogram or audio from a mel\n * or MFCC representation, and the phase reconstruction they share.\n */\n\nimport type { GuardedOptions } from './_feature_validation';\nimport { validateMelFrequencyRange, validatePositiveIntegers } from './_feature_validation';\nimport { resolveFftOptions } from './_fft_options';\nimport type { SpectralFrameRequest } from './feature_spectral';\nimport { getSonareModule } from './module_state';\nimport type { MelPowerResult, StftPowerResult } from './public_types';\nimport { assertFiniteScalar, assertSampleRate, assertSamples } from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nexport interface MfccToMelRequest extends GuardedOptions {\n mfccCoefficients: Float32Array;\n nMfcc: number;\n nFrames: number;\n nMels?: number;\n /** Lifter used by the forward MFCC transform; zero means no liftering. */\n lifter?: number;\n}\n\n/** Canonical request form for reconstruction from a Mel power spectrogram. */\nexport interface MelToStftRequest extends GuardedOptions {\n melPower: Float32Array;\n nMels: number;\n nFrames: number;\n sampleRate?: number;\n nFft?: number;\n fmin?: number;\n fmax?: number;\n htk?: boolean;\n}\n\n/** Canonical request form for Griffin-Lim reconstruction from Mel power. */\nexport interface MelToAudioRequest extends MelToStftRequest {\n hopLength?: number;\n nIter?: number;\n}\n\nexport interface GriffinLimRequest extends GuardedOptions {\n magnitude: Float32Array;\n nBins: number;\n nFrames: number;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n nIter?: number;\n momentum?: number;\n}\n\n/** Canonical request form for Griffin-Lim reconstruction from MFCCs. */\nexport interface MfccToAudioRequest extends MfccToMelRequest {\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n fmin?: number;\n fmax?: number;\n nIter?: number;\n htk?: boolean;\n}\n\nfunction validateMatrix(\n fnName: string,\n data: Float32Array,\n rows: number,\n frames: number,\n dataName: string,\n rowName: string,\n options: GuardedOptions = {},\n): void {\n validatePositiveIntegers(fnName, { [rowName]: rows, nFrames: frames });\n assertSamples(fnName, data, options.validate !== false, dataName);\n const expectedLength = rows * frames;\n if (!Number.isSafeInteger(expectedLength) || data.length !== expectedLength) {\n throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);\n }\n}\n\n/**\n * Approximate inverse of a Mel filterbank: Mel power spectrogram -> STFT power\n * spectrogram. Mirrors `feature::mel_to_stft`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param fmin - Lower Mel band edge in Hz (default: 0)\n * @param fmax - Upper Mel band edge in Hz (default: sr/2 when 0)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns STFT power spectrogram result\n */\nexport function melToStft(request: MelToStftRequest): StftPowerResult;\nexport function melToStft(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate?: number,\n nFft?: number,\n fmin?: number,\n fmax?: number,\n htk?: boolean,\n options?: GuardedOptions,\n): StftPowerResult;\nexport function melToStft(\n melPower: Float32Array | MelToStftRequest,\n nMels = 0,\n nFrames = 0,\n sampleRate = 22050,\n nFft = 2048,\n fmin = 0,\n fmax = 0,\n htk = false,\n options: GuardedOptions = {},\n): StftPowerResult {\n if (!(melPower instanceof Float32Array)) {\n const request = melPower;\n return melToStft(\n request.melPower,\n request.nMels,\n request.nFrames,\n request.sampleRate,\n request.nFft,\n request.fmin,\n request.fmax,\n request.htk,\n request,\n );\n }\n assertSampleRate('melToStft', sampleRate);\n validateMatrix('melToStft', melPower, nMels, nFrames, 'melPower', 'nMels', options);\n // Not on the shared FFT rule: this inverts a filterbank rather than running a\n // transform, so `nFft` only sizes the output to `nFft / 2 + 1` bins and an odd\n // size is accepted by the core and by the Node surface alike.\n validatePositiveIntegers('melToStft', { nFft });\n validateMelFrequencyRange('melToStft', fmin, fmax, sampleRate);\n return requireModule().melToStft(melPower, nMels, nFrames, sampleRate, nFft, fmin, fmax, htk);\n}\n\n/**\n * Reconstruct audio from a Mel power spectrogram via Griffin-Lim. Mirrors\n * `feature::mel_to_audio`.\n *\n * @param melPower - Mel power spectrogram [nMels x nFrames] row-major\n * @param nMels - Number of Mel bands\n * @param nFrames - Number of time frames\n * @param sampleRate - Sample rate in Hz\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function melToAudio(request: MelToAudioRequest): Float32Array;\nexport function melToAudio(\n melPower: Float32Array,\n nMels: number,\n nFrames: number,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n nIter?: number,\n htk?: boolean,\n options?: GuardedOptions,\n): Float32Array;\nexport function melToAudio(\n melPower: Float32Array | MelToAudioRequest,\n nMels = 0,\n nFrames = 0,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n htk = false,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(melPower instanceof Float32Array)) {\n const request = melPower;\n return melToAudio(\n request.melPower,\n request.nMels,\n request.nFrames,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.nIter,\n request.htk,\n request,\n );\n }\n assertSampleRate('melToAudio', sampleRate);\n validateMatrix('melToAudio', melPower, nMels, nFrames, 'melPower', 'nMels', options);\n const fft = resolveFftOptions('melToAudio', nFft, hopLength);\n validatePositiveIntegers('melToAudio', { nIter });\n validateMelFrequencyRange('melToAudio', fmin, fmax, sampleRate);\n return requireModule().melToAudio(\n melPower,\n nMels,\n nFrames,\n sampleRate,\n fft.nFft,\n fft.hopLength,\n fmin,\n fmax,\n nIter,\n htk,\n );\n}\n\n/** Reconstruct audio from an STFT magnitude matrix via Griffin-Lim. */\nexport function griffinLim(request: GriffinLimRequest): Float32Array;\nexport function griffinLim(\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nIter?: number,\n momentum?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function griffinLim(\n magnitude: Float32Array | GriffinLimRequest,\n nBins = 0,\n nFrames = 0,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nIter = 32,\n momentum = 0.99,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(magnitude instanceof Float32Array)) {\n const request = magnitude;\n return griffinLim(\n request.magnitude,\n request.nBins,\n request.nFrames,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nIter,\n request.momentum,\n request,\n );\n }\n assertSampleRate('griffinLim', sampleRate);\n validateMatrix('griffinLim', magnitude, nBins, nFrames, 'magnitude', 'nBins', options);\n const fft = resolveFftOptions('griffinLim', nFft, hopLength);\n validatePositiveIntegers('griffinLim', { nIter });\n return requireModule().griffinLim(\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n fft.nFft,\n fft.hopLength,\n nIter,\n momentum,\n );\n}\n\n/**\n * Invert MFCC coefficients back to a Mel power spectrogram. Mirrors\n * `feature::mfcc_to_mel`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins to reconstruct (default: 128)\n * @returns Mel power spectrogram result\n */\nexport function mfccToMel(request: MfccToMelRequest): MelPowerResult;\nexport function mfccToMel(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels?: number,\n lifter?: number,\n options?: GuardedOptions,\n): MelPowerResult;\nexport function mfccToMel(\n mfccCoefficients: Float32Array | MfccToMelRequest,\n nMfcc = 0,\n nFrames = 0,\n nMels = 128,\n lifter = 0,\n options: GuardedOptions = {},\n): MelPowerResult {\n if (!(mfccCoefficients instanceof Float32Array)) {\n const request = mfccCoefficients;\n return mfccToMel(\n request.mfccCoefficients,\n request.nMfcc,\n request.nFrames,\n request.nMels,\n request.lifter,\n request,\n );\n }\n validateMatrix(\n 'mfccToMel',\n mfccCoefficients,\n nMfcc,\n nFrames,\n 'mfccCoefficients',\n 'nMfcc',\n options,\n );\n validatePositiveIntegers('mfccToMel', { nMels });\n return requireModule().mfccToMel(mfccCoefficients, nMfcc, nFrames, nMels, lifter);\n}\n\n/**\n * Reconstruct audio directly from MFCC coefficients via Griffin-Lim. Mirrors\n * `feature::mfcc_to_audio`.\n *\n * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major\n * @param nMfcc - Number of MFCC coefficients\n * @param nFrames - Number of time frames\n * @param nMels - Number of Mel bins (default: 128)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum Mel frequency in Hz (default: 0)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)\n * @param nIter - Griffin-Lim iterations (default: 32)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Reconstructed audio samples (mono, float32)\n */\nexport function mfccToAudio(request: MfccToAudioRequest): Float32Array;\nexport function mfccToAudio(\n mfccCoefficients: Float32Array,\n nMfcc: number,\n nFrames: number,\n nMels?: number,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n nIter?: number,\n htk?: boolean,\n lifter?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function mfccToAudio(\n mfccCoefficients: Float32Array | MfccToAudioRequest,\n nMfcc = 0,\n nFrames = 0,\n nMels = 128,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 0,\n fmax = 0,\n nIter = 32,\n htk = false,\n lifter = 0,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(mfccCoefficients instanceof Float32Array)) {\n const request = mfccCoefficients;\n return mfccToAudio(\n request.mfccCoefficients,\n request.nMfcc,\n request.nFrames,\n request.nMels,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.nIter,\n request.htk,\n request.lifter,\n request,\n );\n }\n assertSampleRate('mfccToAudio', sampleRate);\n validateMatrix(\n 'mfccToAudio',\n mfccCoefficients,\n nMfcc,\n nFrames,\n 'mfccCoefficients',\n 'nMfcc',\n options,\n );\n const fft = resolveFftOptions('mfccToAudio', nFft, hopLength);\n validatePositiveIntegers('mfccToAudio', { nMels, nIter });\n validateMelFrequencyRange('mfccToAudio', fmin, fmax, sampleRate);\n return requireModule().mfccToAudio(\n mfccCoefficients,\n nMfcc,\n nFrames,\n nMels,\n sampleRate,\n fft.nFft,\n fft.hopLength,\n fmin,\n fmax,\n nIter,\n htk,\n lifter,\n );\n}\n\nexport interface PhaseVocoderRequest extends SpectralFrameRequest {\n rate: number;\n}\n\n/**\n * Phase-vocoder time-scale modification (rate > 1 faster, < 1 slower).\n */\nexport function phaseVocoder(request: PhaseVocoderRequest): Float32Array;\nexport function phaseVocoder(\n samples: Float32Array,\n sampleRate: number,\n rate: number,\n nFft?: number,\n hopLength?: number,\n): Float32Array;\nexport function phaseVocoder(\n samples: Float32Array | PhaseVocoderRequest,\n sampleRate = 22050,\n rate = 1,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return phaseVocoder(r.samples, r.sampleRate ?? 22050, r.rate, r.nFft, r.hopLength);\n }\n // Matches the addon. A finite value too wide for a float is not covered here\n // and cannot be — it is still finite to Number.isFinite; the core's own guard\n // refuses the infinity it becomes.\n assertFiniteScalar('phaseVocoder', rate, 'rate');\n return requireModule().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);\n}\n","/**\n * Programme loudness over interleaved audio, as the broadcast standards define\n * it.\n */\n\nimport { getSonareModule } from './module_state';\nimport type { WasmLufsResult, WasmLufsSeriesResult } from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport { assertInterleavedSamples, assertSampleRate } from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nexport interface LufsInterleavedRequest extends ValidateOptions {\n samples: Float32Array;\n channels: number;\n sampleRate?: number;\n}\n\nexport interface LufsSeriesInterleavedRequest extends ValidateOptions {\n samples: Float32Array;\n channels: number;\n sampleRate?: number;\n}\n\nexport interface Ebur128LoudnessRangeRequest extends ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/**\n * Channel-weighted multichannel integrated loudness + LRA (ITU-R BS.1770 /\n * EBU R128) from an interleaved buffer of `frames * channels` samples. The\n * per-channel frame count is derived from the buffer length and `channels`.\n *\n * Pass the buffer's actual `sampleRate`: the default (22050) is non-standard for\n * audio, and K-weighting is sample-rate dependent, so a wrong rate yields wrong\n * loudness.\n */\nexport function lufsInterleaved(request: LufsInterleavedRequest): WasmLufsResult;\nexport function lufsInterleaved(\n samples: Float32Array,\n channels: number,\n sampleRate?: number,\n options?: ValidateOptions,\n): WasmLufsResult;\nexport function lufsInterleaved(\n samples: Float32Array | LufsInterleavedRequest,\n channels = 0,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): WasmLufsResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return lufsInterleaved(r.samples, r.channels, r.sampleRate, r);\n }\n assertSampleRate('lufsInterleaved', sampleRate);\n assertInterleavedSamples('lufsInterleaved', samples, channels, options.validate !== false);\n return requireModule().lufsInterleaved(samples, channels, sampleRate);\n}\n\n/**\n * Per-block momentary (400 ms) and short-term (3 s) LUFS series for an\n * interleaved buffer of `frames * channels` samples, measured with ITU-R\n * BS.1770-4 channel summing. The per-channel frame count is derived from the\n * buffer length and `channels`.\n *\n * This is not recoverable from `momentaryLufs` / `shortTermLufs`: those measure\n * one channel each, and the standard sums the K-weighted per-channel block\n * energies rather than mixing per-channel loudness in dB. Both series come out\n * of one K-weighting pass. For `channels === 1` they match the mono meters\n * element for element.\n *\n * Pass the buffer's actual `sampleRate`: the default (22050) is non-standard for\n * audio, and K-weighting is sample-rate dependent, so a wrong rate yields wrong\n * loudness.\n *\n * @example\n * ```ts\n * const { momentary, shortTerm } = lufsSeriesInterleaved({\n * samples: interleavedStereo,\n * channels: 2,\n * sampleRate: 48000,\n * });\n * ```\n */\nexport function lufsSeriesInterleaved(request: LufsSeriesInterleavedRequest): WasmLufsSeriesResult;\nexport function lufsSeriesInterleaved(\n samples: Float32Array,\n channels: number,\n sampleRate?: number,\n options?: ValidateOptions,\n): WasmLufsSeriesResult;\nexport function lufsSeriesInterleaved(\n samples: Float32Array | LufsSeriesInterleavedRequest,\n channels = 0,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): WasmLufsSeriesResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return lufsSeriesInterleaved(r.samples, r.channels, r.sampleRate, r);\n }\n assertSampleRate('lufsSeriesInterleaved', sampleRate);\n assertInterleavedSamples('lufsSeriesInterleaved', samples, channels, options.validate !== false);\n return requireModule().lufsSeriesInterleaved(samples, channels, sampleRate);\n}\n\n/**\n * Standards-compliant EBU R128 loudness range (LRA) in LU. Pass the buffer's\n * actual `sampleRate`: the default (22050) is non-standard and K-weighting is\n * sample-rate dependent.\n */\nexport function ebur128LoudnessRange(request: Ebur128LoudnessRangeRequest): number;\nexport function ebur128LoudnessRange(samples: Float32Array, sampleRate?: number): number;\nexport function ebur128LoudnessRange(\n samples: Float32Array | Ebur128LoudnessRangeRequest,\n sampleRate = 22050,\n): number {\n if (!(samples instanceof Float32Array)) {\n return ebur128LoudnessRange(samples.samples, samples.sampleRate);\n }\n return requireModule().ebur128LoudnessRange(samples, sampleRate);\n}\n","import { validatePositiveIntegers } from './_feature_validation';\nimport { resolveFftOptions } from './_fft_options';\nimport { ErrorCode, SonareError } from './errors';\nimport { getSonareModule } from './module_state';\nimport type {\n AnalyzeSectionsOptions,\n BoundaryOptions,\n BoundaryResult,\n CqtResult,\n LufsResult,\n MelodyResult,\n OnsetStrengthMultiResult,\n Section,\n SectionType,\n} from './public_types';\nimport type { WasmFourierTempogramResult, WasmNnlsChromaResult } from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport {\n assertFiniteScalar,\n assertPositiveInteger,\n assertSampleRate,\n assertSamples,\n assertVqtGamma,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\ntype AnalyzeSectionsGuardedOptions = AnalyzeSectionsOptions & ValidateOptions;\ntype BoundaryGuardedOptions = BoundaryOptions & ValidateOptions;\ntype MelodyGuardedOptions = MelodyOptions & ValidateOptions;\n\n/** Canonical request form shared by the Constant-Q transform variants. */\nexport interface CqtRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n fmin?: number;\n nBins?: number;\n binsPerOctave?: number;\n}\n\n/** Canonical request form for {@link vqt}. */\nexport interface VqtRequest extends CqtRequest {\n gamma?: number;\n}\n\nexport interface OnsetEnvelopeRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n nMels?: number;\n}\n\nexport interface OnsetStrengthMultiRequest extends OnsetEnvelopeRequest {\n nBands?: number;\n}\n\nexport interface FourierTempogramRequest extends GuardedOptions {\n onsetEnvelope: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n winLength?: number;\n center?: boolean;\n norm?: boolean;\n}\n\nexport interface TempogramRatioRequest extends GuardedOptions {\n tempogramData: Float32Array;\n winLength?: number;\n sampleRate?: number;\n hopLength?: number;\n factors?: Float32Array | number[];\n}\n\nexport interface CqtToAudioRequest extends GuardedOptions {\n magnitude: Float32Array;\n nBins: number;\n nFrames: number;\n sampleRate?: number;\n hopLength?: number;\n fmin?: number;\n binsPerOctave?: number;\n nIter?: number;\n}\n\nexport interface VqtToAudioRequest extends CqtToAudioRequest {\n gamma?: number;\n}\n\nexport interface AnalyzeSectionsRequest extends AnalyzeSectionsGuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n/** Canonical (and only) call form for {@link detectBoundaries}. */\nexport interface DetectBoundariesRequest extends BoundaryGuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\nexport interface AnalyzeMelodyRequest extends MelodyGuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\nexport interface LufsRequest extends ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\nexport interface NnlsChromaRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n enableStftBlend?: boolean;\n stftBlendWeight?: number;\n stftBlendNFft?: number;\n hopLength?: number;\n}\n\nfunction validateMusicSamples(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\nfunction validateFrequencyBounds(fnName: string, fmin: number, fmax?: number): void {\n assertFiniteScalar(fnName, fmin, 'fmin');\n if (fmin < 0) {\n throw new RangeError(`${fnName}: fmin must be non-negative`);\n }\n if (fmax !== undefined) {\n assertFiniteScalar(fnName, fmax, 'fmax');\n if (fmax <= fmin) {\n throw new RangeError(`${fnName}: fmax must be greater than fmin`);\n }\n }\n}\n\n/**\n * Compute NNLS (non-negative least squares) chromagram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns NNLS chroma result\n */\nexport function nnlsChroma(request: NnlsChromaRequest): WasmNnlsChromaResult;\nexport function nnlsChroma(\n samples: Float32Array,\n sampleRate?: number,\n options?: Omit<NnlsChromaRequest, 'samples' | 'sampleRate'>,\n): WasmNnlsChromaResult;\nexport function nnlsChroma(\n samples: Float32Array | NnlsChromaRequest,\n sampleRate = 22050,\n options: Omit<NnlsChromaRequest, 'samples' | 'sampleRate'> = {},\n): WasmNnlsChromaResult {\n if (!(samples instanceof Float32Array)) {\n return nnlsChroma(samples.samples, samples.sampleRate, samples);\n }\n validateMusicSamples('nnlsChroma', samples, sampleRate, options);\n const hopLength = options.hopLength === undefined ? 512 : options.hopLength;\n assertPositiveInteger('nnlsChroma', hopLength, 'hopLength');\n if (hopLength > 2 ** 31 - 1) {\n throw new RangeError('nnlsChroma: hopLength must fit in a signed 32-bit integer');\n }\n return requireModule().nnlsChromaEx(\n samples,\n sampleRate,\n options.enableStftBlend ?? true,\n options.stftBlendWeight ?? 0.55,\n options.stftBlendNFft ?? 4096,\n hopLength,\n );\n}\n\n/**\n * Compute the Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function cqt(request: CqtRequest): CqtResult;\nexport function cqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function cqt(\n samples: Float32Array | CqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return cqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request,\n );\n }\n validateMusicSamples('cqt', samples, sampleRate, options);\n validatePositiveIntegers('cqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('cqt', fmin);\n return requireModule().cqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the pseudo Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function pseudoCqt(request: CqtRequest): CqtResult;\nexport function pseudoCqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function pseudoCqt(\n samples: Float32Array | CqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return pseudoCqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request,\n );\n }\n validateMusicSamples('pseudoCqt', samples, sampleRate, options);\n validatePositiveIntegers('pseudoCqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('pseudoCqt', fmin);\n return requireModule().pseudoCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the hybrid Constant-Q Transform magnitude.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @returns CQT magnitude result\n */\nexport function hybridCqt(request: CqtRequest): CqtResult;\nexport function hybridCqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function hybridCqt(\n samples: Float32Array | CqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return hybridCqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request,\n );\n }\n validateMusicSamples('hybridCqt', samples, sampleRate, options);\n validatePositiveIntegers('hybridCqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('hybridCqt', fmin);\n return requireModule().hybridCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);\n}\n\n/**\n * Compute the Variable-Q Transform magnitude (gamma controls Q).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)\n * @param nBins - Number of frequency bins (default: 84)\n * @param binsPerOctave - Bins per octave (default: 12)\n * @param gamma - Bandwidth offset; a negative value or NaN selects the automatic\n * ERB-derived value, while 0 is equivalent to CQT (default: -1)\n * @returns VQT magnitude result (same shape as CQT)\n */\nexport function vqt(request: VqtRequest): CqtResult;\nexport function vqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n nBins?: number,\n binsPerOctave?: number,\n gamma?: number,\n options?: GuardedOptions,\n): CqtResult;\nexport function vqt(\n samples: Float32Array | VqtRequest,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n nBins = 84,\n binsPerOctave = 12,\n gamma = -1,\n options: GuardedOptions = {},\n): CqtResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return vqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.nBins,\n request.binsPerOctave,\n request.gamma,\n request,\n );\n }\n validateMusicSamples('vqt', samples, sampleRate, options);\n validatePositiveIntegers('vqt', { hopLength, nBins, binsPerOctave });\n validateFrequencyBounds('vqt', fmin);\n assertVqtGamma('vqt', gamma);\n return requireModule().vqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave, gamma);\n}\n\nfunction validateCqtInverse(\n fnName: string,\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate: number,\n hopLength: number,\n fmin: number,\n binsPerOctave: number,\n nIter: number,\n options: GuardedOptions,\n): void {\n assertSampleRate(fnName, sampleRate);\n validatePositiveIntegers(fnName, { nBins, nFrames, hopLength, binsPerOctave, nIter });\n if (nIter > 256) {\n throw new RangeError(`${fnName}: nIter must be at most 256`);\n }\n validateFrequencyBounds(fnName, fmin);\n if (fmin === 0) {\n throw new RangeError(`${fnName}: fmin must be positive`);\n }\n if (magnitude.length !== nBins * nFrames) {\n throw new RangeError(`${fnName}: magnitude length must equal nBins * nFrames`);\n }\n assertSamples(fnName, magnitude, options.validate !== false);\n}\n\n/** Reconstruct mono audio from row-major CQT magnitude via Griffin-Lim. */\nexport function cqtToAudio(request: CqtToAudioRequest): Float32Array;\nexport function cqtToAudio(\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n binsPerOctave?: number,\n nIter?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function cqtToAudio(\n magnitude: Float32Array | CqtToAudioRequest,\n nBins = 0,\n nFrames = 0,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n binsPerOctave = 12,\n nIter = 32,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(magnitude instanceof Float32Array)) {\n const request = magnitude;\n return cqtToAudio(\n request.magnitude,\n request.nBins,\n request.nFrames,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.binsPerOctave,\n request.nIter,\n request,\n );\n }\n validateCqtInverse(\n 'cqtToAudio',\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n nIter,\n options,\n );\n return requireModule().cqtToAudio(\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n nIter,\n );\n}\n\n/** Reconstruct mono audio from row-major VQT magnitude via Griffin-Lim. */\nexport function vqtToAudio(request: VqtToAudioRequest): Float32Array;\nexport function vqtToAudio(\n magnitude: Float32Array,\n nBins: number,\n nFrames: number,\n sampleRate?: number,\n hopLength?: number,\n fmin?: number,\n binsPerOctave?: number,\n gamma?: number,\n nIter?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function vqtToAudio(\n magnitude: Float32Array | VqtToAudioRequest,\n nBins = 0,\n nFrames = 0,\n sampleRate = 22050,\n hopLength = 512,\n fmin = 32.70319566257483,\n binsPerOctave = 12,\n gamma = -1,\n nIter = 32,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(magnitude instanceof Float32Array)) {\n const request = magnitude;\n return vqtToAudio(\n request.magnitude,\n request.nBins,\n request.nFrames,\n request.sampleRate,\n request.hopLength,\n request.fmin,\n request.binsPerOctave,\n request.gamma,\n request.nIter,\n request,\n );\n }\n validateCqtInverse(\n 'vqtToAudio',\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n nIter,\n options,\n );\n assertVqtGamma('vqtToAudio', gamma);\n return requireModule().vqtToAudio(\n magnitude,\n nBins,\n nFrames,\n sampleRate,\n hopLength,\n fmin,\n binsPerOctave,\n gamma,\n nIter,\n );\n}\n\n/**\n * Detect song-structure sections (intro/verse/chorus/...).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param minSectionSec - Minimum section duration in seconds (default: 4.0)\n * @returns Array of detected sections\n */\nexport function analyzeSections(request: AnalyzeSectionsRequest): Section[];\nexport function analyzeSections(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeSectionsGuardedOptions,\n): Section[];\nexport function analyzeSections(\n samples: Float32Array | AnalyzeSectionsRequest,\n sampleRate = 22050,\n options: AnalyzeSectionsGuardedOptions = {},\n): Section[] {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return analyzeSections(r.samples, r.sampleRate, r);\n }\n validateMusicSamples('analyzeSections', samples, sampleRate, options);\n validatePositiveIntegers('analyzeSections', {\n nFft: options.nFft ?? 2048,\n hopLength: options.hopLength ?? 512,\n });\n assertFiniteScalar('analyzeSections', options.minSectionSec ?? 4.0, 'minSectionSec');\n if ((options.minSectionSec ?? 4.0) < 0) {\n throw new RangeError('analyzeSections: minSectionSec must be non-negative');\n }\n // The embind value marshalling returns an array whose constructor is not this\n // realm's Array; chaining .map() onto it propagates that constructor via\n // Symbol.species, leaving a result that structuredClone (and so postMessage to\n // a Worker) rejects with \"could not be cloned\". Array.from() re-roots it as a\n // plain Array before mapping.\n const sections = requireModule().analyzeSections(\n samples,\n sampleRate,\n options.nFft ?? 2048,\n options.hopLength ?? 512,\n options.minSectionSec ?? 4.0,\n );\n return Array.from(sections, (s) => ({ ...s, type: s.type as SectionType }));\n}\n\n/**\n * Detect structural boundaries and return the novelty curve behind them.\n *\n * This is the unlabelled layer {@link analyzeSections} is built on, not a\n * coarser view of its output: sections are labelled spans, these are the\n * transitions plus the continuous curve they were picked from, so a caller\n * applying its own threshold needs this and cannot derive it from a section\n * list.\n *\n * @param request - Samples, sample rate and {@link BoundaryOptions}\n * @returns The boundaries, the novelty curve, and the analysis grid they live on\n * @throws {@link SonareError} with `InvalidParameter` when both `useMfcc` and\n * `useChroma` are `false`: the two feature streams are combined frame-for-frame,\n * so with neither enabled there is nothing to combine.\n *\n * @example\n * ```ts\n * const { boundaries, noveltyCurve, noveltyPeak } = detectBoundaries({\n * samples,\n * sampleRate: 44100,\n * absoluteThreshold: 0.01,\n * });\n * // `noveltyCurve` is scaled by its own maximum; recover the raw response with\n * // `noveltyCurve[i] * noveltyPeak`.\n * ```\n */\nexport function detectBoundaries(request: DetectBoundariesRequest): BoundaryResult {\n const { samples, sampleRate = 22050 } = request;\n validateMusicSamples('detectBoundaries', samples, sampleRate, request);\n // The request IS the options bag: every field is read straight off it, so an\n // omitted one reaches the embind wrapper absent and takes BoundaryConfig's own\n // default. Restating the ten defaults here would make them the effective ones\n // on npm and leave the core's unreachable, and nothing compares the two.\n const sizes: Record<string, number> = {};\n for (const name of ['nFft', 'hopLength', 'kernelSize', 'nMfcc', 'nChroma'] as const) {\n const value = request[name];\n if (value != null) {\n sizes[name] = value;\n }\n }\n validatePositiveIntegers('detectBoundaries', sizes);\n for (const name of ['threshold', 'absoluteThreshold', 'peakDistance'] as const) {\n const value = request[name];\n if (value == null) {\n continue;\n }\n assertFiniteScalar('detectBoundaries', value, name);\n if (value < 0) {\n throw new RangeError(`detectBoundaries: ${name} must be non-negative`);\n }\n }\n // Only an explicit pair of falses; either one omitted leaves the other stream\n // on, so there is still something to combine.\n if (request.useMfcc === false && request.useChroma === false) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n 'detectBoundaries: require useMfcc or useChroma',\n );\n }\n const result = requireModule().detectBoundaries(samples, sampleRate, request);\n // Re-root the embind array as a plain Array, for the reason analyzeSections\n // spells out: chaining onto it propagates a constructor structuredClone\n // rejects, so a result posted from a Worker would fail to clone.\n return {\n boundaries: Array.from(result.boundaries, (b) => ({\n time: b.time,\n frame: b.frame,\n strength: b.strength,\n })),\n noveltyCurve: result.noveltyCurve,\n noveltyPeak: result.noveltyPeak,\n sampleRate: result.sampleRate,\n hopLength: result.hopLength,\n nFrames: result.nFrames,\n frameStride: result.frameStride,\n };\n}\n\n/** Options for {@link analyzeMelody}. All fields are optional. */\nexport interface MelodyOptions {\n /** Lowest f0 (Hz) the tracker will consider. Default 65 (≈ C2). */\n fmin?: number;\n /** Highest f0 (Hz) the tracker will consider. Default 2093 (≈ C7). */\n fmax?: number;\n /** Analysis frame length in samples. Default 2048. */\n frameLength?: number;\n /** Hop length between frames in samples. Default 256. */\n hopLength?: number;\n /** Voicing confidence threshold in [0,1]; frames below are unvoiced. Default 0.1. */\n threshold?: number;\n /**\n * Use the pYIN tracker (Viterbi-smoothed) instead of plain per-frame YIN.\n * Produces a less octave-jumpy contour. Defaults to `false`.\n */\n usePyin?: boolean;\n /**\n * When {@link usePyin} is `true`, zero-pad by `frameLength / 2` so frame\n * `i` is centered at `i * hopLength` (matches `librosa.pyin(center=True)`).\n * Ignored by the plain-YIN path. Defaults to `true`.\n */\n center?: boolean;\n}\n\n/**\n * Extract the melody contour from monophonic audio via YIN (or pYIN).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Tracker + tuning options ({@link MelodyOptions})\n * @returns Melody contour with per-frame pitch points and summary stats\n */\nexport function analyzeMelody(request: AnalyzeMelodyRequest): MelodyResult;\nexport function analyzeMelody(\n samples: Float32Array,\n sampleRate?: number,\n options?: MelodyGuardedOptions,\n): MelodyResult;\nexport function analyzeMelody(\n samples: Float32Array | AnalyzeMelodyRequest,\n sampleRate = 22050,\n options: MelodyGuardedOptions = {},\n): MelodyResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return analyzeMelody(r.samples, r.sampleRate, r);\n }\n validateMusicSamples('analyzeMelody', samples, sampleRate, options);\n const fmin = options.fmin ?? 65.0;\n const fmax = options.fmax ?? 2093.0;\n validateFrequencyBounds('analyzeMelody', fmin, fmax);\n // The melody tracker's fmin is a YIN pitch floor: 0 is meaningless, and the\n // flat C ABI (sonare_analyze_melody) rejects it with InvalidParameter.\n // validateFrequencyBounds only guards fmin >= 0, so enforce strict positivity\n // here and report the same branded error the Node/Python surfaces raise.\n if (fmin <= 0) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n 'analyzeMelody: fmin must be positive',\n );\n }\n validatePositiveIntegers('analyzeMelody', {\n frameLength: options.frameLength ?? 2048,\n hopLength: options.hopLength ?? 256,\n });\n const threshold = options.threshold ?? 0.1;\n assertFiniteScalar('analyzeMelody', threshold, 'threshold');\n if (threshold <= 0) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n 'analyzeMelody: threshold must be positive',\n );\n }\n return requireModule().analyzeMelody(\n samples,\n sampleRate,\n options.fmin ?? 65.0,\n options.fmax ?? 2093.0,\n options.frameLength ?? 2048,\n options.hopLength ?? 256,\n options.threshold ?? 0.1,\n options.usePyin ?? false,\n options.center ?? true,\n );\n}\n\n/**\n * Compute the onset strength envelope.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @returns Onset envelope for each frame\n */\nexport function onsetEnvelope(request: OnsetEnvelopeRequest): Float32Array;\nexport function onsetEnvelope(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function onsetEnvelope(\n samples: Float32Array | OnsetEnvelopeRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return onsetEnvelope(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request,\n );\n }\n validateMusicSamples('onsetEnvelope', samples, sampleRate, options);\n const fft = resolveFftOptions('onsetEnvelope', nFft, hopLength);\n validatePositiveIntegers('onsetEnvelope', { nMels });\n return requireModule().onsetEnvelope(samples, sampleRate, fft.nFft, fft.hopLength, nMels);\n}\n\n/**\n * Compute multi-band onset strength envelopes.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param nBands - Number of onset bands (default: 3)\n * @returns Multi-band onset matrix\n */\nexport function onsetStrengthMulti(request: OnsetStrengthMultiRequest): OnsetStrengthMultiResult;\nexport function onsetStrengthMulti(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n nBands?: number,\n options?: GuardedOptions,\n): OnsetStrengthMultiResult;\nexport function onsetStrengthMulti(\n samples: Float32Array | OnsetStrengthMultiRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nBands = 3,\n options: GuardedOptions = {},\n): OnsetStrengthMultiResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return onsetStrengthMulti(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request.nBands,\n request,\n );\n }\n validateMusicSamples('onsetStrengthMulti', samples, sampleRate, options);\n const fft = resolveFftOptions('onsetStrengthMulti', nFft, hopLength);\n validatePositiveIntegers('onsetStrengthMulti', { nMels, nBands });\n return requireModule().onsetStrengthMulti(\n samples,\n sampleRate,\n fft.nFft,\n fft.hopLength,\n nMels,\n nBands,\n );\n}\n\n/**\n * Compute the Fourier tempogram from an onset envelope.\n *\n * @param onsetEnvelope - Onset strength envelope (float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param winLength - Window length in frames (default: 384)\n * @returns Fourier tempogram result\n */\nexport function fourierTempogram(request: FourierTempogramRequest): WasmFourierTempogramResult;\nexport function fourierTempogram(\n onsetEnvelope: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n winLength?: number,\n center?: boolean,\n norm?: boolean,\n options?: GuardedOptions,\n): WasmFourierTempogramResult;\nexport function fourierTempogram(\n onsetEnvelope: Float32Array | FourierTempogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n winLength = 384,\n center = true,\n norm = true,\n options: GuardedOptions = {},\n): WasmFourierTempogramResult {\n if (!(onsetEnvelope instanceof Float32Array)) {\n const request = onsetEnvelope;\n return fourierTempogram(\n request.onsetEnvelope,\n request.sampleRate,\n request.hopLength,\n request.winLength,\n request.center,\n request.norm,\n request,\n );\n }\n assertSampleRate('fourierTempogram', sampleRate);\n assertSamples('fourierTempogram', onsetEnvelope, options.validate !== false, 'onsetEnvelope');\n validatePositiveIntegers('fourierTempogram', { hopLength, winLength });\n return requireModule().fourierTempogram(\n onsetEnvelope,\n sampleRate,\n hopLength,\n winLength,\n center,\n norm,\n );\n}\n\n/**\n * Compute tempogram ratio features.\n *\n * @param tempogramData - Tempogram data (float32)\n * @param winLength - Window length in frames (default: 384)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param factors - Lag ratios to evaluate. When omitted or empty, the library\n * default {0.5, 1, 2, 3, 4} is used.\n * @returns Tempogram ratio features (one value per factor)\n */\nexport function tempogramRatio(request: TempogramRatioRequest): Float32Array;\nexport function tempogramRatio(\n tempogramData: Float32Array,\n winLength?: number,\n sampleRate?: number,\n hopLength?: number,\n factors?: Float32Array | number[],\n options?: GuardedOptions,\n): Float32Array;\nexport function tempogramRatio(\n tempogramData: Float32Array | TempogramRatioRequest,\n winLength = 384,\n sampleRate = 22050,\n hopLength = 512,\n factors?: Float32Array | number[],\n options: GuardedOptions = {},\n): Float32Array {\n if (!(tempogramData instanceof Float32Array)) {\n const request = tempogramData;\n return tempogramRatio(\n request.tempogramData,\n request.winLength,\n request.sampleRate,\n request.hopLength,\n request.factors,\n request,\n );\n }\n assertSampleRate('tempogramRatio', sampleRate);\n assertSamples('tempogramRatio', tempogramData, options.validate !== false, 'tempogramData');\n validatePositiveIntegers('tempogramRatio', { winLength, hopLength });\n return requireModule().tempogramRatio(tempogramData, winLength, sampleRate, hopLength, factors);\n}\n\n/**\n * Measure loudness (EBU R128 / ITU-R BS.1770).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz. The default (22050) is non-standard for\n * audio; pass the buffer's actual rate, as K-weighting is sample-rate\n * dependent and a wrong rate yields wrong loudness.\n * @returns Loudness measurement result\n */\nexport function lufs(request: LufsRequest): LufsResult;\nexport function lufs(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): LufsResult;\nexport function lufs(\n samples: Float32Array | LufsRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): LufsResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return lufs(r.samples, r.sampleRate, r);\n }\n assertSampleRate('lufs', sampleRate);\n assertSamples('lufs', samples, options.validate !== false);\n return requireModule().lufs(samples, sampleRate);\n}\n\n/**\n * Compute the momentary loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz. The default (22050) is non-standard and\n * K-weighting is sample-rate dependent; pass the buffer's actual rate.\n * @returns Momentary LUFS values over time\n */\nexport function momentaryLufs(request: LufsRequest): Float32Array;\nexport function momentaryLufs(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): Float32Array;\nexport function momentaryLufs(\n samples: Float32Array | LufsRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return momentaryLufs(r.samples, r.sampleRate, r);\n }\n assertSampleRate('momentaryLufs', sampleRate);\n assertSamples('momentaryLufs', samples, options.validate !== false);\n return requireModule().momentaryLufs(samples, sampleRate);\n}\n\n/**\n * Compute the short-term loudness (LUFS) over time.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz. The default (22050) is non-standard and\n * K-weighting is sample-rate dependent; pass the buffer's actual rate.\n * @returns Short-term LUFS values over time\n */\nexport function shortTermLufs(request: LufsRequest): Float32Array;\nexport function shortTermLufs(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): Float32Array;\nexport function shortTermLufs(\n samples: Float32Array | LufsRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return shortTermLufs(r.samples, r.sampleRate, r);\n }\n assertSampleRate('shortTermLufs', sampleRate);\n assertSamples('shortTermLufs', samples, options.validate !== false);\n return requireModule().shortTermLufs(samples, sampleRate);\n}\n","import type { SpectralFrameRequest } from './feature_spectral';\nimport { getSonareModule } from './module_state';\nimport type { NoteSegment, PiptrackResult, PitchResult } from './public_types';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n// ============================================================================\n// Features - Pitch\n// ============================================================================\n\n/**\n * Detect pitch using YIN algorithm.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.1)\n * @param fillNa - Retained for compatibility; YIN always returns a finite per-frame estimate.\n * @returns Pitch detection result\n */\nexport interface PitchYinRequest {\n samples: Float32Array;\n sampleRate?: number;\n frameLength?: number;\n hopLength?: number;\n fmin?: number;\n fmax?: number;\n threshold?: number;\n fillNa?: boolean;\n}\n\nexport interface PiptrackRequest {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n fmin?: number;\n fmax?: number;\n threshold?: number;\n}\n\n/** Per-bin spectral pitch candidates and peak magnitudes (librosa.piptrack). */\nexport function piptrack(request: PiptrackRequest): PiptrackResult;\nexport function piptrack(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n threshold?: number,\n): PiptrackResult;\nexport function piptrack(\n samples: Float32Array | PiptrackRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n fmin = 150,\n fmax = 4000,\n threshold = 0.1,\n): PiptrackResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return piptrack(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.threshold,\n );\n }\n return requireModule().piptrack(samples, sampleRate, nFft, hopLength, fmin, fmax, threshold);\n}\n\nexport function pitchYin(request: PitchYinRequest): PitchResult;\nexport function pitchYin(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n threshold?: number,\n fillNa?: boolean,\n): PitchResult;\nexport function pitchYin(\n samples: Float32Array | PitchYinRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.1,\n fillNa = false,\n): PitchResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return pitchYin(\n request.samples,\n request.sampleRate,\n request.frameLength,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.threshold,\n request.fillNa,\n );\n }\n return requireModule().pitchYin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n\n/**\n * Detect pitch using pYIN algorithm (probabilistic YIN with HMM smoothing).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param fmin - Minimum frequency in Hz (default: 65)\n * @param fmax - Maximum frequency in Hz (default: 2093)\n * @param threshold - YIN threshold (default: 0.1)\n * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)\n * @returns Pitch detection result\n */\nexport interface PitchPyinRequest extends PitchYinRequest {}\n\nexport function pitchPyin(request: PitchPyinRequest): PitchResult;\nexport function pitchPyin(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n fmin?: number,\n fmax?: number,\n threshold?: number,\n fillNa?: boolean,\n): PitchResult;\nexport function pitchPyin(\n samples: Float32Array | PitchPyinRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n fmin = 65.0,\n fmax = 2093.0,\n threshold = 0.1,\n fillNa = false,\n): PitchResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return pitchPyin(\n request.samples,\n request.sampleRate,\n request.frameLength,\n request.hopLength,\n request.fmin,\n request.fmax,\n request.threshold,\n request.fillNa,\n );\n }\n return requireModule().pitchPyin(\n samples,\n sampleRate,\n frameLength,\n hopLength,\n fmin,\n fmax,\n threshold,\n fillNa,\n );\n}\n\n/** Parameters for segmenting an F0 track into stable monophonic notes. */\nexport interface NoteSegmentsRequest {\n f0Hz: Float32Array;\n /**\n * Per-frame voicing values in `[0, 1]`; anything below `voicedThreshold` is\n * unvoiced.\n *\n * Pass {@link PitchResult.voicedFlag} converted to `0`/`1`. Do **not** pass\n * {@link pitchPyin}'s `voicedProb`: that value is the frame's voiced\n * observation mass and rises with F0 for a fixed `frameLength`, so a fixed\n * threshold silently returns no segments at all for low-register material\n * (a steady tone below roughly C5 never reaches 0.5).\n */\n voicedProb: Float32Array;\n frameRate: number;\n /** Cents of pitch change that start a new segment. Default 50. */\n segmentationThresholdCents?: number;\n /** Shortest segment kept, in ms. Default 30. */\n minNoteMs?: number;\n /** Reference pitch each segment's cents are measured against. Default 440. */\n referenceHz?: number;\n /** Voicing threshold applied to `voicedProb`; defaults to `0.5`. */\n voicedThreshold?: number;\n}\n\n/**\n * Segment a caller-supplied monophonic F0 track into stable note regions.\n *\n * `f0Hz` and `voicedProb` must have the same non-zero length. Zero-Hz frames\n * and values below `voicedThreshold` (default `0.5`) are treated as unvoiced.\n */\nexport function noteSegments(request: NoteSegmentsRequest): NoteSegment[] {\n return requireModule().noteSegments(request.f0Hz, request.voicedProb, request.frameRate, {\n segmentationThresholdCents: request.segmentationThresholdCents,\n minNoteMs: request.minNoteMs,\n referenceHz: request.referenceHz,\n voicedThreshold: request.voicedThreshold,\n });\n}\n\n// ============================================================================\n// Features - Tuning\n// ============================================================================\n\nexport interface PitchTuningRequest {\n frequencies: Float32Array;\n resolution?: number;\n binsPerOctave?: number;\n}\n\nexport interface EstimateTuningRequest extends SpectralFrameRequest {\n resolution?: number;\n binsPerOctave?: number;\n}\n\n/**\n * Estimate the global tuning offset from a set of frequencies\n * (librosa.pitch_tuning). Returns a deviation in fractions of a bin.\n */\nexport function pitchTuning(request: PitchTuningRequest): number;\nexport function pitchTuning(\n frequencies: Float32Array,\n resolution?: number,\n binsPerOctave?: number,\n): number;\nexport function pitchTuning(\n frequencies: Float32Array | PitchTuningRequest,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n if (!(frequencies instanceof Float32Array)) {\n const r = frequencies;\n return pitchTuning(r.frequencies, r.resolution, r.binsPerOctave);\n }\n return requireModule().pitchTuning(frequencies, resolution, binsPerOctave);\n}\n\n/**\n * Estimate the tuning offset of an audio signal (librosa.estimate_tuning).\n */\nexport function estimateTuning(request: EstimateTuningRequest): number;\nexport function estimateTuning(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n resolution?: number,\n binsPerOctave?: number,\n): number;\nexport function estimateTuning(\n samples: Float32Array | EstimateTuningRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n resolution = 0.01,\n binsPerOctave = 12,\n): number {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return estimateTuning(\n r.samples,\n r.sampleRate,\n r.nFft,\n r.hopLength,\n r.resolution,\n r.binsPerOctave,\n );\n }\n return requireModule().estimateTuning(\n samples,\n sampleRate,\n nFft,\n hopLength,\n resolution,\n binsPerOctave,\n );\n}\n","/**\n * Frame-level spectral descriptors: the scalar shape measures taken per STFT\n * frame, and the zero-crossing counts beside them.\n */\n\nimport { getSonareModule } from './module_state';\nimport type { WasmMatrix2dResult } from './sonare.js';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n/** Canonical request form for frame-based spectral feature extraction. */\nexport interface SpectralFrameRequest {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n}\n\nexport interface SpectralRolloffRequest extends SpectralFrameRequest {\n rollPercent?: number;\n}\n\nexport interface ZeroCrossingRateRequest {\n samples: Float32Array;\n sampleRate?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\nexport interface SpectralContrastRequest extends SpectralFrameRequest {\n nBands?: number;\n fmin?: number;\n quantile?: number;\n}\n\nexport interface PolyFeaturesRequest extends SpectralFrameRequest {\n order?: number;\n}\n\nexport interface ZeroCrossingsRequest {\n samples: Float32Array;\n threshold?: number;\n refMagnitude?: boolean;\n pad?: boolean;\n zeroPos?: boolean;\n}\n\n// ============================================================================\n// Features - Spectral\n// ============================================================================\n\n/**\n * Compute spectral centroid (center of mass of spectrum).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral centroid in Hz for each frame\n */\nexport function spectralCentroid(request: SpectralFrameRequest): Float32Array;\nexport function spectralCentroid(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n): Float32Array;\nexport function spectralCentroid(\n samples: Float32Array | SpectralFrameRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralCentroid(samples.samples, samples.sampleRate, samples.nFft, samples.hopLength);\n }\n return requireModule().spectralCentroid(samples, sampleRate, nFft, hopLength);\n}\n\n/**\n * Compute spectral contrast (librosa.feature.spectral_contrast).\n *\n * @remarks\n * Band 0 spans `[0, fmin]`, so an `fmin` below one analysis bin\n * (`sampleRate / nFft`) leaves it empty after the band trim. Row 0 is still\n * finite, but comes from the other bands' extremes rather than from itself, and\n * is neither level-invariant nor confined to the band. Keep `fmin` at or above\n * one bin width for row 0 to mean anything — at the defaults (22050 Hz, 2048)\n * one bin is 10.8 Hz, so only a small `nFft` or a tiny `fmin` reaches this.\n *\n * @returns Matrix2d of shape (nBands + 1) x nFrames.\n */\nexport function spectralContrast(request: SpectralContrastRequest): WasmMatrix2dResult;\nexport function spectralContrast(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nBands?: number,\n fmin?: number,\n quantile?: number,\n): WasmMatrix2dResult;\nexport function spectralContrast(\n samples: Float32Array | SpectralContrastRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nBands = 6,\n fmin = 200.0,\n quantile = 0.02,\n): WasmMatrix2dResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return spectralContrast(\n r.samples,\n r.sampleRate,\n r.nFft,\n r.hopLength,\n r.nBands,\n r.fmin,\n r.quantile,\n );\n }\n return requireModule().spectralContrast(\n samples,\n sampleRate,\n nFft,\n hopLength,\n nBands,\n fmin,\n quantile,\n );\n}\n\n/**\n * Fit per-frame polynomial coefficients (librosa.feature.poly_features).\n *\n * @returns Matrix2d of shape (order + 1) x nFrames.\n */\nexport function polyFeatures(request: PolyFeaturesRequest): WasmMatrix2dResult;\nexport function polyFeatures(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n order?: number,\n): WasmMatrix2dResult;\nexport function polyFeatures(\n samples: Float32Array | PolyFeaturesRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n order = 1,\n): WasmMatrix2dResult {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return polyFeatures(r.samples, r.sampleRate, r.nFft, r.hopLength, r.order);\n }\n return requireModule().polyFeatures(samples, sampleRate, nFft, hopLength, order);\n}\n\n/**\n * Locate zero-crossing indices of a signal (librosa.zero_crossings).\n */\nexport function zeroCrossings(request: ZeroCrossingsRequest): Int32Array;\nexport function zeroCrossings(\n samples: Float32Array,\n threshold?: number,\n refMagnitude?: boolean,\n pad?: boolean,\n zeroPos?: boolean,\n): Int32Array;\nexport function zeroCrossings(\n samples: Float32Array | ZeroCrossingsRequest,\n threshold = 1e-10,\n refMagnitude = false,\n pad = true,\n zeroPos = true,\n): Int32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return zeroCrossings(r.samples, r.threshold, r.refMagnitude, r.pad, r.zeroPos);\n }\n return requireModule().zeroCrossings(samples, threshold, refMagnitude, pad, zeroPos);\n}\n\n/**\n * Compute spectral bandwidth.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral bandwidth in Hz for each frame\n */\nexport function spectralBandwidth(request: SpectralFrameRequest & { p?: number }): Float32Array;\nexport function spectralBandwidth(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n p?: number,\n): Float32Array;\nexport function spectralBandwidth(\n samples: Float32Array | (SpectralFrameRequest & { p?: number }),\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n p = 2,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralBandwidth(\n samples.samples,\n samples.sampleRate,\n samples.nFft,\n samples.hopLength,\n samples.p,\n );\n }\n return requireModule().spectralBandwidth(samples, sampleRate, nFft, hopLength, p);\n}\n\n/**\n * Compute spectral rolloff frequency.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param rollPercent - Percentage threshold (default: 0.85)\n * @returns Rolloff frequency in Hz for each frame\n */\nexport function spectralRolloff(request: SpectralRolloffRequest): Float32Array;\nexport function spectralRolloff(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n rollPercent?: number,\n): Float32Array;\nexport function spectralRolloff(\n samples: Float32Array | SpectralRolloffRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n rollPercent = 0.85,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralRolloff(\n samples.samples,\n samples.sampleRate,\n samples.nFft,\n samples.hopLength,\n samples.rollPercent,\n );\n }\n return requireModule().spectralRolloff(samples, sampleRate, nFft, hopLength, rollPercent);\n}\n\n/**\n * Compute spectral flatness.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Spectral flatness for each frame (0 = tonal, 1 = noise-like)\n */\nexport function spectralFlatness(request: SpectralFrameRequest): Float32Array;\nexport function spectralFlatness(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n): Float32Array;\nexport function spectralFlatness(\n samples: Float32Array | SpectralFrameRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralFlatness(samples.samples, samples.sampleRate, samples.nFft, samples.hopLength);\n }\n return requireModule().spectralFlatness(samples, sampleRate, nFft, hopLength);\n}\n\nexport function spectralFlux(request: SpectralFrameRequest & { lag?: number }): Float32Array;\nexport function spectralFlux(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n lag?: number,\n): Float32Array;\nexport function spectralFlux(\n samples: Float32Array | (SpectralFrameRequest & { lag?: number }),\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n lag = 1,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return spectralFlux(\n samples.samples,\n samples.sampleRate,\n samples.nFft,\n samples.hopLength,\n samples.lag,\n );\n }\n return requireModule().spectralFlux(samples, sampleRate, nFft, hopLength, lag);\n}\n\n/**\n * Compute zero crossing rate.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Zero crossing rate for each frame\n */\nexport function zeroCrossingRate(request: ZeroCrossingRateRequest): Float32Array;\nexport function zeroCrossingRate(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n): Float32Array;\nexport function zeroCrossingRate(\n samples: Float32Array | ZeroCrossingRateRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return zeroCrossingRate(\n samples.samples,\n samples.sampleRate,\n samples.frameLength,\n samples.hopLength,\n );\n }\n return requireModule().zeroCrossingRate(samples, sampleRate, frameLength, hopLength);\n}\n\n/**\n * Compute RMS energy.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param frameLength - Frame length (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns RMS energy for each frame\n */\nexport function rmsEnergy(request: ZeroCrossingRateRequest): Float32Array;\nexport function rmsEnergy(\n samples: Float32Array,\n sampleRate?: number,\n frameLength?: number,\n hopLength?: number,\n): Float32Array;\nexport function rmsEnergy(\n samples: Float32Array | ZeroCrossingRateRequest,\n sampleRate = 22050,\n frameLength = 2048,\n hopLength = 512,\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n return rmsEnergy(samples.samples, samples.sampleRate, samples.frameLength, samples.hopLength);\n }\n return requireModule().rmsEnergy(samples, sampleRate, frameLength, hopLength);\n}\n","/**\n * Spectrogram and chroma representations, and the silence trim that shares\n * their input checks.\n */\n\nimport type { GuardedOptions } from './_feature_validation';\nimport { validateMelFrequencyRange, validatePositiveIntegers } from './_feature_validation';\nimport { resolveFftOptions } from './_fft_options';\nimport { getSonareModule } from './module_state';\nimport type {\n ChromaResult,\n MelSpectrogramResult,\n MfccResult,\n ReassignedSpectrogramResult,\n StftResult,\n} from './public_types';\nimport {\n assertFiniteScalar,\n assertPositiveInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\n/** Canonical request form for basic frame-based spectrogram features. */\nexport interface SpectrogramRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n nFft?: number;\n hopLength?: number;\n}\n\n/**\n * Options for the constant-Q chroma variants.\n *\n * Carries no `nFft`: these are built on a constant-Q transform, which resolves\n * frequency through per-bin filter lengths rather than a framed FFT, so there\n * is no FFT size to set. Use `chroma` for the STFT-framed chromagram.\n */\nexport interface ChromaSpectrogramRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n nChroma?: number;\n binsPerOctave?: number;\n}\n\n/**\n * Options for the bass-focused chroma.\n *\n * Unlike {@link ChromaSpectrogramRequest} this carries no `binsPerOctave`: the\n * bass chroma fixes its bin count and its lowest frequency together, so the\n * resolution is not independently settable through this entry point.\n */\nexport interface BassChromaSpectrogramRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n hopLength?: number;\n nChroma?: number;\n}\n\n/**\n * Compile-time guard for the two request shapes above. A field the entry point\n * cannot forward is worse than a missing one: it type-checks, runs, and returns\n * the default silently. These aliases fail to compile if either field appears,\n * so adding one has to be a deliberate act.\n */\ntype AbsentKey<T extends never> = T;\n\ntype _ChromaRequestHasNoFftSize = AbsentKey<Extract<keyof ChromaSpectrogramRequest, 'nFft'>>;\n\ntype _BassChromaRequestHasNoResolutionControls = AbsentKey<\n Extract<keyof BassChromaSpectrogramRequest, 'nFft' | 'binsPerOctave'>\n>;\n\nexport interface MelSpectrogramRequest extends SpectrogramRequest {\n nMels?: number;\n fmin?: number;\n fmax?: number;\n htk?: boolean;\n}\n\nexport interface MfccRequest extends MelSpectrogramRequest {\n nMfcc?: number;\n lifter?: number;\n}\n\nexport interface MelDeltaRequest extends GuardedOptions {\n features: Float32Array;\n nFeatures: number;\n nFrames: number;\n width?: number;\n}\n\nexport interface ReassignedSpectrogramRequest extends SpectrogramRequest {\n refPower?: number;\n fillNan?: boolean;\n}\n\nexport interface TrimRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate: number;\n thresholdDb?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\nfunction validateSpectrogramSamples(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\n/**\n * Trim silence from beginning and end of audio.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz\n * @param thresholdDb - Silence threshold in dB (default: -60 dB)\n * @returns Trimmed audio\n */\nexport function trim(request: TrimRequest): Float32Array;\nexport function trim(\n samples: Float32Array,\n sampleRate: number,\n thresholdDb?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function trim(\n samples: Float32Array,\n sampleRate: number,\n thresholdDb?: number,\n frameLength?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function trim(\n samples: Float32Array | TrimRequest,\n sampleRate = 22050,\n thresholdDb = -60.0,\n frameLengthOrOptions?: number | GuardedOptions,\n hopLength?: number,\n options: GuardedOptions = {},\n): Float32Array {\n if (!(samples instanceof Float32Array)) {\n const r = samples;\n return trim(r.samples, r.sampleRate, r.thresholdDb, r.frameLength, r.hopLength, r);\n }\n if (frameLengthOrOptions === null) {\n throw new TypeError('trim: frameLength must be an integer or options object');\n }\n if (\n frameLengthOrOptions !== undefined &&\n typeof frameLengthOrOptions !== 'number' &&\n typeof frameLengthOrOptions !== 'object'\n ) {\n throw new TypeError('trim: frameLength must be an integer or options object');\n }\n const positionalOptions =\n typeof frameLengthOrOptions === 'object' && frameLengthOrOptions !== null\n ? frameLengthOrOptions\n : options;\n const positionalFrameLength =\n typeof frameLengthOrOptions === 'number' ? frameLengthOrOptions : undefined;\n const resolvedFrameLength = positionalFrameLength ?? 2048;\n const resolvedHopLength = hopLength === undefined ? 512 : hopLength;\n validateSpectrogramSamples('trim', samples, sampleRate, positionalOptions);\n assertFiniteScalar('trim', thresholdDb, 'thresholdDb');\n assertPositiveInteger('trim', resolvedFrameLength, 'frameLength');\n assertPositiveInteger('trim', resolvedHopLength, 'hopLength');\n if (resolvedFrameLength > 2 ** 31 - 1 || resolvedHopLength > 2 ** 31 - 1) {\n throw new RangeError('trim: frameLength and hopLength must fit in a signed 32-bit integer');\n }\n return requireModule().trimEx(\n samples,\n sampleRate,\n thresholdDb,\n resolvedFrameLength,\n resolvedHopLength,\n );\n}\n\n// ============================================================================\n// Features - Spectrogram\n// ============================================================================\n\n/**\n * Compute Short-Time Fourier Transform (STFT).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with magnitude and power spectrograms\n */\nexport function stft(request: SpectrogramRequest): StftResult;\nexport function stft(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): StftResult;\nexport function stft(\n samples: Float32Array | SpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): StftResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return stft(request.samples, request.sampleRate, request.nFft, request.hopLength, request);\n }\n validateSpectrogramSamples('stft', samples, sampleRate, options);\n const fft = resolveFftOptions('stft', nFft, hopLength);\n return requireModule().stft(samples, sampleRate, fft.nFft, fft.hopLength);\n}\n\n/**\n * Compute STFT and return magnitude in decibels.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns STFT result with dB values\n */\nexport function stftDb(request: SpectrogramRequest): {\n nBins: number;\n nFrames: number;\n db: Float32Array;\n};\nexport function stftDb(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): { nBins: number; nFrames: number; db: Float32Array };\nexport function stftDb(\n samples: Float32Array | SpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): { nBins: number; nFrames: number; db: Float32Array } {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return stftDb(request.samples, request.sampleRate, request.nFft, request.hopLength, request);\n }\n validateSpectrogramSamples('stftDb', samples, sampleRate, options);\n const fft = resolveFftOptions('stftDb', nFft, hopLength);\n return requireModule().stftDb(samples, sampleRate, fft.nFft, fft.hopLength);\n}\n\n/**\n * Compute Chroma Energy Normalized Statistics.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function chromaCens(request: ChromaSpectrogramRequest): ChromaResult;\nexport function chromaCens(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n nChroma?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function chromaCens(\n samples: Float32Array | ChromaSpectrogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n binsPerOctave = 36,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return chromaCens(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.nChroma,\n request.binsPerOctave,\n request,\n );\n }\n validateSpectrogramSamples('chromaCens', samples, sampleRate, options);\n validatePositiveIntegers('chromaCens', { hopLength, nChroma, binsPerOctave });\n if (binsPerOctave % nChroma !== 0) {\n throw new RangeError('chromaCens: binsPerOctave must be a multiple of nChroma');\n }\n return requireModule().chromaCens(samples, sampleRate, hopLength, nChroma, binsPerOctave);\n}\n\n/**\n * Compute a constant-Q chromagram (librosa.feature.chroma_cqt).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function chromaCqt(request: ChromaSpectrogramRequest): ChromaResult;\nexport function chromaCqt(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n nChroma?: number,\n binsPerOctave?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function chromaCqt(\n samples: Float32Array | ChromaSpectrogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n binsPerOctave = 36,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return chromaCqt(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.nChroma,\n request.binsPerOctave,\n request,\n );\n }\n validateSpectrogramSamples('chromaCqt', samples, sampleRate, options);\n validatePositiveIntegers('chromaCqt', { hopLength, nChroma, binsPerOctave });\n if (binsPerOctave % nChroma !== 0) {\n throw new RangeError('chromaCqt: binsPerOctave must be a multiple of nChroma');\n }\n return requireModule().chromaCqt(samples, sampleRate, hopLength, nChroma, binsPerOctave);\n}\n\n/**\n * Compute low-frequency bass chroma.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param hopLength - Hop length (default: 512)\n * @param nChroma - Number of chroma bins (default: 12)\n * @returns Chroma result\n */\nexport function bassChroma(request: BassChromaSpectrogramRequest): ChromaResult;\nexport function bassChroma(\n samples: Float32Array,\n sampleRate?: number,\n hopLength?: number,\n nChroma?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function bassChroma(\n samples: Float32Array | BassChromaSpectrogramRequest,\n sampleRate = 22050,\n hopLength = 512,\n nChroma = 12,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return bassChroma(\n request.samples,\n request.sampleRate,\n request.hopLength,\n request.nChroma,\n request,\n );\n }\n validateSpectrogramSamples('bassChroma', samples, sampleRate, options);\n validatePositiveIntegers('bassChroma', { hopLength, nChroma });\n return requireModule().bassChroma(samples, sampleRate, hopLength, nChroma);\n}\n\n// ============================================================================\n// Features - Mel Spectrogram\n// ============================================================================\n\n/**\n * Compute Mel spectrogram.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default).\n * Set with `fmax` to round-trip with `melToStft` / `melToAudio`.\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @returns Mel spectrogram result\n */\nexport function melSpectrogram(request: MelSpectrogramRequest): MelSpectrogramResult;\nexport function melSpectrogram(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n fmin?: number,\n fmax?: number,\n htk?: boolean,\n options?: GuardedOptions,\n): MelSpectrogramResult;\nexport function melSpectrogram(\n samples: Float32Array | MelSpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n fmin = 0,\n fmax = 0,\n htk = false,\n options: GuardedOptions = {},\n): MelSpectrogramResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return melSpectrogram(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request.fmin,\n request.fmax,\n request.htk,\n request,\n );\n }\n validateSpectrogramSamples('melSpectrogram', samples, sampleRate, options);\n const fft = resolveFftOptions('melSpectrogram', nFft, hopLength);\n validatePositiveIntegers('melSpectrogram', { nMels });\n validateMelFrequencyRange('melSpectrogram', fmin, fmax, sampleRate);\n return requireModule().melSpectrogram(\n samples,\n sampleRate,\n fft.nFft,\n fft.hopLength,\n nMels,\n fmin,\n fmax,\n htk,\n );\n}\n\n/**\n * Compute MFCC (Mel-Frequency Cepstral Coefficients).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @param nMels - Number of Mel bands (default: 128)\n * @param nMfcc - Number of MFCC coefficients (default: 20)\n * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default)\n * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)\n * @param htk - Use the HTK Mel formula instead of Slaney (default: false)\n * @param lifter - Cepstral liftering coefficient (default: 0 = no liftering)\n * @returns MFCC result\n */\nexport function mfcc(request: MfccRequest): MfccResult;\nexport function mfcc(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n nMels?: number,\n nMfcc?: number,\n fmin?: number,\n fmax?: number,\n htk?: boolean,\n lifter?: number,\n options?: GuardedOptions,\n): MfccResult;\nexport function mfcc(\n samples: Float32Array | MfccRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n nMels = 128,\n nMfcc = 20,\n fmin = 0,\n fmax = 0,\n htk = false,\n lifter = 0,\n options: GuardedOptions = {},\n): MfccResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return mfcc(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.nMels,\n request.nMfcc,\n request.fmin,\n request.fmax,\n request.htk,\n request.lifter,\n request,\n );\n }\n validateSpectrogramSamples('mfcc', samples, sampleRate, options);\n const fft = resolveFftOptions('mfcc', nFft, hopLength);\n validatePositiveIntegers('mfcc', { nMels, nMfcc });\n validateMelFrequencyRange('mfcc', fmin, fmax, sampleRate);\n return requireModule().mfcc(\n samples,\n sampleRate,\n fft.nFft,\n fft.hopLength,\n nMels,\n nMfcc,\n fmin,\n fmax,\n htk,\n lifter,\n );\n}\n\n/** First-order regression delta of a row-major feature matrix. */\nexport function melDelta(request: MelDeltaRequest): Float32Array;\nexport function melDelta(\n features: Float32Array,\n nFeatures: number,\n nFrames: number,\n width?: number,\n): Float32Array;\nexport function melDelta(\n features: Float32Array | MelDeltaRequest,\n nFeatures?: number,\n nFrames?: number,\n width = 9,\n): Float32Array {\n const request: MelDeltaRequest =\n features instanceof Float32Array\n ? { features, nFeatures: nFeatures ?? 0, nFrames: nFrames ?? 0, width }\n : features;\n assertPositiveInteger('melDelta', request.nFeatures, 'nFeatures');\n assertPositiveInteger('melDelta', request.nFrames, 'nFrames');\n assertPositiveInteger('melDelta', request.width ?? 9, 'width');\n if ((request.width ?? 9) < 3 || (request.width ?? 9) % 2 === 0) {\n throw new RangeError('melDelta: width must be an odd integer of at least 3');\n }\n if (request.features.length !== request.nFeatures * request.nFrames) {\n throw new RangeError('melDelta: feature matrix length must equal nFeatures * nFrames');\n }\n return requireModule().melDelta(\n request.features,\n request.nFeatures,\n request.nFrames,\n request.width ?? 9,\n );\n}\n\n/** Auger-Flandrin reassigned spectrogram (row-major [nBins x nFrames] arrays). */\nexport function reassignedSpectrogram(\n request: ReassignedSpectrogramRequest,\n): ReassignedSpectrogramResult;\nexport function reassignedSpectrogram(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n refPower?: number,\n fillNan?: boolean,\n): ReassignedSpectrogramResult;\nexport function reassignedSpectrogram(\n samples: Float32Array | ReassignedSpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n refPower = 1e-6,\n fillNan = false,\n): ReassignedSpectrogramResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return reassignedSpectrogram(\n request.samples,\n request.sampleRate,\n request.nFft,\n request.hopLength,\n request.refPower,\n request.fillNan,\n );\n }\n assertSamples('reassignedSpectrogram', samples, true);\n assertSampleRate('reassignedSpectrogram', sampleRate);\n assertPositiveInteger('reassignedSpectrogram', nFft, 'nFft');\n assertPositiveInteger('reassignedSpectrogram', hopLength, 'hopLength');\n assertFiniteScalar('reassignedSpectrogram', refPower, 'refPower');\n if (refPower < 0) {\n throw new RangeError('reassignedSpectrogram: refPower must be non-negative');\n }\n return requireModule().reassignedSpectrogram(\n samples,\n sampleRate,\n nFft,\n hopLength,\n refPower,\n fillNan,\n );\n}\n\n// ============================================================================\n// Features - Chroma\n// ============================================================================\n\n/**\n * Compute STFT chromagram (librosa.feature.chroma_stft).\n *\n * The chroma filterbank uses a fixed tuning of 0 (concert A440). Unlike\n * librosa.feature.chroma_stft — which estimates tuning from the signal when none\n * is given — this does NOT auto-estimate and takes no tuning argument. A\n * tuning offset from {@link estimateTuning} is applied through `analyze`'s\n * `tuning` option (and to chords through `detectChords`).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param nFft - FFT size (default: 2048)\n * @param hopLength - Hop length (default: 512)\n * @returns Chroma features result\n */\nexport function chroma(request: SpectrogramRequest): ChromaResult;\nexport function chroma(\n samples: Float32Array,\n sampleRate?: number,\n nFft?: number,\n hopLength?: number,\n options?: GuardedOptions,\n): ChromaResult;\nexport function chroma(\n samples: Float32Array | SpectrogramRequest,\n sampleRate = 22050,\n nFft = 2048,\n hopLength = 512,\n options: GuardedOptions = {},\n): ChromaResult {\n if (!(samples instanceof Float32Array)) {\n const request = samples;\n return chroma(request.samples, request.sampleRate, request.nFft, request.hopLength, request);\n }\n validateSpectrogramSamples('chroma', samples, sampleRate, options);\n const fft = resolveFftOptions('chroma', nFft, hopLength);\n return requireModule().chroma(samples, sampleRate, fft.nFft, fft.hopLength);\n}\n","import { ErrorCode, SonareError } from './errors';\nimport { getSonareModule } from './module_state';\nimport type { ValidateOptions } from './validation';\nimport {\n assertInterleavedSamples,\n assertNonNegativeInteger,\n assertPositiveInteger,\n assertSamples,\n assertSamplesInWindow,\n} from './validation';\n\n// The FFT size the library falls back to when `nFft` is 0 or omitted. Mirrored\n// here so the windowed pre-scan covers exactly the span the call will read; a\n// test pins it against the `nFft` the library reports back for a 0 request.\nconst DEFAULT_SPECTRUM_N_FFT = 2048;\n\n/**\n * Validates a true-peak oversample factor: `0` (meaning \"use the default 4\") or\n * a power of two in `[1, 16]`. The native layer applies the same `0 -> 4`\n * normalization (see `metering::true_peak_db`), so the raw factor can be passed\n * through unchanged after this check. Kept module-local (not exported) so it does\n * not surface as a WASM-only symbol with no C-API counterpart.\n */\nfunction assertOversampleFactor(fnName: string, factor: number): void {\n const normalized = factor === 0 ? 4 : factor;\n if (\n !Number.isInteger(normalized) ||\n normalized < 1 ||\n normalized > 16 ||\n (normalized & (normalized - 1)) !== 0\n ) {\n throw new SonareError(\n ErrorCode.InvalidParameter,\n 'InvalidParameter',\n `${fnName}: oversampleFactor must be 0 or a power of two from 1 to 16`,\n );\n }\n}\n\n// ============================================================================\n// Metering — basic / true-peak / clipping / dynamic range\n// ============================================================================\n\n/** One contiguous run of clipped samples reported by `meteringDetectClipping`. */\nexport interface ClippingRegion {\n startSample: number;\n endSample: number;\n length: number;\n peak: number;\n}\n\n/** Aggregated clipping report. */\nexport interface ClippingReport {\n clippedSamples: number;\n clippingRatio: number;\n maxClippedPeak: number;\n regions: ClippingRegion[];\n}\n\n/** Sliding-window dynamic range report. */\nexport interface DynamicRangeReport {\n dynamicRangeDb: number;\n lowPercentileDb: number;\n highPercentileDb: number;\n windowRmsDb: Float32Array;\n}\n\n/** Options for {@link meteringDetectClipping}. All fields are optional. */\nexport interface MeteringDetectClippingOptions extends ValidateOptions {\n /** Linear absolute threshold. Default 0.999. */\n threshold?: number;\n /** Minimum run length to report. Default 1. */\n minRegionSamples?: number;\n}\n\n/** Options for {@link meteringDynamicRange}. All fields are optional. */\nexport interface MeteringDynamicRangeOptions extends ValidateOptions {\n /** Window length in seconds (0 = library default, 3 s). Default 0. */\n windowSec?: number;\n /** Hop length in seconds (0 = library default, 1 s). Default 0. */\n hopSec?: number;\n /** Low percentile in [0,1] (negative = library default, 0.10). Default -1. */\n lowPercentile?: number;\n /** High percentile in [0,1] (negative = library default, 0.95). Default -1. */\n highPercentile?: number;\n}\n\n/** Canonical request form for single-channel meter readings. */\nexport interface MeteringSamplesRequest extends ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for true-peak analysis. */\nexport interface MeteringTruePeakRequest extends MeteringSamplesRequest {\n oversampleFactor?: number;\n}\n\n/** Canonical request form for clipping analysis. */\nexport interface MeteringDetectClippingRequest extends MeteringDetectClippingOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for dynamic-range analysis. */\nexport interface MeteringDynamicRangeRequest extends MeteringDynamicRangeOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\nfunction requireModule() {\n return getSonareModule();\n}\n\nexport function meteringPeakDb(request: MeteringSamplesRequest): number;\nexport function meteringPeakDb(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringPeakDb(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringPeakDb', request.samples, request.validate !== false);\n return requireModule().meteringPeakDb(request.samples, request.sampleRate ?? 22050);\n}\n\nexport function meteringRmsDb(request: MeteringSamplesRequest): number;\nexport function meteringRmsDb(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringRmsDb(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringRmsDb', request.samples, request.validate !== false);\n return requireModule().meteringRmsDb(request.samples, request.sampleRate ?? 22050);\n}\n\nexport interface MeteringSilenceRatioRequest extends MeteringSamplesRequest {\n thresholdDb?: number;\n frameLength?: number;\n hopLength?: number;\n}\n\nexport function meteringSilenceRatio(request: MeteringSilenceRatioRequest): number;\nexport function meteringSilenceRatio(\n samples: Float32Array,\n sampleRate?: number,\n thresholdDb?: number,\n frameLength?: number,\n hopLength?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringSilenceRatio(\n samples: Float32Array | MeteringSilenceRatioRequest,\n sampleRate = 22050,\n thresholdDb = -45,\n frameLength = 1024,\n hopLength = 256,\n options: ValidateOptions = {},\n): number {\n const request =\n samples instanceof Float32Array\n ? { samples, sampleRate, thresholdDb, frameLength, hopLength, ...options }\n : samples;\n assertSamples('meteringSilenceRatio', request.samples, request.validate !== false);\n return requireModule().meteringSilenceRatio(\n request.samples,\n request.sampleRate ?? 22050,\n request.thresholdDb ?? -45,\n request.frameLength ?? 1024,\n request.hopLength ?? 256,\n );\n}\n\nexport function meteringCrestFactorDb(request: MeteringSamplesRequest): number;\nexport function meteringCrestFactorDb(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringCrestFactorDb(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringCrestFactorDb', request.samples, request.validate !== false);\n return requireModule().meteringCrestFactorDb(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Crest factor in dB across both channels of a stereo pair.\n *\n * Takes the peak across both channels and the RMS over both together. An\n * out-of-phase pair cancels in the `0.5 * (left + right)` downmix\n * {@link meteringCrestFactorDb} would need, which understates its RMS and so\n * overstates the crest factor.\n */\nexport function meteringCrestFactorDbStereo(request: MeteringStereoRequest): number {\n assertSamples('meteringCrestFactorDbStereo', request.left, request.validate !== false);\n assertSamples('meteringCrestFactorDbStereo', request.right, request.validate !== false);\n return requireModule().meteringCrestFactorDbStereo(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n );\n}\n\nexport function meteringDcOffset(request: MeteringSamplesRequest): number;\nexport function meteringDcOffset(\n samples: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringDcOffset(\n samples: Float32Array | MeteringSamplesRequest,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringDcOffset', request.samples, request.validate !== false);\n return requireModule().meteringDcOffset(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Inter-sample (true) peak in dBFS. `oversampleFactor` must be a power of two\n * in [1, 16]; pass 0 to use the library default (4).\n */\nexport function meteringTruePeakDb(request: MeteringTruePeakRequest): number;\nexport function meteringTruePeakDb(\n samples: Float32Array,\n sampleRate?: number,\n oversampleFactor?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringTruePeakDb(\n samples: Float32Array | MeteringTruePeakRequest,\n sampleRate = 22050,\n oversampleFactor = 4,\n options: ValidateOptions = {},\n): number {\n const request =\n samples instanceof Float32Array\n ? { samples, sampleRate, oversampleFactor, ...options }\n : samples;\n assertSamples('meteringTruePeakDb', request.samples, request.validate !== false);\n const factor = request.oversampleFactor ?? 4;\n assertOversampleFactor('meteringTruePeakDb', factor);\n return requireModule().meteringTruePeakDb(request.samples, request.sampleRate ?? 22050, factor);\n}\n\n/**\n * Detect contiguous runs of clipped samples.\n *\n * @param threshold Linear absolute threshold (default 0.999).\n * @param minRegionSamples Minimum run length to report (default 1).\n */\nexport function meteringDetectClipping(request: MeteringDetectClippingRequest): ClippingReport;\nexport function meteringDetectClipping(\n samples: Float32Array,\n sampleRate?: number,\n options?: MeteringDetectClippingOptions,\n): ClippingReport;\nexport function meteringDetectClipping(\n samples: Float32Array | MeteringDetectClippingRequest,\n sampleRate = 22050,\n options: MeteringDetectClippingOptions = {},\n): ClippingReport {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringDetectClipping', request.samples, request.validate !== false);\n const minRegionSamples = request.minRegionSamples ?? 1;\n assertNonNegativeInteger('meteringDetectClipping', minRegionSamples, 'minRegionSamples');\n return requireModule().meteringDetectClipping(\n request.samples,\n request.sampleRate ?? 22050,\n request.threshold ?? 0.999,\n minRegionSamples,\n );\n}\n\n/**\n * Sliding-window dynamic range for mono audio. Pass 0 for window/hop to use the library\n * default (window=3 s, hop=1 s). The percentiles use a NEGATIVE sentinel for\n * \"use the library default\" (low=0.10, high=0.95) because 0 is a literal 0th\n * percentile; omitted percentiles therefore default to -1.\n */\nexport function meteringDynamicRange(request: MeteringDynamicRangeRequest): DynamicRangeReport;\nexport function meteringDynamicRange(\n samples: Float32Array,\n sampleRate?: number,\n options?: MeteringDynamicRangeOptions,\n): DynamicRangeReport;\nexport function meteringDynamicRange(\n samples: Float32Array | MeteringDynamicRangeRequest,\n sampleRate = 22050,\n options: MeteringDynamicRangeOptions = {},\n): DynamicRangeReport {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringDynamicRange', request.samples, request.validate !== false);\n return requireModule().meteringDynamicRange(\n request.samples,\n request.sampleRate ?? 22050,\n request.windowSec ?? 0,\n request.hopSec ?? 0,\n request.lowPercentile ?? -1,\n request.highPercentile ?? -1,\n );\n}\n\n// ============================================================================\n// Metering — stereo / phase-scope / spectrum\n// ============================================================================\n\n/** Mid/side vectorscope point series for a (left, right) stereo pair. */\nexport interface VectorscopeReport {\n mid: Float32Array;\n side: Float32Array;\n}\n\n/** Phase-scope (Lissajous) point series plus summary stats. */\nexport interface PhaseScopeReport {\n mid: Float32Array;\n side: Float32Array;\n radius: Float32Array;\n angleRad: Float32Array;\n correlation: number;\n averageAbsAngleRad: number;\n maxRadius: number;\n}\n\n/** Options for `meteringSpectrum`. */\nexport interface SpectrumOptions {\n /** FFT size. Pass 0 / omit for the library default (2048). */\n nFft?: number;\n /** Apply fractional-octave smoothing to magnitude. */\n applyOctaveSmoothing?: boolean;\n /** Smoothing fraction (e.g. 3 = 1/3-octave). 0 / omit = library default (3). */\n octaveFraction?: number;\n /** Linear reference for the dB conversion. 0 / omit = 1.0. */\n dbRef?: number;\n /** Linear floor used to avoid log(0). 0 / omit = library default. */\n dbAmin?: number;\n}\n\n/** Single-frame magnitude / power / dB spectrum returned by `meteringSpectrum`. */\nexport interface SpectrumReport {\n frequencies: Float32Array;\n magnitude: Float32Array;\n power: Float32Array;\n db: Float32Array;\n nFft: number;\n sampleRate: number;\n}\n\n/** Options for {@link waveformPeaks}. All fields are optional. */\nexport interface WaveformPeaksOptions extends ValidateOptions {\n /** Bucket width in frames. Default 512. */\n samplesPerBucket?: number;\n}\n\n/** Options for {@link waveformPeakPyramid}. All fields are optional. */\nexport interface WaveformPeakPyramidOptions extends ValidateOptions {\n /** Bucket widths in frames, one per zoom level. Default [512, 1024, 2048, 4096]. */\n samplesPerBucketLevels?: number[];\n}\n\n/** Canonical request form for stereo meter readings. */\nexport interface MeteringStereoRequest extends ValidateOptions {\n left: Float32Array;\n right: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for display-decimated stereo scopes. */\nexport interface MeteringStereoDecimatedRequest extends MeteringStereoRequest {\n maxPoints?: number;\n}\n\n/** Options for the scope functions (mirrors the Node `ScopeOptions`). */\nexport interface ScopeOptions extends ValidateOptions {\n /**\n * Upper bound on the returned point count. Omit / `0` (or a value `>= length`)\n * yields one point per input sample; otherwise the point cloud is\n * deterministically decimated to at most `maxPoints` points for display.\n */\n maxPoints?: number;\n}\n\n/** Canonical request form for whole-signal spectrum analysis. */\nexport interface MeteringSpectrumRequest extends SpectrumOptions, ValidateOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Canonical request form for a single spectrum frame. */\nexport interface MeteringSpectrumFrameRequest extends MeteringSpectrumRequest {\n frameOffset?: number;\n}\n\n/** Canonical request form for waveform bucket generation. */\nexport interface WaveformPeaksRequest extends WaveformPeaksOptions {\n samples: Float32Array;\n channels: number;\n}\n\n/** Canonical request form for multi-resolution waveform bucket generation. */\nexport interface WaveformPeakPyramidRequest extends WaveformPeakPyramidOptions {\n samples: Float32Array;\n channels: number;\n}\n\n/** Per-channel min/max waveform buckets. Arrays are channel-major. */\nexport interface WaveformPeaksReport {\n min: Float32Array;\n max: Float32Array;\n channels: number;\n bucketCount: number;\n samplesPerBucket: number;\n}\n\n/** Uncentered correlation (cosine similarity) in [-1, 1] between equal-length channels. */\nexport function meteringStereoCorrelation(request: MeteringStereoRequest): number;\nexport function meteringStereoCorrelation(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringStereoCorrelation(\n left: Float32Array | MeteringStereoRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringStereoCorrelation', request.left, validate, 'left');\n assertSamples('meteringStereoCorrelation', request.right, validate, 'right');\n return requireModule().meteringStereoCorrelation(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n );\n}\n\n/**\n * Stereo width as `sqrt(side_energy / mid_energy)` in `[0, +Infinity)`: the\n * side/mid RMS *amplitude* ratio, not the energy ratio. 0 = pure mono, ~1 =\n * wide stereo, larger = increasingly decorrelated / out-of-phase. The value is\n * unbounded and returns `Infinity` when the mid channel is silent (a\n * mono-collapsed / fully out-of-phase signal).\n *\n * Convert to dB with `20 * Math.log10(value)`; `10 * Math.log10` would\n * understate the true energy ratio by half.\n */\nexport function meteringStereoWidth(request: MeteringStereoRequest): number;\nexport function meteringStereoWidth(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ValidateOptions,\n): number;\nexport function meteringStereoWidth(\n left: Float32Array | MeteringStereoRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ValidateOptions = {},\n): number {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringStereoWidth', request.left, validate, 'left');\n assertSamples('meteringStereoWidth', request.right, validate, 'right');\n return requireModule().meteringStereoWidth(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n );\n}\n\n/**\n * Mid/side vectorscope point series. By default emits one point per input\n * sample; pass `maxPoints` to get a display-sized decimated point set (matching\n * the Node `meteringVectorscope` shape).\n */\nexport function meteringVectorscope(request: MeteringStereoDecimatedRequest): VectorscopeReport;\nexport function meteringVectorscope(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ScopeOptions,\n): VectorscopeReport;\nexport function meteringVectorscope(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ScopeOptions = {},\n): VectorscopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringVectorscope', request.left, validate, 'left');\n assertSamples('meteringVectorscope', request.right, validate, 'right');\n return requireModule().meteringVectorscopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Display-sized mid/side vectorscope.\n *\n * @deprecated Pass `maxPoints` to {@link meteringVectorscope} instead; it now\n * folds `maxPoints` into the request, matching the Node surface. This alias is\n * kept for backward compatibility and simply delegates.\n */\nexport function meteringVectorscopeDecimated(\n request: MeteringStereoDecimatedRequest,\n): VectorscopeReport;\nexport function meteringVectorscopeDecimated(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n maxPoints?: number,\n options?: ValidateOptions,\n): VectorscopeReport;\nexport function meteringVectorscopeDecimated(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n maxPoints = 0,\n options: ValidateOptions = {},\n): VectorscopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, maxPoints, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringVectorscopeDecimated', request.left, validate, 'left');\n assertSamples('meteringVectorscopeDecimated', request.right, validate, 'right');\n return requireModule().meteringVectorscopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Phase-scope point series plus summary stats. By default emits one point per\n * input sample; pass `maxPoints` to decimate the point cloud for display\n * (matching the Node `meteringPhaseScope` shape). The summary stats are always\n * computed over the full-resolution signal.\n */\nexport function meteringPhaseScope(request: MeteringStereoDecimatedRequest): PhaseScopeReport;\nexport function meteringPhaseScope(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n options?: ScopeOptions,\n): PhaseScopeReport;\nexport function meteringPhaseScope(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n options: ScopeOptions = {},\n): PhaseScopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringPhaseScope', request.left, validate, 'left');\n assertSamples('meteringPhaseScope', request.right, validate, 'right');\n return requireModule().meteringPhaseScopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Display-sized phase scope.\n *\n * @deprecated Pass `maxPoints` to {@link meteringPhaseScope} instead; it now\n * folds `maxPoints` into the request, matching the Node surface. This alias is\n * kept for backward compatibility and simply delegates.\n */\nexport function meteringPhaseScopeDecimated(\n request: MeteringStereoDecimatedRequest,\n): PhaseScopeReport;\nexport function meteringPhaseScopeDecimated(\n left: Float32Array,\n right: Float32Array,\n sampleRate?: number,\n maxPoints?: number,\n options?: ValidateOptions,\n): PhaseScopeReport;\nexport function meteringPhaseScopeDecimated(\n left: Float32Array | MeteringStereoDecimatedRequest,\n right?: Float32Array,\n sampleRate = 22050,\n maxPoints = 0,\n options: ValidateOptions = {},\n): PhaseScopeReport {\n const request =\n left instanceof Float32Array\n ? { left, right: right as Float32Array, sampleRate, maxPoints, ...options }\n : left;\n const validate = request.validate !== false;\n assertSamples('meteringPhaseScopeDecimated', request.left, validate, 'left');\n assertSamples('meteringPhaseScopeDecimated', request.right, validate, 'right');\n return requireModule().meteringPhaseScopeDecimated(\n request.left,\n request.right,\n request.sampleRate ?? 22050,\n request.maxPoints ?? 0,\n );\n}\n\n/**\n * Welch-averaged magnitude / power / dB spectrum over the WHOLE mono signal (split\n * into Hann-windowed, 50%-overlapping `nFft`-length frames whose power spectra\n * are averaged). For a true single-frame snapshot, use\n * {@link meteringSpectrumFrame}.\n */\nexport function meteringSpectrum(request: MeteringSpectrumRequest): SpectrumReport;\nexport function meteringSpectrum(\n samples: Float32Array,\n sampleRate?: number,\n options?: SpectrumOptions & ValidateOptions,\n): SpectrumReport;\nexport function meteringSpectrum(\n samples: Float32Array | MeteringSpectrumRequest,\n sampleRate = 22050,\n options: SpectrumOptions & ValidateOptions = {},\n): SpectrumReport {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n assertSamples('meteringSpectrum', request.samples, request.validate !== false);\n return requireModule().meteringSpectrum(request.samples, request.sampleRate ?? 22050, request);\n}\n\n/**\n * True single-frame magnitude / power / dB spectrum (one Hann-windowed\n * `nFft`-length FFT), for spectrum-analyzer \"moment\" snapshots that must not be\n * time-averaged like {@link meteringSpectrum}. The analysis frame spans\n * `[frameOffset, frameOffset + nFft)`; samples past the end are zero-padded.\n *\n * The frame is also the only span validated: a non-finite sample inside it is\n * rejected, while one outside it neither reaches the FFT nor refuses the call.\n * The emptiness and `sampleRate` checks still cover the whole buffer. Cost per\n * call is therefore set by `nFft` rather than by the length of the buffer, so an\n * analyzer may poll a long recording frame by frame.\n */\nexport function meteringSpectrumFrame(request: MeteringSpectrumFrameRequest): SpectrumReport;\nexport function meteringSpectrumFrame(\n samples: Float32Array,\n sampleRate?: number,\n frameOffset?: number,\n options?: SpectrumOptions & ValidateOptions,\n): SpectrumReport;\nexport function meteringSpectrumFrame(\n samples: Float32Array | MeteringSpectrumFrameRequest,\n sampleRate = 22050,\n frameOffset = 0,\n options: SpectrumOptions & ValidateOptions = {},\n): SpectrumReport {\n const request =\n samples instanceof Float32Array ? { samples, sampleRate, frameOffset, ...options } : samples;\n const nFft = request.nFft ?? 0;\n assertSamplesInWindow(\n 'meteringSpectrumFrame',\n request.samples,\n request.validate !== false,\n request.frameOffset ?? 0,\n nFft > 0 ? nFft : DEFAULT_SPECTRUM_N_FFT,\n );\n return requireModule().meteringSpectrumFrame(\n request.samples,\n request.sampleRate ?? 22050,\n request.frameOffset ?? 0,\n request,\n );\n}\n\n/**\n * Compute per-channel min/max waveform buckets from interleaved audio.\n *\n * A non-finite sample is rejected rather than skipped, and `{ validate: false }`\n * does not change that — it only skips the JS pre-scan that names the offending\n * index. A bucket whose samples are not finite has no min/max to report, and the\n * `0`/`0` it would otherwise carry is what a waveform display draws as silence.\n */\nexport function waveformPeaks(request: WaveformPeaksRequest): WaveformPeaksReport;\nexport function waveformPeaks(\n samples: Float32Array,\n channels: number,\n options?: WaveformPeaksOptions,\n): WaveformPeaksReport;\nexport function waveformPeaks(\n samples: Float32Array | WaveformPeaksRequest,\n channels?: number,\n options: WaveformPeaksOptions = {},\n): WaveformPeaksReport {\n const request =\n samples instanceof Float32Array\n ? { samples, channels: channels as number, ...options }\n : samples;\n assertInterleavedSamples(\n 'waveformPeaks',\n request.samples,\n request.channels,\n request.validate !== false,\n );\n const samplesPerBucket = request.samplesPerBucket ?? 512;\n assertPositiveInteger('waveformPeaks', samplesPerBucket, 'samplesPerBucket');\n return requireModule().waveformPeaks(request.samples, request.channels, samplesPerBucket);\n}\n\n/**\n * Compute waveform peak buckets for several zoom levels.\n *\n * Shares {@link waveformPeaks}' bucket kernel, so a non-finite sample is\n * rejected here on the same rule.\n */\nexport function waveformPeakPyramid(request: WaveformPeakPyramidRequest): WaveformPeaksReport[];\nexport function waveformPeakPyramid(\n samples: Float32Array,\n channels: number,\n options?: WaveformPeakPyramidOptions,\n): WaveformPeaksReport[];\nexport function waveformPeakPyramid(\n samples: Float32Array | WaveformPeakPyramidRequest,\n channels?: number,\n options: WaveformPeakPyramidOptions = {},\n): WaveformPeaksReport[] {\n const request =\n samples instanceof Float32Array\n ? { samples, channels: channels as number, ...options }\n : samples;\n assertInterleavedSamples(\n 'waveformPeakPyramid',\n request.samples,\n request.channels,\n request.validate !== false,\n );\n const levels = request.samplesPerBucketLevels ?? [512, 1024, 2048, 4096];\n if (levels.length === 0) {\n throw new RangeError('waveformPeakPyramid: samplesPerBucketLevels must not be empty');\n }\n levels.forEach((level, index) => {\n assertPositiveInteger('waveformPeakPyramid', level, `samplesPerBucketLevels[${index}]`);\n });\n return requireModule().waveformPeakPyramid(request.samples, request.channels, levels);\n}\n","/**\n * Built-in mastering presets. The restoration presets — `vinyl`, `tapeHiss`,\n * `fieldRecording`, `voiceMemo` and `shellac78` — enable repair stages only and\n * leave level alone. Every other preset carries an integrated-loudness target\n * and a true-peak ceiling, which are not equally binding: the ceiling always\n * holds, while the loudness target is what one normalization pass aims at.\n *\n * Reaching a target above the input's loudness costs gain the input's peak\n * headroom may not have, so the stage drives its true-peak limiter up to\n * `loudness.maxLimiterGainReductionDb` (12 dB by default) to close the distance\n * and stops there. Material needing more limiting than that — and material where\n * the limiter's own gain reduction takes back part of the applied gain, which a\n * single pass does not re-measure — finishes below target with\n * `loudnessTargetLimited` set on the result. Peak-normalized input, whose\n * headroom is ~0 dB, is the common case for both. Read `outputLufs` for what was\n * achieved rather than assuming the preset's target.\n *\n * The restoration presets' repair stages, like every classical denoise\n * configuration, can mistake a steady tone -- a calibration tone, a drone, a\n * long held note -- for noise and pull it down by the configured reduction\n * depth. Check for musical sustained tones before applying one.\n */\nexport type MasteringPreset =\n | 'pop'\n | 'edm'\n | 'acoustic'\n | 'hipHop'\n | 'aiMusic'\n | 'speech'\n | 'streaming'\n | 'youtube'\n | 'broadcast'\n | 'podcast'\n | 'audiobook'\n | 'cinema'\n | 'jpop'\n | 'ambient'\n | 'lofi'\n | 'classical'\n | 'drumAndBass'\n | 'techno'\n | 'metal'\n | 'trap'\n | 'rnb'\n | 'jazz'\n | 'kpop'\n | 'trance'\n | 'gameOst'\n | 'vinyl'\n | 'tapeHiss'\n | 'fieldRecording'\n | 'voiceMemo'\n | 'shellac78';\n\nexport interface StreamingPlatform {\n name: string;\n targetLufs: number;\n ceilingDb: number;\n}\n\n// BEGIN GENERATED SoloProcessor (make processor-types)\n/**\n * Every processor name `masteringProcessorNames()` can return, and therefore\n * every name `masteringProcess` / `masteringProcessStereo` accept.\n */\nexport const SOLO_PROCESSORS = [\n 'dynamics.brickwallLimiter',\n 'dynamics.compressor',\n 'dynamics.deesser',\n 'dynamics.duckingProcessor',\n 'dynamics.expander',\n 'dynamics.gate',\n 'dynamics.limiter',\n 'dynamics.parallelComp',\n 'dynamics.sidechainRouter',\n 'dynamics.transientShaper',\n 'dynamics.upwardCompressor',\n 'dynamics.upwardExpander',\n 'dynamics.vocalRider',\n 'effects.acoustic.roomMorph',\n 'effects.delay.stereo',\n 'effects.filter.vowel',\n 'effects.gsEfx',\n 'effects.modulation.autoWah',\n 'effects.modulation.chorus',\n 'effects.modulation.ensemble',\n 'effects.modulation.flanger',\n 'effects.modulation.phaser',\n 'effects.modulation.pitchShifter',\n 'effects.modulation.ringModulator',\n 'effects.modulation.rotary',\n 'effects.modulation.wah',\n 'effects.reverb.convolution',\n 'effects.reverb.dattorro',\n 'effects.reverb.fdn',\n 'effects.reverb.plate',\n 'effects.reverb.room',\n 'effects.reverb.velvet',\n 'eq.apiStyle',\n 'eq.bandPass',\n 'eq.cutFilter',\n 'eq.dynamic',\n 'eq.equalizer',\n 'eq.graphic',\n 'eq.linearPhase',\n 'eq.midSide',\n 'eq.minimumPhase',\n 'eq.parametric',\n 'eq.pultec',\n 'eq.shelving',\n 'eq.tilt',\n 'final.bitDepth',\n 'final.dither',\n 'final.outputChain',\n 'maximizer.adaptiveRelease',\n 'maximizer.loudnessOptimize',\n 'maximizer.maximizer',\n 'maximizer.softKneeMax',\n 'maximizer.truePeakLimiter',\n 'multiband.compressor',\n 'multiband.dynamicEq',\n 'multiband.expander',\n 'multiband.imager',\n 'multiband.limiter',\n 'multiband.saturation',\n 'repair.declick',\n 'repair.declip',\n 'repair.decrackle',\n 'repair.dehum',\n 'repair.denoiseClassical',\n 'repair.dereverbClassical',\n 'repair.trimSilence',\n 'saturation.ampSim',\n 'saturation.bitcrusher',\n 'saturation.exciter',\n 'saturation.hardClipper',\n 'saturation.multibandExciter',\n 'saturation.softClipper',\n 'saturation.tape',\n 'saturation.transformer',\n 'saturation.tube',\n 'saturation.waveshaper',\n 'spectral.airBand',\n 'spectral.lowEndFocus',\n 'spectral.presenceEnhancer',\n 'spectral.spectralShaper',\n 'stereo.autoPan',\n 'stereo.binaural',\n 'stereo.haasEnhancer',\n 'stereo.imager',\n 'stereo.monoMaker',\n 'stereo.phaseAlign',\n 'stereo.stereoBalance',\n 'utility.gain',\n] as const;\n\nexport type SoloProcessor = (typeof SOLO_PROCESSORS)[number];\n// END GENERATED SoloProcessor\n\nexport type PairProcessor =\n | 'match.applyMatchEq'\n | 'match.alignReferenceToSource'\n | 'match.abSwitch'\n | 'match.abCrossfade';\n\n/** Pair processors with a stereo entry point. */\nexport type StereoPairProcessor = 'match.abCrossfade';\n\nexport type PairAnalysis =\n | 'match.referenceLoudness'\n | 'match.tonalBalance'\n | 'match.tonalBalanceLogBands'\n | 'match.matchEqCurve'\n | 'match.estimateReferenceDelaySamples';\n\nexport type StereoAnalysis = 'stereo.monoCompatCheck' | 'stereo.monoCompatCheckLogBands';\n\n/** Options for `mastering`. All fields are optional. */\nexport interface MasteringOptions {\n /** Target integrated LUFS. Default -14. */\n targetLufs?: number;\n /** True/sample peak ceiling in dBFS. Default -1. */\n ceilingDb?: number;\n /** Oversampling factor used for peak estimation. Default 4. */\n truePeakOversample?: number;\n /** Post true-peak limiter release in ms. Default 0 => library default (50 ms). */\n releaseMs?: number;\n /** Apply the static loudness gain at the input (pre-oversample) rate. Default false. */\n applyGainAtInputRate?: boolean;\n}\n\n/** What gain-matching one take to another's loudness took, and produced. */\nexport interface LoudnessMatchResult {\n /** The source take at the reference's loudness. */\n samples: Float32Array;\n sampleRate: number;\n /**\n * The reference take's BS.1770 integrated loudness. Non-finite for a silent\n * or below-gate take — the documented outcome, not a failure.\n */\n referenceLufs: number;\n /** The matched take's, before the gain. Non-finite in the same case. */\n sourceLufs: number;\n /**\n * `referenceLufs - sourceLufs`. Applied with no upper bound, and 0 whenever\n * either loudness is non-finite.\n */\n appliedGainDb: number;\n /**\n * The matched take's true peak after the gain, in dBTP.\n *\n * The match does not cap the gain, so this can sit above 0 dBTP: clamping to\n * headroom would leave a near-full-scale source at its own loudness, which is\n * the one thing a loudness match must not do. Limit downstream if the peak\n * matters more than the match.\n */\n matchedTruePeakDbtp: number;\n}\n\n/** Stereo counterpart of {@link LoudnessMatchResult}. */\nexport interface LoudnessMatchStereoResult {\n /** The left source channel, gain-matched to the reference loudness. */\n left: Float32Array;\n /** The right source channel, gain-matched with the same gain as `left`. */\n right: Float32Array;\n sampleRate: number;\n /** The reference program's BS.1770 integrated loudness. */\n referenceLufs: number;\n /** The stereo source program's loudness before the gain. */\n sourceLufs: number;\n /** One gain applied to both source channels, in dB. */\n appliedGainDb: number;\n /** Maximum true peak across the matched left and right channels, in dBTP. */\n matchedTruePeakDbtp: number;\n}\n\n/**\n * Mastering loudness/true-peak processing result\n */\nexport interface MasteringResult {\n samples: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n /** True when peak headroom prevented the requested LUFS target. */\n loudnessTargetLimited?: boolean;\n latencySamples?: number;\n /**\n * Samples the named processor replaced with a finite in-domain one,\n * keeping the output finite and in range.\n *\n * A non-finite sample supplied by the caller is rejected before the\n * processor runs, so a replacement is always of a value the processor\n * itself produced.\n *\n * Whether this can be non-zero depends on which processor was named: one\n * that does not substitute reports zero because it has nothing to replace\n * with, not because nothing needed replacing. The counter saturates rather\n * than wrapping, because a wrapped total could read as the one value zero\n * is reserved for.\n *\n * @example\n * ```ts\n * const result = masteringProcess({\n * processorName: 'maximizer.truePeakLimiter',\n * samples,\n * sampleRate,\n * });\n * if (result.nonFiniteSubstitutionCount > 0) {\n * // `result.samples` is not derived from `samples` everywhere\n * }\n * ```\n */\n nonFiniteSubstitutionCount: number;\n}\n\nexport type MasteringProcessorParams = Record<string, number | boolean>;\n\n/**\n * Params accepted by the assistant entry points. Every key is numeric except\n * two NAMES: `targetPlatform`, a delivery target (`'broadcast'`, `'podcast'`,\n * `'club'`, ...), and `preset`, the mastering preset the suggestion starts from\n * (default `'streaming'`; restoration presets are refused). The assistant never\n * picks a preset from the audio. A number is rejected for either: the numeric\n * index the C ABI carries is a transport detail for callers that cannot pass a\n * string, not part of the JavaScript vocabulary.\n */\nexport type MasteringAssistantParams = Record<string, number | boolean | string>;\n\n/**\n * Nested mastering-chain configuration. A boolean toggles a module/processor's\n * `enabled` flag; setting any field implicitly enables its module unless\n * `enabled: false` is also given.\n *\n * Exception — color stages as `masterAudio` overrides: the `saturation.tape`\n * and `saturation.exciter` stages are engaged from an override only when you\n * pass `enabled: true` explicitly. On a preset where they are off, adjusting a\n * parameter alone (e.g. `saturation: { tape: { driveDb: 6 } }`) has no audible\n * effect; use `saturation: { tape: { enabled: true, driveDb: 6 } }`.\n */\nexport interface MasteringChainConfig {\n repair?: {\n /** `boolean` is retained as a deprecated shorthand for `{ enabled }`. */\n denoise?:\n | boolean\n | {\n enabled?: boolean;\n /** 0 = log-MMSE, 1 = MMSE-STSA, 2 = spectral subtraction. */\n mode?: number;\n /** 0 = quantile, 1 = MCRA, 2 = IMCRA, 3 = speech-presence probability. */\n noiseEstimator?: number;\n nFft?: number;\n hopLength?: number;\n ddAlpha?: number;\n reductionDb?: number;\n /** @deprecated Use `reductionDb`; converted to it (dB = -20*log10(gainFloor)). */\n gainFloor?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n noiseEstimationQuantile?: number;\n speechPresenceGain?: boolean;\n gainSmoothing?: boolean;\n };\n nFft?: number;\n hopLength?: number;\n ddAlpha?: number;\n reductionDb?: number;\n /** @deprecated Use `denoise.reductionDb`; converted to it (dB = -20*log10(gainFloor)). */\n gainFloor?: number;\n declip?: {\n enabled?: boolean;\n clipThreshold?: number;\n lpcOrder?: number;\n iterations?: number;\n lpcBlend?: number;\n };\n decrackle?: {\n enabled?: boolean;\n threshold?: number;\n /** 0 = median, 1 = wavelet shrinkage. */\n mode?: number;\n levels?: number;\n };\n dehum?: {\n enabled?: boolean;\n fundamentalHz?: number;\n harmonics?: number;\n q?: number;\n adaptive?: boolean;\n searchRangeHz?: number;\n adaptation?: number;\n frameSize?: number;\n pllBandwidth?: number;\n /** 0 = subtract the tracked harmonics, 1 = cascaded notches. */\n mode?: number;\n };\n declick?: {\n enabled?: boolean;\n threshold?: number;\n neighborRatio?: number;\n maxClickSamples?: number;\n lpcOrder?: number;\n residualRatio?: number;\n };\n dereverb?: {\n enabled?: boolean;\n threshold?: number;\n attenuation?: number;\n nFft?: number;\n hopLength?: number;\n t60Sec?: number;\n lateDelayMs?: number;\n overSubtraction?: number;\n spectralFloor?: number;\n wpeEnabled?: boolean;\n wpeIterations?: number;\n wpeTaps?: number;\n wpeStrength?: number;\n };\n };\n eq?: {\n /** Canonical nested tilt stage. */\n tilt?: {\n enabled?: boolean;\n tiltDb?: number;\n pivotHz?: number;\n };\n /** @deprecated Use `eq.tilt.tiltDb`. */\n tiltDb?: number;\n /** @deprecated Use `eq.tilt.pivotHz`. */\n pivotHz?: number;\n };\n dynamics?: {\n compressor?: {\n enabled?: boolean;\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n kneeDb?: number;\n makeupGainDb?: number;\n autoMakeup?: boolean;\n };\n deesser?: {\n enabled?: boolean;\n frequencyHz?: number;\n thresholdDb?: number;\n ratio?: number;\n attackMs?: number;\n releaseMs?: number;\n rangeDb?: number;\n bandpassQ?: number;\n };\n transientShaper?: {\n enabled?: boolean;\n attackGainDb?: number;\n sustainGainDb?: number;\n fastAttackMs?: number;\n fastReleaseMs?: number;\n slowAttackMs?: number;\n slowReleaseMs?: number;\n sensitivity?: number;\n maxGainDb?: number;\n gainSmoothingMs?: number;\n lookaheadMs?: number;\n };\n multibandComp?: {\n enabled?: boolean;\n lowCutoffHz?: number;\n highCutoffHz?: number;\n lowThresholdDb?: number;\n lowRatio?: number;\n lowAttackMs?: number;\n lowReleaseMs?: number;\n midThresholdDb?: number;\n midRatio?: number;\n midAttackMs?: number;\n midReleaseMs?: number;\n highThresholdDb?: number;\n highRatio?: number;\n highAttackMs?: number;\n highReleaseMs?: number;\n };\n };\n saturation?: {\n tape?: {\n enabled?: boolean;\n driveDb?: number;\n saturation?: number;\n hysteresis?: number;\n outputGainDb?: number;\n speedIps?: number;\n headBumpDb?: number;\n bias?: number;\n gapLoss?: number;\n /** Jiles-Atherton core oversampling: 1 (default), 2, or 4. */\n oversampleFactor?: number;\n };\n exciter?: {\n enabled?: boolean;\n frequencyHz?: number;\n driveDb?: number;\n amount?: number;\n q?: number;\n evenOddMix?: number;\n /**\n * Antialiasing mode ordinal: 0 = none, 3 = 4x oversampling. The ADAA\n * modes (1, 2) name a member the exciter does not implement and are\n * rejected; an ordinal outside 0-3 is rejected as out of range.\n */\n aliasing?: number;\n };\n };\n spectral?: {\n airBand?: {\n enabled?: boolean;\n amount?: number;\n shelfFrequencyHz?: number;\n dynamicThresholdDb?: number;\n dynamicRangeDb?: number;\n };\n };\n stereo?: {\n imager?: {\n enabled?: boolean;\n width?: number;\n outputGainDb?: number;\n decorrelationAmount?: number;\n preserveEnergy?: boolean;\n };\n monoMaker?: {\n enabled?: boolean;\n amount?: number;\n frequencyHz?: number;\n };\n };\n maximizer?: {\n truePeakLimiter?: {\n enabled?: boolean;\n ceilingDb?: number;\n lookaheadMs?: number;\n releaseMs?: number;\n oversampleFactor?: number;\n applyGainAtInputRate?: boolean;\n };\n };\n loudness?: {\n enabled?: boolean;\n targetLufs?: number;\n ceilingDb?: number;\n truePeakOversample?: number;\n releaseMs?: number;\n applyGainAtInputRate?: boolean;\n /**\n * How deep, in dB, the stage may drive its post-gain true-peak limiter to\n * reach {@link targetLufs}. Default 12. The static normalization gain may\n * exceed the peak headroom toward `ceilingDb` by this much; `0` restores a\n * strict headroom clamp, under which peak-normalized input keeps its input\n * loudness whatever target is asked for. `ceilingDb` holds at every setting.\n */\n maxLimiterGainReductionDb?: number;\n };\n /**\n * Dot-notation spelling of any leaf above, e.g. `'loudness.targetLufs': -20`\n * beside or instead of `loudness: { targetLufs: -20 }`. It is the form the C\n * ABI carries parameters in, so a caller assembling overrides dynamically can\n * emit it directly; the core validates the key and rejects an unknown one.\n * The nested spelling is canonical — prefer it in hand-written code, where it\n * is checked field by field while a dotted key is only checked at run time.\n */\n [flatKey: `${string}.${string}`]: number | boolean | undefined;\n}\n\n/**\n * Configuration for the block-by-block {@link StreamingMasteringChain}.\n *\n * Extends {@link MasteringChainConfig} with optional precomputed loudness\n * parameters. The streaming chain cannot measure whole-signal integrated LUFS,\n * so an enabled `loudness` stage normally throws at construction. To let a\n * preset's streaming preview match its offline render, the caller may\n * precompute the loudness normalization gain offline (e.g.\n * `targetLufs - measuredIntegratedLufs`) and supply it here.\n */\nexport interface StreamingMasteringChainConfig extends MasteringChainConfig {\n /**\n * Precomputed static loudness gain in dB. When omitted (the default), an\n * enabled `loudness` stage still throws. When provided and `loudness.enabled`\n * is set, the chain applies this fixed gain per block before the loudness\n * stage's true-peak limiter instead of throwing.\n */\n loudnessStaticGainDb?: number;\n\n /**\n * Offline-measured true-peak (dBFS) of the source the static gain was\n * computed for. When provided, the static gain is clamped to\n * `(loudness.ceilingDb - loudnessStaticGainPeakDb) +\n * max(loudness.maxLimiterGainReductionDb, 0)` so the streaming preview\n * does not drive the loudness limiter harder than the offline chain. When\n * omitted (the default) the static gain is applied verbatim.\n */\n loudnessStaticGainPeakDb?: number;\n}\n\n/** Gain reduction reported by a single dynamics/maximizer chain stage. */\nexport interface StageGainReduction {\n /** Stage identifier, e.g. `\"dynamics.compressor\"`. */\n stage: string;\n /**\n * Most recent (typically last-block) gain reduction in dB (negative or\n * zero); for multiband stages it is the most-reduced band.\n */\n gainReductionDb: number;\n}\n\n/** Existing EBU R128 measurements captured before or after mastering. */\nexport interface MasteringLoudnessSummary {\n integratedLufs: number;\n maxMomentaryLufs: number;\n maxShortTermLufs: number;\n truePeakDbtp: number;\n loudnessRange: number;\n}\n\n/** Compact explanation of how an offline mastering chain changed a program. */\nexport interface MasteringReport {\n before: MasteringLoudnessSummary;\n after: MasteringLoudnessSummary;\n appliedGainDb: number;\n maxGainReductionDb: number;\n loudnessTargetLimited: boolean;\n /** 32 logarithmically-spaced after-minus-before spectral energy deltas (dB). */\n bandEnergyDeltaDb: Float32Array;\n}\n\nexport interface MasteringChainResult {\n /** Latency-compensated offline output; no separate latency field is reported. */\n samples: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n stages: string[];\n /**\n * ITU-R BS.1770-4 true peak of the output (dBTP). Lets callers verify a\n * preset ceiling was met without a second oversampled scan.\n *\n * The oversample factor follows the peak-limiting stage the chain actually\n * applied, so it is not fixed: the loudness stage's true-peak oversample\n * (default 4x) when loudness is enabled, and the maximizer true-peak\n * limiter's own oversample factor when loudness is disabled but that stage\n * ran. The two disagree by roughly 0.02 dB between 4x and 8x, so comparing\n * this against an independently measured peak needs the same factor.\n */\n outputTruePeakDbtp: number;\n /** EBU Tech 3342 Loudness Range of the output (LU). */\n outputLra: number;\n /** True when peak headroom prevented the requested LUFS target. */\n loudnessTargetLimited: boolean;\n /**\n * Samples a stage replaced with a finite in-domain one, keeping the\n * output finite and in range.\n *\n * A non-finite sample supplied by the caller is rejected before any stage\n * runs, so a replacement is always of a value a stage itself produced.\n *\n * Only the true-peak limiters replace anything, so with the maximizer's\n * limiter and the loudness stage both disabled a zero here means no stage\n * was able to replace anything rather than that nothing needed replacing.\n * Aggregated, so it does not identify which one substituted; run a limiter\n * individually through {@link masteringProcess} to attribute a non-zero count.\n */\n nonFiniteSubstitutionCount: number;\n /** Per-stage gain reductions for the dynamics/maximizer stages (a subset of `stages`). */\n stageGainReductions: StageGainReduction[];\n report: MasteringReport;\n}\n\nexport interface MasteringChainStereoResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n stages: string[];\n /** See {@link MasteringChainResult} for field semantics. */\n outputTruePeakDbtp: number;\n outputLra: number;\n loudnessTargetLimited: boolean;\n /**\n * See {@link MasteringChainResult.nonFiniteSubstitutionCount}. Aggregated\n * over both channels, so it does not identify which channel substituted.\n */\n nonFiniteSubstitutionCount: number;\n stageGainReductions: StageGainReduction[];\n report: MasteringReport;\n}\n\n/**\n * @deprecated Use {@link MasteringChainStereoResult}. Retained as an alias for\n * source compatibility; the canonical name matches the Node and Python\n * bindings (`MasteringChainStereoResult`).\n */\nexport type MasteringStereoChainResult = MasteringChainStereoResult;\n\nexport interface MasteringStereoResult {\n left: Float32Array;\n right: Float32Array;\n sampleRate: number;\n inputLufs: number;\n outputLufs: number;\n appliedGainDb: number;\n latencySamples: number;\n /** True when peak headroom prevented the requested LUFS target. */\n loudnessTargetLimited: boolean;\n /**\n * See {@link MasteringResult.nonFiniteSubstitutionCount}. Aggregated over both\n * channels, so it does not identify which channel substituted.\n */\n nonFiniteSubstitutionCount: number;\n}\n","import type { ValidateOptions } from './validation';\n\n/**\n * Pitch class enum (C=0, C#=1, ..., B=11)\n */\nexport const PitchClass = {\n C: 0,\n Cs: 1,\n D: 2,\n Ds: 3,\n E: 4,\n F: 5,\n Fs: 6,\n G: 7,\n Gs: 8,\n A: 9,\n As: 10,\n B: 11,\n} as const;\n\nexport type PitchClass = (typeof PitchClass)[keyof typeof PitchClass];\n\n/**\n * Musical mode\n */\nexport const Mode = {\n Major: 0,\n Minor: 1,\n Dorian: 2,\n Phrygian: 3,\n Lydian: 4,\n Mixolydian: 5,\n Locrian: 6,\n} as const;\n\nexport type Mode = (typeof Mode)[keyof typeof Mode];\n\nexport type TempogramMode = 'autocorrelation' | 'auto' | 'ac' | 'cosine' | 0 | 1;\n\nexport const KeyProfile = {\n KrumhanslSchmuckler: 0,\n Temperley: 1,\n Shaath: 2,\n FaraldoEDMT: 3,\n FaraldoEDMA: 4,\n FaraldoEDMM: 5,\n BellmanBudge: 6,\n} as const;\n\nexport type KeyProfile = (typeof KeyProfile)[keyof typeof KeyProfile];\n\nexport type KeyProfileName =\n | 'ks'\n | 'krumhansl'\n | 'temperley'\n | 'shaath'\n | 'keyfinder'\n | 'faraldo-edmt'\n | 'edmt'\n | 'faraldo-edma'\n | 'edma'\n | 'faraldo-edmm'\n | 'edmm'\n | 'bellman-budge'\n | 'bellman';\n\n/**\n * Chord quality\n */\nexport const ChordQuality = {\n Major: 0,\n Minor: 1,\n Diminished: 2,\n Augmented: 3,\n Dominant7: 4,\n Major7: 5,\n Minor7: 6,\n Sus2: 7,\n Sus4: 8,\n Unknown: 9,\n Add9: 10,\n MinorAdd9: 11,\n Dim7: 12,\n HalfDim7: 13,\n Major9: 14,\n Dominant9: 15,\n Sus2Add4: 16,\n Major6: 17,\n Minor6: 18,\n MinorMajor7: 19,\n Dominant7Sus4: 20,\n Dominant11: 21,\n Dominant13: 22,\n Dominant7Flat9: 23,\n Dominant7Sharp9: 24,\n} as const;\n\nexport type ChordQuality = (typeof ChordQuality)[keyof typeof ChordQuality];\n\n/**\n * Section type.\n *\n * `PreChorus` is never produced by `analyze()`: it has no detection branch, so\n * filtering sections on it always yields an empty result. Every other value is\n * reachable. `Unknown` means the analyzer did not name the segment: no\n * boundary was detected, the segment matched none of the positive branches, or\n * the evidence for a musical function was too weak to assert one. The first\n * case comes with `confidence` 0; the last keeps the sub-threshold score, so a\n * caller can see how close the segment came to a label.\n */\nexport const SectionType = {\n Intro: 0,\n Verse: 1,\n PreChorus: 2,\n Chorus: 3,\n Bridge: 4,\n Instrumental: 5,\n Outro: 6,\n Unknown: 7,\n} as const;\n\nexport type SectionType = (typeof SectionType)[keyof typeof SectionType];\n\n/**\n * Detected musical key\n */\nexport interface Key {\n root: PitchClass;\n mode: Mode;\n /**\n * Share of the model's belief that this key is the answer, in `[0, 1)`.\n *\n * A softmax over the profile correlations of every candidate that was scored,\n * so it falls as the runner-up closes in and two keys that split the evidence\n * -- a relative major and minor, typically -- each report about half.\n *\n * This is the model's own belief, **not** a measured accuracy. It says how\n * decisively the chroma picked this key out of the candidate set; it does not\n * say how often that pick is right, and nothing here has been fitted against\n * annotated recordings. A confident wrong answer is entirely possible, so a\n * pipeline that branches on it must choose its own threshold against its own\n * material.\n */\n confidence: number;\n name: string;\n shortName: string;\n}\n\nexport interface KeyDetectionOptions extends ValidateOptions {\n nFft?: number;\n hopLength?: number;\n useHpss?: boolean;\n loudnessWeighted?: boolean;\n highPassHz?: number;\n modes?:\n | Mode[]\n | ('major' | 'minor' | 'dorian' | 'phrygian' | 'lydian' | 'mixolydian' | 'locrian')[]\n | 'major-minor'\n | 'all'\n | 'modal';\n profile?: KeyProfile | KeyProfileName;\n genreHint?: 'auto' | 'edm' | 'electronic' | 'dance' | 'pop' | 'classical' | 'jazz' | string;\n}\n\nexport interface KeyCandidate {\n key: Key;\n correlation: number;\n}\n\nexport interface ChordDetectionOptions extends ValidateOptions {\n minDuration?: number;\n smoothingWindow?: number;\n /** Final-template correlation threshold in [0, 1]; below it emits Unknown / N.C. */\n threshold?: number;\n useTriadsOnly?: boolean;\n /** STFT chroma window in samples at 22050 Hz, rescaled to the input rate so its duration is the same at every rate. */\n nFft?: number;\n hopLength?: number;\n useBeatSync?: boolean;\n useHmm?: boolean;\n hmmBeamWidth?: number;\n useKeyContext?: boolean;\n keyRoot?: PitchClass;\n keyMode?: Mode;\n detectInversions?: boolean;\n chromaMethod?: 'stft' | 'nnls';\n /**\n * Tuning offset of the recording in fractions of a semitone, the unit\n * `estimateTuning` returns; must be in `[-0.5, 0.5)`. Default 0 (concert A440).\n */\n tuning?: number;\n}\n\n/** Options for `analyzeBpm`. All fields are optional. */\nexport interface AnalyzeBpmOptions extends ValidateOptions {\n /** Lowest BPM to consider. Default 30. */\n bpmMin?: number;\n /** Highest BPM to consider. Default 300. */\n bpmMax?: number;\n /** Tempo prior the tracker is biased toward. Default 120. */\n startBpm?: number;\n /** FFT size for the onset envelope. Default 2048. */\n nFft?: number;\n /** Hop length for the onset envelope. Default 512. */\n hopLength?: number;\n /** Number of tempo candidates to return. Default 5. */\n maxCandidates?: number;\n}\n\n/** Options for `analyzeRhythm`. All fields are optional. */\nexport interface AnalyzeRhythmOptions extends ValidateOptions {\n /** Lowest BPM to consider. Default 60. */\n bpmMin?: number;\n /** Highest BPM to consider. Default 200. */\n bpmMax?: number;\n /** Tempo prior the tracker is biased toward. Default 120. */\n startBpm?: number;\n /** FFT size for the onset envelope. Default 2048. */\n nFft?: number;\n /** Hop length for the onset envelope. Default 512. */\n hopLength?: number;\n}\n\n/** Options for `analyzeDynamics`. All fields are optional. */\nexport interface AnalyzeDynamicsOptions extends ValidateOptions {\n /** Loudness-curve window length in seconds. Default 0.4. */\n windowSec?: number;\n /** Hop length for the loudness curve. Default 512. */\n hopLength?: number;\n /** Crest-factor (dB) below which the signal is flagged as compressed. Default 6. */\n compressionThreshold?: number;\n}\n\n/** Options for `analyzeTimbre`. All fields are optional. */\nexport interface AnalyzeTimbreOptions extends ValidateOptions {\n /** FFT size. Default 2048. */\n nFft?: number;\n /** Hop length. Default 512. */\n hopLength?: number;\n /** Number of Mel bands. Default 128. */\n nMels?: number;\n /** Number of MFCCs. Default 13. */\n nMfcc?: number;\n /** Per-window analysis length in seconds. Default 0.5. */\n windowSec?: number;\n}\n\n/** Options for `analyzeSections`. All fields are optional. */\nexport interface AnalyzeSectionsOptions {\n /** FFT size. Default 2048. */\n nFft?: number;\n /** Hop length. Default 512. */\n hopLength?: number;\n /** Minimum section duration in seconds. Default 4. */\n minSectionSec?: number;\n}\n\n/**\n * Detected beat\n */\nexport interface Beat {\n /** Beat position in seconds. */\n time: number;\n /**\n * Onset-envelope value sampled at the beat's frame.\n *\n * @remarks\n * A single raw frame of the onset envelope, not a normalized or relative\n * salience: it is unbounded, its scale depends on the material, and it moves\n * with any jitter in the beat position. For accent scoring use\n * {@link BeatObservations.onsetStrength}, which is the windowed aggregate the\n * library's own downbeat pass scores.\n */\n strength: number;\n}\n\n/**\n * Beat-level evidence behind the downbeat and meter decisions.\n *\n * @remarks\n * These are inputs to the library's decision, not outputs of it, exposed so a\n * caller running its own meter work scores the same evidence instead of\n * reconstructing a weaker approximation from the frame-level onset envelope.\n * Each non-empty stream holds one value per entry of\n * {@link AnalysisResult.beats} and indexes in parallel with it. An empty stream\n * means the analysis could not produce it, which is not the same as every beat\n * having scored zero.\n */\nexport interface BeatObservations {\n /**\n * Beat-local onset-strength window.\n *\n * @remarks\n * Unlike {@link Beat.strength} this is aggregated over a window around the\n * beat rather than sampled at a single frame, so it is the stream to score\n * accents with.\n */\n onsetStrength: number[];\n /**\n * Beat-local low-frequency energy — the accent evidence a log-spectral\n * difference discards. Empty when the analysis ran without audio.\n */\n lowFrequencyEnergy: number[];\n /** Per-beat chord-change evidence. Empty until chords are analyzed. */\n chordChange: number[];\n}\n\n/**\n * Detected chord\n */\nexport interface Chord {\n root: PitchClass;\n bass: PitchClass;\n /** Canonical core spelling; stable across all language bindings. */\n rootName: string;\n /** Canonical core spelling; stable across all language bindings. */\n bassName: string;\n quality: ChordQuality;\n start: number;\n end: number;\n /** Derived from `end - start`; the core carries only the two endpoints. */\n duration: number;\n confidence: number;\n name: string;\n}\n\n/** A chord in {@link AnalysisResult.chords}, which carries its function in the key. */\nexport interface AnalysisChord extends Chord {\n /**\n * Roman numeral of the chord relative to {@link AnalysisResult.key}, e.g.\n * `'V7'`, `'vi'`, `'bVII'`. The same spelling `chordFunctionalAnalysis`\n * returns for that chord and key. Empty for a chord that is N.C.\n */\n romanNumeral: string;\n}\n\nexport interface ChordAnalysisResult {\n chords: Chord[];\n}\n\n/**\n * Detected section\n */\nexport interface Section {\n type: SectionType;\n start: number;\n end: number;\n energyLevel: number;\n confidence: number;\n name: string;\n}\n\n/** Options for `detectBoundaries`. All fields are optional. */\nexport interface BoundaryOptions {\n /** FFT size used for the structural features. Default 2048. */\n nFft?: number;\n /** Hop length in samples. Default 512. */\n hopLength?: number;\n /** Checkerboard kernel size in frames. Default 64. */\n kernelSize?: number;\n /**\n * Relative novelty threshold, applied to the curve after it has been scaled by\n * its own maximum. Selects how prominent a peak must be *within this track*; it\n * says nothing about how much the features actually changed. Default 0.3.\n */\n threshold?: number;\n /**\n * Novelty floor applied to the raw response before that scaling, asking whether\n * anything changed at all. Default 0.005. Set to 0 to gate on {@link threshold}\n * alone -- but self-scaling turns residual fluctuation into peaks of 1.0, so a\n * stationary input then segments anyway. Lowering the floor does not recover\n * level-only structure: a level change turns the feature vector about five times\n * less than a comparable pitch change, landing below what steady noise produces,\n * so the noise is admitted first.\n */\n absoluteThreshold?: number;\n /** Number of MFCC coefficients. Default 13. */\n nMfcc?: number;\n /** Number of chroma bins. Default 12. */\n nChroma?: number;\n /** Minimum spacing between peaks, in seconds. Default 2. */\n peakDistance?: number;\n /** Use MFCC features. Default `true`. */\n useMfcc?: boolean;\n /** Use chroma features. Default `true`. */\n useChroma?: boolean;\n}\n\n/**\n * A single detected structural boundary (mirrors the C `SonareBoundary`).\n */\nexport interface Boundary {\n /** Boundary time in seconds (the authoritative output). */\n time: number;\n /**\n * Index into the analysis grid, on {@link BoundaryResult.sampleRate}'s time\n * base rather than the source's. For a long-form input the feature grid is\n * additionally mean-pooled, so this indexes the pooled grid; use `time` for\n * sample/second mapping either way.\n */\n frame: number;\n /** Boundary strength (novelty score). */\n strength: number;\n}\n\n/**\n * Result of `detectBoundaries` (mirrors the C `SonareBoundaryResult`).\n */\nexport interface BoundaryResult {\n /** Detected transitions, in time order. */\n boundaries: Boundary[];\n /**\n * Novelty curve scaled by its own maximum, one value per analysis frame. A\n * peak of 1 means \"the most novel frame here\", not \"a large change\"; multiply\n * by {@link noveltyPeak} to recover the raw response\n * {@link BoundaryOptions.absoluteThreshold} is compared against.\n */\n noveltyCurve: Float32Array;\n /**\n * The largest raw checkerboard response, before normalization. Zero when the\n * curve was left unnormalized because nothing rose above the numerical floor.\n */\n noveltyPeak: number;\n /**\n * The rate the analysis ran at, not the input's: a source above 22050 Hz is\n * resampled to 22050 Hz before any feature is computed, which is what makes\n * {@link Boundary.frame} interpretable.\n */\n sampleRate: number;\n /** Hop length the analysis grid was built on. */\n hopLength: number;\n /** Analysis frame count, pooled for a long-form input. */\n nFrames: number;\n /**\n * Feature pooling stride: 1 for every realistic input length, otherwise the\n * number of raw STFT frames averaged into each analysis frame.\n */\n frameStride: number;\n}\n\n/**\n * A single melody contour point (mirrors the C `SonareMelodyPoint`).\n */\nexport interface MelodyPoint {\n /** Frame time in seconds. */\n time: number;\n /** Estimated fundamental frequency in Hz (0 when unvoiced). */\n frequency: number;\n /** Voicing confidence in `[0, 1]`. */\n confidence: number;\n}\n\n/**\n * Melody analysis result (mirrors the C `SonareMelodyResult`).\n */\nexport interface MelodyResult {\n points: MelodyPoint[];\n pitchRangeOctaves: number;\n pitchStability: number;\n meanFrequency: number;\n vibratoRate: number;\n}\n\n/**\n * Timbre characteristics\n */\nexport interface Timbre {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\n/**\n * Dynamics characteristics\n */\nexport interface Dynamics {\n dynamicRangeDb: number;\n peakDb: number;\n rmsDb: number;\n loudnessRangeDb: number;\n crestFactor: number;\n isCompressed: boolean;\n}\n\n/**\n * Time signature\n */\nexport interface TimeSignature {\n numerator: number;\n denominator: number;\n /**\n * Support for this signature in `[0, 1]`.\n *\n * @remarks\n * What it measures depends on which field the signature arrived in. On\n * {@link MeterEstimate.timeSignature} it is derived from the margin over the\n * runner-up; on a {@link MeterEstimate.candidates} entry it is that\n * candidate's share of the summed support. The two are not comparable, so\n * read the value from the field you meant rather than from whichever one is\n * to hand.\n */\n confidence: number;\n}\n\n/**\n * Meter estimated over a caller-supplied beat series.\n */\nexport interface MeterEstimate {\n /**\n * Selected time signature.\n *\n * @remarks\n * Its `confidence` is the margin over the runner-up — how separated the\n * winner is — not the share-of-support a {@link candidates} entry carries\n * under the same field name.\n */\n timeSignature: TimeSignature;\n /** Beat index the first measure starts on, in `[0, timeSignature.numerator)`. */\n downbeatPhase: number;\n /**\n * Whether a search ran, as opposed to the fixed fallback being reported.\n *\n * @remarks\n * `false` means the beat series was too short to score any candidate, and\n * every other field then carries that fallback rather than a measurement —\n * `timeSignature.confidence` included, which is 0, so an unchecked read\n * degrades toward \"no idea\" rather than toward a middling detection. Read\n * this before treating a short span's answer as a detection.\n */\n searched: boolean;\n /**\n * How the bar divides, in beats per accent group.\n *\n * @remarks\n * `[3, 2, 2]` is the 7/8 an aksak meter notates as 3+2+2, and `[2, 2]` an\n * ordinary four. Always sums to `timeSignature.numerator`.\n *\n * A single entry means no internal division was resolved — the numerator has\n * none to find, it was too wide to search, or the span was too short to\n * search at all.\n *\n * This is also what tells a compound bar from a simple one: per-beat accents\n * cannot say how a beat subdivides, so a six accented 3+3 keeps the requested\n * denominator and reports `[3, 3]` rather than being promoted to 6/8.\n */\n grouping: number[];\n /**\n * Multi-comb score per requested candidate numerator.\n *\n * @remarks\n * Parallel to the `candidateNumerators` that were requested, in the order\n * they were given. This does NOT index alike with {@link candidates}, which\n * is ordered by descending support.\n *\n * Standardized and signed: zero is the level a numerator reaches on beats\n * carrying no meter, so a negative entry means less support than noise would\n * produce. Only the ordering and the gaps between entries carry meaning.\n *\n * Comparable only within one result. A score grows with the square root of\n * how many beats were scored, so the same meter over twice the beats scores\n * about 1.41 times as high; a segmentation search comparing spans of\n * different lengths has to normalize for length first.\n */\n candidateScores: number[];\n /**\n * Candidate signatures ordered by descending support.\n *\n * @remarks\n * A ranking, so entry `k` is the k-th best hypothesis — not the k-th\n * requested numerator. Use {@link candidateScores} to read the score of a\n * specific requested numerator.\n *\n * Each entry's `confidence` is that candidate's share of the summed support,\n * so the entries sum to one. It is a different quantity from\n * {@link timeSignature}'s margin-derived confidence, which shares the field\n * name and nothing else.\n */\n candidates: TimeSignature[];\n}\n\n/** Existing tempo-estimator hypothesis retained by unified analysis. */\nexport interface BpmHypothesis {\n value: number;\n confidence: number;\n relation: 'primary' | 'half' | 'double' | 'other';\n}\n\n/**\n * Rhythm features\n */\nexport interface RhythmFeatures {\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n tempoStability: number;\n timeSignature: TimeSignature;\n}\n\n/**\n * Melody contour from the unified analysis (pitch trajectory + summary stats).\n */\nexport interface MelodyContour {\n pitchRangeOctaves: number;\n pitchStability: number;\n meanFrequency: number;\n vibratoRate: number;\n pitches: MelodyPoint[];\n}\n\n/**\n * Complete analysis result\n */\nexport interface AnalysisResult {\n bpm: number;\n bpmConfidence: number;\n bpmCandidates: BpmHypothesis[];\n key: Key;\n timeSignature: TimeSignature;\n timeSignatureCandidates: TimeSignature[];\n beatTimes: Float32Array;\n beats: Beat[];\n /**\n * Indices into {@link AnalysisResult.beats} that fall on a measure start.\n *\n * @remarks\n * Not the same length as `beats` — it holds one entry per detected downbeat,\n * and each entry indexes `beats`, so `beats[downbeatIndices[k]]` is the k-th\n * downbeat. Testing a beat for downbeat status is a membership check on this\n * list rather than a time comparison against a separate downbeat series.\n */\n downbeatIndices: number[];\n /**\n * Beat index the first measure starts on, in `[0, timeSignature.numerator)`.\n *\n * @remarks\n * The meter estimator's phase, so `downbeatIndices` normally begins at this\n * value. It is not re-derived when downbeats are refined from chord and\n * low-frequency-energy evidence, so the two can disagree when the refinement\n * moves the first measure start.\n */\n downbeatPhase: number;\n /**\n * Beat-level evidence behind the downbeat and meter decisions, parallel to\n * {@link AnalysisResult.beats}.\n */\n beatObservations: BeatObservations;\n /**\n * Smoothed local tempo at each beat, in BPM, parallel to\n * {@link AnalysisResult.beats}.\n *\n * @remarks\n * Empty unless `computeTempoCurve` was set, and empty regardless when fewer\n * than two beats were detected, since a tempo is a property of the interval\n * between two beats. The last entry repeats the tempo of the interval leading\n * into the final beat, which opens no interval of its own.\n *\n * Values are continuous, not points on a tempo grid: each is a weighted\n * average, in log tempo, of the beat intervals around it. A steady tempo\n * reads within about 1% at every beat, and a tempo that moves is followed a\n * few beats late.\n *\n * This is the local tempo rather than {@link AnalysisResult.bpm} resampled:\n * on material whose tempo moves it departs from `bpm`, and reading a single\n * number out of it is not how to get the global tempo.\n */\n beatLocalBpm: number[];\n chords: AnalysisChord[];\n sections: Section[];\n timbre: Timbre;\n dynamics: Dynamics;\n rhythm: RhythmFeatures;\n melody: MelodyContour;\n form: string;\n}\n","import type { ProjectAutomationCurve } from './project_types';\nimport type {\n AutomationCurve,\n MeterTap,\n PanLawInput,\n PanMode,\n SendTiming,\n SidechainSourceKind,\n} from './public_types';\n\n/** Resolve a numeric ordinal in an inclusive range without coercion. */\nexport function resolveOrdinalInRange(\n value: unknown,\n min: number,\n max: number,\n enumName: string,\n): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < min || value > max) {\n throw new RangeError(`Invalid ${enumName}: ${String(value)}`);\n }\n return value;\n}\n\n/** Resolve a public enum spelling or ordinal without permitting unknown values. */\nexport function resolveEnumOrdinal(\n value: unknown,\n values: Readonly<Record<string, number>>,\n enumName: string,\n): number {\n if (typeof value === 'number') {\n const ordinals = Object.values(values);\n const ordinal = resolveOrdinalInRange(\n value,\n Math.min(...ordinals),\n Math.max(...ordinals),\n enumName,\n );\n if (!ordinals.includes(ordinal)) {\n throw new RangeError(`Invalid ${enumName}: ${String(value)}`);\n }\n return ordinal;\n }\n if (typeof value === 'string') {\n const ordinal = values[value];\n if (ordinal !== undefined) {\n return ordinal;\n }\n }\n throw new RangeError(`Invalid ${enumName}: ${String(value)}`);\n}\n\n/**\n * Automation curve spellings and their `SonareAutomationCurve` ordinals.\n *\n * Single source of truth for the vocabulary: {@link AutomationCurve} and\n * {@link ProjectAutomationCurve} are derived from these keys, so a spelling\n * cannot be documented without resolving, or resolve without being documented.\n */\nexport const AUTOMATION_CURVE_VALUES = {\n linear: 0,\n exponential: 1,\n hold: 2,\n 's-curve': 3,\n} as const;\n\n/**\n * The Project facade additionally accepts the legacy `'scurve'` spelling for\n * compatibility with project data written before `'s-curve'` was canonical.\n * The Node package declares the same pair of tables, so a breakpoint accepted\n * by one facade resolves to the same ordinal on the other.\n */\nexport const PROJECT_AUTOMATION_CURVE_VALUES = {\n ...AUTOMATION_CURVE_VALUES,\n scurve: 3,\n} as const;\nconst PAN_LAW_VALUES: Readonly<Record<string, number>> = {\n const3db: 0,\n 'const-3db': 0,\n '-3db': 0,\n 'const4.5db': 1,\n 'const-4.5db': 1,\n '-4.5db': 1,\n const6db: 2,\n 'const-6db': 2,\n '-6db': 2,\n linear0db: 3,\n 'linear-0db': 3,\n linear: 3,\n '0db': 3,\n} as const;\nconst PAN_MODE_VALUES = {\n balance: 0,\n pan: 1,\n stereopan: 1,\n 'stereo-pan': 1,\n dualpan: 2,\n 'dual-pan': 2,\n} as const;\nconst METER_TAP_VALUES = { preFader: 0, postFader: 1 } as const;\nconst SEND_TIMING_VALUES = { postFader: 0, preFader: 1 } as const;\nconst SIDECHAIN_SOURCE_KIND_VALUES = { track: 0, bus: 1 } as const;\nconst TRACK_MONITOR_MODE_VALUES = { off: 0, pfl: 1, afl: 2 } as const;\n\nexport function automationCurveCode(curve: AutomationCurve): number {\n return resolveEnumOrdinal(curve, AUTOMATION_CURVE_VALUES, 'automation curve');\n}\n\n/** Resolve a Project automation breakpoint curve, legacy spellings included. */\nexport function projectAutomationCurveCode(curve: ProjectAutomationCurve | undefined): number {\n return resolveEnumOrdinal(curve ?? 'linear', PROJECT_AUTOMATION_CURVE_VALUES, 'automation curve');\n}\n\nexport function panLawCode(panLaw: PanLawInput): number {\n const normalized = typeof panLaw === 'string' ? panLaw.toLowerCase().replace(/_/g, '-') : panLaw;\n return resolveEnumOrdinal(normalized, PAN_LAW_VALUES, 'pan law');\n}\n\nexport function panModeCode(panMode: PanMode | number): number {\n const normalized =\n typeof panMode === 'string' ? panMode.replace(/_/g, '-').toLowerCase() : panMode;\n return resolveEnumOrdinal(normalized, PAN_MODE_VALUES, 'pan mode');\n}\n\nexport function meterTapCode(tap: MeterTap | number): number {\n return resolveEnumOrdinal(tap, METER_TAP_VALUES, 'meter tap');\n}\n\nexport function sendTimingCode(timing: SendTiming | number): number {\n // Mirrors SonareSendTiming: post-fader is 0 (so an omitted/zeroed value is\n // post-fader), pre-fader is 1. A raw number is passed through as the C ABI int.\n // An unknown string is rejected rather than silently routed to post-fader,\n // matching the sibling enum-code helpers and Node's sendTimingValue.\n return resolveEnumOrdinal(timing, SEND_TIMING_VALUES, 'send timing');\n}\n\n/** Resolve a sidechain source kind to its `SonareSidechainSourceKind` ordinal. */\nexport function sidechainSourceKindCode(kind: SidechainSourceKind | number): number {\n return resolveEnumOrdinal(kind, SIDECHAIN_SOURCE_KIND_VALUES, 'sidechain source kind');\n}\n\n/** Resolve a per-track PFL/AFL monitor mode to its C-ABI ordinal. */\nexport function trackMonitorModeCode(mode: unknown): number {\n return resolveEnumOrdinal(mode, TRACK_MONITOR_MODE_VALUES, 'track monitor mode');\n}\n","import { resolveEnumOrdinal } from './codes';\nimport type {\n AnalysisResult,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChordQuality,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n PitchClass,\n SectionType,\n} from './public_types';\nimport { KeyProfile as KeyProfileValues, Mode } from './public_types';\nimport type {\n WasmAnalysisResult,\n WasmChordAnalysisResult,\n WasmKeyCandidateResult,\n} from './sonare.js';\n\nconst PITCH_CLASS_NAMES = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n] as const;\n\nfunction pitchClassName(value: number): string {\n return PITCH_CLASS_NAMES[value] ?? 'C';\n}\n\nexport function convertKeyCandidate(wasm: WasmKeyCandidateResult): KeyCandidate {\n return {\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n correlation: wasm.correlation,\n };\n}\n\n// Consolidated spelling -> ordinal tables, resolved through the same\n// resolveEnumOrdinal() primitive as panModeCode/panLawCode/etc. in ./codes.\n// An unmapped string or an out-of-range numeric ordinal throws RangeError\n// instead of silently resolving to `undefined` (which used to reach the WASM\n// layer as a mistyped argument) or passing an unvalidated raw number through.\nconst KEY_MODE_VALUES: Readonly<Record<string, number>> = {\n major: Mode.Major,\n minor: Mode.Minor,\n dorian: Mode.Dorian,\n phrygian: Mode.Phrygian,\n lydian: Mode.Lydian,\n mixolydian: Mode.Mixolydian,\n locrian: Mode.Locrian,\n};\n\nconst KEY_PROFILE_VALUES: Readonly<Record<KeyProfileName, number>> = {\n ks: KeyProfileValues.KrumhanslSchmuckler,\n krumhansl: KeyProfileValues.KrumhanslSchmuckler,\n temperley: KeyProfileValues.Temperley,\n shaath: KeyProfileValues.Shaath,\n keyfinder: KeyProfileValues.Shaath,\n 'faraldo-edmt': KeyProfileValues.FaraldoEDMT,\n edmt: KeyProfileValues.FaraldoEDMT,\n 'faraldo-edma': KeyProfileValues.FaraldoEDMA,\n edma: KeyProfileValues.FaraldoEDMA,\n 'faraldo-edmm': KeyProfileValues.FaraldoEDMM,\n edmm: KeyProfileValues.FaraldoEDMM,\n 'bellman-budge': KeyProfileValues.BellmanBudge,\n bellman: KeyProfileValues.BellmanBudge,\n};\n\nexport function keyModeValues(modes: KeyDetectionOptions['modes'] | undefined): number[] {\n if (!modes) {\n return [];\n }\n if (modes === 'major-minor') {\n return [Mode.Major, Mode.Minor];\n }\n if (modes === 'all' || modes === 'modal') {\n return [\n Mode.Major,\n Mode.Minor,\n Mode.Dorian,\n Mode.Phrygian,\n Mode.Lydian,\n Mode.Mixolydian,\n Mode.Locrian,\n ];\n }\n return modes.map((mode) => resolveEnumOrdinal(mode, KEY_MODE_VALUES, 'key mode'));\n}\n\nexport function keyProfileValue(profile: KeyDetectionOptions['profile'] | undefined): number {\n if (profile === undefined) {\n return -1;\n }\n return resolveEnumOrdinal(profile, KEY_PROFILE_VALUES, 'key profile');\n}\n\nexport function convertChordAnalysisResult(wasm: WasmChordAnalysisResult): ChordAnalysisResult {\n return {\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n rootName: pitchClassName(c.root),\n bassName: pitchClassName(c.bass),\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n duration: c.end - c.start,\n confidence: c.confidence,\n name: c.name,\n })),\n };\n}\n\nexport function chordChromaMethodValue(method: ChordDetectionOptions['chromaMethod']): number {\n if (method === 'stft') {\n return 0;\n }\n if (method === 'nnls') {\n return 1;\n }\n throw new Error(`Invalid chord chroma method: ${method}`);\n}\n\nexport function convertAnalysisResult(wasm: WasmAnalysisResult): AnalysisResult {\n const beatTimes = new Float32Array(wasm.beats.length);\n for (let i = 0; i < wasm.beats.length; i++) {\n beatTimes[i] = wasm.beats[i].time;\n }\n return {\n bpm: wasm.bpm,\n bpmConfidence: wasm.bpmConfidence,\n bpmCandidates: wasm.bpmCandidates.map((candidate) => ({\n value: candidate.value,\n confidence: candidate.confidence,\n relation: candidate.relation,\n })),\n key: {\n root: wasm.key.root as PitchClass,\n mode: wasm.key.mode as Mode,\n confidence: wasm.key.confidence,\n name: wasm.key.name,\n shortName: wasm.key.shortName,\n },\n timeSignature: wasm.timeSignature,\n timeSignatureCandidates: wasm.timeSignatureCandidates,\n beatTimes,\n beats: wasm.beats,\n downbeatIndices: wasm.downbeatIndices,\n downbeatPhase: wasm.downbeatPhase,\n beatObservations: wasm.beatObservations,\n beatLocalBpm: wasm.beatLocalBpm,\n chords: wasm.chords.map((c) => ({\n root: c.root as PitchClass,\n bass: c.bass as PitchClass,\n rootName: pitchClassName(c.root),\n bassName: pitchClassName(c.bass),\n quality: c.quality as ChordQuality,\n start: c.start,\n end: c.end,\n duration: c.end - c.start,\n confidence: c.confidence,\n name: c.name,\n romanNumeral: c.romanNumeral,\n })),\n sections: wasm.sections.map((s) => ({\n type: s.type as SectionType,\n start: s.start,\n end: s.end,\n energyLevel: s.energyLevel,\n confidence: s.confidence,\n name: s.name,\n })),\n timbre: wasm.timbre,\n dynamics: wasm.dynamics,\n rhythm: wasm.rhythm,\n melody: wasm.melody,\n form: wasm.form,\n };\n}\n","import {\n chordChromaMethodValue,\n convertAnalysisResult,\n convertChordAnalysisResult,\n convertKeyCandidate,\n keyModeValues,\n keyProfileValue,\n} from './analysis_helpers';\nimport { getSonareModule } from './module_state';\nimport type {\n AcousticOptions,\n AcousticResult,\n AnalysisResult,\n AnalyzeBpmOptions,\n AnalyzeDynamicsOptions,\n AnalyzeRhythmOptions,\n AnalyzeTimbreOptions,\n ChordAnalysisResult,\n ChordDetectionOptions,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n MeterEstimate,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomMorphOptions,\n RoomMorphResult,\n} from './public_types';\nimport { Mode, PitchClass } from './public_types';\nimport type { ProgressCallback, WasmAcousticResult } from './sonare.js';\nimport type { ValidateOptions } from './validation';\nimport {\n assertFiniteScalar,\n assertNonNegativeInteger,\n assertSampleRate,\n assertSamples,\n} from './validation';\n\nfunction requireModule() {\n return getSonareModule();\n}\n\ntype GuardedOptions = ValidateOptions;\n\n/** Canonical request form for one-shot analysis functions. */\nexport interface SamplesRequest extends GuardedOptions {\n samples: Float32Array;\n sampleRate?: number;\n}\n\n/** Peak-picking configuration for {@link detectOnsets}. */\nexport interface OnsetDetectOptions {\n nFft?: number;\n hopLength?: number;\n threshold?: number;\n preMax?: number;\n postMax?: number;\n preAvg?: number;\n postAvg?: number;\n delta?: number;\n wait?: number;\n backtrack?: boolean;\n backtrackRange?: number;\n}\nexport interface DetectOnsetsRequest extends SamplesRequest, OnsetDetectOptions {}\n\n/** Canonical request form for key detection functions. */\nexport interface DetectKeyRequest extends KeyDetectionOptions, SamplesRequest {}\n\n/** Canonical request form for analysis with synchronous progress reporting. */\nexport interface AnalyzeWithProgressRequest extends SamplesRequest {\n onProgress?: ProgressCallback;\n cancel?: () => boolean;\n /** Analysis options, with the same fields and defaults {@link analyze} takes. */\n options?: MusicAnalyzeOptions;\n}\n\n/** Canonical request form for chord detection. */\nexport interface DetectChordsRequest extends ChordDetectionOptions, SamplesRequest {}\n\n/** Canonical request form for functional chord analysis. */\nexport interface ChordFunctionalAnalysisRequest extends DetectChordsRequest {\n keyRoot: PitchClass;\n /** Musical mode; defaults to {@link Mode.Major}. */\n keyMode?: Mode;\n}\n\n/** Canonical request form for impulse-response analysis. */\nexport interface AnalyzeImpulseResponseRequest extends SamplesRequest {\n nOctaveBands?: number;\n minDecayDb?: number;\n}\n\n/** Canonical request form for acoustic analysis. */\nexport interface DetectAcousticRequest extends AcousticOptions, SamplesRequest {}\n\n/** Canonical request form for equivalent-room estimation. */\nexport interface EstimateRoomRequest extends RoomEstimateOptions, SamplesRequest {}\n\n/** Canonical request form for room-reverb morphing. */\nexport interface RoomMorphRequest extends RoomMorphOptions, GuardedOptions {\n samples: Float32Array;\n sampleRate: number;\n}\n\n/** Canonical request forms for detailed music-analysis APIs. */\nexport interface AnalyzeBpmRequest extends AnalyzeBpmOptions, SamplesRequest {}\nexport interface AnalyzeRhythmRequest extends AnalyzeRhythmOptions, SamplesRequest {}\nexport interface AnalyzeDynamicsRequest extends AnalyzeDynamicsOptions, SamplesRequest {}\nexport interface AnalyzeTimbreRequest extends AnalyzeTimbreOptions, SamplesRequest {}\n\nfunction validateAnalysisInput(\n fnName: string,\n samples: Float32Array,\n sampleRate: number,\n options: GuardedOptions = {},\n): void {\n assertSampleRate(fnName, sampleRate);\n assertSamples(fnName, samples, options.validate !== false);\n}\n\n// ============================================================================\n// Quick API (High-level Analysis)\n// ============================================================================\n\n/**\n * Detect BPM from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected BPM\n */\nexport function detectBpm(request: SamplesRequest): number;\nexport function detectBpm(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions,\n): number;\nexport function detectBpm(\n samples: Float32Array | SamplesRequest,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): number {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectBpm', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectBpm(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Detect musical key from audio samples.\n *\n * The chroma is read at concert A440; a tuning offset is applied through\n * {@link analyze}'s `tuning` option (and to chords through {@link detectChords}).\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Detected key\n */\nexport function detectKey(request: DetectKeyRequest): Key;\nexport function detectKey(\n samples: Float32Array,\n sampleRate?: number,\n options?: KeyDetectionOptions,\n): Key;\nexport function detectKey(\n samples: Float32Array | DetectKeyRequest,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): Key {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectKey', request.samples, request.sampleRate ?? 22050, request);\n const result = requireModule()._detectKeyWithOptions(\n request.samples,\n request.sampleRate ?? 22050,\n request.nFft ?? 4096,\n request.hopLength ?? 512,\n request.useHpss ?? false,\n request.loudnessWeighted ?? false,\n request.highPassHz ?? 0,\n keyModeValues(request.modes),\n keyProfileValue(request.profile),\n request.genreHint ?? '',\n );\n return {\n root: result.root as PitchClass,\n mode: result.mode as Mode,\n confidence: result.confidence,\n name: result.name,\n shortName: result.shortName,\n };\n}\n\nexport function detectKeyCandidates(request: DetectKeyRequest): KeyCandidate[];\nexport function detectKeyCandidates(\n samples: Float32Array,\n sampleRate?: number,\n options?: KeyDetectionOptions,\n): KeyCandidate[];\nexport function detectKeyCandidates(\n samples: Float32Array | DetectKeyRequest,\n sampleRate = 22050,\n options: KeyDetectionOptions = {},\n): KeyCandidate[] {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput(\n 'detectKeyCandidates',\n request.samples,\n request.sampleRate ?? 22050,\n request,\n );\n // The embind value marshalling returns an array whose constructor is not this\n // realm's Array; chaining .map() onto it propagates that constructor via\n // Symbol.species, leaving a result that structuredClone (and so postMessage to\n // a Worker) rejects with \"could not be cloned\". Array.from() re-roots it as a\n // plain Array before mapping.\n const candidates = requireModule()._detectKeyCandidates(\n request.samples,\n request.sampleRate ?? 22050,\n request.nFft ?? 4096,\n request.hopLength ?? 512,\n request.useHpss ?? false,\n request.loudnessWeighted ?? false,\n request.highPassHz ?? 0,\n keyModeValues(request.modes),\n keyProfileValue(request.profile),\n request.genreHint ?? '',\n );\n return Array.from(candidates, convertKeyCandidate);\n}\n\n/**\n * Detect onset times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of onset times in seconds\n */\nexport function detectOnsets(request: DetectOnsetsRequest): Float32Array;\nexport function detectOnsets(\n samples: Float32Array,\n sampleRate?: number,\n options?: OnsetDetectOptions & GuardedOptions,\n): Float32Array;\nexport function detectOnsets(\n samples: Float32Array | DetectOnsetsRequest,\n sampleRate = 22050,\n options: OnsetDetectOptions & GuardedOptions = {},\n): Float32Array {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectOnsets', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectOnsets(request.samples, request.sampleRate ?? 22050, request);\n}\n\n/**\n * Detect beat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of beat times in seconds\n */\nexport function detectBeats(request: SamplesRequest): Float32Array;\nexport function detectBeats(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function detectBeats(\n samples: Float32Array | SamplesRequest,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): Float32Array {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectBeats', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectBeats(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Detect downbeat times from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Array of downbeat times in seconds\n */\nexport function detectDownbeats(request: SamplesRequest): Float32Array;\nexport function detectDownbeats(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions,\n): Float32Array;\nexport function detectDownbeats(\n samples: Float32Array | SamplesRequest,\n sampleRate = 22050,\n options: GuardedOptions = {},\n): Float32Array {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectDownbeats', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().detectDownbeats(request.samples, request.sampleRate ?? 22050);\n}\n\n/**\n * Detect chords from audio samples.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param options - Optional chord detection settings\n * @returns Detected chord segments\n */\nexport function detectChords(request: DetectChordsRequest): ChordAnalysisResult;\nexport function detectChords(\n samples: Float32Array,\n sampleRate?: number,\n options?: ChordDetectionOptions,\n): ChordAnalysisResult;\nexport function detectChords(\n samples: Float32Array | DetectChordsRequest,\n sampleRate = 22050,\n options: ChordDetectionOptions = {},\n): ChordAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectChords', request.samples, request.sampleRate ?? 22050, request);\n const result = requireModule().detectChords(\n request.samples,\n request.sampleRate ?? 22050,\n request.minDuration ?? 0.3,\n request.smoothingWindow ?? 2.0,\n request.threshold ?? 0.5,\n request.useTriadsOnly ?? false,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.useBeatSync ?? true,\n request.useHmm ?? false,\n request.hmmBeamWidth ?? 24,\n request.useKeyContext ?? false,\n request.keyRoot ?? PitchClass.C,\n request.keyMode ?? Mode.Major,\n request.detectInversions ?? false,\n chordChromaMethodValue(request.chromaMethod ?? 'stft'),\n request.tuning ?? 0,\n );\n return convertChordAnalysisResult(result);\n}\n\n/**\n * Functional (Roman-numeral) harmonic analysis of the detected chord\n * progression, relative to the given key. Mirrors the C-ABI\n * `sonare_chord_functional_analysis` and the Node/Python `chordFunctionalAnalysis`.\n *\n * @returns One Roman-numeral label (e.g. \"I\", \"IV\", \"V\", \"vi\") per detected chord\n */\nexport function chordFunctionalAnalysis(request: ChordFunctionalAnalysisRequest): string[];\nexport function chordFunctionalAnalysis(\n samples: Float32Array,\n keyRoot: PitchClass,\n keyMode?: Mode,\n sampleRate?: number,\n options?: ChordDetectionOptions,\n): string[];\nexport function chordFunctionalAnalysis(\n samples: Float32Array | ChordFunctionalAnalysisRequest,\n keyRoot?: PitchClass,\n keyMode?: Mode,\n sampleRate = 22050,\n options: ChordDetectionOptions = {},\n): string[] {\n const request =\n samples instanceof Float32Array\n ? { samples, keyRoot, keyMode, sampleRate, ...options }\n : samples;\n validateAnalysisInput(\n 'chordFunctionalAnalysis',\n request.samples,\n request.sampleRate ?? 22050,\n request,\n );\n return requireModule().chordFunctionalAnalysis(\n request.samples,\n request.keyRoot as PitchClass,\n request.keyMode ?? Mode.Major,\n request.sampleRate ?? 22050,\n request.minDuration ?? 0.3,\n request.smoothingWindow ?? 2.0,\n request.threshold ?? 0.5,\n request.useTriadsOnly ?? false,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.useBeatSync ?? true,\n request.useHmm ?? false,\n request.hmmBeamWidth ?? 24,\n request.useKeyContext ?? false,\n request.detectInversions ?? false,\n chordChromaMethodValue(request.chromaMethod ?? 'stft'),\n request.tuning ?? 0,\n );\n}\n\n/**\n * Options for {@link analyze}. Every field is optional and falls back to the\n * core default when omitted.\n */\nexport interface MusicAnalyzeOptions {\n nFft?: number;\n hopLength?: number;\n bpmMin?: number;\n bpmMax?: number;\n startBpm?: number;\n useTriadsOnly?: boolean;\n useHpss?: boolean;\n chromaHighpassHz?: number;\n useBassWeighted?: boolean;\n chromaHopMultiplier?: number;\n useChordHmm?: boolean;\n useChordKeyContext?: boolean;\n chordHmmBeamWidth?: number;\n detectChordInversions?: boolean;\n /**\n * Track a locally updated tempo prior during beat tracking (default: false).\n */\n adaptiveTempo?: boolean;\n /**\n * Length of the local tempo context in beats (default: 8). Must be positive.\n */\n tempoUpdateIntervalBeats?: number;\n /**\n * Decode a per-beat local tempo curve into\n * {@link AnalysisResult.beatLocalBpm} (default: false).\n *\n * @remarks\n * Off by default because it is an extra output rather than a better analysis:\n * nothing else in the result changes, and a caller that does not read the\n * curve would pay a decode over the beat grid for nothing.\n *\n * The curve describes the beat grid it was decoded from, and beat tracking\n * holds a fixed tempo prior unless {@link MusicAnalyzeOptions.adaptiveTempo}\n * is also set, so measuring a tempo that moves needs both.\n */\n computeTempoCurve?: boolean;\n /**\n * Meter numerators the estimator scores (default: `[3, 4, 6]`).\n *\n * @remarks\n * Adding a numerator widens the search; it does not force the result. The\n * list must hold between 1 and 16 entries, each in `[2, 32]`.\n */\n meterCandidateNumerators?: number[];\n /**\n * Beat unit reported for the detected meter (default: 4). Must be a power of\n * two in `[1, 32]`. The estimator still reports 8 on its own when it resolves\n * a compound meter, so this is the unit for everything else.\n */\n meterDenominator?: number;\n /**\n * Tuning offset of the recording in fractions of a semitone, the unit\n * `estimateTuning` returns; must be in `[-0.5, 0.5)`. Every chroma the\n * analysis builds (key, chords, sections) is shifted by it, so a recording\n * that is not at A440 reads its key and chords on its own pitch grid.\n * Default 0 (concert A440).\n */\n tuning?: number;\n}\nexport interface MusicAnalyzeRequest extends SamplesRequest, MusicAnalyzeOptions {}\n\n/**\n * Perform complete music analysis.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @returns Complete analysis result\n *\n * @remarks\n * This call is synchronous and blocks until analysis completes. Unlike the\n * Node binding (which offers `analyzeAsync` on a libuv worker thread), the\n * WASM build runs on a single thread, so there is no non-blocking variant —\n * the DSP pipeline always runs to completion on the calling thread. To keep\n * the UI responsive for long inputs, drive this from a Web Worker and use\n * {@link analyzeWithProgress} to report progress.\n */\nexport function analyze(request: MusicAnalyzeRequest): AnalysisResult;\nexport function analyze(\n samples: Float32Array,\n sampleRate?: number,\n options?: GuardedOptions & MusicAnalyzeOptions,\n): AnalysisResult;\nexport function analyze(\n samples: Float32Array | MusicAnalyzeRequest,\n sampleRate = 22050,\n options: GuardedOptions & MusicAnalyzeOptions = {},\n): AnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyze', request.samples, request.sampleRate ?? 22050, request);\n const result = requireModule().analyze(request.samples, request.sampleRate ?? 22050, request);\n return convertAnalysisResult(result);\n}\n\n/**\n * Canonical request form for {@link estimateMeter}.\n *\n * @remarks\n * Every scoring field is optional and falls back to the core default when\n * omitted; the core validates them and rejects a value it cannot answer rather\n * than substituting one.\n */\nexport interface EstimateMeterRequest {\n /** Beat positions in seconds, non-decreasing. */\n beatTimes: ArrayLike<number>;\n /**\n * Per-beat accent value, the same length as {@link beatTimes}.\n *\n * @remarks\n * `AnalysisResult.beatObservations.onsetStrength` is the intended source —\n * it is the windowed value the library's own downbeat pass scores.\n * `beats[].strength` also works but is a single unwindowed envelope frame.\n * Neither needs pre-scaling: the series is divided by its own maximum before\n * scoring, so only the accent contrast within it is read.\n *\n * A series assembled by hand from {@link onsetEnvelope} — one frame read at\n * each beat time — is neither of those, and it carries a sample-rate\n * dependence neither of them has: a hop counted in samples frames a different\n * amount of time at each rate, so one waveform sampled at 32000, 44100 and\n * 48000 Hz has produced three different winning numerators off beat times\n * identical to the sample. Widening the read to a window around the beat does\n * not remove it. A browser decodes at the output device's rate, so that is a\n * different answer per visitor for the same clip.\n */\n beatStrengths: ArrayLike<number>;\n /**\n * Meter numerators to score (default: `[3, 4, 6]`).\n *\n * @remarks\n * Adding a numerator widens the search; it does not force the result. The\n * list must hold between 1 and 16 entries, each in `[2, 32]`.\n */\n candidateNumerators?: number[];\n /**\n * Beat unit reported for the detected meter (default: 4). Must be a power of\n * two in `[1, 32]`.\n *\n * @remarks\n * Reported as requested: whether a beat divides into three is measured from\n * energy *between* the beats, which per-beat accents do not carry, so a\n * compound meter is not resolvable here. A six accented 3+3 comes back with\n * this denominator and `grouping === [3, 3]`.\n */\n denominator?: number;\n /** Weight of the downbeat accent term (default: 1). */\n downbeatWeight?: number;\n /** Weight of the measure-periodicity term (default: 0.5). */\n measureWeight?: number;\n /** Weight of the subdivision term (default: 0.15). */\n subdivisionWeight?: number;\n /**\n * Score ratio above which a compound meter is preferred (default: 0.85).\n *\n * @remarks\n * Only consulted when there is a subdivision to measure, so it has no effect\n * here — this entry point scores per-beat accents alone.\n */\n compoundSubdivisionThreshold?: number;\n}\n\n/**\n * Estimate meter over a caller-supplied beat series.\n *\n * @param request - Beat series plus optional scoring configuration\n * @returns The selected signature, its downbeat phase and grouping, and the\n * scored candidates\n *\n * @remarks\n * Scores only the per-beat strengths, so no audio and no frame-level onset\n * envelope is needed: an arbitrary span of an existing analysis can be scored\n * without re-running it. Pass `beatObservations.onsetStrength` rather than\n * `beats[].strength` — see {@link EstimateMeterRequest.beatStrengths}.\n *\n * The result carries `grouping` alongside the numerator: how the bar divides\n * into accent groups of two and three beats, so a seven comes back as `[3, 2,\n * 2]` or `[2, 2, 3]` rather than as a bare seven.\n *\n * Check `searched` before reading anything as a detection: a series too short\n * to score any candidate reports a fixed fallback instead, and `candidateScores`\n * grows with the square root of how many beats were scored, so scores from\n * spans of different lengths are not directly comparable.\n */\nexport function estimateMeter(request: EstimateMeterRequest): MeterEstimate {\n return requireModule().estimateMeter(request.beatTimes, request.beatStrengths, request);\n}\n\nexport function analyzeImpulseResponse(request: AnalyzeImpulseResponseRequest): AcousticResult;\nexport function analyzeImpulseResponse(\n samples: Float32Array,\n sampleRate?: number,\n nOctaveBands?: number,\n minDecayDb?: number,\n): AcousticResult;\nexport function analyzeImpulseResponse(\n samples: Float32Array | AnalyzeImpulseResponseRequest,\n sampleRate = 48000,\n nOctaveBands = 6,\n minDecayDb?: number,\n): AcousticResult {\n const request =\n samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands, minDecayDb } : samples;\n // Only `undefined` takes the default. `null` falls through to\n // assertFiniteScalar, which refuses it with the same wording as any other\n // non-finite value -- Number.isFinite(null) is false, so the case needs no\n // branch of its own, and the one that was here answered it with a different\n // error class than the check three lines down.\n const resolvedMinDecayDb = request.minDecayDb === undefined ? 30.0 : request.minDecayDb;\n assertFiniteScalar('analyzeImpulseResponse', resolvedMinDecayDb, 'minDecayDb');\n if (resolvedMinDecayDb <= 0) {\n throw new RangeError('analyzeImpulseResponse: minDecayDb must be greater than zero');\n }\n validateAnalysisInput(\n 'analyzeImpulseResponse',\n request.samples,\n request.sampleRate ?? 48000,\n request,\n );\n const result: WasmAcousticResult = requireModule().analyzeImpulseResponseEx(\n request.samples,\n request.sampleRate ?? 48000,\n request.nOctaveBands ?? 6,\n resolvedMinDecayDb,\n );\n return result;\n}\n\nexport function detectAcoustic(request: DetectAcousticRequest): AcousticResult;\nexport function detectAcoustic(\n samples: Float32Array,\n sampleRate?: number,\n options?: AcousticOptions,\n): AcousticResult;\nexport function detectAcoustic(\n samples: Float32Array | DetectAcousticRequest,\n sampleRate = 48000,\n options: AcousticOptions = {},\n): AcousticResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('detectAcoustic', request.samples, request.sampleRate ?? 48000, request);\n const result: WasmAcousticResult = requireModule().detectAcoustic(\n request.samples,\n request.sampleRate ?? 48000,\n request.nOctaveBands ?? 6,\n request.nThirdOctaveSubbands ?? 24,\n request.minDecayDb ?? 30.0,\n request.noiseFloorMarginDb ?? 10.0,\n );\n return result;\n}\n\n/**\n * Synthesize a room impulse response from shoebox geometry. `hasError` is true\n * when the source/listener falls outside the room (the RIR is then empty).\n */\nexport function synthesizeRir(options: RirSynthOptions = {}): RirResult {\n const module = requireModule();\n if (typeof module.synthesizeRir !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n return module.synthesizeRir(options);\n}\n\n/**\n * Estimate an equivalent room (volume/dimensions/absorption/DRR) from a\n * recording or impulse response.\n */\nexport function estimateRoom(request: EstimateRoomRequest): RoomEstimateResult;\nexport function estimateRoom(\n samples: Float32Array,\n sampleRate?: number,\n options?: RoomEstimateOptions,\n): RoomEstimateResult;\nexport function estimateRoom(\n samples: Float32Array | EstimateRoomRequest,\n sampleRate = 48000,\n options: RoomEstimateOptions = {},\n): RoomEstimateResult {\n const module = requireModule();\n if (typeof module.estimateRoom !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('estimateRoom', request.samples, request.sampleRate ?? 48000, request);\n return module.estimateRoom(request.samples, request.sampleRate ?? 48000, request);\n}\n\n/**\n * Morph a recording's reverberation toward a target room (creative FX, not\n * dereverberation).\n *\n * Returns the morphed samples in `audio` (input length plus the target room's\n * reverb tail) alongside the target-room synthesis's own `diagnostics`, which\n * report a room other than the one requested — see {@link RoomMorphResult}.\n */\nexport function roomMorph(request: RoomMorphRequest): RoomMorphResult;\nexport function roomMorph(\n samples: Float32Array,\n sampleRate: number,\n options?: RoomMorphOptions,\n): RoomMorphResult;\nexport function roomMorph(\n samples: Float32Array | RoomMorphRequest,\n sampleRate?: number,\n options: RoomMorphOptions = {},\n): RoomMorphResult {\n const module = requireModule();\n if (typeof module.roomMorph !== 'function') {\n throw new Error('libsonare was built without acoustic-simulation support');\n }\n const request =\n samples instanceof Float32Array\n ? { samples, sampleRate: sampleRate as number, ...options }\n : samples;\n validateAnalysisInput('roomMorph', request.samples, request.sampleRate, request);\n return module.roomMorph(request.samples, request.sampleRate, request);\n}\n\n/**\n * Perform complete music analysis with progress reporting.\n *\n * @param samples - Audio samples (mono, float32)\n * @param sampleRate - Sample rate in Hz (default: 22050)\n * @param onProgress - Progress callback (progress: 0-1, stage: string)\n * @returns Complete analysis result\n */\nexport function analyzeWithProgress(request: AnalyzeWithProgressRequest): AnalysisResult;\nexport function analyzeWithProgress(\n samples: Float32Array,\n sampleRate: number | undefined,\n onProgress: ProgressCallback,\n options?: MusicAnalyzeOptions,\n): AnalysisResult;\nexport function analyzeWithProgress(\n samples: Float32Array | AnalyzeWithProgressRequest,\n sampleRate = 22050,\n onProgress?: ProgressCallback,\n options?: MusicAnalyzeOptions,\n): AnalysisResult {\n const request: AnalyzeWithProgressRequest =\n samples instanceof Float32Array\n ? { samples, sampleRate, onProgress: onProgress as ProgressCallback, options }\n : samples;\n validateAnalysisInput(\n 'analyzeWithProgress',\n request.samples,\n request.sampleRate ?? 22050,\n request,\n );\n // The module reads options with the same reader analyze uses.\n const result = requireModule().analyzeWithProgress(\n request.samples,\n request.sampleRate ?? 22050,\n request.options ?? {},\n request.onProgress ?? (() => {}),\n request.cancel ?? (() => false),\n );\n return convertAnalysisResult(result);\n}\n\nexport interface BpmCandidate {\n bpm: number;\n confidence: number;\n}\n\nexport interface BpmAnalysisResult {\n bpm: number;\n confidence: number;\n candidates: BpmCandidate[];\n autocorrelation: Float32Array;\n tempogram: Float32Array;\n}\n\nexport interface RhythmAnalysisResult {\n timeSignature: { numerator: number; denominator: number; confidence: number };\n syncopation: number;\n grooveType: string;\n patternRegularity: number;\n tempoStability: number;\n /**\n * The beat tracker's own tempo, refined from the local beat period. It is a\n * third figure rather than either tempo entry point's: measured against\n * synthesized click trains it differs from both at every sample rate, and\n * lands closer to the known tempo than either. Analysed at the sample rate\n * you pass, so `nFft` and `hopLength` are in samples of your buffer.\n */\n bpm: number;\n beatIntervals: Float32Array;\n}\n\n/**\n * Dynamics metrics returned by {@link analyzeDynamics}.\n *\n * The Node package declares the same shape under the same name; the two are\n * pinned to one field list by `tests/conformance/shared_type_shapes.json`.\n */\nexport interface DynamicsResult {\n dynamicRangeDb: number;\n peakDb: number;\n rmsDb: number;\n crestFactor: number;\n loudnessRangeDb: number;\n isCompressed: boolean;\n /** Loudness curve timestamps (seconds), parallel to {@link loudnessRmsDb}. */\n loudnessTimes: Float32Array;\n /** Loudness curve RMS values (dB), parallel to {@link loudnessTimes}. */\n loudnessRmsDb: Float32Array;\n}\n\n/**\n * @deprecated Use {@link DynamicsResult}. Retained so code written against the\n * WASM-only spelling keeps compiling; the Node package exports the same alias.\n */\nexport type DynamicsAnalysisResult = DynamicsResult;\n\n/** Timbre metrics for one analysis window. Entries are ordered by time in `timbreOverTime`. */\nexport interface TimbreFrame {\n brightness: number;\n warmth: number;\n density: number;\n roughness: number;\n complexity: number;\n}\n\nexport interface TimbreAnalysisResult extends TimbreFrame {\n spectralCentroid: Float32Array;\n spectralFlatness: Float32Array;\n spectralRolloff: Float32Array;\n /** Time-varying timbre metrics, one entry per analysis window. */\n timbreOverTime: TimbreFrame[];\n}\n\n/**\n * Detailed BPM analysis (BPM, confidence, alternate candidates, autocorrelation,\n * tempogram). Matches the Node `analyzeBpm` / Python `analyze_bpm` surface.\n */\nexport function analyzeBpm(request: AnalyzeBpmRequest): BpmAnalysisResult;\nexport function analyzeBpm(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeBpmOptions,\n): BpmAnalysisResult;\nexport function analyzeBpm(\n samples: Float32Array | AnalyzeBpmRequest,\n sampleRate = 22050,\n options: AnalyzeBpmOptions = {},\n): BpmAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeBpm', request.samples, request.sampleRate ?? 22050, request);\n assertNonNegativeInteger('analyzeBpm', request.maxCandidates ?? 5, 'maxCandidates');\n return requireModule().analyzeBpm(\n request.samples,\n request.sampleRate ?? 22050,\n request.bpmMin ?? 30.0,\n request.bpmMax ?? 300.0,\n request.startBpm ?? 120.0,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.maxCandidates ?? 5,\n );\n}\n\n/**\n * Detailed rhythm analysis (time signature, groove, syncopation, beat intervals).\n */\nexport function analyzeRhythm(request: AnalyzeRhythmRequest): RhythmAnalysisResult;\nexport function analyzeRhythm(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeRhythmOptions,\n): RhythmAnalysisResult;\nexport function analyzeRhythm(\n samples: Float32Array | AnalyzeRhythmRequest,\n sampleRate = 22050,\n options: AnalyzeRhythmOptions = {},\n): RhythmAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeRhythm', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().analyzeRhythm(\n request.samples,\n request.sampleRate ?? 22050,\n request.bpmMin ?? 60.0,\n request.bpmMax ?? 200.0,\n request.startBpm ?? 120.0,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n );\n}\n\n/**\n * Dynamics analysis (RMS, peak, crest factor, LRA, loudness curve).\n */\nexport function analyzeDynamics(request: AnalyzeDynamicsRequest): DynamicsResult;\nexport function analyzeDynamics(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeDynamicsOptions,\n): DynamicsResult;\nexport function analyzeDynamics(\n samples: Float32Array | AnalyzeDynamicsRequest,\n sampleRate = 22050,\n options: AnalyzeDynamicsOptions = {},\n): DynamicsResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeDynamics', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().analyzeDynamics(\n request.samples,\n request.sampleRate ?? 22050,\n request.windowSec ?? 0.4,\n request.hopLength ?? 512,\n request.compressionThreshold ?? 6.0,\n );\n}\n\n/**\n * Timbre analysis (brightness/warmth/density/roughness/complexity plus spectral\n * features and per-window timbre frames).\n */\nexport function analyzeTimbre(request: AnalyzeTimbreRequest): TimbreAnalysisResult;\nexport function analyzeTimbre(\n samples: Float32Array,\n sampleRate?: number,\n options?: AnalyzeTimbreOptions,\n): TimbreAnalysisResult;\nexport function analyzeTimbre(\n samples: Float32Array | AnalyzeTimbreRequest,\n sampleRate = 22050,\n options: AnalyzeTimbreOptions = {},\n): TimbreAnalysisResult {\n const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;\n validateAnalysisInput('analyzeTimbre', request.samples, request.sampleRate ?? 22050, request);\n return requireModule().analyzeTimbre(\n request.samples,\n request.sampleRate ?? 22050,\n request.nFft ?? 2048,\n request.hopLength ?? 512,\n request.nMels ?? 128,\n request.nMfcc ?? 13,\n request.windowSec ?? 0.5,\n );\n}\n\n/**\n * Whether this WASM build was compiled with FFmpeg support. Mirrors Node /\n * Python `hasFfmpegSupport`. In the published WASM binding this currently\n * always returns `false` (FFmpeg is not bundled into the .wasm), but the API\n * exists so caller code can branch on capabilities portably.\n */\nexport function hasFfmpegSupport(): boolean {\n return requireModule().hasFfmpegSupport();\n}\n","/**\n * Analysis and feature-extraction entry point for the smaller WASM binary.\n *\n * This entry intentionally omits mastering, mixing, realtime engines, Project,\n * and other native-handle APIs. Import the package root when those surfaces are\n * required.\n */\n\nimport { setSonareModule } from './module_state';\nimport type { SonareCapabilities } from './public_types';\nimport type { SonareModule } from './sonare.js';\n\nexport { ErrorCode, isSonareError, SonareError } from './errors';\nexport * from './feature_core';\n// Several modules here also hold functions the analysis-only embind source set\n// never registers, so those are re-exported by name rather than wholesale:\n// `export *` published symbols that imported fine and then threw\n// \"is not a function\" at call time, on a binary that never had them. Types stay\n// wholesale — a type cannot fail to resolve. `analysis-entry.test.ts` guards\n// these lists in one direction: every function the entry exports must be\n// registered by the module it loads, so a name the analysis binary lacks fails\n// as a test rather than at a caller's first call. The other direction is not\n// guarded and a strict form of it would be wrong — the module also registers\n// enums, emscripten internals and raw `_` / `Ex` variants this entry withholds\n// deliberately — so a name dropped from a list below shrinks the published\n// surface silently.\nexport type * from './feature_decompose';\nexport {\n segmentAgglomerative,\n segmentCrossSimilarity,\n segmentLagToRecurrence,\n segmentPathEnhance,\n segmentRecurrenceMatrix,\n segmentRecurrenceToLag,\n segmentSubsegment,\n} from './feature_decompose';\nexport type * from './feature_inverse';\nexport { griffinLim, melToAudio, melToStft, mfccToAudio, mfccToMel } from './feature_inverse';\nexport type * from './feature_loudness';\nexport { ebur128LoudnessRange, lufsInterleaved, lufsSeriesInterleaved } from './feature_loudness';\nexport * from './feature_music';\nexport * from './feature_pitch';\nexport type * from './feature_resample';\nexport type * from './feature_spectral';\nexport {\n polyFeatures,\n rmsEnergy,\n spectralBandwidth,\n spectralCentroid,\n spectralContrast,\n spectralFlatness,\n spectralFlux,\n spectralRolloff,\n zeroCrossingRate,\n zeroCrossings,\n} from './feature_spectral';\nexport type * from './feature_spectrogram';\nexport {\n bassChroma,\n chroma,\n chromaCens,\n chromaCqt,\n melDelta,\n melSpectrogram,\n mfcc,\n reassignedSpectrogram,\n stft,\n stftDb,\n} from './feature_spectrogram';\nexport * from './metering';\nexport * from './public_types';\nexport type {\n AnalyzeBpmRequest,\n AnalyzeDynamicsRequest,\n AnalyzeImpulseResponseRequest,\n AnalyzeRhythmRequest,\n AnalyzeTimbreRequest,\n AnalyzeWithProgressRequest,\n BpmAnalysisResult,\n BpmCandidate,\n ChordFunctionalAnalysisRequest,\n DetectAcousticRequest,\n DetectChordsRequest,\n DetectKeyRequest,\n DynamicsAnalysisResult,\n DynamicsResult,\n EstimateMeterRequest,\n MusicAnalyzeOptions,\n MusicAnalyzeRequest,\n RhythmAnalysisResult,\n SamplesRequest,\n TimbreAnalysisResult,\n TimbreFrame,\n} from './quick_analysis';\nexport {\n analyze,\n analyzeBpm,\n analyzeDynamics,\n analyzeImpulseResponse,\n analyzeRhythm,\n analyzeTimbre,\n analyzeWithProgress,\n chordFunctionalAnalysis,\n detectAcoustic,\n detectBeats,\n detectBpm,\n detectChords,\n detectDownbeats,\n detectKey,\n detectKeyCandidates,\n detectOnsets,\n estimateMeter,\n hasFfmpegSupport,\n} from './quick_analysis';\n\nlet module: SonareModule | null = null;\nlet initPromise: Promise<void> | null = null;\n\n/** Initialize the analysis-only WASM module. */\nexport async function init(options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n moduleFactory?: (options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n }) => Promise<SonareModule>;\n}): Promise<void> {\n if (module) {\n return;\n }\n if (initPromise) {\n return initPromise;\n }\n initPromise = (async () => {\n try {\n const createModule = options?.moduleFactory ?? (await import('./sonare-analysis.js')).default;\n module = await createModule(options);\n setSonareModule(module);\n } catch (error) {\n initPromise = null;\n throw error;\n }\n })();\n return initPromise;\n}\n\n/** Whether this analysis entry has loaded its WASM module. */\nexport function isInitialized(): boolean {\n return module !== null;\n}\n\n/** Version reported by the loaded analysis WASM module. */\nexport function version(): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.version();\n}\n\n/** Build capabilities for the loaded analysis-only module. */\nexport function capabilities(): SonareCapabilities {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.capabilities();\n}\n\n/** Packed C-ABI version for compatibility checks. */\nexport function abiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.abiVersion();\n}\n\n/** Realtime command-queue ABI version shared with the full entry. */\nexport function engineAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.engineAbiVersion();\n}\n\n/** Voice-changer ABI version retained for cross-entry compatibility checks. */\nexport function voiceChangerAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceChangerAbiVersion();\n}\n"],"mappings":"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","names":["ErrorCode","module","onsetEnvelope","requireModule","requireModule","requireModule","requireModule","requireModule","onsetEnvelope","requireModule","requireModule","requireModule","requireModule","requireModule","requireModule","requireModule"]}