declare let Ennuiboard ; import * as audio from "./audio" ; import * as config from "./config" ; import * as log from "./log" ; import * as net from "./net" ; import * as capture from "./capture" ; import { prot } from "./protocol" ; import * as ui from "./ui" ; import * as util from "./util" ; import * as vad from "./vad" ; import * as waveform from "./waveform" ; let sentRecently = false ; let periodic = null ; export let useNR = false ; export function setUseNR ( to ) { useNR = to ; } export let vadSensitivity = 0 ; export function setVadSensitivity ( to ) { vadSensitivity = to ; } export let vadNoiseGate = - 100 ; export function setVadNoiseGate ( to ) { vadNoiseGate = to ; } function rtcVad ( destination , to ) { vad . setRTCVadOn ( to ) ; util . dispatchEvent ( "vad.rtc" ) ; destination . getTracks ( ) . forEach ( function ( track ) { track . enabled = to ; } ) ; } export function localProcessing ( ) { Promise . all ( [ ] ) . then ( function ( ) { if ( ! audio . userMedia ) { return new Promise ( function ( res ) { util . events . addEventListener ( "usermediaready" , res , { once : true } ) ; } ) ; } } ) . then ( function ( ) { sentRecently = true ; audio . setLastSentTime ( performance . now ( ) + 2500 ) ; if ( ! periodic ) { periodic = setInterval ( function ( ) { const now = performance . now ( ) ; sentRecently = ( audio . lastSentTime > now - 1500 ) ; if ( sentRecently ) log . popStatus ( "notencoding" ) ; else log . pushStatus ( "notencoding" , "Audio encoding is not functioning!" ) ; if ( typeof Ennuiboard !== "undefined" && Ennuiboard . enabled . gamepad ) Ennuiboard . gamepad . poll ( ) ; } , 100 ) ; } return localProcessingWorker ( ) ; } ) . catch ( net . promiseFail ( ) ) ; } function localProcessingWorker ( ) { let studio = ( ui . ui . video . mode === ui . ViewMode . Studio ) ; let wd ; function studioSwapped ( ) { if ( studio ) { const user = ui . ui . video . users [ net . selfId ] ; if ( ! user ) { studio = false ; studioSwapped ( ) ; } else { wd = new waveform . Waveform ( "self" , audio . ac . sampleRate / 1024 , user . waveformWrapper , null ) ; } } else { wd = new waveform . Waveform ( "self" , audio . ac . sampleRate / 1024 , ui . ui . wave . wrapper , ui . ui . wave . watcher ) ; } } studioSwapped ( ) ; return capture . createCapture ( audio . ac , { ms : audio . userMedia , bufferSize : 1024 , outStream : true , sampleRate : "sampleRate" , workerCommand : { c : "filter" , useNR : useNR , sentRecently : sentRecently , vadSensitivity : vadSensitivity , vadNoiseGate : vadNoiseGate , useTranscription : config . useTranscription } } ) . then ( capture => { let lastUseNR = useNR ; let lastSentRecently = sentRecently ; let lastVadSensitivity = vadSensitivity ; let lastVadNoiseGate = vadNoiseGate ; capture . worker . onmessage = function ( ev ) { const msg = ev . data ; if ( msg . c === "state" ) { vad . setRawVadOn ( msg . rawVadOn ) ; if ( msg . rtcVadOn !== vad . rtcVadOn ) rtcVad ( capture . destination , msg . rtcVadOn ) ; if ( msg . vadOn !== vad . vadOn ) { if ( msg . vadOn ) wd . updateWaveRetroactive ( vad . vadExtension ) ; vad . setVadOn ( msg . vadOn ) ; util . dispatchEvent ( "ui.speech" , { user : null , status : msg . vadOn } ) ; } } else if ( msg . c === "max" ) { const nowStudio = ( ui . ui . video . mode === ui . ViewMode . Studio ) ; if ( studio !== nowStudio ) { studio = nowStudio ; studioSwapped ( ) ; } wd . push ( msg . m , net . transmitting ? ( vad . rawVadOn ? 3 : ( vad . vadOn ? 2 : 1 ) ) : 0 ) ; wd . updateWave ( msg . m , sentRecently ) ; } else if ( msg . c === "vosk" ) { ui . caption ( net . selfId , msg . result . text || msg . result . partial , false , msg . complete ) ; util . dispatchEvent ( "proc.caption" , msg ) ; if ( msg . complete && msg . result . result && audio . timeOffset && net . mode === prot . mode . rec ) { const result = msg . result . result ; const offset = performance . now ( ) - Date . now ( ) + audio . timeOffset ; for ( let i = 0 ; i < result . length ; i ++ ) { const word = result [ i ] ; word . start = Math . round ( word . start * 1000 + offset ) ; word . end = Math . round ( word . end * 1000 + offset ) ; if ( word . conf === 1 ) delete word . conf ; } const resBuf = util . encodeText ( JSON . stringify ( result ) ) ; const p = prot . parts . caption . cs ; const out = new DataView ( new ArrayBuffer ( p . length + resBuf . length ) ) ; out . setUint32 ( 0 , prot . ids . caption , true ) ; ( new Uint8Array ( out . buffer ) ) . set ( resBuf , p . data ) ; net . dataSock . send ( out . buffer ) ; } } if ( useNR !== lastUseNR || sentRecently !== lastSentRecently || vadSensitivity !== lastVadSensitivity || vadNoiseGate !== lastVadNoiseGate ) { capture . worker . postMessage ( { c : "state" , useNR , sentRecently , vadSensitivity , vadNoiseGate } ) ; lastUseNR = useNR ; lastSentRecently = sentRecently ; lastVadSensitivity = vadSensitivity ; lastVadNoiseGate = vadNoiseGate ; } } ; audio . setUserMediaRTC ( capture . destination ) ; util . dispatchEvent ( "usermediartcready" , { } ) ; util . events . addEventListener ( "usermediastopped" , function ( ) { capture . disconnect ( ) ; localProcessing ( ) ; } , { once : true } ) ; } ) ; }