void Render(sF32 *outbuf, sInt samples) { const sF32 step=sF32(PAULARATE)/sF32(OUTRATE); const sF32 pan=1; const sF32 vm0=MasterVolume*sFSqrt(pan); const sF32 vm1=MasterVolume*sFSqrt(1-pan); for (sInt s=0; sWritePos) Calc(); sF32 outl0=0, outl1=0; sF32 outr0=0, outr1=0; // this needs optimization. SSE would come to mind. sInt offs=(ReadPos-FIR_WIDTH-1)&(RBSIZE-1); sF32 vl=RingBuf[offs]; sF32 vr=RingBuf[offs+RBSIZE]; for (sInt i=1; i<2*FIR_WIDTH-1; i++) { sF32 w=FIRMem[i]; outl0+=vl*w; outr0+=vr*w; offs=(offs+1)&(RBSIZE-1); vl=RingBuf[offs]; vr=RingBuf[offs+RBSIZE]; outl1+=vl*w; outr1+=vr*w; } sF32 outl=sLerp(outl0,outl1,ReadFrac); sF32 outr=sLerp(outr0,outr1,ReadFrac); *outbuf++=vm0*outl+vm1*outr; *outbuf++=vm1*outl+vm0*outr; ReadFrac+=step; sInt rfi=sInt(ReadFrac); ReadPos=(ReadPos+rfi)&(RBSIZE-1); ReadFrac-=rfi; } }