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.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/etc/claude.md +9 -4
- package/etc/keyfiles.txt +19 -0
- package/etc/speechflow.yaml +4 -4
- package/package.json +3 -3
- package/speechflow-cli/dst/speechflow-main-api.d.ts +12 -0
- package/speechflow-cli/dst/speechflow-main-api.js +319 -0
- package/speechflow-cli/dst/speechflow-main-api.js.map +1 -0
- package/speechflow-cli/dst/speechflow-main-cli.d.ts +28 -0
- package/speechflow-cli/dst/speechflow-main-cli.js +271 -0
- package/speechflow-cli/dst/speechflow-main-cli.js.map +1 -0
- package/speechflow-cli/dst/speechflow-main-config.d.ts +9 -0
- package/speechflow-cli/dst/speechflow-main-config.js +27 -0
- package/speechflow-cli/dst/speechflow-main-config.js.map +1 -0
- package/speechflow-cli/dst/speechflow-main-graph.d.ts +34 -0
- package/speechflow-cli/dst/speechflow-main-graph.js +365 -0
- package/speechflow-cli/dst/speechflow-main-graph.js.map +1 -0
- package/speechflow-cli/dst/speechflow-main-nodes.d.ts +10 -0
- package/speechflow-cli/dst/speechflow-main-nodes.js +60 -0
- package/speechflow-cli/dst/speechflow-main-nodes.js.map +1 -0
- package/speechflow-cli/dst/speechflow-main-status.d.ts +11 -0
- package/speechflow-cli/dst/speechflow-main-status.js +60 -0
- package/speechflow-cli/dst/speechflow-main-status.js.map +1 -0
- package/speechflow-cli/dst/speechflow-main.d.ts +7 -0
- package/speechflow-cli/dst/speechflow-main.js +127 -0
- package/speechflow-cli/dst/speechflow-main.js.map +1 -0
- package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js +4 -4
- package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-compressor.js +5 -6
- package/speechflow-cli/dst/speechflow-node-a2a-compressor.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js +5 -5
- package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-expander.js +5 -6
- package/speechflow-cli/dst/speechflow-node-a2a-expander.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js +5 -5
- package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-filler.js +3 -3
- package/speechflow-cli/dst/speechflow-node-a2a-filler.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-gain.js +2 -2
- package/speechflow-cli/dst/speechflow-node-a2a-gain.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-gender.js +4 -4
- package/speechflow-cli/dst/speechflow-node-a2a-gender.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-meter.js +2 -2
- package/speechflow-cli/dst/speechflow-node-a2a-meter.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js +4 -4
- package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-speex.js +4 -4
- package/speechflow-cli/dst/speechflow-node-a2a-speex.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2a-vad.js +4 -4
- package/speechflow-cli/dst/speechflow-node-a2a-vad.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-amazon.js +6 -6
- package/speechflow-cli/dst/speechflow-node-a2t-amazon.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js +4 -4
- package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-a2t-openai.js +4 -4
- package/speechflow-cli/dst/speechflow-node-a2t-openai.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2a-amazon.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2a-amazon.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-amazon.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-amazon.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-deepl.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-deepl.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-google.js +5 -5
- package/speechflow-cli/dst/speechflow-node-t2t-google.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-modify.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-modify.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-ollama.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-ollama.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-openai.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-openai.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-sentence.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-sentence.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-t2t-transformers.js +2 -2
- package/speechflow-cli/dst/speechflow-node-t2t-transformers.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-x2x-filter.js +2 -2
- package/speechflow-cli/dst/speechflow-node-x2x-filter.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-device.js +5 -5
- package/speechflow-cli/dst/speechflow-node-xio-device.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-file.js +27 -27
- package/speechflow-cli/dst/speechflow-node-xio-file.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-mqtt.js +4 -4
- package/speechflow-cli/dst/speechflow-node-xio-mqtt.js.map +1 -1
- package/speechflow-cli/dst/speechflow-node-xio-websocket.js +7 -7
- package/speechflow-cli/dst/speechflow-node-xio-websocket.js.map +1 -1
- package/speechflow-cli/dst/{speechflow-utils-audio-wt.js → speechflow-util-audio-wt.js} +1 -1
- package/speechflow-cli/dst/speechflow-util-audio-wt.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util-audio.d.ts +22 -0
- package/speechflow-cli/dst/speechflow-util-audio.js +251 -0
- package/speechflow-cli/dst/speechflow-util-audio.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util-error.d.ts +14 -0
- package/speechflow-cli/dst/speechflow-util-error.js +131 -0
- package/speechflow-cli/dst/speechflow-util-error.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util-queue.d.ts +68 -0
- package/speechflow-cli/dst/speechflow-util-queue.js +338 -0
- package/speechflow-cli/dst/speechflow-util-queue.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util-stream.d.ts +18 -0
- package/speechflow-cli/dst/speechflow-util-stream.js +219 -0
- package/speechflow-cli/dst/speechflow-util-stream.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util-webaudio-wt.js +124 -0
- package/speechflow-cli/dst/speechflow-util-webaudio-wt.js.map +1 -0
- package/speechflow-cli/dst/{speechflow-utils-audio.js → speechflow-util-webaudio.js} +2 -2
- package/speechflow-cli/dst/speechflow-util-webaudio.js.map +1 -0
- package/speechflow-cli/dst/speechflow-util.d.ts +4 -0
- package/speechflow-cli/dst/speechflow-util.js +26 -0
- package/speechflow-cli/dst/speechflow-util.js.map +1 -0
- package/speechflow-cli/dst/speechflow.js +3 -912
- package/speechflow-cli/dst/speechflow.js.map +1 -1
- package/speechflow-cli/etc/oxlint.jsonc +4 -1
- package/speechflow-cli/package.json +1 -0
- package/speechflow-cli/src/lib.d.ts +2 -0
- package/speechflow-cli/src/speechflow-main-api.ts +315 -0
- package/speechflow-cli/src/speechflow-main-cli.ts +259 -0
- package/speechflow-cli/src/speechflow-main-config.ts +17 -0
- package/speechflow-cli/src/speechflow-main-graph.ts +370 -0
- package/speechflow-cli/src/speechflow-main-nodes.ts +61 -0
- package/speechflow-cli/src/speechflow-main-status.ts +70 -0
- package/speechflow-cli/src/speechflow-main.ts +106 -0
- package/speechflow-cli/src/speechflow-node-a2a-compressor-wt.ts +4 -4
- package/speechflow-cli/src/speechflow-node-a2a-compressor.ts +5 -6
- package/speechflow-cli/src/speechflow-node-a2a-expander-wt.ts +5 -5
- package/speechflow-cli/src/speechflow-node-a2a-expander.ts +5 -6
- package/speechflow-cli/src/speechflow-node-a2a-ffmpeg.ts +5 -5
- package/speechflow-cli/src/speechflow-node-a2a-filler.ts +4 -4
- package/speechflow-cli/src/speechflow-node-a2a-gain.ts +2 -2
- package/speechflow-cli/src/speechflow-node-a2a-gender.ts +4 -4
- package/speechflow-cli/src/speechflow-node-a2a-meter.ts +2 -2
- package/speechflow-cli/src/speechflow-node-a2a-rnnoise.ts +4 -4
- package/speechflow-cli/src/speechflow-node-a2a-speex.ts +4 -4
- package/speechflow-cli/src/speechflow-node-a2a-vad.ts +4 -4
- package/speechflow-cli/src/speechflow-node-a2t-amazon.ts +7 -7
- package/speechflow-cli/src/speechflow-node-a2t-deepgram.ts +5 -5
- package/speechflow-cli/src/speechflow-node-a2t-openai.ts +5 -5
- package/speechflow-cli/src/speechflow-node-t2a-amazon.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2a-kokoro.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-amazon.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-deepl.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-google.ts +5 -5
- package/speechflow-cli/src/speechflow-node-t2t-modify.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-ollama.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-openai.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-sentence.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +2 -2
- package/speechflow-cli/src/speechflow-node-t2t-transformers.ts +2 -2
- package/speechflow-cli/src/speechflow-node-x2x-filter.ts +2 -2
- package/speechflow-cli/src/speechflow-node-xio-device.ts +5 -5
- package/speechflow-cli/src/speechflow-node-xio-file.ts +9 -10
- package/speechflow-cli/src/speechflow-node-xio-mqtt.ts +5 -5
- package/speechflow-cli/src/speechflow-node-xio-websocket.ts +7 -7
- package/speechflow-cli/src/{speechflow-utils-audio.ts → speechflow-util-audio.ts} +131 -1
- package/speechflow-cli/src/speechflow-util-error.ts +184 -0
- package/speechflow-cli/src/speechflow-util-queue.ts +320 -0
- package/speechflow-cli/src/speechflow-util-stream.ts +197 -0
- package/speechflow-cli/src/speechflow-util.ts +10 -0
- package/speechflow-cli/src/speechflow.ts +3 -953
- package/speechflow-ui-db/dst/index.js +1 -1
- package/speechflow-ui-db/etc/vite-client.mts +0 -2
- package/speechflow-ui-db/src/app.vue +20 -19
- package/speechflow-ui-st/dst/index.js +1 -1
- package/speechflow-ui-st/etc/vite-client.mts +0 -2
- package/speechflow-ui-st/src/app.vue +10 -6
- package/speechflow-cli/dst/speechflow-node-a2a-dynamics-wt.js +0 -208
- package/speechflow-cli/dst/speechflow-node-a2a-dynamics-wt.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-a2a-dynamics.d.ts +0 -15
- package/speechflow-cli/dst/speechflow-node-a2a-dynamics.js +0 -312
- package/speechflow-cli/dst/speechflow-node-a2a-dynamics.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.d.ts +0 -18
- package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.js +0 -312
- package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.d.ts +0 -19
- package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.js +0 -351
- package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-t2a-awspolly.d.ts +0 -16
- package/speechflow-cli/dst/speechflow-node-t2a-awspolly.js +0 -204
- package/speechflow-cli/dst/speechflow-node-t2a-awspolly.js.map +0 -1
- package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.d.ts +0 -13
- package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.js +0 -175
- package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.js.map +0 -1
- package/speechflow-cli/dst/speechflow-utils-audio-wt.js.map +0 -1
- package/speechflow-cli/dst/speechflow-utils-audio.js.map +0 -1
- package/speechflow-cli/dst/speechflow-utils.d.ts +0 -108
- package/speechflow-cli/dst/speechflow-utils.js +0 -746
- package/speechflow-cli/dst/speechflow-utils.js.map +0 -1
- package/speechflow-cli/src/speechflow-utils.ts +0 -810
- /package/speechflow-cli/dst/{speechflow-node-a2a-dynamics-wt.d.ts → speechflow-util-audio-wt.d.ts} +0 -0
- /package/speechflow-cli/dst/{speechflow-utils-audio-wt.d.ts → speechflow-util-webaudio-wt.d.ts} +0 -0
- /package/speechflow-cli/dst/{speechflow-utils-audio.d.ts → speechflow-util-webaudio.d.ts} +0 -0
- /package/speechflow-cli/src/{speechflow-utils-audio-wt.ts → speechflow-util-audio-wt.ts} +0 -0
|
@@ -1,312 +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
|
-
/* standard dependencies */
|
|
45
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
46
|
-
const node_stream_1 = __importDefault(require("node:stream"));
|
|
47
|
-
/* external dependencies */
|
|
48
|
-
const node_web_audio_api_1 = require("node-web-audio-api");
|
|
49
|
-
/* internal dependencies */
|
|
50
|
-
const speechflow_node_1 = __importDefault(require("./speechflow-node"));
|
|
51
|
-
const utils = __importStar(require("./speechflow-utils"));
|
|
52
|
-
const speechflow_utils_audio_1 = require("./speechflow-utils-audio");
|
|
53
|
-
/* audio dynamics class */
|
|
54
|
-
class AudioDynamics extends speechflow_utils_audio_1.WebAudio {
|
|
55
|
-
/* internal state */
|
|
56
|
-
config;
|
|
57
|
-
dynamicsNode = null;
|
|
58
|
-
gainNode = null;
|
|
59
|
-
/* construct object */
|
|
60
|
-
constructor(sampleRate, channels, config = {}) {
|
|
61
|
-
super(sampleRate, channels);
|
|
62
|
-
/* store configuration */
|
|
63
|
-
this.config = {
|
|
64
|
-
mode: config.mode ?? "compress",
|
|
65
|
-
type: config.type ?? "standalone",
|
|
66
|
-
sideChainMode: config.sideChainMode ?? "compress",
|
|
67
|
-
thresholdDb: config.thresholdDb ?? -23,
|
|
68
|
-
ratio: config.ratio ?? 4.0,
|
|
69
|
-
attackMs: config.attackMs ?? 10,
|
|
70
|
-
releaseMs: config.releaseMs ?? 50,
|
|
71
|
-
kneeDb: config.kneeDb ?? 6.0,
|
|
72
|
-
makeupDb: config.makeupDb ?? 0,
|
|
73
|
-
expandThresholdDb: config.expandThresholdDb ?? -45,
|
|
74
|
-
expandRatio: config.expandRatio ?? 4.0,
|
|
75
|
-
floorDb: config.floorDb ?? -64
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
/* setup object */
|
|
79
|
-
async setup() {
|
|
80
|
-
await super.setup();
|
|
81
|
-
/* add audio worklet module */
|
|
82
|
-
const url = node_path_1.default.resolve(__dirname, "speechflow-node-a2a-dynamics-wt.js");
|
|
83
|
-
await this.audioContext.audioWorklet.addModule(url);
|
|
84
|
-
/* determine operation modes (based on compressor logic) */
|
|
85
|
-
const needsDynamics = (this.config.type === "standalone") ||
|
|
86
|
-
(this.config.type === "sidechain" && this.config.sideChainMode === "measure");
|
|
87
|
-
const needsGain = (this.config.type === "standalone") ||
|
|
88
|
-
(this.config.type === "sidechain" && this.config.sideChainMode === "adjust");
|
|
89
|
-
/* create dynamics worklet node */
|
|
90
|
-
if (needsDynamics) {
|
|
91
|
-
this.dynamicsNode = new node_web_audio_api_1.AudioWorkletNode(this.audioContext, "dynamics", {
|
|
92
|
-
numberOfInputs: 1,
|
|
93
|
-
numberOfOutputs: 1,
|
|
94
|
-
processorOptions: {
|
|
95
|
-
sampleRate: this.audioContext.sampleRate
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
/* create gain node */
|
|
100
|
-
if (needsGain)
|
|
101
|
-
this.gainNode = this.audioContext.createGain();
|
|
102
|
-
/* connect nodes (according to type and mode) */
|
|
103
|
-
if (this.config.type === "standalone") {
|
|
104
|
-
this.sourceNode.connect(this.dynamicsNode);
|
|
105
|
-
if (this.gainNode !== null) {
|
|
106
|
-
this.dynamicsNode.connect(this.gainNode);
|
|
107
|
-
this.gainNode.connect(this.captureNode);
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
this.dynamicsNode.connect(this.captureNode);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
else if (this.config.type === "sidechain" && this.config.sideChainMode === "measure") {
|
|
114
|
-
this.sourceNode.connect(this.dynamicsNode);
|
|
115
|
-
}
|
|
116
|
-
else if (this.config.type === "sidechain" && this.config.sideChainMode === "adjust") {
|
|
117
|
-
this.sourceNode.connect(this.gainNode);
|
|
118
|
-
this.gainNode.connect(this.captureNode);
|
|
119
|
-
}
|
|
120
|
-
/* configure dynamics worklet node */
|
|
121
|
-
const currentTime = this.audioContext.currentTime;
|
|
122
|
-
if (needsDynamics) {
|
|
123
|
-
const node = this.dynamicsNode;
|
|
124
|
-
const params = node.parameters;
|
|
125
|
-
/* map mode string to number */
|
|
126
|
-
const modeNum = this.config.mode === "compress" ? 0 :
|
|
127
|
-
this.config.mode === "expand" ? 1 : 2;
|
|
128
|
-
params.get("mode").setValueAtTime(modeNum, currentTime);
|
|
129
|
-
params.get("threshold").setValueAtTime(this.config.thresholdDb, currentTime);
|
|
130
|
-
params.get("ratio").setValueAtTime(this.config.ratio, currentTime);
|
|
131
|
-
params.get("attack").setValueAtTime(this.config.attackMs / 1000, currentTime);
|
|
132
|
-
params.get("release").setValueAtTime(this.config.releaseMs / 1000, currentTime);
|
|
133
|
-
params.get("knee").setValueAtTime(this.config.kneeDb, currentTime);
|
|
134
|
-
params.get("makeup").setValueAtTime(this.config.makeupDb, currentTime);
|
|
135
|
-
params.get("expandThreshold").setValueAtTime(this.config.expandThresholdDb, currentTime);
|
|
136
|
-
params.get("expandRatio").setValueAtTime(this.config.expandRatio, currentTime);
|
|
137
|
-
params.get("floor").setValueAtTime(this.config.floorDb, currentTime);
|
|
138
|
-
}
|
|
139
|
-
/* configure gain node */
|
|
140
|
-
if (needsGain) {
|
|
141
|
-
const gain = Math.pow(10, this.config.makeupDb / 20);
|
|
142
|
-
this.gainNode.gain.setValueAtTime(gain, currentTime);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
/* get the current gain reduction */
|
|
146
|
-
getGainReduction() {
|
|
147
|
-
const processor = this.dynamicsNode?.port?.processor;
|
|
148
|
-
return processor?.reduction ?? 0;
|
|
149
|
-
}
|
|
150
|
-
/* set the current gain */
|
|
151
|
-
setGain(decibel) {
|
|
152
|
-
const gain = Math.pow(10, decibel / 20);
|
|
153
|
-
this.gainNode?.gain.setTargetAtTime(gain, this.audioContext.currentTime, 0.002);
|
|
154
|
-
}
|
|
155
|
-
/* destroy the dynamics processor */
|
|
156
|
-
async destroy() {
|
|
157
|
-
await super.destroy();
|
|
158
|
-
/* destroy nodes */
|
|
159
|
-
if (this.dynamicsNode !== null) {
|
|
160
|
-
this.dynamicsNode.disconnect();
|
|
161
|
-
this.dynamicsNode = null;
|
|
162
|
-
}
|
|
163
|
-
if (this.gainNode !== null) {
|
|
164
|
-
this.gainNode.disconnect();
|
|
165
|
-
this.gainNode = null;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/* SpeechFlow node for unified dynamics processing in audio-to-audio passing */
|
|
170
|
-
class SpeechFlowNodeDynamics extends speechflow_node_1.default {
|
|
171
|
-
/* declare official node name */
|
|
172
|
-
static name = "dynamics";
|
|
173
|
-
/* internal state */
|
|
174
|
-
destroyed = false;
|
|
175
|
-
dynamics = null;
|
|
176
|
-
bus = null;
|
|
177
|
-
intervalId = null;
|
|
178
|
-
/* construct node */
|
|
179
|
-
constructor(id, cfg, opts, args) {
|
|
180
|
-
super(id, cfg, opts, args);
|
|
181
|
-
/* declare node configuration parameters */
|
|
182
|
-
this.configure({
|
|
183
|
-
mode: { type: "string", val: "compress", match: /^(?:compress|expand|both)$/ },
|
|
184
|
-
type: { type: "string", val: "standalone", match: /^(?:standalone|sidechain)$/ },
|
|
185
|
-
sideChainMode: { type: "string", val: "compress", match: /^(?:compress|measure|adjust)$/ },
|
|
186
|
-
bus: { type: "string", val: "dynamics", match: /^.+$/ },
|
|
187
|
-
thresholdDb: { type: "number", val: -23, match: (n) => n <= 0 && n >= -100 },
|
|
188
|
-
ratio: { type: "number", val: 4.0, match: (n) => n >= 1 && n <= 20 },
|
|
189
|
-
attackMs: { type: "number", val: 10, match: (n) => n >= 0 && n <= 1000 },
|
|
190
|
-
releaseMs: { type: "number", val: 50, match: (n) => n >= 0 && n <= 1000 },
|
|
191
|
-
kneeDb: { type: "number", val: 6.0, match: (n) => n >= 0 && n <= 40 },
|
|
192
|
-
makeupDb: { type: "number", val: 0, match: (n) => n >= -24 && n <= 24 },
|
|
193
|
-
expandThresholdDb: { type: "number", val: -45, match: (n) => n <= 0 && n >= -100 },
|
|
194
|
-
expandRatio: { type: "number", val: 4.0, match: (n) => n >= 1 && n <= 20 },
|
|
195
|
-
floorDb: { type: "number", val: -64, match: (n) => n <= 0 && n >= -100 }
|
|
196
|
-
});
|
|
197
|
-
/* sanity check mode and type combinations */
|
|
198
|
-
if (this.params.type === "standalone" && this.params.sideChainMode !== "compress")
|
|
199
|
-
throw new Error("type \"standalone\" implies sideChainMode \"compress\"");
|
|
200
|
-
if (this.params.type === "sidechain" && this.params.sideChainMode === "compress")
|
|
201
|
-
throw new Error("type \"sidechain\" implies sideChainMode \"measure\" or \"adjust\"");
|
|
202
|
-
if (this.params.mode === "expand" && this.params.floorDb >= this.params.expandThresholdDb)
|
|
203
|
-
throw new Error("floor dB must be less than expand threshold dB for proper expansion");
|
|
204
|
-
/* declare node input/output format */
|
|
205
|
-
this.input = "audio";
|
|
206
|
-
this.output = "audio";
|
|
207
|
-
}
|
|
208
|
-
/* open node */
|
|
209
|
-
async open() {
|
|
210
|
-
/* clear destruction flag */
|
|
211
|
-
this.destroyed = false;
|
|
212
|
-
/* setup dynamics */
|
|
213
|
-
this.dynamics = new AudioDynamics(this.config.audioSampleRate, this.config.audioChannels, {
|
|
214
|
-
mode: this.params.mode,
|
|
215
|
-
type: this.params.type,
|
|
216
|
-
sideChainMode: this.params.sideChainMode,
|
|
217
|
-
thresholdDb: this.params.thresholdDb,
|
|
218
|
-
ratio: this.params.ratio,
|
|
219
|
-
attackMs: this.params.attackMs,
|
|
220
|
-
releaseMs: this.params.releaseMs,
|
|
221
|
-
kneeDb: this.params.kneeDb,
|
|
222
|
-
makeupDb: this.params.makeupDb,
|
|
223
|
-
expandThresholdDb: this.params.expandThresholdDb,
|
|
224
|
-
expandRatio: this.params.expandRatio,
|
|
225
|
-
floorDb: this.params.floorDb
|
|
226
|
-
});
|
|
227
|
-
await this.dynamics.setup();
|
|
228
|
-
/* optionally establish sidechain processing */
|
|
229
|
-
if (this.params.type === "sidechain") {
|
|
230
|
-
this.bus = this.accessBus(this.params.bus);
|
|
231
|
-
if (this.params.sideChainMode === "measure") {
|
|
232
|
-
this.intervalId = setInterval(() => {
|
|
233
|
-
const decibel = this.dynamics?.getGainReduction();
|
|
234
|
-
this.bus?.emit("sidechain-decibel", decibel);
|
|
235
|
-
}, 10);
|
|
236
|
-
}
|
|
237
|
-
else if (this.params.sideChainMode === "adjust") {
|
|
238
|
-
this.bus.on("sidechain-decibel", (decibel) => {
|
|
239
|
-
this.dynamics?.setGain(decibel);
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
/* establish a transform stream */
|
|
244
|
-
const self = this;
|
|
245
|
-
this.stream = new node_stream_1.default.Transform({
|
|
246
|
-
readableObjectMode: true,
|
|
247
|
-
writableObjectMode: true,
|
|
248
|
-
decodeStrings: false,
|
|
249
|
-
transform(chunk, encoding, callback) {
|
|
250
|
-
if (self.destroyed) {
|
|
251
|
-
callback(new Error("stream already destroyed"));
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
if (!Buffer.isBuffer(chunk.payload))
|
|
255
|
-
callback(new Error("invalid chunk payload type"));
|
|
256
|
-
else {
|
|
257
|
-
/* process chunk through dynamics */
|
|
258
|
-
const payload = utils.convertBufToI16(chunk.payload);
|
|
259
|
-
self.dynamics?.process(payload).then((result) => {
|
|
260
|
-
if (self.destroyed)
|
|
261
|
-
throw new Error("stream already destroyed");
|
|
262
|
-
if ((self.params.type === "standalone") ||
|
|
263
|
-
(self.params.type === "sidechain" && self.params.sideChainMode === "adjust")) {
|
|
264
|
-
/* take over processed data */
|
|
265
|
-
const payload = utils.convertI16ToBuf(result);
|
|
266
|
-
chunk.payload = payload;
|
|
267
|
-
}
|
|
268
|
-
this.push(chunk);
|
|
269
|
-
callback();
|
|
270
|
-
}).catch((error) => {
|
|
271
|
-
callback(new Error(`dynamics processing failed: ${error}`));
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
final(callback) {
|
|
276
|
-
if (self.destroyed) {
|
|
277
|
-
callback();
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
this.push(null);
|
|
281
|
-
callback();
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
/* close node */
|
|
286
|
-
async close() {
|
|
287
|
-
/* indicate destruction */
|
|
288
|
-
this.destroyed = true;
|
|
289
|
-
/* clear interval */
|
|
290
|
-
if (this.intervalId !== null) {
|
|
291
|
-
clearInterval(this.intervalId);
|
|
292
|
-
this.intervalId = null;
|
|
293
|
-
}
|
|
294
|
-
/* destroy bus */
|
|
295
|
-
if (this.bus !== null) {
|
|
296
|
-
this.bus.removeAllListeners();
|
|
297
|
-
this.bus = null;
|
|
298
|
-
}
|
|
299
|
-
/* destroy dynamics */
|
|
300
|
-
if (this.dynamics !== null) {
|
|
301
|
-
await this.dynamics.destroy();
|
|
302
|
-
this.dynamics = null;
|
|
303
|
-
}
|
|
304
|
-
/* close stream */
|
|
305
|
-
if (this.stream !== null) {
|
|
306
|
-
this.stream.destroy();
|
|
307
|
-
this.stream = null;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
exports.default = SpeechFlowNodeDynamics;
|
|
312
|
-
//# sourceMappingURL=speechflow-node-a2a-dynamics.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"speechflow-node-a2a-dynamics.js","sourceRoot":"","sources":["../src/speechflow-node-a2a-dynamics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import SpeechFlowNode from "./speechflow-node";
|
|
2
|
-
export default class SpeechFlowNodeA2TAWSTranscribe extends SpeechFlowNode {
|
|
3
|
-
static name: string;
|
|
4
|
-
private client;
|
|
5
|
-
private clientStream;
|
|
6
|
-
private destroyed;
|
|
7
|
-
private initTimeout;
|
|
8
|
-
private connectionTimeout;
|
|
9
|
-
private queue;
|
|
10
|
-
constructor(id: string, cfg: {
|
|
11
|
-
[id: string]: any;
|
|
12
|
-
}, opts: {
|
|
13
|
-
[id: string]: any;
|
|
14
|
-
}, args: any[]);
|
|
15
|
-
status(): Promise<{}>;
|
|
16
|
-
open(): Promise<void>;
|
|
17
|
-
close(): Promise<void>;
|
|
18
|
-
}
|
|
@@ -1,312 +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
|
-
/* standard dependencies */
|
|
45
|
-
const node_stream_1 = __importDefault(require("node:stream"));
|
|
46
|
-
/* external dependencies */
|
|
47
|
-
const client_transcribe_streaming_1 = require("@aws-sdk/client-transcribe-streaming");
|
|
48
|
-
const luxon_1 = require("luxon");
|
|
49
|
-
/* internal dependencies */
|
|
50
|
-
const speechflow_node_1 = __importStar(require("./speechflow-node"));
|
|
51
|
-
const utils = __importStar(require("./speechflow-utils"));
|
|
52
|
-
/* helper class for an asynchronous queue */
|
|
53
|
-
class AsyncQueue {
|
|
54
|
-
queue = [];
|
|
55
|
-
resolvers = [];
|
|
56
|
-
push(v) {
|
|
57
|
-
const resolve = this.resolvers.shift();
|
|
58
|
-
if (resolve) {
|
|
59
|
-
if (v !== null)
|
|
60
|
-
resolve({ value: v });
|
|
61
|
-
else
|
|
62
|
-
resolve({ value: null, done: true });
|
|
63
|
-
}
|
|
64
|
-
else
|
|
65
|
-
this.queue.push(v);
|
|
66
|
-
}
|
|
67
|
-
destroy() {
|
|
68
|
-
while (this.resolvers.length > 0) {
|
|
69
|
-
const resolve = this.resolvers.shift();
|
|
70
|
-
resolve?.({ value: null, done: true });
|
|
71
|
-
}
|
|
72
|
-
this.queue.length = 0;
|
|
73
|
-
}
|
|
74
|
-
async *[Symbol.asyncIterator]() {
|
|
75
|
-
while (true) {
|
|
76
|
-
if (this.queue.length > 0) {
|
|
77
|
-
const v = this.queue.shift();
|
|
78
|
-
if (v === undefined || v === null)
|
|
79
|
-
return;
|
|
80
|
-
yield v;
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
const it = await new Promise((resolve) => this.resolvers.push(resolve));
|
|
85
|
-
if (it.done)
|
|
86
|
-
return;
|
|
87
|
-
yield it.value;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
/* SpeechFlow node for AWS Transcribe speech-to-text conversion */
|
|
93
|
-
class SpeechFlowNodeA2TAWSTranscribe extends speechflow_node_1.default {
|
|
94
|
-
/* declare official node name */
|
|
95
|
-
static name = "a2t-awstranscribe";
|
|
96
|
-
/* internal state */
|
|
97
|
-
client = null;
|
|
98
|
-
clientStream = null;
|
|
99
|
-
destroyed = false;
|
|
100
|
-
initTimeout = null;
|
|
101
|
-
connectionTimeout = null;
|
|
102
|
-
queue = null;
|
|
103
|
-
/* construct node */
|
|
104
|
-
constructor(id, cfg, opts, args) {
|
|
105
|
-
super(id, cfg, opts, args);
|
|
106
|
-
/* declare node configuration parameters */
|
|
107
|
-
this.configure({
|
|
108
|
-
key: { type: "string", val: process.env.SPEECHFLOW_AMAZON_KEY },
|
|
109
|
-
secKey: { type: "string", val: process.env.SPEECHFLOW_AMAZON_KEY_SEC },
|
|
110
|
-
region: { type: "string", val: "eu-central-1" },
|
|
111
|
-
language: { type: "string", val: "en", match: /^(?:de|en)$/ },
|
|
112
|
-
interim: { type: "boolean", val: false }
|
|
113
|
-
});
|
|
114
|
-
/* sanity check parameters */
|
|
115
|
-
if (!this.params.key)
|
|
116
|
-
throw new Error("AWS Access Key not configured");
|
|
117
|
-
if (!this.params.secKey)
|
|
118
|
-
throw new Error("AWS Secret Access Key not configured");
|
|
119
|
-
/* declare node input/output format */
|
|
120
|
-
this.input = "audio";
|
|
121
|
-
this.output = "text";
|
|
122
|
-
}
|
|
123
|
-
/* one-time status of node */
|
|
124
|
-
async status() {
|
|
125
|
-
return {};
|
|
126
|
-
}
|
|
127
|
-
/* open node */
|
|
128
|
-
async open() {
|
|
129
|
-
/* sanity check situation */
|
|
130
|
-
if (this.config.audioBitDepth !== 16 || !this.config.audioLittleEndian)
|
|
131
|
-
throw new Error("Amazon Transcribe node currently supports PCM-S16LE audio only");
|
|
132
|
-
/* clear destruction flag */
|
|
133
|
-
this.destroyed = false;
|
|
134
|
-
/* create queue for results */
|
|
135
|
-
this.queue = new utils.SingleQueue();
|
|
136
|
-
/* create a store for the meta information */
|
|
137
|
-
const metastore = new utils.TimeStore();
|
|
138
|
-
/* connect to Amazon Transcribe API */
|
|
139
|
-
this.client = new client_transcribe_streaming_1.TranscribeStreamingClient({
|
|
140
|
-
region: this.params.region,
|
|
141
|
-
credentials: {
|
|
142
|
-
accessKeyId: this.params.key,
|
|
143
|
-
secretAccessKey: this.params.secKey
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
if (this.client === null)
|
|
147
|
-
throw new Error("failed to establish Amazon Transcribe client");
|
|
148
|
-
/* create an AudioStream for Amazon Transcribe */
|
|
149
|
-
const audioQueue = new AsyncQueue();
|
|
150
|
-
const audioStream = (async function* (q) {
|
|
151
|
-
for await (const chunk of q) {
|
|
152
|
-
yield { AudioEvent: { AudioChunk: chunk } };
|
|
153
|
-
}
|
|
154
|
-
})(audioQueue);
|
|
155
|
-
/* start streaming */
|
|
156
|
-
const ensureAudioStreamActive = async () => {
|
|
157
|
-
if (this.clientStream !== null || this.destroyed)
|
|
158
|
-
return;
|
|
159
|
-
const language = this.params.language === "de" ? "de-DE" : "en-US";
|
|
160
|
-
const command = new client_transcribe_streaming_1.StartStreamTranscriptionCommand({
|
|
161
|
-
LanguageCode: language,
|
|
162
|
-
EnablePartialResultsStabilization: this.params.interim,
|
|
163
|
-
...(this.params.interim ? { PartialResultsStability: "low" } : {}),
|
|
164
|
-
MediaEncoding: "pcm",
|
|
165
|
-
MediaSampleRateHertz: this.config.audioSampleRate,
|
|
166
|
-
AudioStream: audioStream,
|
|
167
|
-
});
|
|
168
|
-
const response = await this.client.send(command);
|
|
169
|
-
const stream = response.TranscriptResultStream;
|
|
170
|
-
if (!stream)
|
|
171
|
-
throw new Error("no TranscriptResultStream returned");
|
|
172
|
-
this.clientStream = stream;
|
|
173
|
-
(async () => {
|
|
174
|
-
for await (const event of stream) {
|
|
175
|
-
const te = event.TranscriptEvent;
|
|
176
|
-
if (!te?.Transcript?.Results)
|
|
177
|
-
continue;
|
|
178
|
-
for (const result of te.Transcript.Results) {
|
|
179
|
-
const alt = result.Alternatives?.[0];
|
|
180
|
-
if (!alt?.Transcript)
|
|
181
|
-
continue;
|
|
182
|
-
if (result.IsPartial && !this.params.interim)
|
|
183
|
-
continue;
|
|
184
|
-
const text = alt.Transcript ?? "";
|
|
185
|
-
const kind = result.IsPartial ? "intermediate" : "final";
|
|
186
|
-
const tsStart = luxon_1.Duration.fromMillis((result.StartTime ?? 0) * 1000).plus(this.timeZeroOffset);
|
|
187
|
-
const tsEnd = luxon_1.Duration.fromMillis((result.EndTime ?? 0) * 1000).plus(this.timeZeroOffset);
|
|
188
|
-
const metas = metastore.fetch(tsStart, tsEnd);
|
|
189
|
-
const meta = metas.reduce((prev, curr) => {
|
|
190
|
-
curr.forEach((val, key) => { prev.set(key, val); });
|
|
191
|
-
return prev;
|
|
192
|
-
}, new Map());
|
|
193
|
-
if (this.params.interim) {
|
|
194
|
-
const words = [];
|
|
195
|
-
for (const item of alt.Items ?? []) {
|
|
196
|
-
if (item.Type === "pronunciation") {
|
|
197
|
-
words.push({
|
|
198
|
-
word: item.Content,
|
|
199
|
-
start: luxon_1.Duration.fromMillis((item.StartTime ?? 0) * 1000).plus(this.timeZeroOffset),
|
|
200
|
-
end: luxon_1.Duration.fromMillis((item.EndTime ?? 0) * 1000).plus(this.timeZeroOffset)
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
meta.set("words", words);
|
|
205
|
-
}
|
|
206
|
-
metastore.prune(tsStart);
|
|
207
|
-
const chunk = new speechflow_node_1.SpeechFlowChunk(tsStart, tsEnd, kind, "text", text, meta);
|
|
208
|
-
this.queue?.write(chunk);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
})().catch((err) => {
|
|
212
|
-
this.log("warning", `failed to establish connectivity to Amazon Transcribe: ${err}`);
|
|
213
|
-
});
|
|
214
|
-
};
|
|
215
|
-
/* remember opening time to receive time zero offset */
|
|
216
|
-
this.timeOpen = luxon_1.DateTime.now();
|
|
217
|
-
/* provide Duplex stream and internally attach to Deepgram API */
|
|
218
|
-
const self = this;
|
|
219
|
-
this.stream = new node_stream_1.default.Duplex({
|
|
220
|
-
writableObjectMode: true,
|
|
221
|
-
readableObjectMode: true,
|
|
222
|
-
decodeStrings: false,
|
|
223
|
-
highWaterMark: 1,
|
|
224
|
-
write(chunk, encoding, callback) {
|
|
225
|
-
if (self.destroyed || self.client === null) {
|
|
226
|
-
callback(new Error("stream already destroyed"));
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
if (chunk.type !== "audio")
|
|
230
|
-
callback(new Error("expected audio input chunk"));
|
|
231
|
-
else if (!Buffer.isBuffer(chunk.payload))
|
|
232
|
-
callback(new Error("expected Buffer input chunk"));
|
|
233
|
-
else {
|
|
234
|
-
if (chunk.payload.byteLength > 0) {
|
|
235
|
-
self.log("debug", `send data (${chunk.payload.byteLength} bytes)`);
|
|
236
|
-
if (chunk.meta.size > 0)
|
|
237
|
-
metastore.store(chunk.timestampStart, chunk.timestampEnd, chunk.meta);
|
|
238
|
-
audioQueue.push(new Uint8Array(chunk.payload)); /* intentionally discard all time information */
|
|
239
|
-
ensureAudioStreamActive().catch((error) => {
|
|
240
|
-
self.log("error", `failed to start audio stream: ${utils.ensureError(error).message}`);
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
callback();
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
read(size) {
|
|
247
|
-
if (self.destroyed || self.queue === null) {
|
|
248
|
-
this.push(null);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
self.queue.read().then((chunk) => {
|
|
252
|
-
if (self.destroyed) {
|
|
253
|
-
this.push(null);
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
if (chunk === null) {
|
|
257
|
-
self.log("info", "received EOF signal");
|
|
258
|
-
this.push(null);
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
self.log("debug", `received data (${chunk.payload.length} bytes): "${chunk.payload}"`);
|
|
262
|
-
this.push(chunk);
|
|
263
|
-
}
|
|
264
|
-
}).catch((error) => {
|
|
265
|
-
if (!self.destroyed)
|
|
266
|
-
self.log("error", `queue read error: ${utils.ensureError(error).message}`);
|
|
267
|
-
});
|
|
268
|
-
},
|
|
269
|
-
final(callback) {
|
|
270
|
-
if (self.destroyed || self.client === null) {
|
|
271
|
-
callback();
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
utils.run(() => self.client.destroy(), (error) => self.log("warning", `error closing Amazon Transcribe connection: ${error}`));
|
|
275
|
-
audioQueue.push(null); /* do not push null to stream, let Amazon Transcribe do it */
|
|
276
|
-
audioQueue.destroy();
|
|
277
|
-
callback();
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
/* close node */
|
|
282
|
-
async close() {
|
|
283
|
-
/* indicate destruction first to stop all async operations */
|
|
284
|
-
this.destroyed = true;
|
|
285
|
-
/* cleanup all timers */
|
|
286
|
-
if (this.initTimeout !== null) {
|
|
287
|
-
clearTimeout(this.initTimeout);
|
|
288
|
-
this.initTimeout = null;
|
|
289
|
-
}
|
|
290
|
-
if (this.connectionTimeout !== null) {
|
|
291
|
-
clearTimeout(this.connectionTimeout);
|
|
292
|
-
this.connectionTimeout = null;
|
|
293
|
-
}
|
|
294
|
-
/* close queue */
|
|
295
|
-
if (this.queue !== null) {
|
|
296
|
-
this.queue.write(null);
|
|
297
|
-
this.queue = null;
|
|
298
|
-
}
|
|
299
|
-
/* close Amazon Transcribe connection */
|
|
300
|
-
if (this.client !== null) {
|
|
301
|
-
this.client.destroy();
|
|
302
|
-
this.client = null;
|
|
303
|
-
}
|
|
304
|
-
/* close stream */
|
|
305
|
-
if (this.stream !== null) {
|
|
306
|
-
this.stream.destroy();
|
|
307
|
-
this.stream = null;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
exports.default = SpeechFlowNodeA2TAWSTranscribe;
|
|
312
|
-
//# sourceMappingURL=speechflow-node-a2t-awstranscribe.js.map
|