added packages back in, replaced var w/ let
This commit is contained in:
+42
-40
@@ -19,10 +19,11 @@
|
||||
*
|
||||
* Any failure falls back to the unprocessed mic so calls never break.
|
||||
*/
|
||||
// TODO: MAKE THIS A TS FILE
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var params;
|
||||
let params;
|
||||
try {
|
||||
params = new URLSearchParams(window.location.search);
|
||||
if (params.get('lotusDenoise') !== 'ml') return;
|
||||
@@ -33,31 +34,31 @@
|
||||
// Derive the parent origin for postMessage targetOrigin from the parentUrl
|
||||
// widget param (a full URL) so denoise-status messages aren't broadcast with
|
||||
// '*'. Fall back to this frame's own origin if parentUrl is missing/malformed.
|
||||
var targetOrigin;
|
||||
let targetOrigin;
|
||||
try {
|
||||
var parentUrl = params.get('parentUrl');
|
||||
let parentUrl = params.get('parentUrl');
|
||||
targetOrigin = parentUrl ? new URL(parentUrl).origin : window.location.origin;
|
||||
} catch (e) {
|
||||
targetOrigin = window.location.origin;
|
||||
}
|
||||
|
||||
var md = navigator.mediaDevices;
|
||||
let md = navigator.mediaDevices;
|
||||
if (!md || typeof md.getUserMedia !== 'function') return;
|
||||
if (typeof AudioWorkletNode === 'undefined' || typeof AudioContext === 'undefined') return;
|
||||
|
||||
var ASSET_BASE = './denoise/';
|
||||
let ASSET_BASE = './denoise/';
|
||||
|
||||
var MODEL = params.get('lotusModel') || 'rnnoise';
|
||||
let MODEL = params.get('lotusModel') || 'rnnoise';
|
||||
// DTLN (@workadventure) targets 16 kHz and does not resample internally, so
|
||||
// its whole graph runs in a 16 kHz context; RNNoise/Speex (sapphi) and
|
||||
// DeepFilterNet 3 are 48 kHz fullband. The processed MediaStreamTrack is
|
||||
// published to LiveKit either way (WebRTC/Opus resamples as needed).
|
||||
var SAMPLE_RATE = MODEL === 'dtln' ? 16000 : 48000;
|
||||
var USE_NATIVE_NS = params.get('lotusNativeNS') === 'true';
|
||||
var USE_GATE = params.get('lotusGate') === 'true';
|
||||
var GATE_THRESHOLD = parseFloat(params.get('lotusGateThreshold') || '-45');
|
||||
let SAMPLE_RATE = MODEL === 'dtln' ? 16000 : 48000;
|
||||
let USE_NATIVE_NS = params.get('lotusNativeNS') === 'true';
|
||||
let USE_GATE = params.get('lotusGate') === 'true';
|
||||
let GATE_THRESHOLD = parseFloat(params.get('lotusGateThreshold') || '-45');
|
||||
|
||||
var PROCESSORS = {
|
||||
let PROCESSORS = {
|
||||
rnnoise: {
|
||||
name: '@sapphi-red/web-noise-suppressor/rnnoise',
|
||||
script: 'rnnoiseWorklet.js',
|
||||
@@ -91,9 +92,9 @@
|
||||
},
|
||||
};
|
||||
|
||||
var origGetUserMedia = md.getUserMedia.bind(md);
|
||||
var wasmPromises = {};
|
||||
var ctxPromise = null;
|
||||
let origGetUserMedia = md.getUserMedia.bind(md);
|
||||
let wasmPromises = {};
|
||||
let ctxPromise = null;
|
||||
|
||||
function checkSimd() {
|
||||
try {
|
||||
@@ -112,12 +113,12 @@
|
||||
|
||||
function loadWasm(modelId) {
|
||||
if (wasmPromises[modelId]) return wasmPromises[modelId];
|
||||
var p = PROCESSORS[modelId];
|
||||
let p = PROCESSORS[modelId];
|
||||
if (!p || !p.wasm) return Promise.resolve(null);
|
||||
|
||||
wasmPromises[modelId] = (modelId === 'rnnoise' ? checkSimd() : Promise.resolve(false)).then(
|
||||
function (simd) {
|
||||
var file = simd && p.simdWasm ? p.simdWasm : p.wasm;
|
||||
let file = simd && p.simdWasm ? p.simdWasm : p.wasm;
|
||||
return fetch(ASSET_BASE + file).then(function (r) {
|
||||
if (!r.ok) {
|
||||
if (simd && p.simdWasm)
|
||||
@@ -137,7 +138,7 @@
|
||||
function getContext() {
|
||||
if (!ctxPromise) {
|
||||
ctxPromise = (function () {
|
||||
var ctx = new AudioContext({ sampleRate: SAMPLE_RATE });
|
||||
let ctx = new AudioContext({ sampleRate: SAMPLE_RATE });
|
||||
if (ctx.sampleRate !== SAMPLE_RATE) {
|
||||
try {
|
||||
ctx.close();
|
||||
@@ -146,7 +147,7 @@
|
||||
}
|
||||
// Load worklet modules. DTLN registers its own processor via the
|
||||
// dynamic-imported helper (see buildMlNode), so it needs nothing here.
|
||||
var scripts = [];
|
||||
let scripts = [];
|
||||
if (MODEL === 'rnnoise' || MODEL === 'speex') scripts.push(PROCESSORS[MODEL].script);
|
||||
if (USE_GATE) scripts.push(PROCESSORS.gate.script);
|
||||
|
||||
@@ -169,7 +170,7 @@
|
||||
return ctxPromise;
|
||||
}
|
||||
|
||||
var hasNotifiedActive = false;
|
||||
let hasNotifiedActive = false;
|
||||
|
||||
// Build the ML denoise AudioWorkletNode. RNNoise/Speex are flat sapphi
|
||||
// worklets we instantiate directly with the fetched WASM binary. DTLN comes
|
||||
@@ -187,9 +188,9 @@
|
||||
if (MODEL === 'deepfilternet') {
|
||||
// Resolve an absolute self-hosted base so the package's cdnUrl override
|
||||
// fetches our vendored df_bg.wasm + ONNX model (never the upstream CDN).
|
||||
var dfnBase = new URL(ASSET_BASE + 'deepfilternet', window.location.href).href;
|
||||
let dfnBase = new URL(ASSET_BASE + 'deepfilternet', window.location.href).href;
|
||||
return import(ASSET_BASE + PROCESSORS.deepfilternet.esm).then(function (mod) {
|
||||
var core = new mod.DeepFilterNet3Core({
|
||||
let core = new mod.DeepFilterNet3Core({
|
||||
sampleRate: SAMPLE_RATE,
|
||||
noiseReductionLevel: 80,
|
||||
assetConfig: { cdnUrl: dfnBase },
|
||||
@@ -212,7 +213,8 @@
|
||||
});
|
||||
});
|
||||
}
|
||||
var node = new AudioWorkletNode(ctx, PROCESSORS[MODEL].name, {
|
||||
|
||||
let node = new AudioWorkletNode(ctx, PROCESSORS[MODEL].name, {
|
||||
channelCount: 1,
|
||||
numberOfInputs: 1,
|
||||
numberOfOutputs: 1,
|
||||
@@ -230,21 +232,21 @@
|
||||
}
|
||||
|
||||
function processStream(stream) {
|
||||
var audioTracks = stream.getAudioTracks();
|
||||
let audioTracks = stream.getAudioTracks();
|
||||
if (audioTracks.length === 0) return Promise.resolve(stream);
|
||||
|
||||
return Promise.all([loadWasm(MODEL), getContext()])
|
||||
.then(function (res) {
|
||||
var wasmBinary = res[0];
|
||||
var ctx = res[1];
|
||||
let wasmBinary = res[0];
|
||||
let ctx = res[1];
|
||||
|
||||
var source = ctx.createMediaStreamSource(stream);
|
||||
var dest = ctx.createMediaStreamDestination();
|
||||
var head = source;
|
||||
let source = ctx.createMediaStreamSource(stream);
|
||||
let dest = ctx.createMediaStreamDestination();
|
||||
let head = source;
|
||||
|
||||
// 1. Optional Noise Gate
|
||||
if (USE_GATE) {
|
||||
var gateNode = new AudioWorkletNode(ctx, PROCESSORS.gate.name, {
|
||||
let gateNode = new AudioWorkletNode(ctx, PROCESSORS.gate.name, {
|
||||
processorOptions: {
|
||||
openThreshold: GATE_THRESHOLD,
|
||||
closeThreshold: GATE_THRESHOLD - 5,
|
||||
@@ -258,7 +260,7 @@
|
||||
|
||||
// 2. ML Processor
|
||||
return buildMlNode(ctx, wasmBinary).then(function (ml) {
|
||||
var mlNode = ml.node;
|
||||
let mlNode = ml.node;
|
||||
head.connect(mlNode);
|
||||
mlNode.connect(dest);
|
||||
|
||||
@@ -266,15 +268,15 @@
|
||||
// the track handoff — audio flows via bypassUntilReady meanwhile.
|
||||
if (ml.ready && typeof ml.ready.then === 'function') {
|
||||
ml.ready.catch(function (err) {
|
||||
var m = err instanceof Error ? err.message : String(err);
|
||||
let m = err instanceof Error ? err.message : String(err);
|
||||
console.error('[lotus-denoise] ' + MODEL + ' init failed:', m);
|
||||
});
|
||||
}
|
||||
|
||||
var origTrack = audioTracks[0];
|
||||
var processedTrack = dest.stream.getAudioTracks()[0];
|
||||
let origTrack = audioTracks[0];
|
||||
let processedTrack = dest.stream.getAudioTracks()[0];
|
||||
|
||||
var torndown = false;
|
||||
let torndown = false;
|
||||
function cleanup() {
|
||||
if (torndown) return;
|
||||
torndown = true;
|
||||
@@ -293,7 +295,7 @@
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
var rawStop = processedTrack.stop.bind(processedTrack);
|
||||
let rawStop = processedTrack.stop.bind(processedTrack);
|
||||
processedTrack.stop = function () {
|
||||
cleanup();
|
||||
rawStop();
|
||||
@@ -319,7 +321,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
var out = new MediaStream();
|
||||
let out = new MediaStream();
|
||||
out.addTrack(processedTrack);
|
||||
stream.getVideoTracks().forEach(function (t) {
|
||||
out.addTrack(t);
|
||||
@@ -328,7 +330,7 @@
|
||||
});
|
||||
})
|
||||
.catch(function (e) {
|
||||
var msg = e instanceof Error ? e.message : String(e);
|
||||
let msg = e instanceof Error ? e.message : String(e);
|
||||
console.error('[lotus-denoise] Setup failed:', msg);
|
||||
window.parent.postMessage(
|
||||
{ type: 'lotus-denoise-status', active: false, error: msg },
|
||||
@@ -339,10 +341,10 @@
|
||||
}
|
||||
|
||||
navigator.mediaDevices.getUserMedia = function (constraints) {
|
||||
var wantsAudio = !!(constraints && constraints.audio);
|
||||
var effective = constraints;
|
||||
let wantsAudio = !!(constraints && constraints.audio);
|
||||
let effective = constraints;
|
||||
if (wantsAudio) {
|
||||
var audioC =
|
||||
let audioC =
|
||||
typeof constraints.audio === 'object' ? Object.assign({}, constraints.audio) : {};
|
||||
audioC.noiseSuppression = USE_NATIVE_NS;
|
||||
audioC.channelCount = 1;
|
||||
|
||||
Reference in New Issue
Block a user