You are not recognized as the original poster of this topic.
var{sin,cos,floor,random,PI}=Math,TAU=Math.PI*2,mod=(n,m)=>(n%m+m)%m,
audioCtx=new(AudioContext||webkitAudioContext)(),
bufferSize=1024,sampleRate=audioCtx.sampleRate,globalTime=0,δt=1/sampleRate,
scriptNode,isPlaying=false;
function DSP(t){
//return sin(TAU*220*t);
return[sin(TAU*440*t)*sin(t),sin(TAU*440*t)*cos(t)];
}
function toggleAudio(){
if(!scriptNode){
scriptNode=audioCtx.createScriptProcessor(bufferSize,0,2); //AudioWorklet is recommended today but requires external files.
scriptNode.onaudioprocess=e=>{
let outBuffer=e.outputBuffer,signal,
outL=outBuffer.getChannelData(0),
outR=outBuffer.getChannelData(1);
for(let i=0;i<bufferSize;i++){
signal=DSP(globalTime);
if(typeof signal==="number"){
outL[i]=outR[i]=signal;
}else{
outL[i]=signal[0];outR[i]=signal[1];
}
globalTime+=δt;
}
};
scriptNode.connect(audioCtx.destination);
audioCtx.resume();isPlaying=true;
}else if(isPlaying){
scriptNode.disconnect(audioCtx.destination);isPlaying=false;
}else{
scriptNode.connect(audioCtx.destination);audioCtx.resume();isPlaying=true;
}
}
toggleAudio(); //Play, but call again to pause.