34 lines
1.8 KiB
JavaScript
34 lines
1.8 KiB
JavaScript
import {ToneDetector} from './test-signals.js';
|
|
import {AudioPilot} from './continuity-signals.js';
|
|
|
|
// Explicit paired-signal mode only. Bounded numeric observations; never PCM.
|
|
class PairedSignals extends AudioWorkletProcessor {
|
|
constructor() {
|
|
super();this.detector=new ToneDetector(sampleRate);this.pilot=new AudioPilot(sampleRate);
|
|
this.frames=0;this.inputFrames=0;this.zeros=0;this.energy=0;this.peak=0;
|
|
this.events=[];this.overflow=0;this.credit=true;this.next=0;this.stopped=false;
|
|
this.port.onmessage=({data})=>{if(data==='ack')this.credit=true;if(data==='stop')this.stopped=true;};
|
|
}
|
|
process(inputs,outputs) {
|
|
if(this.stopped||this.frames>=sampleRate*185)return false;
|
|
this.frames+=outputs[0]?.[0]?.length??128;
|
|
const samples=inputs[0]?.[0];
|
|
if(samples) {
|
|
this.pilot.process(samples,currentFrame);
|
|
for(const x of samples){this.inputFrames++;this.energy+=x*x;this.peak=Math.max(this.peak,Math.abs(x));if(x===0)this.zeros++;}
|
|
for(const event of this.detector.process(samples,currentFrame)) {
|
|
if(this.events.length<32)this.events.push(event);else this.overflow++;
|
|
}
|
|
}
|
|
if(this.credit&&this.frames>=this.next) {
|
|
this.port.postMessage({activity:{inputFrames:this.inputFrames,processedFrames:this.frames,
|
|
exactZeroFrames:this.zeros,rms:this.inputFrames?Math.sqrt(this.energy/this.inputFrames):0,
|
|
peak:this.peak,sampleRate},signals:this.events,overflow:this.overflow,pilot:this.pilot.summary()});
|
|
this.events=[];this.credit=false;this.next=this.frames+sampleRate;
|
|
}
|
|
// Browser initializes every output block to zero. No mic monitoring.
|
|
return true;
|
|
}
|
|
}
|
|
registerProcessor('av-paired-signals',PairedSignals);
|