mirror of
https://github.com/vector-im/element-call.git
synced 2026-05-25 11:14:37 +00:00
148 lines
4.1 KiB
TypeScript
148 lines
4.1 KiB
TypeScript
/*
|
|
Copyright 2024 New Vector Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { DeepFilterNoiseFilterProcessor } from "deepfilternet3-noise-filter";
|
|
import { logger } from "matrix-js-sdk/lib/logger";
|
|
|
|
/**
|
|
* Wrapper for DeepFilterNet3 Noise Suppression Processor.
|
|
* Integrates with LiveKit audio track processing.
|
|
*/
|
|
export class NoiseSuppressionTransformer {
|
|
private processor: DeepFilterNoiseFilterProcessor | null = null;
|
|
private initialized = false;
|
|
private readonly sampleRate: number = 48000;
|
|
|
|
/**
|
|
* Initialize the noise suppression processor
|
|
* @param level - Noise reduction level (0-1)
|
|
* @param enabled - Whether noise suppression is enabled
|
|
*/
|
|
public async initialize(
|
|
level: number = 0.75,
|
|
enabled: boolean = true,
|
|
): Promise<void> {
|
|
if (this.initialized) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Clamp level between 0-1
|
|
const clampedLevel = Math.max(0, Math.min(1, level));
|
|
|
|
// Determine asset URL based on environment
|
|
// In development, use local proxy to avoid CORS issues
|
|
// In production, use direct CDN or custom assetConfig
|
|
const isProduction = import.meta.env.PROD;
|
|
const assetUrl = isProduction
|
|
? process.env.VITE_NOISE_SUPPRESSION_CDN_URL ||
|
|
"https://cdn.mezon.ai/AI/models/datas/noise_suppression/deepfilternet3"
|
|
: `${window.location.origin}/assets/deepfilternet3`;
|
|
|
|
this.processor = new DeepFilterNoiseFilterProcessor({
|
|
sampleRate: this.sampleRate,
|
|
noiseReductionLevel: clampedLevel * 100,
|
|
enabled,
|
|
assetConfig: {
|
|
cdnUrl: assetUrl,
|
|
},
|
|
});
|
|
|
|
this.initialized = true;
|
|
logger.log(
|
|
`[NoiseSuppressionTransformer] Initialized with level=${clampedLevel}, enabled=${enabled}, assetUrl=${assetUrl}`,
|
|
);
|
|
} catch (error) {
|
|
logger.error(
|
|
"[NoiseSuppressionTransformer] Initialization failed:",
|
|
error,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the underlying processor instance
|
|
*/
|
|
public getProcessor(): DeepFilterNoiseFilterProcessor | null {
|
|
return this.processor;
|
|
}
|
|
|
|
/**
|
|
* Set the noise reduction level (0-1)
|
|
*/
|
|
public setSuppressionLevel(level: number): void {
|
|
if (!this.processor) {
|
|
logger.warn(
|
|
"[NoiseSuppressionTransformer] Processor not initialized, cannot set suppression level",
|
|
);
|
|
return;
|
|
}
|
|
|
|
const clampedLevel = Math.max(0, Math.min(1, level));
|
|
try {
|
|
this.processor.setSuppressionLevel(clampedLevel * 100);
|
|
logger.log(
|
|
`[NoiseSuppressionTransformer] Suppression level set to ${clampedLevel}`,
|
|
);
|
|
} catch (error) {
|
|
logger.error(
|
|
"[NoiseSuppressionTransformer] Failed to set suppression level:",
|
|
error,
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enable or disable noise suppression
|
|
*/
|
|
public setEnabled(enabled: boolean): void {
|
|
if (!this.processor) {
|
|
logger.warn(
|
|
"[NoiseSuppressionTransformer] Processor not initialized, cannot set enabled state",
|
|
);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
this.processor.setEnabled(enabled);
|
|
logger.log(
|
|
`[NoiseSuppressionTransformer] Noise suppression ${enabled ? "enabled" : "disabled"}`,
|
|
);
|
|
// Log processor state for debugging
|
|
const processorState = (this.processor as any).enabled;
|
|
logger.debug(
|
|
`[NoiseSuppressionTransformer] Processor internal state: enabled=${processorState}`,
|
|
);
|
|
} catch (error) {
|
|
logger.error(
|
|
"[NoiseSuppressionTransformer] Failed to set enabled state:",
|
|
error,
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clean up resources
|
|
*/
|
|
public destroy(): void {
|
|
if (this.processor) {
|
|
try {
|
|
// Note: DeepFilterNoiseFilterProcessor may have a destroy method
|
|
// Call it if available
|
|
if (typeof (this.processor as any).destroy === "function") {
|
|
(this.processor as any).destroy();
|
|
}
|
|
} catch (error) {
|
|
logger.error("[NoiseSuppressionTransformer] Cleanup failed:", error);
|
|
}
|
|
this.processor = null;
|
|
this.initialized = false;
|
|
}
|
|
}
|
|
}
|