interface AudioWorkletProcessor { readonly port : MessagePort ; process ( inputs , outputs , parameters ) : boolean ; } declare const AudioWorkletProcessor ; declare function registerProcessor ( name , processorCtor ) ; const bufSz = 96000 ; class WorkerProcessor extends AudioWorkletProcessor { workerPort : MessagePort ; canShared : boolean ; outgoing : Float32Array [ ] ; outgoingRW : Int32Array ; incoming : Float32Array [ ] ; incomingRW : Int32Array ; constructor ( options ? ) { super ( options ) ; this . canShared = typeof SharedArrayBuffer !== "undefined" ; this . port . onmessage = ev => { const msg = ev . data ; switch ( msg . c ) { case "workerPort" : this . workerPort = msg . p ; this . workerPort . onmessage = ev => { let writeHead = this . incomingRW [ 1 ] ; const buf = ev . data . d ; const len = buf [ 0 ] . length ; if ( writeHead + len > bufSz ) { const brk = bufSz - writeHead ; for ( let i = 0 ; i < this . incoming . length ; i ++ ) { this . incoming [ i ] . set ( buf [ i % buf . length ] . subarray ( 0 , brk ) , writeHead ) ; this . incoming [ i ] . set ( buf [ i % buf . length ] . subarray ( brk ) , 0 ) ; } } else { for ( let i = 0 ; i < this . incoming . length ; i ++ ) this . incoming [ i ] . set ( buf [ i % buf . length ] , writeHead ) ; } writeHead = ( writeHead + len ) % bufSz ; this . incomingRW [ 1 ] = writeHead ; } ; break ; } } ; } process ( inputs , outputs , parameters ) { if ( ! this . workerPort || inputs . length === 0 || inputs [ 0 ] . length === 0 ) return true ; if ( ! this . incoming ) { const chans = inputs [ 0 ] . length ; this . incoming = [ ] ; for ( let i = 0 ; i < chans ; i ++ ) { this . incoming . push ( new Float32Array ( this . canShared ? new SharedArrayBuffer ( bufSz * 4 ) : new ArrayBuffer ( bufSz * 4 ) ) ) ; } this . incomingRW = new Int32Array ( this . canShared ? new SharedArrayBuffer ( 8 ) : new ArrayBuffer ( 8 ) ) ; if ( this . canShared ) { this . outgoing = [ ] ; for ( let i = 0 ; i < chans ; i ++ ) { this . outgoing . push ( new Float32Array ( new SharedArrayBuffer ( bufSz * 4 ) ) ) ; } this . outgoingRW = new Int32Array ( new SharedArrayBuffer ( 8 ) ) ; console . log ( "[INFO] AWP: Using shared memory" ) ; this . workerPort . postMessage ( { c : "buffers" , incoming : this . incoming , incomingRW : this . incomingRW , outgoing : this . outgoing , outgoingRW : this . outgoingRW } ) ; } else { console . log ( "[INFO] AWP: Not using shared memory" ) ; } } const inp = inputs [ 0 ] ; if ( this . canShared ) { let writeHead = this . outgoingRW [ 1 ] ; const len = inp [ 0 ] . length ; if ( writeHead + len > bufSz ) { const brk = bufSz - writeHead ; for ( let i = 0 ; i < this . outgoing . length ; i ++ ) { this . outgoing [ i ] . set ( inp [ i % inp . length ] . subarray ( 0 , brk ) , writeHead ) ; this . outgoing [ i ] . set ( inp [ i % inp . length ] . subarray ( brk ) , 0 ) ; } } else { for ( let i = 0 ; i < this . outgoing . length ; i ++ ) this . outgoing [ i ] . set ( inp [ i % inp . length ] , writeHead ) ; } writeHead = ( writeHead + len ) % bufSz ; Atomics . store ( this . outgoingRW , 1 , writeHead ) ; Atomics . notify ( this . outgoingRW , 1 ) ; } else { this . workerPort . postMessage ( Date . now ( ) ) ; this . workerPort . postMessage ( inputs [ 0 ] ) ; } let readHead = this . incomingRW [ 0 ] ; let writeHead ; if ( this . canShared ) writeHead = Atomics . load ( this . incomingRW , 1 ) ; else writeHead = this . incomingRW [ 1 ] ; if ( readHead === writeHead ) return true ; let len = writeHead - readHead ; if ( len < 0 ) len += bufSz ; if ( len > 4800 ) { readHead = writeHead - 4800 ; if ( readHead < 0 ) readHead += bufSz ; } if ( len < outputs [ 0 ] . length ) return true ; const out = outputs [ 0 ] ; const readEnd = ( readHead + out [ 0 ] . length ) % bufSz ; if ( readEnd < readHead ) { const brk = bufSz - readHead ; for ( let i = 0 ; i < out . length ; i ++ ) { out [ i ] . set ( this . incoming [ i % this . incoming . length ] . subarray ( readHead ) , 0 ) ; out [ i ] . set ( this . incoming [ i % this . incoming . length ] . subarray ( 0 , readEnd ) , brk ) ; } } else { for ( let i = 0 ; i < out . length ; i ++ ) { out [ i ] . set ( this . incoming [ i % this . incoming . length ] . subarray ( readHead , readEnd ) , 0 ) ; } } if ( this . canShared ) { Atomics . store ( this . incomingRW , 0 , readEnd ) ; Atomics . notify ( this . incomingRW , 0 ) ; } else { this . incomingRW [ 0 ] = readEnd ; } return true ; } } registerProcessor ( "worker-processor" , WorkerProcessor ) ;