speechflow 0.9.9 → 1.1.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 (120) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +57 -9
  3. package/dst/speechflow-node-a2a-ffmpeg.js +1 -0
  4. package/dst/speechflow-node-a2a-ffmpeg.js.map +1 -0
  5. package/dst/{speechflow-node-gemma.d.ts → speechflow-node-a2a-meter.d.ts} +2 -3
  6. package/dst/speechflow-node-a2a-meter.js +151 -0
  7. package/dst/speechflow-node-a2a-meter.js.map +1 -0
  8. package/dst/speechflow-node-a2a-mute.d.ts +16 -0
  9. package/dst/speechflow-node-a2a-mute.js +90 -0
  10. package/dst/speechflow-node-a2a-mute.js.map +1 -0
  11. package/dst/speechflow-node-a2a-vad.js +130 -289
  12. package/dst/speechflow-node-a2a-vad.js.map +1 -0
  13. package/dst/speechflow-node-a2a-wav.js +1 -0
  14. package/dst/speechflow-node-a2a-wav.js.map +1 -0
  15. package/dst/speechflow-node-a2t-deepgram.d.ts +3 -0
  16. package/dst/speechflow-node-a2t-deepgram.js +18 -2
  17. package/dst/speechflow-node-a2t-deepgram.js.map +1 -0
  18. package/dst/speechflow-node-t2a-elevenlabs.d.ts +3 -0
  19. package/dst/speechflow-node-t2a-elevenlabs.js +9 -1
  20. package/dst/speechflow-node-t2a-elevenlabs.js.map +1 -0
  21. package/dst/speechflow-node-t2a-kokoro.js +1 -0
  22. package/dst/speechflow-node-t2a-kokoro.js.map +1 -0
  23. package/dst/speechflow-node-t2t-deepl.d.ts +3 -0
  24. package/dst/speechflow-node-t2t-deepl.js +9 -1
  25. package/dst/speechflow-node-t2t-deepl.js.map +1 -0
  26. package/dst/speechflow-node-t2t-format.js +1 -0
  27. package/dst/speechflow-node-t2t-format.js.map +1 -0
  28. package/dst/speechflow-node-t2t-ollama.js +1 -0
  29. package/dst/speechflow-node-t2t-ollama.js.map +1 -0
  30. package/dst/speechflow-node-t2t-openai.js +2 -1
  31. package/dst/speechflow-node-t2t-openai.js.map +1 -0
  32. package/dst/speechflow-node-t2t-subtitle.js +1 -0
  33. package/dst/speechflow-node-t2t-subtitle.js.map +1 -0
  34. package/dst/speechflow-node-t2t-transformers.js +10 -6
  35. package/dst/speechflow-node-t2t-transformers.js.map +1 -0
  36. package/dst/speechflow-node-x2x-trace.js +2 -1
  37. package/dst/speechflow-node-x2x-trace.js.map +1 -0
  38. package/dst/speechflow-node-xio-device.js +4 -1
  39. package/dst/speechflow-node-xio-device.js.map +1 -0
  40. package/dst/speechflow-node-xio-file.js +4 -1
  41. package/dst/speechflow-node-xio-file.js.map +1 -0
  42. package/dst/speechflow-node-xio-mqtt.js +8 -5
  43. package/dst/speechflow-node-xio-mqtt.js.map +1 -0
  44. package/dst/speechflow-node-xio-websocket.js +6 -5
  45. package/dst/speechflow-node-xio-websocket.js.map +1 -0
  46. package/dst/speechflow-node.d.ts +8 -1
  47. package/dst/speechflow-node.js +18 -2
  48. package/dst/speechflow-node.js.map +1 -0
  49. package/dst/speechflow-utils.d.ts +33 -0
  50. package/dst/speechflow-utils.js +183 -1
  51. package/dst/speechflow-utils.js.map +1 -0
  52. package/dst/speechflow.js +259 -16
  53. package/dst/speechflow.js.map +1 -0
  54. package/etc/speechflow.yaml +9 -7
  55. package/etc/stx.conf +1 -1
  56. package/etc/tsconfig.json +2 -2
  57. package/package.json +19 -12
  58. package/src/speechflow-node-a2a-meter.ts +129 -0
  59. package/src/speechflow-node-a2a-mute.ts +101 -0
  60. package/src/speechflow-node-a2a-vad.ts +266 -0
  61. package/src/speechflow-node-a2t-deepgram.ts +18 -2
  62. package/src/speechflow-node-t2a-elevenlabs.ts +9 -1
  63. package/src/speechflow-node-t2t-deepl.ts +9 -1
  64. package/src/speechflow-node-t2t-openai.ts +1 -1
  65. package/src/speechflow-node-t2t-transformers.ts +12 -7
  66. package/src/speechflow-node-x2x-trace.ts +1 -1
  67. package/src/speechflow-node-xio-device.ts +4 -1
  68. package/src/speechflow-node-xio-file.ts +3 -1
  69. package/src/speechflow-node-xio-mqtt.ts +8 -6
  70. package/src/speechflow-node-xio-websocket.ts +11 -11
  71. package/src/speechflow-node.ts +21 -2
  72. package/src/speechflow-utils.ts +195 -0
  73. package/src/speechflow.ts +245 -16
  74. package/dst/speechflow-node-deepgram.d.ts +0 -12
  75. package/dst/speechflow-node-deepgram.js +0 -220
  76. package/dst/speechflow-node-deepl.d.ts +0 -12
  77. package/dst/speechflow-node-deepl.js +0 -128
  78. package/dst/speechflow-node-device.d.ts +0 -13
  79. package/dst/speechflow-node-device.js +0 -205
  80. package/dst/speechflow-node-elevenlabs.d.ts +0 -13
  81. package/dst/speechflow-node-elevenlabs.js +0 -182
  82. package/dst/speechflow-node-ffmpeg.d.ts +0 -13
  83. package/dst/speechflow-node-ffmpeg.js +0 -152
  84. package/dst/speechflow-node-file.d.ts +0 -11
  85. package/dst/speechflow-node-file.js +0 -176
  86. package/dst/speechflow-node-format.d.ts +0 -11
  87. package/dst/speechflow-node-format.js +0 -80
  88. package/dst/speechflow-node-gemma.js +0 -213
  89. package/dst/speechflow-node-mqtt.d.ts +0 -13
  90. package/dst/speechflow-node-mqtt.js +0 -181
  91. package/dst/speechflow-node-opus.d.ts +0 -12
  92. package/dst/speechflow-node-opus.js +0 -135
  93. package/dst/speechflow-node-subtitle.d.ts +0 -12
  94. package/dst/speechflow-node-subtitle.js +0 -96
  95. package/dst/speechflow-node-t2t-gemma.d.ts +0 -13
  96. package/dst/speechflow-node-t2t-gemma.js +0 -233
  97. package/dst/speechflow-node-t2t-opus.d.ts +0 -12
  98. package/dst/speechflow-node-t2t-opus.js +0 -135
  99. package/dst/speechflow-node-trace.d.ts +0 -11
  100. package/dst/speechflow-node-trace.js +0 -88
  101. package/dst/speechflow-node-wav.d.ts +0 -11
  102. package/dst/speechflow-node-wav.js +0 -170
  103. package/dst/speechflow-node-websocket.d.ts +0 -13
  104. package/dst/speechflow-node-websocket.js +0 -275
  105. package/dst/speechflow-node-whisper-common.d.ts +0 -34
  106. package/dst/speechflow-node-whisper-common.js +0 -7
  107. package/dst/speechflow-node-whisper-ggml.d.ts +0 -1
  108. package/dst/speechflow-node-whisper-ggml.js +0 -97
  109. package/dst/speechflow-node-whisper-onnx.d.ts +0 -1
  110. package/dst/speechflow-node-whisper-onnx.js +0 -131
  111. package/dst/speechflow-node-whisper-worker-ggml.d.ts +0 -1
  112. package/dst/speechflow-node-whisper-worker-ggml.js +0 -97
  113. package/dst/speechflow-node-whisper-worker-onnx.d.ts +0 -1
  114. package/dst/speechflow-node-whisper-worker-onnx.js +0 -131
  115. package/dst/speechflow-node-whisper-worker.d.ts +0 -1
  116. package/dst/speechflow-node-whisper-worker.js +0 -116
  117. package/dst/speechflow-node-whisper-worker2.d.ts +0 -1
  118. package/dst/speechflow-node-whisper-worker2.js +0 -82
  119. package/dst/speechflow-node-whisper.d.ts +0 -19
  120. package/dst/speechflow-node-whisper.js +0 -604
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
  ChangeLog
3
3
  =========
4
4
 
5
+ 1.1.0 (2025-07-19)
6
+ ------------------
7
+
8
+ - IMPROVEMENT: allow querying the status of nodes: currently used for gathering credit/usage information
9
+ - BUGFIX: add "final" callback to Stream.Transform of "meter" node
10
+ - BUGFIX: fix positional argument usage in "meter" node
11
+ - UPGRADE: upgrade NPM dependencies
12
+
13
+ 1.0.0 (2025-07-16)
14
+ ------------------
15
+
16
+ - IMPROVEMENT: add "vad" node for voice audio detection
17
+ - IMPROVEMENT: add "mute" node for audio muting
18
+ - IMPROVEMENT: add "meter" node for audio loudness metering
19
+ - IMPROVEMENT: add REST/WebSocket API for external requests to nodes and events from nodes
20
+
5
21
  0.9.9 (2025-07-13)
6
22
  ------------------
7
23
 
package/README.md CHANGED
@@ -97,7 +97,7 @@ They can also be found in the sample [speechflow.yaml](./etc/speechflow.yaml) fi
97
97
  ```
98
98
  file(path: argv.0, mode: "r", type: "audio") |
99
99
  ffmpeg(src: "mp3", dst: "pcm") |
100
- deepgram(language: "de", key: env.SPEECHFLOW_KEY_DEEPGRAM) |
100
+ deepgram(language: "de", key: env.SPEECHFLOW_DEEPGRAM_KEY) |
101
101
  format(width: 80) |
102
102
  file(path: argv.1, mode: "w", type: "text")
103
103
  ```
@@ -107,7 +107,7 @@ They can also be found in the sample [speechflow.yaml](./etc/speechflow.yaml) fi
107
107
  ```
108
108
  file(path: argv.0, mode: "r", type: "audio") |
109
109
  ffmpeg(src: "mp3", dst: "pcm") |
110
- deepgram(language: "de", key: env.SPEECHFLOW_KEY_DEEPGRAM) |
110
+ deepgram(language: "de", key: env.SPEECHFLOW_DEEPGRAM_KEY) |
111
111
  subtitle(format: "vtt") |
112
112
  file(path: argv.1, mode: "w", type: "text")
113
113
  ```
@@ -137,10 +137,10 @@ They can also be found in the sample [speechflow.yaml](./etc/speechflow.yaml) fi
137
137
  device(device: "coreaudio:Elgato Wave:3", mode: "r") | {
138
138
  wav(mode: "encode") |
139
139
  file(path: "program-de.wav", mode: "w", type: "audio"),
140
- deepgram(key: env.SPEECHFLOW_KEY_DEEPGRAM, language: "de") | {
140
+ deepgram(key: env.SPEECHFLOW_DEEPGRAM_KEY, language: "de") | {
141
141
  format(width: 80) |
142
142
  file(path: "program-de.txt", mode: "w", type: "text"),
143
- deepl(key: env.SPEECHFLOW_KEY_DEEPL, src: "de", dst: "en") | {
143
+ deepl(key: env.SPEECHFLOW_DEEPL_KEY, src: "de", dst: "en") | {
144
144
  format(width: 80) |
145
145
  file(path: "program-en.txt", mode: "w", type: "text"),
146
146
  subtitle(format: "vtt") | {
@@ -174,7 +174,10 @@ First a short overview of the available processing nodes:
174
174
  **mqtt**.
175
175
  - Audio-to-Audio nodes:
176
176
  **ffmpeg**,
177
- **wav**.
177
+ **wav**,
178
+ **mute**.
179
+ **meter**.
180
+ **vad**.
178
181
  - Audio-to-Text nodes:
179
182
  **deepgram**.
180
183
  - Text-to-Text nodes:
@@ -282,6 +285,50 @@ First a short overview of the available processing nodes:
282
285
  | ----------- | --------- | -------- | ------------------------ |
283
286
  | **mode** | 0 | "encode" | `/^(?:encode\|decode)$/` |
284
287
 
288
+ - Node: **mute**<br/>
289
+ Purpose: **volume muting node**<br/>
290
+ Example: `mute()`
291
+ Notice: this node has to be externally controlled via REST/WebSockets!
292
+
293
+ | Port | Payload |
294
+ | ------- | ----------- |
295
+ | input | audio |
296
+ | output | audio |
297
+
298
+ | Parameter | Position | Default | Requirement |
299
+ | ----------- | --------- | -------- | ------------------------ |
300
+
301
+ - Node: **meter**<br/>
302
+ Purpose: **Loudness metering node**<br/>
303
+ Example: `meter(250)`
304
+
305
+ | Port | Payload |
306
+ | ------- | ----------- |
307
+ | input | audio |
308
+ | output | audio |
309
+
310
+ | Parameter | Position | Default | Requirement |
311
+ | ----------- | --------- | -------- | ------------------------ |
312
+ | **interval** | 0 | 250 | *none* |
313
+
314
+ - Node: **vad**<br/>
315
+ Purpose: **Voice Audio Detection (VAD) node**<br/>
316
+ Example: `vad()`
317
+
318
+ | Port | Payload |
319
+ | ------- | ----------- |
320
+ | input | audio |
321
+ | output | audio |
322
+
323
+ | Parameter | Position | Default | Requirement |
324
+ | ----------- | --------- | -------- | ------------------------ |
325
+ | **mode** | *none* | "unplugged" | `/^(?:silenced|unplugged)$/` |
326
+ | **posSpeechThreshold** | *none* | 0.50 | *none* |
327
+ | **negSpeechThreshold** | *none* | 0.35 | *none* |
328
+ | **minSpeechFrames** | *none* | 2 | *none* |
329
+ | **redemptionFrames** | *none* | 12 | *none* |
330
+ | **preSpeechPadFrames** | *none* | 1 | *none* |
331
+
285
332
  ### Audio-to-Text Nodes:
286
333
 
287
334
  - Node: **deepgram**<br/>
@@ -296,7 +343,8 @@ First a short overview of the available processing nodes:
296
343
 
297
344
  | Parameter | Position | Default | Requirement |
298
345
  | ------------ | --------- | -------- | ------------------ |
299
- | **key** | *none* | env.SPEECHFLOW\_KEY\_DEEPGRAM | *none* |
346
+ | **key** | *none* | env.SPEECHFLOW\_DEEPGRAM\_KEY | *none* |
347
+ | **keyAdm** | *none* | env.SPEECHFLOW\_DEEPGRAM\_KEY\_ADM | *none* |
300
348
  | **model** | 0 | "nova-3" | *none* |
301
349
  | **version** | 1 | "latest" | *none* |
302
350
  | **language** | 2 | "multi" | *none* |
@@ -315,7 +363,7 @@ First a short overview of the available processing nodes:
315
363
 
316
364
  | Parameter | Position | Default | Requirement |
317
365
  | ------------ | --------- | -------- | ------------------ |
318
- | **key** | *none* | env.SPEECHFLOW\_KEY\_DEEPL | *none* |
366
+ | **key** | *none* | env.SPEECHFLOW\_DEEPL\_KEY | *none* |
319
367
  | **src** | 0 | "de" | `/^(?:de\|en)$/` |
320
368
  | **dst** | 1 | "en" | `/^(?:de\|en)$/` |
321
369
 
@@ -334,7 +382,7 @@ First a short overview of the available processing nodes:
334
382
  | **api** | *none* | "https://api.openai.com" | `/^https?:\/\/.+?:\d+$/` |
335
383
  | **src** | 0 | "de" | `/^(?:de\|en)$/` |
336
384
  | **dst** | 1 | "en" | `/^(?:de\|en)$/` |
337
- | **key** | *none* | env.SPEECHFLOW\_KEY\_OPENAI | *none* |
385
+ | **key** | *none* | env.SPEECHFLOW\_OPENAI\_KEY | *none* |
338
386
  | **model** | *none* | "gpt-4o-mini" | *none* |
339
387
 
340
388
  - Node: **ollama**<br/>
@@ -409,7 +457,7 @@ First a short overview of the available processing nodes:
409
457
 
410
458
  | Parameter | Position | Default | Requirement |
411
459
  | ------------ | --------- | -------- | ------------------ |
412
- | **key** | *none* | env.SPEECHFLOW\_KEY\_ELEVENLABS | *none* |
460
+ | **key** | *none* | env.SPEECHFLOW\_ELEVENLABS\_KEY | *none* |
413
461
  | **voice** | 0 | "Brian" | *none* |
414
462
  | **language** | 1 | "de" | *none* |
415
463
 
@@ -150,3 +150,4 @@ class SpeechFlowNodeFFmpeg extends speechflow_node_1.default {
150
150
  }
151
151
  }
152
152
  exports.default = SpeechFlowNodeFFmpeg;
153
+ //# sourceMappingURL=speechflow-node-a2a-ffmpeg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speechflow-node-a2a-ffmpeg.js","sourceRoot":"","sources":["../src/speechflow-node-a2a-ffmpeg.ts"],"names":[],"mappings":";AAAA;;;;EAIE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEF,6BAA6B;AAC7B,8DAAuD;AAEvD,6BAA6B;AAC7B,yDAAuD;AACvD,iDAAyD;AAEzD,6BAA6B;AAC7B,wEAA6D;AAC7D,0DAA8D;AAE9D,kCAAkC;AAClC,MAAqB,oBAAqB,SAAQ,yBAAc;IAC5D,kCAAkC;IAC3B,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAA;IAE7B,sBAAsB;IACd,YAAY,GAAG,gBAAM,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC1D,MAAM,GAAwB,IAAI,CAAA;IAE1C,sBAAsB;IACtB,YAAa,EAAU,EAAE,GAA4B,EAAE,IAA6B,EAAE,IAAW;QAC7F,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAE1B,6CAA6C;QAC7C,IAAI,CAAC,SAAS,CAAC;YACX,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE;YAC5E,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE;SAC/E,CAAC,CAAA;QAEF,wCAAwC;QACxC,IAAI,CAAC,KAAK,GAAI,OAAO,CAAA;QACrB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAA;IACzB,CAAC;IAED,iBAAiB;IACjB,KAAK,CAAC,IAAI;QACN,8BAA8B;QAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG;YACnC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;QAE5E,sCAAsC;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,yBAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;YAC9C,4BAA4B;YAC5B,QAAQ,EAAW,UAAU;YAC7B,OAAO,EAAY,WAAW;YAC9B,WAAW,EAAQ,EAAE;YACrB,iBAAiB,EAAE,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC5B,GAAG,EAAY,OAAO;gBACtB,IAAI,EAAW,IAAI,CAAC,MAAM,CAAC,eAAe;gBAC1C,IAAI,EAAW,IAAI,CAAC,MAAM,CAAC,aAAa;aAC3C,CAAC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC5B,GAAG,EAAY,KAAK;aACvB,CAAC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC5B,GAAG,EAAY,KAAK;aACvB,CAAC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC;gBAC7B,GAAG,EAAY,MAAM;aACxB,CAAC,CAAC,CAAC,EAAE,CAAC;SACV,CAAC,CAAA;QACF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAChD,6BAA6B;YAC7B,eAAe,EAAI,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC5B,KAAK,EAAU,WAAW;gBAC1B,IAAI,EAAW,IAAI,CAAC,MAAM,CAAC,eAAe;gBAC1C,IAAI,EAAW,IAAI,CAAC,MAAM,CAAC,aAAa;gBACxC,GAAG,EAAY,OAAO;aACzB,CAAC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC5B,GAAG,EAAY,KAAK;aACvB,CAAC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC;gBAC5B,KAAK,EAAU,YAAY;gBAC3B,KAAK,EAAU,MAAM;gBACrB,GAAG,EAAY,KAAK;aACvB,CAAC,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC;gBAC7B,QAAQ,EAAO,SAAS;gBACxB,GAAG,EAAY,MAAM;aACxB,CAAC,CAAC,CAAC,EAAE,CAAC;SACV,CAAC,CAAA;QACF,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;QAEjB,0DAA0D;QAC1D,IAAI,CAAC,MAAM,GAAG,qBAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YAC7B,QAAQ,EAAE,WAAW;YACrB,QAAQ,EAAE,YAAY;SACzB,CAAC,CAAA;QAEF,8DAA8D;QAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,oCAAoC,EAAE,CAAA;QAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,oCAAoC,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACzF,IAAI,CAAC,MAAM,GAAG,qBAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACjE,CAAC;IAED,kBAAkB;IAClB,KAAK,CAAC,KAAK;QACP,2BAA2B;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAChC,IAAI,IAAI,CAAC,MAAM,YAAY,qBAAM,CAAC,MAAM;oBACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;;oBAEpC,OAAO,EAAE,CAAA;YACjB,CAAC,CAAC,CAAA;YACF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;YACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QACtB,CAAC;QAED,uBAAuB;QACvB,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;YAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QACtB,CAAC;IACL,CAAC;;AA3GL,uCA4GC"}
@@ -1,8 +1,7 @@
1
1
  import SpeechFlowNode from "./speechflow-node";
2
- export default class SpeechFlowNodeGemma extends SpeechFlowNode {
2
+ export default class SpeechFlowNodeMeter extends SpeechFlowNode {
3
3
  static name: string;
4
- private ollama;
5
- private setup;
4
+ interval: ReturnType<typeof setInterval> | null;
6
5
  constructor(id: string, cfg: {
7
6
  [id: string]: any;
8
7
  }, opts: {
@@ -0,0 +1,151 @@
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
+ /* standard dependencies */
45
+ const node_stream_1 = __importDefault(require("node:stream"));
46
+ /* external dependencies */
47
+ const audio_inspect_1 = require("audio-inspect");
48
+ /* internal dependencies */
49
+ const speechflow_node_1 = __importDefault(require("./speechflow-node"));
50
+ const utils = __importStar(require("./speechflow-utils"));
51
+ /* SpeechFlow node for audio metering */
52
+ class SpeechFlowNodeMeter extends speechflow_node_1.default {
53
+ /* declare official node name */
54
+ static name = "meter";
55
+ /* internal state */
56
+ interval = null;
57
+ /* construct node */
58
+ constructor(id, cfg, opts, args) {
59
+ super(id, cfg, opts, args);
60
+ /* declare node configuration parameters */
61
+ this.configure({
62
+ interval: { type: "number", pos: 0, val: 250 }
63
+ });
64
+ /* declare node input/output format */
65
+ this.input = "audio";
66
+ this.output = "audio";
67
+ }
68
+ /* open node */
69
+ async open() {
70
+ /* sanity check situation */
71
+ if (this.config.audioBitDepth !== 16 || !this.config.audioLittleEndian)
72
+ throw new Error("VAD node currently supports PCM-S16LE audio only");
73
+ /* internal state */
74
+ const sampleWindowDuration = 3; /* LUFS-S requires 3s */
75
+ const sampleWindowSize = this.config.audioSampleRate * sampleWindowDuration;
76
+ let sampleWindow = new Float32Array(sampleWindowSize);
77
+ sampleWindow.fill(0, 0, sampleWindowSize);
78
+ let lufss = 0;
79
+ let rms = 0;
80
+ /* setup loundess emitting interval */
81
+ this.interval = setInterval(() => {
82
+ this.log("info", `LUFS-S: ${lufss.toFixed(1)} dB, RMS: ${rms.toFixed(1)} dB`);
83
+ this.sendResponse(["meter", "LUFS-S", lufss]);
84
+ this.sendResponse(["meter", "RMS", rms]);
85
+ }, this.params.interval);
86
+ /* provide Duplex stream and internally attach to VAD */
87
+ const self = this;
88
+ this.stream = new node_stream_1.default.Transform({
89
+ writableObjectMode: true,
90
+ readableObjectMode: true,
91
+ decodeStrings: false,
92
+ /* transform audio chunk */
93
+ transform(chunk, encoding, callback) {
94
+ if (!Buffer.isBuffer(chunk.payload))
95
+ callback(new Error("expected audio input as Buffer chunks"));
96
+ else if (chunk.payload.byteLength === 0)
97
+ callback();
98
+ else {
99
+ /* convert audio samples from PCM/I16 to PCM/F32 */
100
+ const data = utils.convertBufToF32(chunk.payload, self.config.audioLittleEndian);
101
+ /* update internal audio sample sliding window */
102
+ const fusion = new Float32Array(sampleWindow.length + data.length);
103
+ fusion.set(sampleWindow, 0);
104
+ fusion.set(data, sampleWindow.length);
105
+ sampleWindow = fusion.slice(fusion.length - sampleWindowSize);
106
+ /* asynchronously calculate the LUFS-S metric */
107
+ setTimeout(() => {
108
+ const audioData = {
109
+ sampleRate: self.config.audioSampleRate,
110
+ numberOfChannels: self.config.audioChannels,
111
+ channelData: [sampleWindow],
112
+ duration: sampleWindowDuration,
113
+ length: sampleWindow.length
114
+ };
115
+ const lufs = (0, audio_inspect_1.getLUFS)(audioData, {
116
+ channelMode: self.config.audioChannels === 1 ? "mono" : "stereo",
117
+ calculateShortTerm: true,
118
+ calculateMomentary: false,
119
+ calculateLoudnessRange: false,
120
+ calculateTruePeak: false
121
+ });
122
+ lufss = lufs.shortTerm ? lufs.shortTerm[0] : 0;
123
+ rms = (0, audio_inspect_1.getRMS)(audioData, { asDB: true });
124
+ }, 0);
125
+ /* pass-through original audio chunk */
126
+ this.push(chunk);
127
+ callback();
128
+ }
129
+ },
130
+ final(callback) {
131
+ this.push(null);
132
+ callback();
133
+ }
134
+ });
135
+ }
136
+ /* close node */
137
+ async close() {
138
+ /* close stream */
139
+ if (this.stream !== null) {
140
+ this.stream.destroy();
141
+ this.stream = null;
142
+ }
143
+ /* stop interval */
144
+ if (this.interval !== null) {
145
+ clearInterval(this.interval);
146
+ this.interval = null;
147
+ }
148
+ }
149
+ }
150
+ exports.default = SpeechFlowNodeMeter;
151
+ //# sourceMappingURL=speechflow-node-a2a-meter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speechflow-node-a2a-meter.js","sourceRoot":"","sources":["../src/speechflow-node-a2a-meter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import SpeechFlowNode from "./speechflow-node";
2
+ type MuteMode = "none" | /* not muted */ "silenced" | /* muted by changing audio samples to silence */ "unplugged";
3
+ export default class SpeechFlowNodeMute extends SpeechFlowNode {
4
+ static name: string;
5
+ private muteMode;
6
+ constructor(id: string, cfg: {
7
+ [id: string]: any;
8
+ }, opts: {
9
+ [id: string]: any;
10
+ }, args: any[]);
11
+ receiveRequest(params: any[]): Promise<void>;
12
+ setMuteMode(mode: MuteMode): void;
13
+ open(): Promise<void>;
14
+ close(): Promise<void>;
15
+ }
16
+ export {};
@@ -0,0 +1,90 @@
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 __importDefault = (this && this.__importDefault) || function (mod) {
8
+ return (mod && mod.__esModule) ? mod : { "default": mod };
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ /* standard dependencies */
12
+ const node_stream_1 = __importDefault(require("node:stream"));
13
+ /* internal dependencies */
14
+ const speechflow_node_1 = __importDefault(require("./speechflow-node"));
15
+ /* SpeechFlow node for muting in audio-to-audio passing */
16
+ class SpeechFlowNodeMute extends speechflow_node_1.default {
17
+ /* declare official node name */
18
+ static name = "mute";
19
+ /* internal state */
20
+ muteMode = "none";
21
+ /* construct node */
22
+ constructor(id, cfg, opts, args) {
23
+ super(id, cfg, opts, args);
24
+ /* declare node configuration parameters */
25
+ this.configure({});
26
+ /* declare node input/output format */
27
+ this.input = "audio";
28
+ this.output = "audio";
29
+ }
30
+ /* receive external request */
31
+ async receiveRequest(params) {
32
+ if (params.length === 2 && params[0] === "mode") {
33
+ if (!params[1].match(/^(?:none|silenced|unplugged)$/))
34
+ throw new Error("mute: invalid mode argument in external request");
35
+ const muteMode = params[1];
36
+ this.setMuteMode(muteMode);
37
+ this.sendResponse(["mute", "mode", muteMode]);
38
+ }
39
+ else
40
+ throw new Error("mute: invalid arguments in external request");
41
+ }
42
+ /* change mute mode */
43
+ setMuteMode(mode) {
44
+ this.log("info", `setting mute mode to "${mode}"`);
45
+ this.muteMode = mode;
46
+ }
47
+ /* open node */
48
+ async open() {
49
+ /* establish a transform stream */
50
+ const self = this;
51
+ this.stream = new node_stream_1.default.Transform({
52
+ readableObjectMode: true,
53
+ writableObjectMode: true,
54
+ decodeStrings: false,
55
+ transform(chunk, encoding, callback) {
56
+ if (!Buffer.isBuffer(chunk.payload))
57
+ callback(new Error("invalid chunk payload type"));
58
+ else if (self.muteMode === "unplugged")
59
+ /* pass-through nothing */
60
+ callback();
61
+ else if (self.muteMode === "silenced") {
62
+ /* pass-through a silenced chunk */
63
+ chunk = chunk.clone();
64
+ const buffer = chunk.payload;
65
+ buffer.fill(0);
66
+ callback();
67
+ }
68
+ else {
69
+ /* pass-through original chunk */
70
+ this.push(chunk);
71
+ callback();
72
+ }
73
+ },
74
+ final(callback) {
75
+ this.push(null);
76
+ callback();
77
+ }
78
+ });
79
+ }
80
+ /* close node */
81
+ async close() {
82
+ /* close stream */
83
+ if (this.stream !== null) {
84
+ this.stream.destroy();
85
+ this.stream = null;
86
+ }
87
+ }
88
+ }
89
+ exports.default = SpeechFlowNodeMute;
90
+ //# sourceMappingURL=speechflow-node-a2a-mute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speechflow-node-a2a-mute.js","sourceRoot":"","sources":["../src/speechflow-node-a2a-mute.ts"],"names":[],"mappings":"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"}