speechflow 0.9.9 → 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 (110) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +48 -1
  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 +147 -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.js +2 -1
  16. package/dst/speechflow-node-a2t-deepgram.js.map +1 -0
  17. package/dst/speechflow-node-t2a-elevenlabs.js +1 -0
  18. package/dst/speechflow-node-t2a-elevenlabs.js.map +1 -0
  19. package/dst/speechflow-node-t2a-kokoro.js +1 -0
  20. package/dst/speechflow-node-t2a-kokoro.js.map +1 -0
  21. package/dst/speechflow-node-t2t-deepl.js +1 -0
  22. package/dst/speechflow-node-t2t-deepl.js.map +1 -0
  23. package/dst/speechflow-node-t2t-format.js +1 -0
  24. package/dst/speechflow-node-t2t-format.js.map +1 -0
  25. package/dst/speechflow-node-t2t-ollama.js +1 -0
  26. package/dst/speechflow-node-t2t-ollama.js.map +1 -0
  27. package/dst/speechflow-node-t2t-openai.js +1 -0
  28. package/dst/speechflow-node-t2t-openai.js.map +1 -0
  29. package/dst/speechflow-node-t2t-subtitle.js +1 -0
  30. package/dst/speechflow-node-t2t-subtitle.js.map +1 -0
  31. package/dst/speechflow-node-t2t-transformers.js +10 -6
  32. package/dst/speechflow-node-t2t-transformers.js.map +1 -0
  33. package/dst/speechflow-node-x2x-trace.js +1 -0
  34. package/dst/speechflow-node-x2x-trace.js.map +1 -0
  35. package/dst/speechflow-node-xio-device.js +1 -0
  36. package/dst/speechflow-node-xio-device.js.map +1 -0
  37. package/dst/speechflow-node-xio-file.js +1 -0
  38. package/dst/speechflow-node-xio-file.js.map +1 -0
  39. package/dst/speechflow-node-xio-mqtt.js +1 -0
  40. package/dst/speechflow-node-xio-mqtt.js.map +1 -0
  41. package/dst/speechflow-node-xio-websocket.js +1 -0
  42. package/dst/speechflow-node-xio-websocket.js.map +1 -0
  43. package/dst/speechflow-node.d.ts +3 -0
  44. package/dst/speechflow-node.js +10 -0
  45. package/dst/speechflow-node.js.map +1 -0
  46. package/dst/speechflow-utils.d.ts +33 -0
  47. package/dst/speechflow-utils.js +183 -1
  48. package/dst/speechflow-utils.js.map +1 -0
  49. package/dst/speechflow.js +209 -6
  50. package/dst/speechflow.js.map +1 -0
  51. package/etc/speechflow.yaml +5 -3
  52. package/etc/stx.conf +1 -1
  53. package/etc/tsconfig.json +2 -2
  54. package/package.json +14 -8
  55. package/src/speechflow-node-a2a-meter.ts +125 -0
  56. package/src/speechflow-node-a2a-mute.ts +101 -0
  57. package/src/speechflow-node-a2a-vad.ts +266 -0
  58. package/src/speechflow-node-a2t-deepgram.ts +1 -1
  59. package/src/speechflow-node-t2t-transformers.ts +12 -7
  60. package/src/speechflow-node-xio-websocket.ts +5 -5
  61. package/src/speechflow-node.ts +12 -0
  62. package/src/speechflow-utils.ts +195 -0
  63. package/src/speechflow.ts +193 -6
  64. package/dst/speechflow-node-deepgram.d.ts +0 -12
  65. package/dst/speechflow-node-deepgram.js +0 -220
  66. package/dst/speechflow-node-deepl.d.ts +0 -12
  67. package/dst/speechflow-node-deepl.js +0 -128
  68. package/dst/speechflow-node-device.d.ts +0 -13
  69. package/dst/speechflow-node-device.js +0 -205
  70. package/dst/speechflow-node-elevenlabs.d.ts +0 -13
  71. package/dst/speechflow-node-elevenlabs.js +0 -182
  72. package/dst/speechflow-node-ffmpeg.d.ts +0 -13
  73. package/dst/speechflow-node-ffmpeg.js +0 -152
  74. package/dst/speechflow-node-file.d.ts +0 -11
  75. package/dst/speechflow-node-file.js +0 -176
  76. package/dst/speechflow-node-format.d.ts +0 -11
  77. package/dst/speechflow-node-format.js +0 -80
  78. package/dst/speechflow-node-gemma.js +0 -213
  79. package/dst/speechflow-node-mqtt.d.ts +0 -13
  80. package/dst/speechflow-node-mqtt.js +0 -181
  81. package/dst/speechflow-node-opus.d.ts +0 -12
  82. package/dst/speechflow-node-opus.js +0 -135
  83. package/dst/speechflow-node-subtitle.d.ts +0 -12
  84. package/dst/speechflow-node-subtitle.js +0 -96
  85. package/dst/speechflow-node-t2t-gemma.d.ts +0 -13
  86. package/dst/speechflow-node-t2t-gemma.js +0 -233
  87. package/dst/speechflow-node-t2t-opus.d.ts +0 -12
  88. package/dst/speechflow-node-t2t-opus.js +0 -135
  89. package/dst/speechflow-node-trace.d.ts +0 -11
  90. package/dst/speechflow-node-trace.js +0 -88
  91. package/dst/speechflow-node-wav.d.ts +0 -11
  92. package/dst/speechflow-node-wav.js +0 -170
  93. package/dst/speechflow-node-websocket.d.ts +0 -13
  94. package/dst/speechflow-node-websocket.js +0 -275
  95. package/dst/speechflow-node-whisper-common.d.ts +0 -34
  96. package/dst/speechflow-node-whisper-common.js +0 -7
  97. package/dst/speechflow-node-whisper-ggml.d.ts +0 -1
  98. package/dst/speechflow-node-whisper-ggml.js +0 -97
  99. package/dst/speechflow-node-whisper-onnx.d.ts +0 -1
  100. package/dst/speechflow-node-whisper-onnx.js +0 -131
  101. package/dst/speechflow-node-whisper-worker-ggml.d.ts +0 -1
  102. package/dst/speechflow-node-whisper-worker-ggml.js +0 -97
  103. package/dst/speechflow-node-whisper-worker-onnx.d.ts +0 -1
  104. package/dst/speechflow-node-whisper-worker-onnx.js +0 -131
  105. package/dst/speechflow-node-whisper-worker.d.ts +0 -1
  106. package/dst/speechflow-node-whisper-worker.js +0 -116
  107. package/dst/speechflow-node-whisper-worker2.d.ts +0 -1
  108. package/dst/speechflow-node-whisper-worker2.js +0 -82
  109. package/dst/speechflow-node-whisper.d.ts +0 -19
  110. package/dst/speechflow-node-whisper.js +0 -604
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
  ChangeLog
3
3
  =========
4
4
 
5
+ 1.0.0 (2025-07-16)
6
+ ------------------
7
+
8
+ - IMPROVEMENT: add "vad" node for voice audio detection
9
+ - IMPROVEMENT: add "mute" node for audio muting
10
+ - IMPROVEMENT: add "meter" node for audio loudness metering
11
+ - IMPROVEMENT: add REST/WebSocket API for external requests to nodes and events from nodes
12
+
5
13
  0.9.9 (2025-07-13)
6
14
  ------------------
7
15
 
package/README.md CHANGED
@@ -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/>
@@ -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":"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"}
@@ -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,147 @@
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", 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
+ });
131
+ }
132
+ /* close node */
133
+ async close() {
134
+ /* close stream */
135
+ if (this.stream !== null) {
136
+ this.stream.destroy();
137
+ this.stream = null;
138
+ }
139
+ /* stop interval */
140
+ if (this.interval !== null) {
141
+ clearInterval(this.interval);
142
+ this.interval = null;
143
+ }
144
+ }
145
+ }
146
+ exports.default = SpeechFlowNodeMeter;
147
+ //# 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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"}