parakeet.ts 1.0.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +286 -0
  3. package/dist/alignment.d.ts +36 -0
  4. package/dist/alignment.d.ts.map +1 -0
  5. package/dist/alignment.js +202 -0
  6. package/dist/alignment.js.map +1 -0
  7. package/dist/audio.d.ts +59 -0
  8. package/dist/audio.d.ts.map +1 -0
  9. package/dist/audio.js +324 -0
  10. package/dist/audio.js.map +1 -0
  11. package/dist/backend.d.ts +61 -0
  12. package/dist/backend.d.ts.map +1 -0
  13. package/dist/backend.js +14 -0
  14. package/dist/backend.js.map +1 -0
  15. package/dist/decode.d.ts +38 -0
  16. package/dist/decode.d.ts.map +1 -0
  17. package/dist/decode.js +124 -0
  18. package/dist/decode.js.map +1 -0
  19. package/dist/hub.d.ts +18 -0
  20. package/dist/hub.d.ts.map +1 -0
  21. package/dist/hub.js +86 -0
  22. package/dist/hub.js.map +1 -0
  23. package/dist/index.d.ts +13 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +19 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/load.d.ts +51 -0
  28. package/dist/load.d.ts.map +1 -0
  29. package/dist/load.js +34 -0
  30. package/dist/load.js.map +1 -0
  31. package/dist/mlx/attention.d.ts +61 -0
  32. package/dist/mlx/attention.d.ts.map +1 -0
  33. package/dist/mlx/attention.js +330 -0
  34. package/dist/mlx/attention.js.map +1 -0
  35. package/dist/mlx/audio.d.ts +46 -0
  36. package/dist/mlx/audio.d.ts.map +1 -0
  37. package/dist/mlx/audio.js +309 -0
  38. package/dist/mlx/audio.js.map +1 -0
  39. package/dist/mlx/backend.d.ts +22 -0
  40. package/dist/mlx/backend.d.ts.map +1 -0
  41. package/dist/mlx/backend.js +67 -0
  42. package/dist/mlx/backend.js.map +1 -0
  43. package/dist/mlx/cache.d.ts +23 -0
  44. package/dist/mlx/cache.d.ts.map +1 -0
  45. package/dist/mlx/cache.js +98 -0
  46. package/dist/mlx/cache.js.map +1 -0
  47. package/dist/mlx/cli.d.ts +12 -0
  48. package/dist/mlx/cli.d.ts.map +1 -0
  49. package/dist/mlx/cli.js +145 -0
  50. package/dist/mlx/cli.js.map +1 -0
  51. package/dist/mlx/conformer.d.ts +81 -0
  52. package/dist/mlx/conformer.d.ts.map +1 -0
  53. package/dist/mlx/conformer.js +315 -0
  54. package/dist/mlx/conformer.js.map +1 -0
  55. package/dist/mlx/index.d.ts +6 -0
  56. package/dist/mlx/index.d.ts.map +1 -0
  57. package/dist/mlx/index.js +9 -0
  58. package/dist/mlx/index.js.map +1 -0
  59. package/dist/mlx/load.d.ts +27 -0
  60. package/dist/mlx/load.d.ts.map +1 -0
  61. package/dist/mlx/load.js +161 -0
  62. package/dist/mlx/load.js.map +1 -0
  63. package/dist/mlx/nn.d.ts +121 -0
  64. package/dist/mlx/nn.d.ts.map +1 -0
  65. package/dist/mlx/nn.js +511 -0
  66. package/dist/mlx/nn.js.map +1 -0
  67. package/dist/mlx/rnnt.d.ts +59 -0
  68. package/dist/mlx/rnnt.d.ts.map +1 -0
  69. package/dist/mlx/rnnt.js +233 -0
  70. package/dist/mlx/rnnt.js.map +1 -0
  71. package/dist/mlx/server.d.ts +34 -0
  72. package/dist/mlx/server.d.ts.map +1 -0
  73. package/dist/mlx/server.js +115 -0
  74. package/dist/mlx/server.js.map +1 -0
  75. package/dist/mlx/utils.d.ts +19 -0
  76. package/dist/mlx/utils.d.ts.map +1 -0
  77. package/dist/mlx/utils.js +103 -0
  78. package/dist/mlx/utils.js.map +1 -0
  79. package/dist/model.d.ts +112 -0
  80. package/dist/model.d.ts.map +1 -0
  81. package/dist/model.js +196 -0
  82. package/dist/model.js.map +1 -0
  83. package/dist/onnx/backend.d.ts +55 -0
  84. package/dist/onnx/backend.d.ts.map +1 -0
  85. package/dist/onnx/backend.js +111 -0
  86. package/dist/onnx/backend.js.map +1 -0
  87. package/dist/onnx/index.d.ts +7 -0
  88. package/dist/onnx/index.d.ts.map +1 -0
  89. package/dist/onnx/index.js +6 -0
  90. package/dist/onnx/index.js.map +1 -0
  91. package/dist/onnx/parakeet.d.ts +44 -0
  92. package/dist/onnx/parakeet.d.ts.map +1 -0
  93. package/dist/onnx/parakeet.js +135 -0
  94. package/dist/onnx/parakeet.js.map +1 -0
  95. package/dist/tokenizer.d.ts +6 -0
  96. package/dist/tokenizer.d.ts.map +1 -0
  97. package/dist/tokenizer.js +8 -0
  98. package/dist/tokenizer.js.map +1 -0
  99. package/package.json +85 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marcin Bunsch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,286 @@
1
+ # parakeet.ts
2
+
3
+ TypeScript runtime for Nvidia Parakeet ASR models. Runs on Apple Silicon via MLX, or Nvidia GPUs (Linux) via ONNX Runtime.
4
+
5
+ > **Not affiliated with NVIDIA.**
6
+
7
+ ## Requirements
8
+
9
+ - Node.js 18.11+
10
+ - [ffmpeg](https://ffmpeg.org/) in `$PATH` (for audio file decoding)
11
+ - A backend, chosen automatically by [`load()`](#usage):
12
+ - **MLX** — Apple Silicon Mac (M1 or later). No extra install.
13
+ - **ONNX Runtime** — everywhere else (CUDA on Linux/Nvidia, CPU otherwise).
14
+ Install the optional `onnxruntime-node` package.
15
+
16
+ ## Install
17
+
18
+ ```sh
19
+ npm install parakeet.ts
20
+ ```
21
+
22
+ ## Backends
23
+
24
+ The model, audio front-end, decode loop, and alignment are backend-agnostic, and
25
+ `load()` picks the right backend for the machine — you normally don't choose one.
26
+ For explicit control, import a backend's loader directly. Every path returns the
27
+ same `ParakeetModel`, so all the examples below work unchanged.
28
+
29
+ | Backend | Runs on | `load()` picks it | Explicit import |
30
+ |---------|---------|-------------------|-----------------|
31
+ | **MLX** | Apple Silicon (Metal) | on Apple Silicon | `parakeet.ts/mlx` — `fromPretrained`, `fromLocal` |
32
+ | **ONNX Runtime** | Nvidia GPU (CUDA, Linux) / CPU | everywhere else | `parakeet.ts/onnx` — `fromLocal` |
33
+
34
+ Each backend has its own default checkpoint (different asset formats, same
35
+ transcripts). The CLI and HTTP server use the MLX backend. See
36
+ [docs/cuda.md](docs/cuda.md) for the dual-backend design and benchmarks.
37
+
38
+ ## Usage
39
+
40
+ ### SDK
41
+
42
+ ```ts
43
+ import { load } from 'parakeet.ts';
44
+
45
+ const model = await load(); // detects the backend, downloads the model on first run
46
+ const result = await model.transcribe('recording.wav');
47
+
48
+ console.log(result.text);
49
+ // "Hello world"
50
+
51
+ console.log(result.sentences);
52
+ // [{ text: 'Hello world', start: 0, end: 1.2, duration: 1.2, tokens: [...] }]
53
+ ```
54
+
55
+ `load()` is the canonical entry point. It selects the backend for the current
56
+ machine — **MLX** on Apple Silicon, **ONNX Runtime** everywhere else — and
57
+ downloads that backend's default checkpoint from HuggingFace Hub on first run,
58
+ caching under `~/.cache/huggingface/hub/`. Subsequent calls load from cache.
59
+
60
+ ```ts
61
+ const model = await load({
62
+ // backend: 'auto' (default) | 'mlx' | 'onnx'
63
+ // model: HF repo id or local directory (default: the backend's checkpoint)
64
+ // cacheDir: override the HF cache root
65
+ // executionProvider: ONNX only — 'cuda' | 'cpu' | ...
66
+ // filterbank: 'interpolated' (default) | 'floor'
67
+ onProgress(file, downloaded, total) {
68
+ console.error(`${file}: ${Math.round((downloaded / total) * 100)}%`);
69
+ },
70
+ });
71
+
72
+ // Ask which backend load() would choose here, without loading:
73
+ import { detectBackend } from 'parakeet.ts';
74
+ detectBackend(); // 'mlx' | 'onnx'
75
+ ```
76
+
77
+ To pin a backend or load from a local directory instead of auto-selecting, use
78
+ the per-backend loaders — see [Backends](#backends) and
79
+ [ONNX Runtime backend](#onnx-runtime-backend):
80
+
81
+ ```ts
82
+ import { fromPretrained, fromLocal } from 'parakeet.ts/mlx';
83
+
84
+ const a = await fromPretrained('mlx-community/parakeet-tdt-0.6b-v3');
85
+ const b = fromLocal('/path/to/mlx-model-dir');
86
+ ```
87
+
88
+ #### Streaming
89
+
90
+ For real-time or incremental transcription, use `StreamingParakeet` directly or the `consumePcmStream` helper:
91
+
92
+ ```ts
93
+ import { consumePcmStream } from 'parakeet.ts';
94
+
95
+ const stream = model.transcribeStream();
96
+ const result = await consumePcmStream(stream, pcmFrameIterable);
97
+ // pcmFrameIterable: AsyncIterable<Float32Array> — 16kHz mono f32le
98
+ ```
99
+
100
+ `consumePcmStream` returns only once the source is exhausted. To surface partial
101
+ transcripts as audio arrives, drive it manually and read the getters after each
102
+ chunk:
103
+
104
+ ```ts
105
+ const stream = model.transcribeStream();
106
+
107
+ for await (const chunk of pcmFrameIterable) {
108
+ await stream.addAudio(chunk); // async
109
+ console.log(stream.result.text); // best current guess (finalized + draft)
110
+ console.log(stream.finalizedResult.text); // committed tokens only — never revised
111
+ }
112
+
113
+ const final = stream.finish(); // commit the remaining draft
114
+ ```
115
+
116
+ Streaming is backend-agnostic — the same `StreamingParakeet` runs on MLX and ONNX.
117
+
118
+ #### Concurrency
119
+
120
+ Each model instance has an internal async mutex. Concurrent `await model.transcribe(...)` calls on the same instance are automatically serialized — no GPU-state corruption. For lower tail latency under bursty load, create a pool:
121
+
122
+ ```ts
123
+ const pool = await Promise.all([load(), load()]);
124
+ let i = 0;
125
+ const next = () => pool[i++ % pool.length];
126
+ ```
127
+
128
+ #### Output shape
129
+
130
+ All entry points return `AlignedResult`:
131
+
132
+ ```ts
133
+ type AlignedResult = {
134
+ text: string;
135
+ sentences: AlignedSentence[];
136
+ };
137
+
138
+ type AlignedSentence = {
139
+ text: string;
140
+ start: number; // seconds
141
+ end: number;
142
+ duration: number;
143
+ tokens: AlignedToken[];
144
+ };
145
+
146
+ type AlignedToken = {
147
+ id: number;
148
+ text: string;
149
+ start: number; // seconds
150
+ duration: number;
151
+ };
152
+ ```
153
+
154
+ ### ONNX Runtime backend
155
+
156
+ On anything other than Apple Silicon, `load()` uses [ONNX Runtime](https://onnxruntime.ai/)
157
+ (CUDA execution provider on Linux/Nvidia, CPU elsewhere). It needs the optional
158
+ runtime:
159
+
160
+ ```sh
161
+ npm install onnxruntime-node
162
+ ```
163
+
164
+ With that installed, `await load()` downloads the default ONNX checkpoint
165
+ ([`istupakov/parakeet-tdt-0.6b-v3-onnx`](https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx))
166
+ and runs — no other setup. Pass the execution provider through if you want to
167
+ override it:
168
+
169
+ ```ts
170
+ const model = await load({ executionProvider: 'cuda' }); // 'cuda' | 'cpu' | 'tensorrt' | 'coreml' | 'dml'
171
+ ```
172
+
173
+ To use your own exported graphs, load a local directory containing
174
+ `encoder-model.onnx` (plus its `encoder-model.onnx.data` sidecar — keep the
175
+ filename), `decoder_joint-model.onnx`, and `vocab.txt`:
176
+
177
+ ```ts
178
+ import { fromLocal } from 'parakeet.ts/onnx';
179
+
180
+ const model = await fromLocal('/path/to/onnx-model-dir', {
181
+ executionProvider: 'cuda', // default: 'cuda' on Linux/Windows x64, 'cpu' elsewhere
182
+ decoderExecutionProvider: 'cpu', // optional: run the small per-step decoder on CPU
183
+ });
184
+ ```
185
+
186
+ Either way `model` is the same `ParakeetModel`, so streaming, concurrency, and
187
+ the [output shape](#output-shape) behave identically. Only TDT and RNN-T
188
+ checkpoints are available as ONNX exports.
189
+
190
+ ### CLI
191
+
192
+ ```sh
193
+ # Transcribe a file (auto-downloads model on first run)
194
+ parakeet recording.wav
195
+
196
+ # JSON output with word-level timestamps
197
+ parakeet recording.wav --json
198
+
199
+ # Different model
200
+ parakeet recording.wav --model mlx-community/parakeet-tdt-0.6b-v3
201
+
202
+ # Stream raw f32le mono 16kHz PCM from stdin
203
+ ffmpeg -i recording.wav -f f32le -ar 16000 -ac 1 - | parakeet --stream
204
+ ```
205
+
206
+ Options:
207
+
208
+ ```
209
+ --model, -m <id> HuggingFace repo ID or local directory (default: mlx-community/parakeet-tdt-0.6b-v3)
210
+ --json, -j Output full AlignedResult JSON instead of plain text
211
+ --stream, -s Read raw f32le mono 16kHz PCM from stdin
212
+ --help, -h Show help
213
+ ```
214
+
215
+ Exit codes: `0` success, `1` file/IO error, `2` model error.
216
+
217
+ ### HTTP server
218
+
219
+ The `parakeet.ts/mlx/server` entry point exports a [Hono](https://hono.dev/) route factory. Install the extra deps first:
220
+
221
+ ```sh
222
+ npm install hono @hono/node-server
223
+ ```
224
+
225
+ ```ts
226
+ import { Hono } from 'hono';
227
+ import { serve } from '@hono/node-server';
228
+ import { fromPretrained } from 'parakeet.ts/mlx';
229
+ import { createParakeetRoutes } from 'parakeet.ts/mlx/server';
230
+
231
+ const model = await fromPretrained('mlx-community/parakeet-tdt-0.6b-v3');
232
+
233
+ const app = new Hono();
234
+ app.route('/asr', createParakeetRoutes({
235
+ model,
236
+ maxDurationSeconds: 300, // default
237
+ idleTimeoutMs: 30_000, // default
238
+ }));
239
+
240
+ serve({ fetch: app.fetch, port: 8080 });
241
+ ```
242
+
243
+ #### `POST /asr/transcribe`
244
+
245
+ Send raw f32le mono 16kHz PCM audio as the request body.
246
+
247
+ **Request headers:**
248
+ ```
249
+ Content-Type: audio/pcm; rate=16000; channels=1; format=f32le
250
+ ```
251
+
252
+ **Response `200`:** `AlignedResult` JSON
253
+
254
+ **Error responses:**
255
+ ```json
256
+ { "error": "<code>", "message": "<human-readable>" }
257
+ ```
258
+
259
+ | Status | Error code | Cause |
260
+ |--------|------------|-------|
261
+ | 408 | `idle_timeout` | No bytes for `idleTimeoutMs` ms |
262
+ | 413 | `payload_too_large` | Audio exceeds `maxDurationSeconds` |
263
+ | 415 | `unsupported_media_type` | Wrong Content-Type |
264
+ | 500 | `internal_error` | Unexpected error |
265
+
266
+ ## Available models
267
+
268
+ | Model | HuggingFace ID | Notes |
269
+ |-------|---------------|-------|
270
+ | Parakeet TDT 0.6B v2 | `mlx-community/parakeet-tdt-0.6b-v2` | |
271
+ | Parakeet TDT 0.6B v3 | `mlx-community/parakeet-tdt-0.6b-v3` | **Default** |
272
+ | Parakeet RNNT 0.6B | `mlx-community/parakeet-rnnt-0.6b` | |
273
+ | Parakeet CTC 0.6B | `mlx-community/parakeet-ctc-0.6b` | |
274
+ | Parakeet TDT-CTC 0.6B | `mlx-community/parakeet-tdt-ctc-0.6b` | |
275
+ | Parakeet TDT 1.1B | `mlx-community/parakeet-tdt-1.1b` | |
276
+
277
+ `load()` downloads a default checkpoint per backend — `mlx-community/parakeet-tdt-0.6b-v3`
278
+ (MLX) or [`istupakov/parakeet-tdt-0.6b-v3-onnx`](https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx)
279
+ (ONNX). The table lists the MLX (`mlx-community`) checkpoints; pass any of them as
280
+ `load({ model })` or to `fromPretrained`. ONNX exports live in their own repos —
281
+ `load({ backend: 'onnx' })` fetches the default automatically, or point
282
+ `fromLocal` at a local directory of graphs.
283
+
284
+ ## License
285
+
286
+ MIT
@@ -0,0 +1,36 @@
1
+ export interface AlignedToken {
2
+ id: number;
3
+ text: string;
4
+ start: float;
5
+ duration: float;
6
+ confidence: float;
7
+ end: float;
8
+ }
9
+ type float = number;
10
+ export declare function makeAlignedToken(id: number, text: string, start: number, duration: number, confidence?: number): AlignedToken;
11
+ export interface AlignedSentence {
12
+ text: string;
13
+ tokens: AlignedToken[];
14
+ start: number;
15
+ end: number;
16
+ duration: number;
17
+ confidence: number;
18
+ }
19
+ export declare function makeAlignedSentence(text: string, tokens: AlignedToken[]): AlignedSentence;
20
+ export interface AlignedResult {
21
+ text: string;
22
+ sentences: AlignedSentence[];
23
+ tokens: AlignedToken[];
24
+ }
25
+ export declare function makeAlignedResult(text: string, sentences: AlignedSentence[]): AlignedResult;
26
+ export interface SentenceConfig {
27
+ maxWords?: number;
28
+ silenceGap?: number;
29
+ maxDuration?: number;
30
+ }
31
+ export declare function tokensToSentences(tokens: AlignedToken[], config?: SentenceConfig): AlignedSentence[];
32
+ export declare function sentencesToResult(sentences: AlignedSentence[]): AlignedResult;
33
+ export declare function mergeLongestContiguous(a: AlignedToken[], b: AlignedToken[], overlapDuration: number): AlignedToken[];
34
+ export declare function mergeLongestCommonSubsequence(a: AlignedToken[], b: AlignedToken[], overlapDuration: number): AlignedToken[];
35
+ export {};
36
+ //# sourceMappingURL=alignment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alignment.d.ts","sourceRoot":"","sources":["../src/alignment.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC;IAClB,GAAG,EAAE,KAAK,CAAC;CACZ;AAGD,KAAK,KAAK,GAAG,MAAM,CAAC;AAEpB,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAY,GACvB,YAAY,CAEd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EAAE,GACrB,eAAe,CASjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,eAAe,EAAE,GAC3B,aAAa,CAQf;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,GAAE,cAAmB,GAC1B,eAAe,EAAE,CAgDnB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,aAAa,CAG7E;AAED,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,YAAY,EAAE,EACjB,CAAC,EAAE,YAAY,EAAE,EACjB,eAAe,EAAE,MAAM,GACtB,YAAY,EAAE,CA2EhB;AAED,wBAAgB,6BAA6B,CAC3C,CAAC,EAAE,YAAY,EAAE,EACjB,CAAC,EAAE,YAAY,EAAE,EACjB,eAAe,EAAE,MAAM,GACtB,YAAY,EAAE,CAsFhB"}
@@ -0,0 +1,202 @@
1
+ export function makeAlignedToken(id, text, start, duration, confidence = 1.0) {
2
+ return { id, text, start, duration, confidence, end: start + duration };
3
+ }
4
+ export function makeAlignedSentence(text, tokens) {
5
+ const sorted = [...tokens].sort((a, b) => a.start - b.start);
6
+ const start = sorted[0].start;
7
+ const end = sorted[sorted.length - 1].end;
8
+ const duration = end - start;
9
+ // Geometric mean of token confidences
10
+ const logSum = sorted.reduce((acc, t) => acc + Math.log(t.confidence + 1e-10), 0);
11
+ const confidence = Math.exp(logSum / sorted.length);
12
+ return { text, tokens: sorted, start, end, duration, confidence };
13
+ }
14
+ export function makeAlignedResult(text, sentences) {
15
+ return {
16
+ text: text.trim(),
17
+ sentences,
18
+ get tokens() {
19
+ return sentences.flatMap(s => s.tokens);
20
+ },
21
+ };
22
+ }
23
+ export function tokensToSentences(tokens, config = {}) {
24
+ if (tokens.length === 0)
25
+ return [];
26
+ const sentences = [];
27
+ let current = [];
28
+ for (let idx = 0; idx < tokens.length; idx++) {
29
+ const token = tokens[idx];
30
+ current.push(token);
31
+ const isPunctuation = token.text.includes('!') ||
32
+ token.text.includes('?') ||
33
+ token.text.includes('。') ||
34
+ token.text.includes('?') ||
35
+ token.text.includes('!') ||
36
+ (token.text.includes('.') &&
37
+ (idx === tokens.length - 1 || tokens[idx + 1].text.includes(' ')));
38
+ const isWordLimit = config.maxWords !== undefined &&
39
+ idx !== tokens.length - 1 &&
40
+ current.filter(t => t.text.includes(' ')).length +
41
+ (tokens[idx + 1].text.includes(' ') ? 1 : 0) >
42
+ config.maxWords;
43
+ const isLongSilence = config.silenceGap !== undefined &&
44
+ idx !== tokens.length - 1 &&
45
+ tokens[idx + 1].start - token.end >= config.silenceGap;
46
+ const isOverDuration = config.maxDuration !== undefined &&
47
+ token.end - current[0].start >= config.maxDuration;
48
+ if (isPunctuation || isWordLimit || isLongSilence || isOverDuration) {
49
+ const text = current.map(t => t.text).join('');
50
+ sentences.push(makeAlignedSentence(text, current));
51
+ current = [];
52
+ }
53
+ }
54
+ if (current.length > 0) {
55
+ const text = current.map(t => t.text).join('');
56
+ sentences.push(makeAlignedSentence(text, current));
57
+ }
58
+ return sentences;
59
+ }
60
+ export function sentencesToResult(sentences) {
61
+ const text = sentences.map(s => s.text).join('');
62
+ return makeAlignedResult(text, sentences);
63
+ }
64
+ export function mergeLongestContiguous(a, b, overlapDuration) {
65
+ if (a.length === 0)
66
+ return b;
67
+ if (b.length === 0)
68
+ return a;
69
+ const aEndTime = a[a.length - 1].end;
70
+ const bStartTime = b[0].start;
71
+ if (aEndTime <= bStartTime)
72
+ return [...a, ...b];
73
+ const overlapA = a.filter(t => t.end > bStartTime - overlapDuration);
74
+ const overlapB = b.filter(t => t.start < aEndTime + overlapDuration);
75
+ const enoughPairs = Math.floor(overlapA.length / 2);
76
+ if (overlapA.length < 2 || overlapB.length < 2) {
77
+ const cutoffTime = (aEndTime + bStartTime) / 2;
78
+ return [
79
+ ...a.filter(t => t.end <= cutoffTime),
80
+ ...b.filter(t => t.start >= cutoffTime),
81
+ ];
82
+ }
83
+ // Find longest contiguous matching subsequence
84
+ let bestContiguous = [];
85
+ for (let i = 0; i < overlapA.length; i++) {
86
+ for (let j = 0; j < overlapB.length; j++) {
87
+ if (overlapA[i].id === overlapB[j].id &&
88
+ Math.abs(overlapA[i].start - overlapB[j].start) < overlapDuration / 2) {
89
+ const current = [];
90
+ let k = i, l = j;
91
+ while (k < overlapA.length &&
92
+ l < overlapB.length &&
93
+ overlapA[k].id === overlapB[l].id &&
94
+ Math.abs(overlapA[k].start - overlapB[l].start) < overlapDuration / 2) {
95
+ current.push([k, l]);
96
+ k++;
97
+ l++;
98
+ }
99
+ if (current.length > bestContiguous.length) {
100
+ bestContiguous = current;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ if (bestContiguous.length >= enoughPairs) {
106
+ const aStartIdx = a.length - overlapA.length;
107
+ const lcsIndicesA = bestContiguous.map(p => aStartIdx + p[0]);
108
+ const lcsIndicesB = bestContiguous.map(p => p[1]);
109
+ const result = [];
110
+ result.push(...a.slice(0, lcsIndicesA[0]));
111
+ for (let i = 0; i < bestContiguous.length; i++) {
112
+ result.push(a[lcsIndicesA[i]]);
113
+ if (i < bestContiguous.length - 1) {
114
+ const nextA = lcsIndicesA[i + 1];
115
+ const nextB = lcsIndicesB[i + 1];
116
+ const gapA = a.slice(lcsIndicesA[i] + 1, nextA);
117
+ const gapB = b.slice(lcsIndicesB[i] + 1, nextB);
118
+ result.push(...(gapB.length > gapA.length ? gapB : gapA));
119
+ }
120
+ }
121
+ result.push(...b.slice(lcsIndicesB[lcsIndicesB.length - 1] + 1));
122
+ return result;
123
+ }
124
+ throw new Error(`No pairs exceeding ${enoughPairs}`);
125
+ }
126
+ export function mergeLongestCommonSubsequence(a, b, overlapDuration) {
127
+ if (a.length === 0)
128
+ return b;
129
+ if (b.length === 0)
130
+ return a;
131
+ const aEndTime = a[a.length - 1].end;
132
+ const bStartTime = b[0].start;
133
+ if (aEndTime <= bStartTime)
134
+ return [...a, ...b];
135
+ const overlapA = a.filter(t => t.end > bStartTime - overlapDuration);
136
+ const overlapB = b.filter(t => t.start < aEndTime + overlapDuration);
137
+ if (overlapA.length < 2 || overlapB.length < 2) {
138
+ const cutoffTime = (aEndTime + bStartTime) / 2;
139
+ return [
140
+ ...a.filter(t => t.end <= cutoffTime),
141
+ ...b.filter(t => t.start >= cutoffTime),
142
+ ];
143
+ }
144
+ // LCS dynamic programming
145
+ const m = overlapA.length;
146
+ const n = overlapB.length;
147
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
148
+ for (let i = 1; i <= m; i++) {
149
+ for (let j = 1; j <= n; j++) {
150
+ if (overlapA[i - 1].id === overlapB[j - 1].id &&
151
+ Math.abs(overlapA[i - 1].start - overlapB[j - 1].start) < overlapDuration / 2) {
152
+ dp[i][j] = dp[i - 1][j - 1] + 1;
153
+ }
154
+ else {
155
+ dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
156
+ }
157
+ }
158
+ }
159
+ // Backtrack
160
+ const lcsPairs = [];
161
+ let i = m, j = n;
162
+ while (i > 0 && j > 0) {
163
+ if (overlapA[i - 1].id === overlapB[j - 1].id &&
164
+ Math.abs(overlapA[i - 1].start - overlapB[j - 1].start) < overlapDuration / 2) {
165
+ lcsPairs.push([i - 1, j - 1]);
166
+ i--;
167
+ j--;
168
+ }
169
+ else if (dp[i - 1][j] > dp[i][j - 1]) {
170
+ i--;
171
+ }
172
+ else {
173
+ j--;
174
+ }
175
+ }
176
+ lcsPairs.reverse();
177
+ if (lcsPairs.length === 0) {
178
+ const cutoffTime = (aEndTime + bStartTime) / 2;
179
+ return [
180
+ ...a.filter(t => t.end <= cutoffTime),
181
+ ...b.filter(t => t.start >= cutoffTime),
182
+ ];
183
+ }
184
+ const aStartIdx = a.length - overlapA.length;
185
+ const lcsIndicesA = lcsPairs.map(p => aStartIdx + p[0]);
186
+ const lcsIndicesB = lcsPairs.map(p => p[1]);
187
+ const result = [];
188
+ result.push(...a.slice(0, lcsIndicesA[0]));
189
+ for (let k = 0; k < lcsPairs.length; k++) {
190
+ result.push(a[lcsIndicesA[k]]);
191
+ if (k < lcsPairs.length - 1) {
192
+ const nextA = lcsIndicesA[k + 1];
193
+ const nextB = lcsIndicesB[k + 1];
194
+ const gapA = a.slice(lcsIndicesA[k] + 1, nextA);
195
+ const gapB = b.slice(lcsIndicesB[k] + 1, nextB);
196
+ result.push(...(gapB.length > gapA.length ? gapB : gapA));
197
+ }
198
+ }
199
+ result.push(...b.slice(lcsIndicesB[lcsIndicesB.length - 1] + 1));
200
+ return result;
201
+ }
202
+ //# sourceMappingURL=alignment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alignment.js","sourceRoot":"","sources":["../src/alignment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ export interface PreprocessArgs {
2
+ sampleRate: number;
3
+ normalize: string;
4
+ windowSize: number;
5
+ windowStride: number;
6
+ window: string;
7
+ features: number;
8
+ nFft: number;
9
+ dither: number;
10
+ padTo: number;
11
+ padValue: number;
12
+ preemph: number | null;
13
+ magPower: number;
14
+ winLength: number;
15
+ hopLength: number;
16
+ /** [features, nFft/2+1], row-major */
17
+ filterbanks: Float32Array;
18
+ }
19
+ /** Log-mel output, laid out [nMels, numFrames] — the encoder's `audio_signal` order. */
20
+ export interface LogMel {
21
+ data: Float32Array;
22
+ nMels: number;
23
+ numFrames: number;
24
+ }
25
+ /** Decode any ffmpeg-readable file to mono float32 PCM in [-1, 1]. */
26
+ export declare function loadAudioRaw(filename: string, samplingRate: number): Float32Array;
27
+ export declare function getWindow(name: string, size: number): Float32Array;
28
+ /**
29
+ * Filterbank as parakeet-mlx builds it: mel points snapped to FFT bins with
30
+ * `floor`. NOTE: at 16 kHz / nFft 512 / 128 mels this collapses 13 rows to all
31
+ * zero — see docs/cuda.md. Kept as the default for bit-compatibility with the
32
+ * existing MLX path and the current test fixtures.
33
+ */
34
+ export declare function computeMelFilterbanks(sr: number, nFft: number, nMels: number, fMin: number, fMax: number): Float32Array;
35
+ /**
36
+ * librosa/NeMo-style filterbank: triangles evaluated on continuous frequencies,
37
+ * so no rows collapse. Matches NVIDIA's reference preprocessor. Opt in via
38
+ * `makePreprocessArgs({ filterbank: 'interpolated' })`.
39
+ */
40
+ export declare function computeMelFilterbanksInterpolated(sr: number, nFft: number, nMels: number, fMin: number, fMax: number): Float32Array;
41
+ export declare function makePreprocessArgs(args: {
42
+ sampleRate: number;
43
+ normalize: string;
44
+ windowSize: number;
45
+ windowStride: number;
46
+ window: string;
47
+ features: number;
48
+ nFft: number;
49
+ dither: number;
50
+ padTo?: number;
51
+ padValue?: number;
52
+ preemph?: number | null;
53
+ magPower?: number;
54
+ /** 'floor' (default, parakeet-mlx compatible) or 'interpolated' (NeMo reference) */
55
+ filterbank?: 'floor' | 'interpolated';
56
+ }): PreprocessArgs;
57
+ /** Log-mel spectrogram from mono PCM. Output is [nMels, numFrames]. */
58
+ export declare function getLogMel(signalIn: Float32Array, args: PreprocessArgs): LogMel;
59
+ //# sourceMappingURL=audio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../src/audio.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IAEjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,WAAW,EAAE,YAAY,CAAC;CAC3B;AAED,wFAAwF;AACxF,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,YAAY,CAqBjF;AA6BD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CASlE;AAsGD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAClE,YAAY,CA0Bd;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC/C,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAClE,YAAY,CAyBd;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,UAAU,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;CACvC,GAAG,cAAc,CAkBjB;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CA0D9E"}