diff --git a/webui/web_demo.html b/webui/web_demo.html
index b73d484..cb42785 100644
--- a/webui/web_demo.html
+++ b/webui/web_demo.html
@@ -598,6 +598,21 @@ function initCall(){
let ws=null,wsActive=false,proc=null,rtc=null,rtSrc=null,playing=[],turns=0,mn=0;
let curMsg=null,curText='',segs=[],start=0,ripT=0,sVol=0,asstPlay=false,raf=0;
let spk=false,userBuf=[];
+ const RT_SAMPLE_RATE=16000,RT_BLOCK=4096;
+ const resamplePcm=(input,inRate,outRate)=>{
+ if(!input.length||inRate===outRate)return input;
+ const outLen=Math.max(1,Math.round(input.length*outRate/inRate));
+ const out=new Float32Array(outLen);
+ const step=inRate/outRate;
+ for(let i=0;i{const out=new Int16Array(input.length);for(let i=0;i{
if(!userBuf.length)return;
const dur=userBuf.reduce((a,c)=>a+c.length,0)/16000;
@@ -654,7 +669,7 @@ function initCall(){
raf=requestAnimationFrame(render);
async function initMic(){
- try{mic=await navigator.mediaDevices.getUserMedia({audio:true});ac=new AudioContext({sampleRate:24000});const s=ac.createMediaStreamSource(mic);ana=ac.createAnalyser();ana.fftSize=256;s.connect(ana);setSt('','connecting');setConn(false,'connecting')}
+ try{mic=await navigator.mediaDevices.getUserMedia({audio:true});ac=new AudioContext();const s=ac.createMediaStreamSource(mic);ana=ac.createAnalyser();ana.fftSize=256;s.connect(ana);setSt('','connecting');setConn(false,'connecting')}
catch(e){setSt('','mic error');setConn(false,'mic error')}
}
@@ -669,7 +684,8 @@ function initCall(){
async function startRT(){
wsActive=true;if(!mic)await initMic();
- rtc=new AudioContext({sampleRate:16000});rtSrc=rtc.createMediaStreamSource(mic);proc=rtc.createScriptProcessor(4096,1,1);
+ rtc=new AudioContext();rtSrc=rtc.createMediaStreamSource(mic);proc=rtc.createScriptProcessor(4096,1,1);
+ let rtAcc=new Float32Array(0);
const pr=location.protocol==='https:'?'wss':'ws';
ws=new WebSocket(`${pr}://${location.host}/ws/realtime`);ws.binaryType='arraybuffer';
ws.onmessage=e=>{
@@ -701,10 +717,15 @@ function initCall(){
start=Date.now();setConn(true,'live');setSt('','idle');sendCtx();
proc.onaudioprocess=e=>{
if(ws.readyState!==1)return;
- const f=e.inputBuffer.getChannelData(0),i16=new Int16Array(f.length);
- for(let i=0;i=RT_BLOCK;off+=RT_BLOCK){
+ const i16=floatToI16(merged.subarray(off,off+RT_BLOCK));
+ ws.send(i16.buffer);
+ if(spk)userBuf.push(new Int16Array(i16));
+ }
+ rtAcc=merged.slice(off);
};
rtSrc.connect(proc);proc.connect(rtc.destination);
};