140 lines
No EOL
4.8 KiB
TypeScript
140 lines
No EOL
4.8 KiB
TypeScript
import {
|
|
InputProcessor,
|
|
kInputProcessorConfigRNNoiseKeys,
|
|
kInputProcessorConfigWebRTCKeys
|
|
} from "tc-shared/voice/RecorderBase";
|
|
import {spawnModal} from "tc-shared/ui/react-elements/modal";
|
|
import {Registry} from "tc-events";
|
|
import {ModalInputProcessorEvents, ModalInputProcessorVariables} from "tc-shared/ui/modal/input-processor/Definitios";
|
|
import {createIpcUiVariableProvider, IpcUiVariableProvider} from "tc-shared/ui/utils/IpcVariable";
|
|
import _ from "lodash";
|
|
import {LogCategory, logError, logTrace} from "tc-shared/log";
|
|
|
|
class Controller {
|
|
readonly events: Registry<ModalInputProcessorEvents>;
|
|
readonly variables: IpcUiVariableProvider<ModalInputProcessorVariables>;
|
|
|
|
private readonly processor: InputProcessor;
|
|
private statisticsTask: number;
|
|
|
|
private currentConfigRNNoise;
|
|
private currentConfigWebRTC;
|
|
private currentStatistics;
|
|
|
|
private filter: string;
|
|
|
|
constructor(processor: InputProcessor) {
|
|
this.processor = processor;
|
|
|
|
this.events = new Registry<ModalInputProcessorEvents>();
|
|
this.variables = createIpcUiVariableProvider();
|
|
|
|
this.filter = "";
|
|
|
|
for(const key of kInputProcessorConfigRNNoiseKeys) {
|
|
this.variables.setVariableProvider(key, () => this.currentConfigRNNoise[key]);
|
|
this.variables.setVariableEditor(key, newValue => {
|
|
if(this.currentConfigRNNoise[key] === newValue) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
const update = {};
|
|
update[key] = newValue;
|
|
this.processor.applyProcessorConfig("rnnoise", update as any);
|
|
} catch (error) {
|
|
logTrace(LogCategory.AUDIO, tr("Tried to apply rnnoise: %o"), this.currentConfigRNNoise);
|
|
this.sendApplyError(error);
|
|
return false;
|
|
}
|
|
|
|
this.currentConfigRNNoise[key] = newValue;
|
|
return true;
|
|
});
|
|
}
|
|
|
|
for(const key of kInputProcessorConfigWebRTCKeys) {
|
|
this.variables.setVariableProvider(key, () => this.currentConfigWebRTC[key]);
|
|
this.variables.setVariableEditor(key, newValue => {
|
|
if(this.currentConfigWebRTC[key] === newValue) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
const update = {};
|
|
update[key] = newValue;
|
|
this.processor.applyProcessorConfig("webrtc-processing", update as any);
|
|
} catch (error) {
|
|
logTrace(LogCategory.AUDIO, tr("Tried to apply webrtc-processing: %o"), this.currentConfigWebRTC);
|
|
this.sendApplyError(error);
|
|
return false;
|
|
}
|
|
|
|
this.currentConfigWebRTC[key] = newValue;
|
|
return true;
|
|
});
|
|
}
|
|
|
|
this.variables.setVariableProvider("propertyFilter", () => this.filter);
|
|
this.variables.setVariableEditor("propertyFilter", newValue => {
|
|
this.filter = newValue;
|
|
});
|
|
|
|
this.currentConfigRNNoise = this.processor.getProcessorConfig("rnnoise");
|
|
this.currentConfigWebRTC = this.processor.getProcessorConfig("webrtc-processing");
|
|
|
|
this.events.on("query_statistics", () => this.sendStatistics(true));
|
|
|
|
this.statisticsTask = setInterval(() => {
|
|
this.sendStatistics(false);
|
|
}, 250);
|
|
}
|
|
|
|
destroy() {
|
|
clearInterval(this.statisticsTask);
|
|
this.events.destroy();
|
|
this.variables.destroy();
|
|
}
|
|
|
|
sendStatistics(force: boolean) {
|
|
const statistics = this.processor.getStatistics();
|
|
if(!force && _.isEqual(this.currentStatistics, statistics)) {
|
|
return;
|
|
}
|
|
|
|
this.currentStatistics = statistics;
|
|
this.events.fire_react("notify_statistics", { statistics: statistics });
|
|
}
|
|
|
|
sendApplyError(error: any) {
|
|
if(error instanceof Error) {
|
|
error = error.message;
|
|
} else if(typeof error !== "string") {
|
|
logError(LogCategory.AUDIO, tr("Failed to apply new processor config: %o"), error);
|
|
error = tr("lookup the console");
|
|
}
|
|
|
|
this.events.fire("notify_apply_error", { message: error });
|
|
}
|
|
}
|
|
|
|
export function spawnInputProcessorModal(processor: InputProcessor) {
|
|
if(__build.target !== "client") {
|
|
throw tr("only the native client supports such modal");
|
|
}
|
|
|
|
const controller = new Controller(processor);
|
|
|
|
const modal = spawnModal("modal-input-processor", [
|
|
controller.events.generateIpcDescription(),
|
|
controller.variables.generateConsumerDescription()
|
|
], {
|
|
popoutable: true,
|
|
popedOut: true
|
|
});
|
|
|
|
modal.getEvents().on("destroy", () => {
|
|
controller.destroy();
|
|
});
|
|
modal.show().then(undefined);
|
|
} |