From 89a2321dd4a2fc3f9ff5604331f7ef85cb5bc410 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Tue, 16 Jun 2026 01:53:24 -0400 Subject: [PATCH] fix(calls): finalize DTLN integration, stabilize build, and fix formatting --- build/lotus-denoise.js | 25 ++++++++++++---- src/app/features/settings/general/General.tsx | 1 + vite.config.js | 29 +++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/build/lotus-denoise.js b/build/lotus-denoise.js index c06e2a9fa..6e272fa49 100644 --- a/build/lotus-denoise.js +++ b/build/lotus-denoise.js @@ -54,6 +54,10 @@ script: 'speexWorklet.js', wasm: 'speex.wasm', }, + dtln: { + name: 'noise-suppression-audio-worklet', + script: 'dtlnWorklet.js', + }, gate: { name: '@sapphi-red/web-noise-suppressor/noise-gate', script: 'noiseGateWorklet.js', @@ -115,6 +119,7 @@ } // Load required modules var scripts = [PROCESSORS[MODEL].script]; + if (MODEL === 'dtln') scripts.push('dtlnProcessor.js'); if (USE_GATE) scripts.push(PROCESSORS.gate.script); return Promise.all( @@ -166,14 +171,24 @@ } // 2. ML Processor - var mlNode = new AudioWorkletNode(ctx, PROCESSORS[MODEL].name, { + var mlOptions = { channelCount: 1, - channelCountMode: 'explicit', numberOfInputs: 1, numberOfOutputs: 1, - outputChannelCount: [1], - processorOptions: { maxChannels: 1, wasmBinary: wasmBinary }, - }); + processorOptions: { maxChannels: 1 }, + }; + + if (MODEL === 'rnnoise' || MODEL === 'speex') { + mlOptions.processorOptions.wasmBinary = wasmBinary; + } else if (MODEL === 'dtln') { + mlOptions.processorOptions = { + wasmBinary: wasmBinary, + model1: ASSET_BASE + 'model_1.tflite', + model2: ASSET_BASE + 'model_2.tflite', + }; + } + + var mlNode = new AudioWorkletNode(ctx, PROCESSORS[MODEL].name, mlOptions); head.connect(mlNode); mlNode.connect(dest); diff --git a/src/app/features/settings/general/General.tsx b/src/app/features/settings/general/General.tsx index 1d221f031..deb44ecd1 100644 --- a/src/app/features/settings/general/General.tsx +++ b/src/app/features/settings/general/General.tsx @@ -1441,6 +1441,7 @@ function Calls() { options={[ { value: 'rnnoise', label: 'RNNoise' }, { value: 'speex', label: 'Speex (Legacy)' }, + { value: 'dtln', label: 'DTLN (Balanced)' }, ]} /> } diff --git a/vite.config.js b/vite.config.js index eb6a53bc1..479017f0e 100644 --- a/vite.config.js +++ b/vite.config.js @@ -97,6 +97,35 @@ function lotusDenoise() { path.join(sapphi, 'noiseGate/workletProcessor.js'), path.join(denoiseDir, 'noiseGateWorklet.js'), ], + // DTLN (WorkAdventure v0.0.4) + [ + path.resolve('cinny/node_modules/@workadventure/noise-suppression/dist/audio-worklet.js'), + path.join(denoiseDir, 'dtlnWorklet.js'), + ], + [ + path.resolve( + 'cinny/node_modules/@workadventure/noise-suppression/dist/assets/audio-worklet-processor.js', + ), + path.join(denoiseDir, 'dtlnProcessor.js'), + ], + [ + path.resolve( + 'cinny/node_modules/@workadventure/noise-suppression/dist/vendor/litert/litert_wasm_internal.wasm', + ), + path.join(denoiseDir, 'litert_wasm_internal.wasm'), + ], + [ + path.resolve( + 'cinny/node_modules/@workadventure/noise-suppression/dist/assets/model_quant_1.tflite', + ), + path.join(denoiseDir, 'model_1.tflite'), + ], + [ + path.resolve( + 'cinny/node_modules/@workadventure/noise-suppression/dist/assets/model_quant_2.tflite', + ), + path.join(denoiseDir, 'model_2.tflite'), + ], ]; const missing = assets.filter(([s]) => !fs.existsSync(s)).map(([s]) => s); if (missing.length > 0) {