@libraz/libsonare 1.7.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +6 -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 +873 -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 +477 -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 +129 -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 +3758 -1362
  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 +457 -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 +652 -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 +510 -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 +164 -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 +850 -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 +3909 -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 +335 -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 +128 -0
  179. package/dist/worklet/engine-mixer-facade.d.ts.map +1 -0
  180. package/dist/worklet/engine-node.d.ts +81 -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 +68 -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 +73 -0
  193. package/dist/worklet/engine-strips.d.ts.map +1 -0
  194. package/dist/worklet/engine-sync.d.ts +37 -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 +397 -0
  199. package/dist/worklet/engine.d.ts.map +1 -0
  200. package/dist/worklet/guards.d.ts +47 -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 +323 -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 +2763 -501
  215. package/dist/worklet.js.map +1 -1
  216. package/package.json +23 -12
  217. package/src/_effects_common.ts +17 -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 +97 -22
  226. package/src/effects_note_ops.ts +635 -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 +377 -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 +282 -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 +346 -32
  246. package/src/mastering_dynamics.ts +22 -11
  247. package/src/metering.ts +67 -24
  248. package/src/mixer.ts +212 -3
  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 +268 -270
  259. package/src/public_types.ts +122 -3
  260. package/src/public_types_acoustic.ts +112 -3
  261. package/src/public_types_mastering.ts +254 -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 +195 -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 +487 -1
  268. package/src/quick_analysis.ts +203 -26
  269. package/src/realtime_engine.ts +711 -28
  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 +1122 -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 +194 -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 +444 -10
  287. package/src/worklet/engine-node.ts +78 -26
  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 +272 -83
  291. package/src/worklet/engine-register.ts +32 -18
  292. package/src/worklet/engine-strips.ts +280 -9
  293. package/src/worklet/engine-sync.ts +14 -6
  294. package/src/worklet/engine.ts +365 -31
  295. package/src/worklet/guards.ts +140 -44
  296. package/src/worklet/messages.ts +227 -2
  297. package/src/worklet/mixer-processor.ts +109 -47
  298. package/src/worklet/playback-processor.ts +300 -0
  299. package/src/worklet/protocol.ts +53 -3
  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
@@ -58,6 +58,464 @@ export interface NoteMoveOptions {
58
58
  targetOnsetSample?: number;
59
59
  }
60
60
 
61
+ /** Segmentation tuning for `extractNotes`. All fields are optional; 0 or absent takes the default. */
62
+ export interface NoteExtractorOptions {
63
+ /** Cents of pitch change that start a new note. Default 50. */
64
+ segmentationThresholdCents?: number;
65
+ /** Shortest span kept as a note, in ms. Default 30. */
66
+ minNoteMs?: number;
67
+ /** Reference pitch the `medianCents` of each note is measured against. Default 440. */
68
+ referenceHz?: number;
69
+ /**
70
+ * Value of `voicedProb` at or above which a frame counts as voiced, in
71
+ * `[0, 1]`. Read only when `voiced` is omitted. Default 0.5.
72
+ *
73
+ * pYIN's `voicedProb` is a frame's voiced observation mass and rises with F0
74
+ * for a fixed frame length, so this default silently drops low registers —
75
+ * pass `pitchPyin`'s `voicedFlag` through `voiced` instead.
76
+ */
77
+ voicedThreshold?: number;
78
+ }
79
+
80
+ /**
81
+ * A pending, non-destructive change to one note. `extractNotes` attaches the
82
+ * identity edit (no move, no transpose, unity gain and stretch, unmuted) to
83
+ * every note it returns; `renderNotes` applies whatever the caller has changed.
84
+ */
85
+ export interface NoteEdit {
86
+ /**
87
+ * Moves the note along the timeline; negative moves it earlier. Where the note
88
+ * lands is not bounds-checked, so a moved note may overwrite a neighbour.
89
+ */
90
+ timeOffsetSamples: number;
91
+ /** Transpose applied to the note's span. */
92
+ pitchShiftSemitones: number;
93
+ /** Level change applied to the note's span. */
94
+ gainDb: number;
95
+ /** `>1` lengthens the note, `<1` shortens it; pitch is preserved. 0 reads as 1. */
96
+ timeStretchRatio: number;
97
+ /**
98
+ * Moves the spectral envelope, in semitones, on top of whatever the pitch
99
+ * shift already did to it.
100
+ *
101
+ * 0 runs no warp at all, so a pitch-only edit is not charged for an LPC
102
+ * analysis-resynthesis round it did not ask for. A pitch shift drags the
103
+ * formants with it, so holding them still is `-pitchShiftSemitones` and the
104
+ * chipmunk is the default. Saturates near -10.3 and +8.7 semitones rather
105
+ * than being rejected.
106
+ */
107
+ formantShiftSemitones: number;
108
+ /**
109
+ * Scales the vibrato measured over the note, stated as a change from it: 0
110
+ * keeps it, -1 flattens it, +1 doubles it.
111
+ *
112
+ * Applying it needs the note's own pitch curve, so `renderNotes` must be given
113
+ * the `f0Hz` track and the note its `frameStart` / `frameEnd` / `medianHz`; a
114
+ * note carrying no usable pitch is rejected rather than left alone. The curve
115
+ * is split at the request's `vibratoCutoffHz`.
116
+ */
117
+ vibratoDepthChange: number;
118
+ /** The same, for the slow drift around the note's centre pitch. */
119
+ driftChange: number;
120
+ /** Silences the note's span; the other fields then do not apply. */
121
+ muted: boolean;
122
+ /**
123
+ * Per-frame linear gain over the note's span, on top of `gainDb`.
124
+ *
125
+ * A set of gain points rather than a signal: it is stretched over whatever
126
+ * length the note renders at, so it survives a time stretch and need not match
127
+ * the note's frame count. One entry is a constant gain, and an empty array is
128
+ * no envelope. Every value must be finite and non-negative.
129
+ */
130
+ amplitudeEnvelope: Float32Array;
131
+ }
132
+
133
+ /**
134
+ * A {@link NoteEdit} as supplied to `renderNotes`, `splitNote` or `mergeNotes`.
135
+ * Every field is optional and an omitted one is the identity, so `{}` leaves the
136
+ * note untouched.
137
+ *
138
+ * `amplitudeEnvelope` is the one field that widens on the way in: a host
139
+ * building an envelope in JS naturally ends up with a plain array, and the
140
+ * points are copied into WASM memory either way. What comes back on a
141
+ * {@link NoteEdit} is always a `Float32Array`.
142
+ */
143
+ export type NoteEditInput = Omit<Partial<NoteEdit>, 'amplitudeEnvelope'> & {
144
+ amplitudeEnvelope?: Float32Array | readonly number[];
145
+ };
146
+
147
+ /**
148
+ * One editable note, returned by `extractNotes` and by
149
+ * `PolyphonicAnalysis.notes()`.
150
+ *
151
+ * Sample bounds are half-open into the source audio. Frame bounds are half-open
152
+ * into whichever framing found the note: the caller's own `f0Hz` track through
153
+ * `extractNotes`, and the analysis's own STFT framing through a
154
+ * `PolyphonicAnalysis`, whose `f0Hz` curve therefore comes from `noteF0(note)`
155
+ * rather than from an array the caller holds.
156
+ *
157
+ * The per-note F0 curve is deliberately not repeated here — through the by-value
158
+ * door it is `f0Hz.subarray(frameStart, frameEnd)`, and through a handle it has its
159
+ * own accessor.
160
+ *
161
+ * `onsetSample` and `offsetSample` are 64-bit on the core side and arrive as JS
162
+ * numbers, which are exact up to `Number.MAX_SAFE_INTEGER`.
163
+ */
164
+ export interface NoteObject {
165
+ /** First sample of the note's span. */
166
+ onsetSample: number;
167
+ /** One past the last sample of the span. */
168
+ offsetSample: number;
169
+ /** First frame of the span, in the framing that found the note. */
170
+ frameStart: number;
171
+ /** One past the last frame of the span. */
172
+ frameEnd: number;
173
+ /** Median measured pitch over the span, in Hz. */
174
+ medianHz: number;
175
+ /** Median pitch in cents above the request's `referenceHz`. */
176
+ medianCents: number;
177
+ /** Pitch steadiness in `[0, 1]`; 1 is perfectly steady. */
178
+ f0Stability: number;
179
+ /** One RMS value per frame of the span (`frameEnd - frameStart` entries). */
180
+ amplitude: Float32Array;
181
+ /** This note's pending edit; the identity as returned. */
182
+ edit: NoteEdit;
183
+ }
184
+
185
+ /**
186
+ * A note handed to `renderNotes`. Only the span, the edit and — for a
187
+ * `vibratoDepthChange` or `driftChange` edit — the frame bounds and the centre
188
+ * are read, so a {@link NoteObject} straight from `extractNotes` can be passed
189
+ * back with its `edit` changed and nothing else.
190
+ */
191
+ export interface NoteObjectInput {
192
+ /** First sample of the note's span. */
193
+ onsetSample: number;
194
+ /** One past the last sample of the span. */
195
+ offsetSample: number;
196
+ /**
197
+ * First frame of the span in the request's `f0Hz` track. Read only when a
198
+ * track is given; a curve edit acts on `f0Hz.subarray(frameStart, frameEnd)`.
199
+ */
200
+ frameStart?: number;
201
+ /** One past the last frame of the span, under the same rule. */
202
+ frameEnd?: number;
203
+ /** The note's centre pitch in Hz, which a curve edit measures its cents against. */
204
+ medianHz?: number;
205
+ /** Omit for the identity edit. */
206
+ edit?: NoteEditInput;
207
+ }
208
+
209
+ /**
210
+ * A note handed to `splitNote` or `mergeNotes`. Both re-derive every note in the
211
+ * set from the audio and the track, so only the frame bounds and the edit are
212
+ * read — and the frame bounds are therefore what a note is identified by.
213
+ */
214
+ export interface NoteSetEntry {
215
+ /** First frame of the span in the request's `f0Hz` track. */
216
+ frameStart: number;
217
+ /** One past the last frame of the span. */
218
+ frameEnd: number;
219
+ /** Omit for the identity edit. */
220
+ edit?: NoteEditInput;
221
+ }
222
+
223
+ /**
224
+ * One note of a reference melody, as `noteTargetsFromSmf` returns it and
225
+ * `assignNoteTargets` reads it.
226
+ *
227
+ * Times are seconds from the start of the audio the notes being corrected were
228
+ * extracted from — a reference is lined up against a take by its own clock, not
229
+ * by a frame index into either one. Every field must be finite.
230
+ */
231
+ export interface NoteTarget {
232
+ /** First second of the target's span. */
233
+ startSec: number;
234
+ /** One past the last second of the span. */
235
+ endSec: number;
236
+ /** The pitch that stretch of the part is supposed to be, as a MIDI number. */
237
+ targetMidi: number;
238
+ }
239
+
240
+ /**
241
+ * What `assignNoteTargets` does with a note that has a measurable pitch and no
242
+ * target.
243
+ *
244
+ * A note carrying no pitch at all is a different case and no policy reaches it:
245
+ * there is nothing to correct from, so it is never assigned and never edited.
246
+ */
247
+ export type NoteTargetUnmatchedPolicy =
248
+ /** Leave the edit alone; the note renders as recorded. Default. */
249
+ | 'leave'
250
+ /** Mute the note's span. */
251
+ | 'mute'
252
+ /** Take the nearest target in time, however far away it is. */
253
+ | 'nearest';
254
+
255
+ /** What `assignNoteTargets` returns. */
256
+ export interface NoteTargetAssignResult {
257
+ /**
258
+ * The note set with each assigned note's `edit.pitchShiftSemitones` — and,
259
+ * under `'mute'`, its `edit.muted` — rewritten. A new array: the notes handed
260
+ * in are not touched, and every other field of a note comes back as it went.
261
+ */
262
+ notes: NoteObject[];
263
+ /**
264
+ * How many notes received a target. Zero is a legitimate answer — a reference
265
+ * that does not line up with the take — which is why it is reported rather
266
+ * than left for the caller to infer from the edits.
267
+ */
268
+ assignedCount: number;
269
+ }
270
+
271
+ /**
272
+ * One note's pitch curve split into a centre, a slow drift and a vibrato by
273
+ * `decomposeNotePitch`.
274
+ *
275
+ * `driftCents[i] + vibratoCents[i]` is the note's own pitch at frame `i`, in
276
+ * cents above `centreHz`, to within float rounding, so the three parts
277
+ * reconstruct the curve. The drift filter is zero phase, so neither curve is
278
+ * shifted in time against the audio.
279
+ */
280
+ export interface PitchDecompositionResult {
281
+ /**
282
+ * The note's steady pitch in Hz. 0 when the note carries no usable pitch, and
283
+ * then both curves are empty.
284
+ */
285
+ centreHz: number;
286
+ /** Slow deviation from `centreHz` in cents, one entry per frame. */
287
+ driftCents: Float32Array;
288
+ /** Fast deviation in cents, over the same frames. */
289
+ vibratoCents: Float32Array;
290
+ }
291
+
292
+ /**
293
+ * Tuning for `analyzePolyphonic`. Every field is optional and 0 or absent takes
294
+ * the documented default.
295
+ *
296
+ * Four fields accept 0 as a value as well as reading it as their default, and are
297
+ * marked below: **pass a negative number to select 0 on those**. Each rejects a
298
+ * negative otherwise, so the two meanings cannot collide.
299
+ *
300
+ * The window function and the centred framing are not settable. Every span, claim
301
+ * and mask offset in this chain is derived against one framing, so a second way to
302
+ * state it would be a second thing to keep in agreement.
303
+ */
304
+ export interface PolyphonicAnalysisOptions {
305
+ /** STFT size the whole chain runs in. Default 4096, the size it is tuned at. */
306
+ nFft?: number;
307
+ /** STFT hop in samples. Default 512. */
308
+ hopLength?: number;
309
+ /** Window length in samples. Defaults to `nFft`. */
310
+ winLength?: number;
311
+ /** Bottom of the cent axis the salience is folded onto, in Hz. Default 55. */
312
+ centRefHz?: number;
313
+ /** Cent-axis resolution. Default 100/3; finer than 1 cent is rejected. */
314
+ centsPerBin?: number;
315
+ /** Top of the cent axis, in Hz. Default 8000. */
316
+ centMaxHz?: number;
317
+ /** Stops weighting bins by tonality, which is on. Default `false`. */
318
+ tonalityOff?: boolean;
319
+ /** Partials summed per F0 candidate. Default 20, at most 128. */
320
+ salienceHarmonics?: number;
321
+ /** Lowest F0 a candidate may take, in Hz. Default 55. */
322
+ f0MinHz?: number;
323
+ /** Highest F0 a candidate may take, in Hz. Default 1760. */
324
+ f0MaxHz?: number;
325
+ /** Harmonic weighting offset, in Hz. Default 27. */
326
+ salienceAlphaHz?: number;
327
+ /** Harmonic weighting scale, in Hz. Default 320. */
328
+ salienceBetaHz?: number;
329
+ /**
330
+ * Partial-series stretch assumed while scoring a candidate, `B` in
331
+ * `f_h = h*f0*sqrt(1 + B*h^2)`. 0 is the default and also a stretch of zero, so
332
+ * it needs no sentinel.
333
+ */
334
+ salienceInharmonicity?: number;
335
+ /** Voices one frame may hold. Default 4, at most 64. */
336
+ maxPolyphony?: number;
337
+ /**
338
+ * Stops the per-frame iteration below this share of the frame's first peak.
339
+ * Default 0.20; **negative selects 0**.
340
+ */
341
+ minFramePeakRatio?: number;
342
+ /** Closest two candidates of one frame may sit. Default 50; **negative selects 0**. */
343
+ minSeparationCents?: number;
344
+ /** Share of a found voice removed before the next iteration. Default 1. */
345
+ subtractionFactor?: number;
346
+ /** A larger move between two frames breaks the ridge. Default 50 cents. */
347
+ maxJumpCents?: number;
348
+ /**
349
+ * A fade below this share of the ridge's own running peak breaks it. Default
350
+ * 0.10; **negative selects 0**.
351
+ */
352
+ minRidgePeakRatio?: number;
353
+ /** Shorter ridges are dropped. Default 140 ms; **negative selects 0**. */
354
+ minRidgeDurationMs?: number;
355
+ /** Partials claimed per note. Default 20, at most 128. */
356
+ maskHarmonics?: number;
357
+ /** Claim half-width in Hann main lobes. Default 1. */
358
+ claimLobes?: number;
359
+ /**
360
+ * Stretch of the claimed partial series, `B` in `f_h = h*f0*sqrt(1 + B*h^2)`.
361
+ * Default 0, which is also a value.
362
+ *
363
+ * Leaving it at 0 for stretched material costs more than a widened claim would:
364
+ * at a piano's `1e-4` the highest partial of a twenty-harmonic claim sits
365
+ * outside the claim entirely, and a partial outside every claim is residual —
366
+ * carried unedited, so it keeps sounding at the old pitch after its note moves.
367
+ */
368
+ inharmonicity?: number;
369
+ /**
370
+ * Fits a stretch per note from the spectrum instead of spending
371
+ * {@link PolyphonicAnalysisOptions.inharmonicity} on every one of them. Default
372
+ * `false`.
373
+ *
374
+ * Off by default because of what it reaches rather than what it costs: at the
375
+ * default framing the fit takes an isolated note in the middle register and
376
+ * refuses a chord. A refused note keeps the declared stretch, so the fit only
377
+ * ever replaces a guess with a measurement —
378
+ * `PolyphonicAnalysis.noteInharmonicity()` reports which notes it reached.
379
+ */
380
+ estimateInharmonicity?: boolean;
381
+ /** Usable partials one fit needs before its result is believed. Default 3. */
382
+ inharmonicityMinPartials?: number;
383
+ /** Largest per-partial misfit a fit may leave, in STFT bins. Default 0.5. */
384
+ inharmonicityMaxResidualBins?: number;
385
+ /** A fitted stretch above this is refused. Default 0.03125. */
386
+ inharmonicityMaxStretch?: number;
387
+ /** Frames per apportionment fit. Default 8, between 4 and 64. */
388
+ windowFrames?: number;
389
+ /** Radians per frame two claimed partials must differ by to be fitted. Default 0.01. */
390
+ minPartialSeparation?: number;
391
+ /** Relative misfit ceiling above which the fit refuses the bin. Default 0.02. */
392
+ maxFitResidual?: number;
393
+ /**
394
+ * Ceiling on one weight's modulus. A weight is a fitted component over the
395
+ * observed bin, so where two partials nearly cancel it exceeds one and the
396
+ * residual carries several times the input there. While every edit is identity
397
+ * that is inaudible — the notes and the residual still sum to the input.
398
+ * Lowering it trades separation for a quieter residual. Default 8.
399
+ */
400
+ maxWeightModulus?: number;
401
+ /** Highest partial usable to refine an F0, in Hz. Default 0, which derives one. */
402
+ maxRefineHz?: number;
403
+ /** Worst F0 error tolerated by the fit, in cents. Default 50. */
404
+ f0ToleranceCents?: number;
405
+ /**
406
+ * Scales each note's reported `f0Stability` only. Every tracked ridge is one
407
+ * note, so a mid-ridge pitch jump is never split into two. Default 50.
408
+ */
409
+ segmentationThresholdCents?: number;
410
+ /**
411
+ * Not read: every tracked ridge is one note, so nothing filters a short note
412
+ * here. Use `minRidgeDurationMs` to drop short ridges instead. Default 30.
413
+ */
414
+ minNoteMs?: number;
415
+ /** Reference pitch each note's `medianCents` is measured against. Default 440. */
416
+ referenceHz?: number;
417
+ }
418
+
419
+ /** Options for `PolyphonicAnalysis.render`. All fields are optional. */
420
+ export interface PolyphonicRenderOptions {
421
+ /**
422
+ * Equal-power cross-fade at each edited note's edges. Default 5 ms; a hard cut
423
+ * is deliberately not selectable, because the seam it leaves is a click.
424
+ */
425
+ fadeMs?: number;
426
+ /**
427
+ * Boundary between the drift and the vibrato that `vibratoDepthChange` and
428
+ * `driftChange` act on, in Hz. Default 3 Hz, and it has to be whatever a curve
429
+ * edit was drawn at.
430
+ */
431
+ vibratoCutoffHz?: number;
432
+ }
433
+
434
+ /**
435
+ * A pending, non-destructive change to one percussive event.
436
+ * `extractPercussiveEvents` attaches the identity edit (no move, unity gain,
437
+ * unmuted) to every event it returns; `renderPercussiveEvents` applies whatever
438
+ * the caller has changed.
439
+ *
440
+ * A struck sound has no steady pitch to edit, so the axes are time and amplitude
441
+ * and there is deliberately nothing else here.
442
+ */
443
+ export interface PercussiveEventEdit {
444
+ /**
445
+ * Moves the hit along the timeline; negative moves it earlier. Where the hit
446
+ * lands is not bounds-checked, so a moved event may be written over a
447
+ * neighbour, and a shift past either end is truncated there.
448
+ */
449
+ timeOffsetSamples: number;
450
+ /** Level change applied to the hit, which is the span's percussive component. */
451
+ gainDb: number;
452
+ /** Silences the hit; the other fields then do not apply. */
453
+ muted: boolean;
454
+ }
455
+
456
+ /**
457
+ * A {@link PercussiveEventEdit} as supplied to `renderPercussiveEvents`. Every
458
+ * field is optional and an omitted one is the identity, so `{}` leaves the event
459
+ * untouched.
460
+ */
461
+ export type PercussiveEventEditInput = Partial<PercussiveEventEdit>;
462
+
463
+ /**
464
+ * One editable percussive event returned by `extractPercussiveEvents`.
465
+ *
466
+ * A struck sound located in time: a span in source samples, three measured
467
+ * figures, and a pending edit. It carries no pitch and is never associated with
468
+ * a {@link NoteObject} — the two models are produced by separate calls and do
469
+ * not refer to each other.
470
+ *
471
+ * `onsetSample` and `offsetSample` are 64-bit on the core side and arrive as JS
472
+ * numbers, which are exact up to `Number.MAX_SAFE_INTEGER`.
473
+ */
474
+ export interface PercussiveEvent {
475
+ /** First sample of the span, backtracked to in front of the transient. */
476
+ onsetSample: number;
477
+ /** One past the last sample of the span; the next onset, or the cap. */
478
+ offsetSample: number;
479
+ /**
480
+ * Detector strength at the onset, on the onset envelope's own scale. It orders
481
+ * events against each other and carries no absolute meaning.
482
+ */
483
+ strength: number;
484
+ /**
485
+ * Peak absolute sample of the percussive component over the span, linear.
486
+ * Measured on the signal `gainDb` scales rather than on the source.
487
+ */
488
+ peakAmplitude: number;
489
+ /**
490
+ * Share of the span's energy the separation assigned to percussion, in
491
+ * `[0, 1]`; 0 when the span is silent.
492
+ *
493
+ * It describes the span rather than the onset that opened it. An isolated hit
494
+ * sits near 1, but a real hit over a loud sustain sits near 0, because the
495
+ * sustain owns the span's energy. So it separates a hit from a note attack
496
+ * only where nothing is sustaining through both, and it is not a test for
497
+ * whether a hit is there.
498
+ */
499
+ percussiveRatio: number;
500
+ /** This event's pending edit; the identity as returned. */
501
+ edit: PercussiveEventEdit;
502
+ }
503
+
504
+ /**
505
+ * An event handed to `renderPercussiveEvents`. Only the span and the edit are
506
+ * read — the three measured figures are ignored — so a {@link PercussiveEvent}
507
+ * straight from `extractPercussiveEvents` can be passed back with its `edit`
508
+ * changed and nothing else.
509
+ */
510
+ export interface PercussiveEventInput {
511
+ /** First sample of the span. */
512
+ onsetSample: number;
513
+ /** One past the last sample of the span. */
514
+ offsetSample: number;
515
+ /** Omit for the identity edit. */
516
+ edit?: PercussiveEventEditInput;
517
+ }
518
+
61
519
  /** How a `spectralEdit` region op modifies the masked bins. */
62
520
  export type SpectralEditMode = 'gain' | 'attenuate' | 'mute' | 'heal';
63
521
 
@@ -82,7 +540,7 @@ export interface SpectralRegionOp {
82
540
 
83
541
  /** STFT + heal parameters for `spectralEdit`. All fields are optional. */
84
542
  export interface SpectralEditOptions {
85
- /** FFT size; must be a power of two (>= 2). Default 2048. */
543
+ /** FFT size; a power of two in `[2, 262144]`. Default 2048. */
86
544
  nFft?: number;
87
545
  /** Hop length; must satisfy 0 < hop <= nFft/2. Default 512. */
88
546
  hopLength?: number;
@@ -189,7 +647,24 @@ export interface ChromaResult {
189
647
  */
190
648
  export interface PitchResult {
191
649
  f0: Float32Array;
650
+ /**
651
+ * pYIN's per-frame voiced **observation mass**, exactly as librosa returns
652
+ * it: the summed probability of the frame's voiced pitch hypotheses.
653
+ *
654
+ * This is NOT a signal-quality confidence and NOT a correction weight. The
655
+ * mass depends on how many periods of the pitch fit inside `frameLength`,
656
+ * because the CMNDF troughs of a long period measured over a short frame are
657
+ * shallower. For a fixed `frameLength` it therefore rises with F0 even when
658
+ * the signal is unchanged: a steady three-harmonic tone at 2048 samples /
659
+ * 48 kHz averages well under 0.1 at C2 and about 0.5 at C5, with every frame
660
+ * flagged voiced throughout.
661
+ *
662
+ * Use {@link voicedFlag} for any voicing decision. In particular, thresholding
663
+ * this value at a fixed 0.5 (`noteSegments`' default) drops entire low
664
+ * registers.
665
+ */
192
666
  voicedProb: Float32Array;
667
+ /** Per-frame voicing decision from the Viterbi path — the voicing oracle. */
193
668
  voicedFlag: boolean[];
194
669
  nFrames: number;
195
670
  medianF0: number;
@@ -245,6 +720,17 @@ export interface LufsResult {
245
720
  loudnessRange: number;
246
721
  }
247
722
 
723
+ /**
724
+ * The two per-block loudness series a multi-channel measurement builds, in
725
+ * LUFS. A signal shorter than a window yields an empty series for it.
726
+ */
727
+ export interface LufsSeriesResult {
728
+ /** 400 ms momentary series. */
729
+ momentary: Float32Array;
730
+ /** 3 s short-term series. */
731
+ shortTerm: Float32Array;
732
+ }
733
+
248
734
  /**
249
735
  * HPSS (Harmonic-Percussive Source Separation) result
250
736
  */