speechflow
Version:
Speech Processing Flow Graph
118 lines • 4.33 kB
JavaScript
;
/*
** SpeechFlow - Speech Processing Flow Graph
** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* standard dependencies */
const node_stream_1 = __importDefault(require("node:stream"));
/* internal dependencies */
const speechflow_node_1 = __importDefault(require("./speechflow-node"));
/* SpeechFlow node for muting in audio-to-audio passing */
class SpeechFlowNodeA2AMute extends speechflow_node_1.default {
/* declare official node name */
static name = "a2a-mute";
/* internal state */
muteMode = "none";
destroyed = false;
/* construct node */
constructor(id, cfg, opts, args) {
super(id, cfg, opts, args);
/* declare node configuration parameters */
this.configure({});
/* declare node input/output format */
this.input = "audio";
this.output = "audio";
}
/* receive external request */
async receiveRequest(params) {
if (this.destroyed)
throw new Error("mute: node already destroyed");
try {
if (params.length === 2 && params[0] === "mode") {
if (typeof params[1] !== "string" ||
!params[1].match(/^(?:none|silenced|unplugged)$/))
throw new Error("mute: invalid mode argument in external request");
const muteMode = params[1];
this.setMuteMode(muteMode);
this.sendResponse(["mute", "mode", muteMode]);
}
else
throw new Error("mute: invalid arguments in external request");
}
catch (error) {
this.log("error", `receive request error: ${error}`);
throw error;
}
}
/* change mute mode */
setMuteMode(mode) {
if (this.destroyed) {
this.log("warning", "attempted to set mute mode on destroyed node");
return;
}
this.log("info", `setting mute mode to "${mode}"`);
this.muteMode = mode;
}
/* open node */
async open() {
/* clear destruction flag */
this.destroyed = false;
/* establish a transform stream */
const self = this;
this.stream = new node_stream_1.default.Transform({
readableObjectMode: true,
writableObjectMode: true,
decodeStrings: false,
transform(chunk, encoding, callback) {
if (self.destroyed) {
callback(new Error("stream already destroyed"));
return;
}
if (!Buffer.isBuffer(chunk.payload))
callback(new Error("invalid chunk payload type"));
else if (self.muteMode === "unplugged")
/* pass-through nothing */
callback();
else if (self.muteMode === "silenced") {
/* pass-through a silenced chunk */
const chunkSilenced = chunk.clone();
chunkSilenced.meta.set("muted", true);
const buffer = chunkSilenced.payload;
buffer.fill(0);
this.push(chunkSilenced);
callback();
}
else {
/* pass-through original chunk */
this.push(chunk);
callback();
}
},
final(callback) {
if (self.destroyed) {
callback();
return;
}
this.push(null);
callback();
}
});
}
/* close node */
async close() {
/* indicate destruction */
this.destroyed = true;
/* close stream */
if (this.stream !== null) {
this.stream.destroy();
this.stream = null;
}
}
}
exports.default = SpeechFlowNodeA2AMute;
//# sourceMappingURL=speechflow-node-a2a-mute.js.map