speechflow 1.6.0 → 1.6.2

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 (192) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/etc/claude.md +9 -4
  4. package/etc/keyfiles.txt +19 -0
  5. package/etc/speechflow.yaml +4 -4
  6. package/package.json +3 -3
  7. package/speechflow-cli/dst/speechflow-main-api.d.ts +12 -0
  8. package/speechflow-cli/dst/speechflow-main-api.js +319 -0
  9. package/speechflow-cli/dst/speechflow-main-api.js.map +1 -0
  10. package/speechflow-cli/dst/speechflow-main-cli.d.ts +28 -0
  11. package/speechflow-cli/dst/speechflow-main-cli.js +271 -0
  12. package/speechflow-cli/dst/speechflow-main-cli.js.map +1 -0
  13. package/speechflow-cli/dst/speechflow-main-config.d.ts +9 -0
  14. package/speechflow-cli/dst/speechflow-main-config.js +27 -0
  15. package/speechflow-cli/dst/speechflow-main-config.js.map +1 -0
  16. package/speechflow-cli/dst/speechflow-main-graph.d.ts +34 -0
  17. package/speechflow-cli/dst/speechflow-main-graph.js +365 -0
  18. package/speechflow-cli/dst/speechflow-main-graph.js.map +1 -0
  19. package/speechflow-cli/dst/speechflow-main-nodes.d.ts +10 -0
  20. package/speechflow-cli/dst/speechflow-main-nodes.js +60 -0
  21. package/speechflow-cli/dst/speechflow-main-nodes.js.map +1 -0
  22. package/speechflow-cli/dst/speechflow-main-status.d.ts +11 -0
  23. package/speechflow-cli/dst/speechflow-main-status.js +60 -0
  24. package/speechflow-cli/dst/speechflow-main-status.js.map +1 -0
  25. package/speechflow-cli/dst/speechflow-main.d.ts +7 -0
  26. package/speechflow-cli/dst/speechflow-main.js +127 -0
  27. package/speechflow-cli/dst/speechflow-main.js.map +1 -0
  28. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js +4 -4
  29. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js.map +1 -1
  30. package/speechflow-cli/dst/speechflow-node-a2a-compressor.js +5 -6
  31. package/speechflow-cli/dst/speechflow-node-a2a-compressor.js.map +1 -1
  32. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js +5 -5
  33. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js.map +1 -1
  34. package/speechflow-cli/dst/speechflow-node-a2a-expander.js +5 -6
  35. package/speechflow-cli/dst/speechflow-node-a2a-expander.js.map +1 -1
  36. package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js +5 -5
  37. package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js.map +1 -1
  38. package/speechflow-cli/dst/speechflow-node-a2a-filler.js +3 -3
  39. package/speechflow-cli/dst/speechflow-node-a2a-filler.js.map +1 -1
  40. package/speechflow-cli/dst/speechflow-node-a2a-gain.js +2 -2
  41. package/speechflow-cli/dst/speechflow-node-a2a-gain.js.map +1 -1
  42. package/speechflow-cli/dst/speechflow-node-a2a-gender.js +4 -4
  43. package/speechflow-cli/dst/speechflow-node-a2a-gender.js.map +1 -1
  44. package/speechflow-cli/dst/speechflow-node-a2a-meter.js +2 -2
  45. package/speechflow-cli/dst/speechflow-node-a2a-meter.js.map +1 -1
  46. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js +4 -4
  47. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js.map +1 -1
  48. package/speechflow-cli/dst/speechflow-node-a2a-speex.js +4 -4
  49. package/speechflow-cli/dst/speechflow-node-a2a-speex.js.map +1 -1
  50. package/speechflow-cli/dst/speechflow-node-a2a-vad.js +4 -4
  51. package/speechflow-cli/dst/speechflow-node-a2a-vad.js.map +1 -1
  52. package/speechflow-cli/dst/speechflow-node-a2t-amazon.js +6 -6
  53. package/speechflow-cli/dst/speechflow-node-a2t-amazon.js.map +1 -1
  54. package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js +4 -4
  55. package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js.map +1 -1
  56. package/speechflow-cli/dst/speechflow-node-a2t-openai.js +4 -4
  57. package/speechflow-cli/dst/speechflow-node-a2t-openai.js.map +1 -1
  58. package/speechflow-cli/dst/speechflow-node-t2a-amazon.js +2 -2
  59. package/speechflow-cli/dst/speechflow-node-t2a-amazon.js.map +1 -1
  60. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js +2 -2
  61. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js.map +1 -1
  62. package/speechflow-cli/dst/speechflow-node-t2t-amazon.js +2 -2
  63. package/speechflow-cli/dst/speechflow-node-t2t-amazon.js.map +1 -1
  64. package/speechflow-cli/dst/speechflow-node-t2t-deepl.js +2 -2
  65. package/speechflow-cli/dst/speechflow-node-t2t-deepl.js.map +1 -1
  66. package/speechflow-cli/dst/speechflow-node-t2t-google.js +5 -5
  67. package/speechflow-cli/dst/speechflow-node-t2t-google.js.map +1 -1
  68. package/speechflow-cli/dst/speechflow-node-t2t-modify.js +2 -2
  69. package/speechflow-cli/dst/speechflow-node-t2t-modify.js.map +1 -1
  70. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js +2 -2
  71. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js.map +1 -1
  72. package/speechflow-cli/dst/speechflow-node-t2t-openai.js +2 -2
  73. package/speechflow-cli/dst/speechflow-node-t2t-openai.js.map +1 -1
  74. package/speechflow-cli/dst/speechflow-node-t2t-sentence.js +2 -2
  75. package/speechflow-cli/dst/speechflow-node-t2t-sentence.js.map +1 -1
  76. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js +2 -2
  77. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js.map +1 -1
  78. package/speechflow-cli/dst/speechflow-node-t2t-transformers.js +2 -2
  79. package/speechflow-cli/dst/speechflow-node-t2t-transformers.js.map +1 -1
  80. package/speechflow-cli/dst/speechflow-node-x2x-filter.js +2 -2
  81. package/speechflow-cli/dst/speechflow-node-x2x-filter.js.map +1 -1
  82. package/speechflow-cli/dst/speechflow-node-xio-device.js +5 -5
  83. package/speechflow-cli/dst/speechflow-node-xio-device.js.map +1 -1
  84. package/speechflow-cli/dst/speechflow-node-xio-file.js +27 -27
  85. package/speechflow-cli/dst/speechflow-node-xio-file.js.map +1 -1
  86. package/speechflow-cli/dst/speechflow-node-xio-mqtt.js +4 -4
  87. package/speechflow-cli/dst/speechflow-node-xio-mqtt.js.map +1 -1
  88. package/speechflow-cli/dst/speechflow-node-xio-websocket.js +7 -7
  89. package/speechflow-cli/dst/speechflow-node-xio-websocket.js.map +1 -1
  90. package/speechflow-cli/dst/{speechflow-utils-audio-wt.js → speechflow-util-audio-wt.js} +1 -1
  91. package/speechflow-cli/dst/speechflow-util-audio-wt.js.map +1 -0
  92. package/speechflow-cli/dst/speechflow-util-audio.d.ts +22 -0
  93. package/speechflow-cli/dst/speechflow-util-audio.js +251 -0
  94. package/speechflow-cli/dst/speechflow-util-audio.js.map +1 -0
  95. package/speechflow-cli/dst/speechflow-util-error.d.ts +14 -0
  96. package/speechflow-cli/dst/speechflow-util-error.js +131 -0
  97. package/speechflow-cli/dst/speechflow-util-error.js.map +1 -0
  98. package/speechflow-cli/dst/speechflow-util-queue.d.ts +68 -0
  99. package/speechflow-cli/dst/speechflow-util-queue.js +338 -0
  100. package/speechflow-cli/dst/speechflow-util-queue.js.map +1 -0
  101. package/speechflow-cli/dst/speechflow-util-stream.d.ts +18 -0
  102. package/speechflow-cli/dst/speechflow-util-stream.js +219 -0
  103. package/speechflow-cli/dst/speechflow-util-stream.js.map +1 -0
  104. package/speechflow-cli/dst/speechflow-util-webaudio-wt.js +124 -0
  105. package/speechflow-cli/dst/speechflow-util-webaudio-wt.js.map +1 -0
  106. package/speechflow-cli/dst/{speechflow-utils-audio.js → speechflow-util-webaudio.js} +2 -2
  107. package/speechflow-cli/dst/speechflow-util-webaudio.js.map +1 -0
  108. package/speechflow-cli/dst/speechflow-util.d.ts +4 -0
  109. package/speechflow-cli/dst/speechflow-util.js +26 -0
  110. package/speechflow-cli/dst/speechflow-util.js.map +1 -0
  111. package/speechflow-cli/dst/speechflow.js +3 -912
  112. package/speechflow-cli/dst/speechflow.js.map +1 -1
  113. package/speechflow-cli/etc/oxlint.jsonc +4 -1
  114. package/speechflow-cli/package.json +1 -0
  115. package/speechflow-cli/src/lib.d.ts +2 -0
  116. package/speechflow-cli/src/speechflow-main-api.ts +315 -0
  117. package/speechflow-cli/src/speechflow-main-cli.ts +259 -0
  118. package/speechflow-cli/src/speechflow-main-config.ts +17 -0
  119. package/speechflow-cli/src/speechflow-main-graph.ts +370 -0
  120. package/speechflow-cli/src/speechflow-main-nodes.ts +61 -0
  121. package/speechflow-cli/src/speechflow-main-status.ts +70 -0
  122. package/speechflow-cli/src/speechflow-main.ts +106 -0
  123. package/speechflow-cli/src/speechflow-node-a2a-compressor-wt.ts +4 -4
  124. package/speechflow-cli/src/speechflow-node-a2a-compressor.ts +5 -6
  125. package/speechflow-cli/src/speechflow-node-a2a-expander-wt.ts +5 -5
  126. package/speechflow-cli/src/speechflow-node-a2a-expander.ts +5 -6
  127. package/speechflow-cli/src/speechflow-node-a2a-ffmpeg.ts +5 -5
  128. package/speechflow-cli/src/speechflow-node-a2a-filler.ts +4 -4
  129. package/speechflow-cli/src/speechflow-node-a2a-gain.ts +2 -2
  130. package/speechflow-cli/src/speechflow-node-a2a-gender.ts +4 -4
  131. package/speechflow-cli/src/speechflow-node-a2a-meter.ts +2 -2
  132. package/speechflow-cli/src/speechflow-node-a2a-rnnoise.ts +4 -4
  133. package/speechflow-cli/src/speechflow-node-a2a-speex.ts +4 -4
  134. package/speechflow-cli/src/speechflow-node-a2a-vad.ts +4 -4
  135. package/speechflow-cli/src/speechflow-node-a2t-amazon.ts +7 -7
  136. package/speechflow-cli/src/speechflow-node-a2t-deepgram.ts +5 -5
  137. package/speechflow-cli/src/speechflow-node-a2t-openai.ts +5 -5
  138. package/speechflow-cli/src/speechflow-node-t2a-amazon.ts +2 -2
  139. package/speechflow-cli/src/speechflow-node-t2a-kokoro.ts +2 -2
  140. package/speechflow-cli/src/speechflow-node-t2t-amazon.ts +2 -2
  141. package/speechflow-cli/src/speechflow-node-t2t-deepl.ts +2 -2
  142. package/speechflow-cli/src/speechflow-node-t2t-google.ts +5 -5
  143. package/speechflow-cli/src/speechflow-node-t2t-modify.ts +2 -2
  144. package/speechflow-cli/src/speechflow-node-t2t-ollama.ts +2 -2
  145. package/speechflow-cli/src/speechflow-node-t2t-openai.ts +2 -2
  146. package/speechflow-cli/src/speechflow-node-t2t-sentence.ts +2 -2
  147. package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +2 -2
  148. package/speechflow-cli/src/speechflow-node-t2t-transformers.ts +2 -2
  149. package/speechflow-cli/src/speechflow-node-x2x-filter.ts +2 -2
  150. package/speechflow-cli/src/speechflow-node-xio-device.ts +5 -5
  151. package/speechflow-cli/src/speechflow-node-xio-file.ts +9 -10
  152. package/speechflow-cli/src/speechflow-node-xio-mqtt.ts +5 -5
  153. package/speechflow-cli/src/speechflow-node-xio-websocket.ts +7 -7
  154. package/speechflow-cli/src/{speechflow-utils-audio.ts → speechflow-util-audio.ts} +131 -1
  155. package/speechflow-cli/src/speechflow-util-error.ts +184 -0
  156. package/speechflow-cli/src/speechflow-util-queue.ts +320 -0
  157. package/speechflow-cli/src/speechflow-util-stream.ts +197 -0
  158. package/speechflow-cli/src/speechflow-util.ts +10 -0
  159. package/speechflow-cli/src/speechflow.ts +3 -953
  160. package/speechflow-ui-db/dst/index.js +1 -1
  161. package/speechflow-ui-db/etc/vite-client.mts +0 -2
  162. package/speechflow-ui-db/src/app.vue +20 -19
  163. package/speechflow-ui-st/dst/index.js +1 -1
  164. package/speechflow-ui-st/etc/vite-client.mts +0 -2
  165. package/speechflow-ui-st/src/app.vue +10 -6
  166. package/speechflow-cli/dst/speechflow-node-a2a-dynamics-wt.js +0 -208
  167. package/speechflow-cli/dst/speechflow-node-a2a-dynamics-wt.js.map +0 -1
  168. package/speechflow-cli/dst/speechflow-node-a2a-dynamics.d.ts +0 -15
  169. package/speechflow-cli/dst/speechflow-node-a2a-dynamics.js +0 -312
  170. package/speechflow-cli/dst/speechflow-node-a2a-dynamics.js.map +0 -1
  171. package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.d.ts +0 -18
  172. package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.js +0 -312
  173. package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.js.map +0 -1
  174. package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.d.ts +0 -19
  175. package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.js +0 -351
  176. package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.js.map +0 -1
  177. package/speechflow-cli/dst/speechflow-node-t2a-awspolly.d.ts +0 -16
  178. package/speechflow-cli/dst/speechflow-node-t2a-awspolly.js +0 -204
  179. package/speechflow-cli/dst/speechflow-node-t2a-awspolly.js.map +0 -1
  180. package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.d.ts +0 -13
  181. package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.js +0 -175
  182. package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.js.map +0 -1
  183. package/speechflow-cli/dst/speechflow-utils-audio-wt.js.map +0 -1
  184. package/speechflow-cli/dst/speechflow-utils-audio.js.map +0 -1
  185. package/speechflow-cli/dst/speechflow-utils.d.ts +0 -108
  186. package/speechflow-cli/dst/speechflow-utils.js +0 -746
  187. package/speechflow-cli/dst/speechflow-utils.js.map +0 -1
  188. package/speechflow-cli/src/speechflow-utils.ts +0 -810
  189. /package/speechflow-cli/dst/{speechflow-node-a2a-dynamics-wt.d.ts → speechflow-util-audio-wt.d.ts} +0 -0
  190. /package/speechflow-cli/dst/{speechflow-utils-audio-wt.d.ts → speechflow-util-webaudio-wt.d.ts} +0 -0
  191. /package/speechflow-cli/dst/{speechflow-utils-audio.d.ts → speechflow-util-webaudio.d.ts} +0 -0
  192. /package/speechflow-cli/src/{speechflow-utils-audio-wt.ts → speechflow-util-audio-wt.ts} +0 -0
@@ -1,746 +0,0 @@
1
- "use strict";
2
- /*
3
- ** SpeechFlow - Speech Processing Flow Graph
4
- ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
5
- ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- var __importDefault = (this && this.__importDefault) || function (mod) {
41
- return (mod && mod.__esModule) ? mod : { "default": mod };
42
- };
43
- Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.CachedRegExp = exports.AsyncQueue = exports.TimeStore = exports.StreamWrapper = exports.Queue = exports.QueuePointer = exports.DoubleQueue = exports.SingleQueue = void 0;
45
- exports.ensureError = ensureError;
46
- exports.ensurePromise = ensurePromise;
47
- exports.run = run;
48
- exports.runner = runner;
49
- exports.importObject = importObject;
50
- exports.audioBufferDuration = audioBufferDuration;
51
- exports.audioArrayDuration = audioArrayDuration;
52
- exports.convertBufToF32 = convertBufToF32;
53
- exports.convertF32ToBuf = convertF32ToBuf;
54
- exports.convertBufToI16 = convertBufToI16;
55
- exports.convertI16ToBuf = convertI16ToBuf;
56
- exports.createTransformStreamForWritableSide = createTransformStreamForWritableSide;
57
- exports.createTransformStreamForReadableSide = createTransformStreamForReadableSide;
58
- exports.ensureStreamChunk = ensureStreamChunk;
59
- exports.streamChunkEncode = streamChunkEncode;
60
- exports.streamChunkDecode = streamChunkDecode;
61
- exports.processInt16ArrayInSegments = processInt16ArrayInSegments;
62
- exports.lin2dB = lin2dB;
63
- exports.dB2lin = dB2lin;
64
- /* standard dependencies */
65
- const node_stream_1 = __importDefault(require("node:stream"));
66
- const node_events_1 = require("node:events");
67
- const arktype_1 = require("arktype");
68
- /* external dependencies */
69
- const luxon_1 = require("luxon");
70
- const CBOR = __importStar(require("cbor2"));
71
- const IntervalTree = __importStar(require("node-interval-tree"));
72
- /* internal dependencies */
73
- const speechflow_node_1 = require("./speechflow-node");
74
- /* helper function for retrieving an Error object */
75
- function ensureError(error, prefix) {
76
- if (error instanceof Error && prefix === undefined)
77
- return error;
78
- let msg = error instanceof Error ?
79
- error.message : String(error);
80
- if (prefix)
81
- msg = `${prefix}: ${msg}`;
82
- return new Error(msg, { cause: error });
83
- }
84
- /* helper function for retrieving a Promise object */
85
- function ensurePromise(arg) {
86
- if (!(arg instanceof Promise))
87
- arg = Promise.resolve(arg);
88
- return arg;
89
- }
90
- /* helper function for running the finally code of "run" */
91
- function runFinally(onfinally) {
92
- if (!onfinally)
93
- return;
94
- try {
95
- onfinally();
96
- }
97
- catch (_error) { /* ignored */ }
98
- }
99
- function run(...args) {
100
- /* support overloaded signatures */
101
- let description;
102
- let action;
103
- let oncatch;
104
- let onfinally;
105
- if (typeof args[0] === "string") {
106
- description = args[0];
107
- action = args[1];
108
- oncatch = args[2];
109
- onfinally = args[3];
110
- }
111
- else {
112
- action = args[0];
113
- oncatch = args[1];
114
- onfinally = args[2];
115
- }
116
- /* perform the action */
117
- let result;
118
- try {
119
- result = action();
120
- }
121
- catch (arg) {
122
- /* synchronous case (error branch) */
123
- let error = ensureError(arg, description);
124
- if (oncatch) {
125
- try {
126
- result = oncatch(error);
127
- }
128
- catch (arg) {
129
- error = ensureError(arg, description);
130
- runFinally(onfinally);
131
- throw error;
132
- }
133
- runFinally(onfinally);
134
- return result;
135
- }
136
- runFinally(onfinally);
137
- throw error;
138
- }
139
- if (result instanceof Promise) {
140
- /* asynchronous case (result or error branch) */
141
- return result.catch((arg) => {
142
- /* asynchronous case (error branch) */
143
- let error = ensureError(arg, description);
144
- if (oncatch) {
145
- try {
146
- return oncatch(error);
147
- }
148
- catch (arg) {
149
- error = ensureError(arg, description);
150
- throw error;
151
- }
152
- }
153
- throw error;
154
- }).finally(() => {
155
- /* asynchronous case (result and error branch) */
156
- runFinally(onfinally);
157
- });
158
- }
159
- else {
160
- /* synchronous case (result branch) */
161
- runFinally(onfinally);
162
- return result;
163
- }
164
- }
165
- function runner(...args) {
166
- /* support overloaded signatures */
167
- let description;
168
- let action;
169
- let oncatch;
170
- let onfinally;
171
- if (typeof args[0] === "string") {
172
- description = args[0];
173
- action = args[1];
174
- oncatch = args[2];
175
- onfinally = args[3];
176
- }
177
- else {
178
- action = args[0];
179
- oncatch = args[1];
180
- onfinally = args[2];
181
- }
182
- /* wrap the "run" operation on "action" into function
183
- which exposes the signature of "action" */
184
- return (...args) => {
185
- if (description)
186
- return run(description, () => action(...args), oncatch, onfinally);
187
- else
188
- return run(() => action(...args), oncatch, onfinally);
189
- };
190
- }
191
- /* import an object with parsing and strict error handling */
192
- function importObject(name, arg, validator) {
193
- const obj = typeof arg === "string" ?
194
- run(`${name}: parsing JSON`, () => JSON.parse(arg)) :
195
- arg;
196
- const result = validator(obj);
197
- if (result instanceof arktype_1.type.errors)
198
- throw new Error(`${name}: validation: ${result.summary}`);
199
- return result;
200
- }
201
- /* calculate duration of an audio buffer */
202
- function audioBufferDuration(buffer, sampleRate = 48000, bitDepth = 16, channels = 1, littleEndian = true) {
203
- /* sanity check parameters */
204
- if (!Buffer.isBuffer(buffer))
205
- throw new Error("invalid input (Buffer expected)");
206
- if (littleEndian !== true)
207
- throw new Error("only Little Endian supported");
208
- if (sampleRate <= 0)
209
- throw new Error("sample rate must be positive");
210
- if (bitDepth <= 0 || bitDepth % 8 !== 0)
211
- throw new Error("bit depth must be positive and multiple of 8");
212
- if (channels <= 0)
213
- throw new Error("channels must be positive");
214
- /* calculate duration */
215
- const bytesPerSample = bitDepth / 8;
216
- const totalSamples = buffer.length / (bytesPerSample * channels);
217
- return totalSamples / sampleRate;
218
- }
219
- /* calculate duration of an audio array */
220
- function audioArrayDuration(arr, sampleRate = 48000, channels = 1) {
221
- /* sanity check parameters */
222
- if (arr.length === 0)
223
- return 0;
224
- if (sampleRate <= 0)
225
- throw new Error("sample rate must be positive");
226
- if (channels <= 0)
227
- throw new Error("channels must be positive");
228
- /* calculate duration */
229
- const totalSamples = arr.length / channels;
230
- return totalSamples / sampleRate;
231
- }
232
- /* helper function: convert Buffer in PCM/I16 to Float32Array in PCM/F32 format */
233
- function convertBufToF32(buf, littleEndian = true) {
234
- if (buf.length % 2 !== 0)
235
- throw new Error("buffer length must be even for 16-bit samples");
236
- const dataView = new DataView(buf.buffer);
237
- const arr = new Float32Array(buf.length / 2);
238
- for (let i = 0; i < arr.length; i++)
239
- arr[i] = dataView.getInt16(i * 2, littleEndian) / 32768;
240
- return arr;
241
- }
242
- /* helper function: convert Float32Array in PCM/F32 to Buffer in PCM/I16 format */
243
- function convertF32ToBuf(arr) {
244
- if (arr.length === 0)
245
- return Buffer.alloc(0);
246
- const int16Array = new Int16Array(arr.length);
247
- for (let i = 0; i < arr.length; i++) {
248
- let sample = arr[i];
249
- if (Number.isNaN(sample))
250
- sample = 0;
251
- int16Array[i] = Math.max(-32768, Math.min(32767, Math.round(sample * 32768)));
252
- }
253
- return Buffer.from(int16Array.buffer);
254
- }
255
- /* helper function: convert Buffer in PCM/I16 to Int16Array */
256
- function convertBufToI16(buf, littleEndian = true) {
257
- if (buf.length % 2 !== 0)
258
- throw new Error("buffer length must be even for 16-bit samples");
259
- const dataView = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
260
- const arr = new Int16Array(buf.length / 2);
261
- for (let i = 0; i < buf.length / 2; i++)
262
- arr[i] = dataView.getInt16(i * 2, littleEndian);
263
- return arr;
264
- }
265
- /* helper function: convert In16Array in PCM/I16 to Buffer */
266
- function convertI16ToBuf(arr, littleEndian = true) {
267
- if (arr.length === 0)
268
- return Buffer.alloc(0);
269
- const buf = Buffer.allocUnsafe(arr.length * 2);
270
- for (let i = 0; i < arr.length; i++) {
271
- if (littleEndian)
272
- buf.writeInt16LE(arr[i], i * 2);
273
- else
274
- buf.writeInt16BE(arr[i], i * 2);
275
- }
276
- return buf;
277
- }
278
- /* create a Duplex/Transform stream which has
279
- object-mode on Writable side and buffer/string-mode on Readable side */
280
- function createTransformStreamForWritableSide() {
281
- return new node_stream_1.default.Transform({
282
- readableObjectMode: true,
283
- writableObjectMode: true,
284
- decodeStrings: false,
285
- highWaterMark: 1,
286
- transform(chunk, encoding, callback) {
287
- this.push(chunk.payload);
288
- callback();
289
- },
290
- final(callback) {
291
- this.push(null);
292
- callback();
293
- }
294
- });
295
- }
296
- /* create a Duplex/Transform stream which has
297
- object-mode on Readable side and buffer/string-mode on Writable side */
298
- function createTransformStreamForReadableSide(type, getTimeZero) {
299
- return new node_stream_1.default.Transform({
300
- readableObjectMode: true,
301
- writableObjectMode: true,
302
- decodeStrings: false,
303
- highWaterMark: (type === "audio" ? 19200 : 65536),
304
- transform(chunk, encoding, callback) {
305
- if (chunk === null) {
306
- this.push(null);
307
- callback();
308
- return;
309
- }
310
- const timeZero = getTimeZero();
311
- const start = luxon_1.DateTime.now().diff(timeZero);
312
- let end = start;
313
- if (type === "audio") {
314
- const duration = audioBufferDuration(chunk);
315
- end = start.plus(duration * 1000);
316
- }
317
- const payload = ensureStreamChunk(type, chunk);
318
- const obj = new speechflow_node_1.SpeechFlowChunk(start, end, "final", type, payload);
319
- this.push(obj);
320
- callback();
321
- },
322
- final(callback) {
323
- this.push(null);
324
- callback();
325
- }
326
- });
327
- }
328
- /* ensure a chunk is of a certain type and format */
329
- function ensureStreamChunk(type, chunk) {
330
- if (chunk instanceof speechflow_node_1.SpeechFlowChunk) {
331
- if (chunk.type !== type)
332
- throw new Error(`invalid payload chunk (expected ${type} type, received ${chunk.type} type)`);
333
- }
334
- else {
335
- if (type === "text" && Buffer.isBuffer(chunk))
336
- chunk = chunk.toString("utf8");
337
- else if (type === "audio" && !Buffer.isBuffer(chunk))
338
- chunk = Buffer.from(chunk);
339
- }
340
- return chunk;
341
- }
342
- /* encode/serialize chunk of data */
343
- function streamChunkEncode(chunk) {
344
- let payload;
345
- if (Buffer.isBuffer(chunk.payload))
346
- payload = new Uint8Array(chunk.payload);
347
- else {
348
- const encoder = new TextEncoder();
349
- payload = encoder.encode(chunk.payload);
350
- }
351
- const data = {
352
- timestampStart: chunk.timestampStart.toMillis(),
353
- timestampEnd: chunk.timestampEnd.toMillis(),
354
- kind: chunk.kind,
355
- type: chunk.type,
356
- payload
357
- };
358
- const _data = CBOR.encode(data);
359
- return _data;
360
- }
361
- /* decode/unserialize chunk of data */
362
- function streamChunkDecode(_data) {
363
- let data;
364
- try {
365
- data = CBOR.decode(_data);
366
- }
367
- catch (err) {
368
- throw new Error(`CBOR decoding failed: ${err}`);
369
- }
370
- let payload;
371
- if (data.type === "audio")
372
- payload = Buffer.from(data.payload);
373
- else
374
- payload = (new TextDecoder()).decode(data.payload);
375
- const chunk = new speechflow_node_1.SpeechFlowChunk(luxon_1.Duration.fromMillis(data.timestampStart), luxon_1.Duration.fromMillis(data.timestampEnd), data.kind, data.type, payload);
376
- return chunk;
377
- }
378
- /* helper class for single item queue */
379
- class SingleQueue extends node_events_1.EventEmitter {
380
- queue = new Array();
381
- write(item) {
382
- this.queue.unshift(item);
383
- this.emit("dequeue");
384
- }
385
- read() {
386
- return new Promise((resolve, reject) => {
387
- const consume = () => this.queue.length > 0 ? this.queue.pop() : null;
388
- const tryToConsume = () => {
389
- const item = consume();
390
- if (item !== null)
391
- resolve(item);
392
- else
393
- this.once("dequeue", tryToConsume);
394
- };
395
- tryToConsume();
396
- });
397
- }
398
- }
399
- exports.SingleQueue = SingleQueue;
400
- /* helper class for double-item queue */
401
- class DoubleQueue extends node_events_1.EventEmitter {
402
- queue0 = new Array();
403
- queue1 = new Array();
404
- notify() {
405
- if (this.queue0.length > 0 && this.queue1.length > 0)
406
- this.emit("dequeue");
407
- }
408
- write0(item) {
409
- this.queue0.unshift(item);
410
- this.notify();
411
- }
412
- write1(item) {
413
- this.queue1.unshift(item);
414
- this.notify();
415
- }
416
- read() {
417
- return new Promise((resolve, reject) => {
418
- const consume = () => {
419
- if (this.queue0.length > 0 && this.queue1.length > 0) {
420
- const item0 = this.queue0.pop();
421
- const item1 = this.queue1.pop();
422
- return [item0, item1];
423
- }
424
- return null;
425
- };
426
- const tryToConsume = () => {
427
- const items = consume();
428
- if (items !== null)
429
- resolve(items);
430
- else
431
- this.once("dequeue", tryToConsume);
432
- };
433
- tryToConsume();
434
- });
435
- }
436
- }
437
- exports.DoubleQueue = DoubleQueue;
438
- /* queue pointer */
439
- class QueuePointer extends node_events_1.EventEmitter {
440
- name;
441
- queue;
442
- /* internal state */
443
- index = 0;
444
- /* construction */
445
- constructor(name, queue) {
446
- super();
447
- this.name = name;
448
- this.queue = queue;
449
- this.setMaxListeners(100);
450
- }
451
- /* positioning operations */
452
- maxPosition() {
453
- return this.queue.elements.length;
454
- }
455
- position(index) {
456
- if (index !== undefined) {
457
- this.index = Math.max(0, Math.min(index, this.queue.elements.length));
458
- this.emit("position", this.index);
459
- }
460
- return this.index;
461
- }
462
- walk(num) {
463
- const indexOld = this.index;
464
- if (num > 0)
465
- this.index = Math.min(this.index + num, this.queue.elements.length);
466
- else if (num < 0)
467
- this.index = Math.max(this.index + num, 0);
468
- if (this.index !== indexOld)
469
- this.emit("position", { start: this.index });
470
- }
471
- walkForwardUntil(type) {
472
- while (this.index < this.queue.elements.length
473
- && this.queue.elements[this.index].type !== type)
474
- this.index++;
475
- this.emit("position", { start: this.index });
476
- }
477
- walkBackwardUntil(type) {
478
- while (this.index > 0
479
- && this.queue.elements[this.index].type !== type)
480
- this.index--;
481
- this.emit("position", { start: this.index });
482
- }
483
- /* search operations */
484
- searchForward(type) {
485
- let position = this.index;
486
- while (position < this.queue.elements.length
487
- && this.queue.elements[position].type !== type)
488
- position++;
489
- this.emit("search", { start: this.index, end: position });
490
- return position;
491
- }
492
- searchBackward(type) {
493
- let position = this.index;
494
- while (position > 0
495
- && this.queue.elements[position].type !== type)
496
- position--;
497
- this.emit("search", { start: position, end: this.index });
498
- return position;
499
- }
500
- /* reading operations */
501
- peek(position) {
502
- if (position === undefined)
503
- position = this.index;
504
- position = Math.max(0, Math.min(position, this.queue.elements.length));
505
- const element = this.queue.elements[position];
506
- this.queue.emit("read", { start: position, end: position });
507
- return element;
508
- }
509
- read() {
510
- const element = this.queue.elements[this.index];
511
- if (this.index < this.queue.elements.length)
512
- this.index++;
513
- this.queue.emit("read", { start: this.index - 1, end: this.index - 1 });
514
- return element;
515
- }
516
- slice(size) {
517
- let slice;
518
- const start = this.index;
519
- if (size !== undefined) {
520
- size = Math.max(0, Math.min(size, this.queue.elements.length - this.index));
521
- slice = this.queue.elements.slice(this.index, this.index + size);
522
- this.index += size;
523
- }
524
- else {
525
- slice = this.queue.elements.slice(this.index);
526
- this.index = this.queue.elements.length;
527
- }
528
- this.queue.emit("read", { start, end: this.index });
529
- return slice;
530
- }
531
- /* writing operations */
532
- touch() {
533
- if (this.index >= this.queue.elements.length)
534
- throw new Error("cannot touch after last element");
535
- this.queue.emit("write", { start: this.index, end: this.index + 1 });
536
- }
537
- append(element) {
538
- this.queue.elements.push(element);
539
- this.index = this.queue.elements.length;
540
- this.queue.emit("write", { start: this.index - 1, end: this.index - 1 });
541
- }
542
- insert(element) {
543
- this.queue.elements.splice(this.index, 0, element);
544
- this.queue.emit("write", { start: this.index - 1, end: this.index });
545
- }
546
- delete() {
547
- if (this.index >= this.queue.elements.length)
548
- throw new Error("cannot delete after last element");
549
- this.queue.elements.splice(this.index, 1);
550
- this.queue.emit("write", { start: this.index, end: this.index });
551
- }
552
- }
553
- exports.QueuePointer = QueuePointer;
554
- /* queue */
555
- class Queue extends node_events_1.EventEmitter {
556
- elements = [];
557
- pointers = new Map();
558
- constructor() {
559
- super();
560
- this.setMaxListeners(100);
561
- }
562
- pointerUse(name) {
563
- if (!this.pointers.has(name))
564
- this.pointers.set(name, new QueuePointer(name, this));
565
- return this.pointers.get(name);
566
- }
567
- pointerDelete(name) {
568
- if (!this.pointers.has(name))
569
- throw new Error("pointer not exists");
570
- this.pointers.delete(name);
571
- }
572
- trim() {
573
- /* determine minimum pointer position */
574
- let min = this.elements.length;
575
- for (const pointer of this.pointers.values())
576
- if (min > pointer.position())
577
- min = pointer.position();
578
- /* trim the maximum amount of first elements */
579
- if (min > 0) {
580
- this.elements.splice(0, min);
581
- /* shift all pointers */
582
- for (const pointer of this.pointers.values())
583
- pointer.position(pointer.position() - min);
584
- }
585
- }
586
- }
587
- exports.Queue = Queue;
588
- /* utility class for wrapping a custom stream into a regular Transform stream */
589
- class StreamWrapper extends node_stream_1.default.Transform {
590
- foreignStream;
591
- onData = (chunk) => { this.push(chunk); };
592
- onError = (err) => { this.emit("error", err); };
593
- onEnd = () => { this.push(null); };
594
- constructor(foreignStream, options = {}) {
595
- options.readableObjectMode = true;
596
- options.writableObjectMode = true;
597
- super(options);
598
- this.foreignStream = foreignStream;
599
- if (typeof this.foreignStream.on === "function") {
600
- this.foreignStream.on("data", this.onData);
601
- this.foreignStream.on("error", this.onError);
602
- this.foreignStream.on("end", this.onEnd);
603
- }
604
- }
605
- _transform(chunk, encoding, callback) {
606
- if (this.destroyed) {
607
- callback(new Error("stream already destroyed"));
608
- return;
609
- }
610
- try {
611
- if (typeof this.foreignStream.write === "function") {
612
- const canContinue = this.foreignStream.write(chunk);
613
- if (canContinue)
614
- callback();
615
- else
616
- this.foreignStream.once("drain", callback);
617
- }
618
- else
619
- throw new Error("foreign stream lacks write method");
620
- }
621
- catch (err) {
622
- callback(err);
623
- }
624
- }
625
- _flush(callback) {
626
- if (this.destroyed) {
627
- callback(new Error("stream already destroyed"));
628
- return;
629
- }
630
- try {
631
- if (typeof this.foreignStream.end === "function")
632
- this.foreignStream.end();
633
- callback();
634
- }
635
- catch (err) {
636
- callback(err);
637
- }
638
- }
639
- _destroy(error, callback) {
640
- if (typeof this.foreignStream.removeListener === "function") {
641
- this.foreignStream.removeListener("data", this.onData);
642
- this.foreignStream.removeListener("error", this.onError);
643
- this.foreignStream.removeListener("end", this.onEnd);
644
- }
645
- super._destroy(error, callback);
646
- }
647
- }
648
- exports.StreamWrapper = StreamWrapper;
649
- class TimeStore extends node_events_1.EventEmitter {
650
- tree = new IntervalTree.IntervalTree();
651
- store(start, end, item) {
652
- this.tree.insert({ low: start.toMillis(), high: end.toMillis(), item });
653
- }
654
- fetch(start, end) {
655
- const intervals = this.tree.search(start.toMillis(), end.toMillis());
656
- return intervals.map((interval) => interval.item);
657
- }
658
- prune(_before) {
659
- const before = _before.toMillis();
660
- const intervals = this.tree.search(0, before - 1);
661
- for (const interval of intervals)
662
- if (interval.low < before && interval.high < before)
663
- this.tree.remove(interval);
664
- }
665
- clear() {
666
- this.tree = new IntervalTree.IntervalTree();
667
- }
668
- }
669
- exports.TimeStore = TimeStore;
670
- /* asynchronous queue */
671
- class AsyncQueue {
672
- queue = [];
673
- resolvers = [];
674
- write(v) {
675
- const resolve = this.resolvers.shift();
676
- if (resolve)
677
- resolve(v);
678
- else
679
- this.queue.push(v);
680
- }
681
- async read() {
682
- if (this.queue.length > 0)
683
- return this.queue.shift();
684
- else
685
- return new Promise((resolve) => this.resolvers.push(resolve));
686
- }
687
- destroy() {
688
- for (const resolve of this.resolvers)
689
- resolve(null);
690
- this.resolvers = [];
691
- this.queue = [];
692
- }
693
- }
694
- exports.AsyncQueue = AsyncQueue;
695
- /* process Int16Array in fixed-size segments */
696
- async function processInt16ArrayInSegments(data, segmentSize, processor) {
697
- /* process full segments */
698
- let i = 0;
699
- while ((i + segmentSize) <= data.length) {
700
- const segment = data.slice(i, i + segmentSize);
701
- const result = await processor(segment);
702
- data.set(result, i);
703
- i += segmentSize;
704
- }
705
- /* process final partial segment if it exists */
706
- if (i < data.length) {
707
- const len = data.length - i;
708
- const segment = new Int16Array(segmentSize);
709
- segment.set(data.slice(i), 0);
710
- segment.fill(0, len, segmentSize);
711
- const result = await processor(segment);
712
- data.set(result.slice(0, len), i);
713
- }
714
- return data;
715
- }
716
- /* cached regular expression class */
717
- class CachedRegExp {
718
- cache = new Map();
719
- compile(pattern) {
720
- if (this.cache.has(pattern))
721
- return this.cache.get(pattern);
722
- try {
723
- const regex = new RegExp(pattern);
724
- this.cache.set(pattern, regex);
725
- return regex;
726
- }
727
- catch (_error) {
728
- return null;
729
- }
730
- }
731
- clear() {
732
- this.cache.clear();
733
- }
734
- size() {
735
- return this.cache.size;
736
- }
737
- }
738
- exports.CachedRegExp = CachedRegExp;
739
- /* helper functions for linear/decibel conversions */
740
- function lin2dB(x) {
741
- return 20 * Math.log10(Math.max(x, 1e-12));
742
- }
743
- function dB2lin(db) {
744
- return Math.pow(10, db / 20);
745
- }
746
- //# sourceMappingURL=speechflow-utils.js.map