- Model dropdown is now ordered by quality/CPU, best first (DeepFilterNet 3 → DTLN → RNNoise → Speex); fix RNNoise's inaccurate "High" voice-quality label. - When a user opts into the ML tier, default to the highest-quality model (DeepFilterNet 3). The tier default stays browser-native (known-good, best perceived in testing so far). - Wire the "Series Suppression" (native-NS-before-ML) toggle into the real call path — it was applied only in the settings tester, so the tester could sound better than the actual call. Default it OFF (a single NS stage is best practice; it's an opt-in test aid). - isMLDenoiseSupported now also requires WebAssembly, so ML isn't offered on strict-CSP shells where it would silently fall back to the raw mic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
97 lines
3.3 KiB
TypeScript
97 lines
3.3 KiB
TypeScript
/**
|
|
* Detection utilities + model catalog for Lotus ML noise suppression
|
|
* (DeepFilterNet 3 / DTLN / RNNoise / Speex). The catalog is ordered by
|
|
* quality (and, correspondingly, CPU cost) — highest first — and drives the
|
|
* order of the model dropdown in settings.
|
|
*/
|
|
|
|
import { DenoiseModelId } from '../state/settings';
|
|
|
|
export type DenoiseModel = {
|
|
id: DenoiseModelId;
|
|
name: string;
|
|
description: string;
|
|
cpuUsage: string;
|
|
binarySize: string;
|
|
transients: 'Poor' | 'Good' | 'Excellent';
|
|
voiceQuality: 'Moderate' | 'High' | 'Very High';
|
|
};
|
|
|
|
// Ordered best-quality (highest CPU) first — this is the dropdown order.
|
|
export const DENOISE_MODELS: DenoiseModel[] = [
|
|
{
|
|
id: 'deepfilternet',
|
|
name: 'DeepFilterNet 3 (beta)',
|
|
description:
|
|
'Studio-grade deep-learning model (48 kHz fullband, ONNX). Best quality; highest CPU and a larger one-time download.',
|
|
cpuUsage: '25-50%',
|
|
binarySize: '~18 MB',
|
|
transients: 'Excellent',
|
|
voiceQuality: 'Very High',
|
|
},
|
|
{
|
|
id: 'dtln',
|
|
name: 'DTLN (beta)',
|
|
description:
|
|
'Dual-signal deep-learning model (16 kHz). Strong on transient noise; moderate CPU.',
|
|
cpuUsage: '10-20%',
|
|
binarySize: '~4 MB',
|
|
transients: 'Excellent',
|
|
voiceQuality: 'High',
|
|
},
|
|
{
|
|
id: 'rnnoise',
|
|
name: 'RNNoise',
|
|
description:
|
|
'Lightweight hybrid model (48 kHz). Very low CPU; good for steady noise like fans, but can sound processed at full strength.',
|
|
cpuUsage: '< 5%',
|
|
binarySize: '< 1 MB',
|
|
transients: 'Good',
|
|
voiceQuality: 'Moderate',
|
|
},
|
|
{
|
|
id: 'speex',
|
|
name: 'Speex (Legacy)',
|
|
description:
|
|
'Classic DSP noise suppressor. Minimal CPU, gentlest on voice; weakest suppression.',
|
|
cpuUsage: '< 2%',
|
|
binarySize: '< 1 MB',
|
|
transients: 'Poor',
|
|
voiceQuality: 'Moderate',
|
|
},
|
|
];
|
|
|
|
export const isMLDenoiseSupported = (): boolean => {
|
|
if (typeof window === 'undefined') return false;
|
|
|
|
// Requirements:
|
|
// 1. AudioContext/webkitAudioContext (Web Audio API)
|
|
// 2. AudioWorklet (Real-time processing in a background thread)
|
|
// 3. getUserMedia (Microphone access)
|
|
const hasAudioContext = !!(window.AudioContext || (window as any).webkitAudioContext);
|
|
// Use `typeof` rather than `!!AudioWorkletNode`: on a browser that has
|
|
// AudioContext but no AudioWorkletNode binding (older Safari/Edge), a bare
|
|
// reference throws ReferenceError, making this feature-detection helper throw
|
|
// instead of returning false.
|
|
const hasAudioWorklet = hasAudioContext && typeof AudioWorkletNode !== 'undefined';
|
|
const hasGetUserMedia = !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
|
|
// Every ML model compiles WebAssembly (and DFN/DTLN load worklets via blob
|
|
// URLs). Under a strict CSP without `wasm-unsafe-eval` (e.g. some desktop/Tauri
|
|
// shells) WASM is unavailable, so gate on it — otherwise we'd offer ML and then
|
|
// silently fall back to the raw mic in-call.
|
|
const hasWasm =
|
|
typeof WebAssembly !== 'undefined' && typeof WebAssembly.instantiate === 'function';
|
|
|
|
return hasAudioWorklet && hasGetUserMedia && hasWasm;
|
|
};
|
|
|
|
/**
|
|
* EXACT requirements for ML Denoise (for UI display).
|
|
*/
|
|
export const ML_DENOISE_REQUIREMENTS = [
|
|
'Modern browser with Web Audio API support',
|
|
'AudioWorklet support (Chrome 66+, Firefox 76+, Safari 14.1+)',
|
|
'WebAssembly (WASM) support',
|
|
'Microphone access',
|
|
];
|