@jpdutoit/squelchy 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ var comb_filter_default = '(()=>{var V=Object.defineProperty;var X=(a,e,r)=>e in
11
11
  var env_follower_default = '(()=>{var d=Object.defineProperty;var h=(t,e,a)=>e in t?d(t,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[e]=a;var u=(t,e,a)=>h(t,typeof e!="symbol"?e+"":e,a);class V extends AudioWorkletProcessor{constructor(){super(...arguments);u(this,"envelope",0)}static get parameterDescriptors(){return[{name:"attack",defaultValue:.01,minValue:.001,maxValue:.5,automationRate:"k-rate"},{name:"release",defaultValue:.1,minValue:.001,maxValue:2,automationRate:"k-rate"}]}process(a,f,l){const s=a[0]?.[0],n=f[0]?.[0];if(!s||!n)return!0;const m=l.attack[0],p=l.release[0],k=Math.exp(-1/(m*sampleRate)),v=Math.exp(-1/(p*sampleRate));let o=this.envelope;for(let r=0;r<s.length;r++){const c=Math.abs(s[r]),i=c>o?k:v;o=i*o+(1-i)*c,n[r]=o}return this.envelope=o,!0}}registerProcessor("env-follower",V);})();\n';
12
12
 
13
13
  // src/lib-runtime/generated/worklet-src/fdn-reverb.ts
14
- var fdn_reverb_default = '(()=>{var nt=Object.defineProperty;var at=(u,c,n)=>c in u?nt(u,c,{enumerable:!0,configurable:!0,writable:!0,value:n}):u[c]=n;var a=(u,c,n)=>at(u,typeof c!="symbol"?c+"":c,n);const ot=[29.7,37.1,41.1,43.7],rt=[5,1.7],it=[4.3,2.3],B=.5,ct=1e-20,lt=500;function pt(u,c){const n=1-u,m=2*Math.PI*c/sampleRate;return u/Math.sqrt(1-2*n*Math.cos(m)+n*n)}class ut extends AudioWorkletProcessor{constructor(n){super();a(this,"combBuf",[]);a(this,"combLen",[]);a(this,"combIdx",[0,0,0,0]);a(this,"combDelaySec",[]);a(this,"lpState",[0,0,0,0]);a(this,"apBuf",[]);a(this,"apLen",[]);a(this,"apIdx",[0,0]);a(this,"sApBuf",[]);a(this,"sApLen",[]);a(this,"sApIdx",[0,0]);a(this,"ceiling");a(this,"g",[0,0,0,0]);a(this,"lpCoef",0);const m=n?.processorOptions?.size??1;this.ceiling=n?.processorOptions?.feedbackCeiling??.995;for(let r=0;r<4;r++){const i=ot[r]/1e3*m,l=Math.max(2,Math.round(i*sampleRate));this.combDelaySec.push(l/sampleRate),this.combLen.push(l),this.combBuf.push(new Float32Array(l))}for(let r=0;r<2;r++){const i=Math.max(2,Math.round(rt[r]/1e3*sampleRate));this.apLen.push(i),this.apBuf.push(new Float32Array(i));const l=Math.max(2,Math.round(it[r]/1e3*sampleRate));this.sApLen.push(l),this.sApBuf.push(new Float32Array(l))}}static get parameterDescriptors(){return[{name:"rt60",defaultValue:2,minValue:.05,maxValue:30,automationRate:"k-rate"},{name:"damping",defaultValue:.55,minValue:0,maxValue:1,automationRate:"k-rate"}]}targetGains(n,m){return this.combDelaySec.map(r=>Math.min(Math.pow(10,-3*r/Math.max(n,.05))/m,this.ceiling))}process(n,m,r){const i=m[0];if(!i||!i[0])return!0;const l=i[0],z=l.length,p=n[0],G=r.rt60[0],j=r.damping[0],N=800*Math.pow(20,Math.max(0,Math.min(1,j))),L=1-Math.exp(-2*Math.PI*N/sampleRate),q=this.targetGains(G,pt(L,lt)),_=.15;for(let t=0;t<4;t++)this.g[t]+=(q[t]-this.g[t])*_;this.lpCoef+=(L-this.lpCoef)*_;const[P,C,O,w]=this.combBuf,[H,W,Z,J]=this.combLen,A=this.g,x=this.lpCoef,o=this.lpState,e=this.combIdx,D=i.length>1?i[1]:null,K=!!(p&&p.length>1);for(let t=0;t<z;t++){let f=0,b=0;if(p&&p.length){for(let s=0;s<p.length;s++)f+=p[s][t];p.length>1&&(f/=p.length),K&&(b=.5*(p[0][t]-p[1][t]))}const Q=P[e[0]],U=C[e[1]],X=O[e[2]],Y=w[e[3]];o[0]+=(Q-o[0])*x,o[1]+=(U-o[1])*x,o[2]+=(X-o[2])*x,o[3]+=(Y-o[3])*x;const E=o[0],T=o[1],V=o[2],k=o[3],v=E*A[0],y=T*A[1],I=V*A[2],R=k*A[3],$=.5*(v+y+I+R),tt=.5*(v-y+I-R),et=.5*(v+y-I-R),st=.5*(v-y-I+R);P[e[0]]=f+b+$,C[e[1]]=f-b+tt,O[e[2]]=f+b+et,w[e[3]]=f-b+st,e[0]=e[0]+1===H?0:e[0]+1,e[1]=e[1]+1===W?0:e[1]+1,e[2]=e[2]+1===Z?0:e[2]+1,e[3]=e[3]+1===J?0:e[3]+1;let S=.5*(E+V),F=.5*(T+k);for(let s=0;s<2;s++){const g=this.apBuf[s],h=this.apIdx[s],d=g[h],M=S+d*B;g[h]=M,S=d-M*B,this.apIdx[s]=h+1===this.apLen[s]?0:h+1}for(let s=0;s<2;s++){const g=this.sApBuf[s],h=this.sApIdx[s],d=g[h],M=F+d*B;g[h]=M,F=d-M*B,this.sApIdx[s]=h+1===this.sApLen[s]?0:h+1}D?(l[t]=S,D[t]=F):l[t]=.5*(S+F)}for(let t=0;t<4;t++)Math.abs(o[t])<ct&&(o[t]=0);for(let t=2;t<i.length;t++)i[t].set(i[t&1]);return!0}}registerProcessor("fdn-reverb",ut);})();\n';
14
+ var fdn_reverb_default = '(()=>{var at=Object.defineProperty;var ot=(h,c,a)=>c in h?at(h,c,{enumerable:!0,configurable:!0,writable:!0,value:a}):h[c]=a;var n=(h,c,a)=>ot(h,typeof c!="symbol"?c+"":c,a);const rt=[29.7,37.1,41.1,43.7],it=[5,1.7],ct=[4.3,2.3],R=.5,lt=1e-20,pt=500;function ht(h,c){const a=1-h,m=2*Math.PI*c/sampleRate;return h/Math.sqrt(1-2*a*Math.cos(m)+a*a)}class ut extends AudioWorkletProcessor{constructor(a){super();n(this,"combBuf",[]);n(this,"combLen",[]);n(this,"combIdx",[0,0,0,0]);n(this,"combDelaySec",[]);n(this,"lpState",[0,0,0,0]);n(this,"apBuf",[]);n(this,"apLen",[]);n(this,"apIdx",[0,0]);n(this,"sApBuf",[]);n(this,"sApLen",[]);n(this,"sApIdx",[0,0]);n(this,"ceiling");n(this,"g",[0,0,0,0]);n(this,"lpCoef",0);n(this,"primed",!1);const m=a?.processorOptions?.size??1;this.ceiling=a?.processorOptions?.feedbackCeiling??.995;for(let r=0;r<4;r++){const i=rt[r]/1e3*m,l=Math.max(2,Math.round(i*sampleRate));this.combDelaySec.push(l/sampleRate),this.combLen.push(l),this.combBuf.push(new Float32Array(l))}for(let r=0;r<2;r++){const i=Math.max(2,Math.round(it[r]/1e3*sampleRate));this.apLen.push(i),this.apBuf.push(new Float32Array(i));const l=Math.max(2,Math.round(ct[r]/1e3*sampleRate));this.sApLen.push(l),this.sApBuf.push(new Float32Array(l))}}static get parameterDescriptors(){return[{name:"rt60",defaultValue:2,minValue:.05,maxValue:30,automationRate:"k-rate"},{name:"damping",defaultValue:.55,minValue:0,maxValue:1,automationRate:"k-rate"}]}targetGains(a,m){return this.combDelaySec.map(r=>Math.min(Math.pow(10,-3*r/Math.max(a,.05))/m,this.ceiling))}process(a,m,r){const i=m[0];if(!i||!i[0])return!0;const l=i[0],j=l.length,p=a[0],N=r.rt60[0],q=r.damping[0],H=800*Math.pow(20,Math.max(0,Math.min(1,q))),S=1-Math.exp(-2*Math.PI*H/sampleRate),F=this.targetGains(N,ht(S,pt));if(!this.primed){for(let t=0;t<4;t++)this.g[t]=F[t];this.lpCoef=S,this.primed=!0}const B=.15;for(let t=0;t<4;t++)this.g[t]+=(F[t]-this.g[t])*B;this.lpCoef+=(S-this.lpCoef)*B;const[L,_,C,P]=this.combBuf,[W,Z,J,K]=this.combLen,A=this.g,v=this.lpCoef,o=this.lpState,e=this.combIdx,O=i.length>1?i[1]:null,Q=!!(p&&p.length>1);for(let t=0;t<j;t++){let f=0,b=0;if(p&&p.length){for(let s=0;s<p.length;s++)f+=p[s][t];p.length>1&&(f/=p.length),Q&&(b=.5*(p[0][t]-p[1][t]))}const U=L[e[0]],X=_[e[1]],Y=C[e[2]],$=P[e[3]];o[0]+=(U-o[0])*v,o[1]+=(X-o[1])*v,o[2]+=(Y-o[2])*v,o[3]+=($-o[3])*v;const w=o[0],D=o[1],E=o[2],T=o[3],V=w*A[0],k=D*A[1],z=E*A[2],G=T*A[3],x=.5*(V+k+z+G),tt=x-k,et=x-V,st=x-z,nt=x-G;L[e[0]]=f+b+tt,_[e[1]]=f-b+et,C[e[2]]=f+b+st,P[e[3]]=f-b+nt,e[0]=e[0]+1===W?0:e[0]+1,e[1]=e[1]+1===Z?0:e[1]+1,e[2]=e[2]+1===J?0:e[2]+1,e[3]=e[3]+1===K?0:e[3]+1;let y=.5*(w+E),I=.5*(D+T);for(let s=0;s<2;s++){const d=this.apBuf[s],u=this.apIdx[s],g=d[u],M=y+g*R;d[u]=M,y=g-M*R,this.apIdx[s]=u+1===this.apLen[s]?0:u+1}for(let s=0;s<2;s++){const d=this.sApBuf[s],u=this.sApIdx[s],g=d[u],M=I+g*R;d[u]=M,I=g-M*R,this.sApIdx[s]=u+1===this.sApLen[s]?0:u+1}O?(l[t]=y,O[t]=I):l[t]=.5*(y+I)}for(let t=0;t<4;t++)Math.abs(o[t])<lt&&(o[t]=0);for(let t=2;t<i.length;t++)i[t].set(i[t&1]);return!0}}registerProcessor("fdn-reverb",ut);})();\n';
15
15
 
16
16
  // src/lib-runtime/generated/worklet-src/flanger.ts
17
17
  var flanger_default = '(()=>{var D=Object.defineProperty;var P=(r,e,i)=>e in r?D(r,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):r[e]=i;var a=(r,e,i)=>P(r,typeof e!="symbol"?e+"":e,i);const M=.009000000000000001,p=class p extends AudioWorkletProcessor{constructor(){super(...arguments);a(this,"bufs",[]);a(this,"writeIdx",0);a(this,"phase",0);a(this,"dcX",[]);a(this,"dcY",[]);a(this,"dcR",1-2*Math.PI*5/sampleRate)}static get parameterDescriptors(){return[{name:"rate",defaultValue:.5,minValue:.05,maxValue:10,automationRate:"a-rate"},{name:"depth",defaultValue:.7,minValue:0,maxValue:1,automationRate:"a-rate"},{name:"feedback",defaultValue:.7,minValue:0,maxValue:.95,automationRate:"a-rate"}]}process(i,E,f){const x=i[0]??[],c=E[0]??[];if(!c.length)return!0;const V=c[0].length,m=f.rate,S=f.depth,A=f.feedback,n=p.LEN,R=c.length;for(;this.bufs.length<R;)this.bufs.push(new Float32Array(n)),this.dcX.push(0),this.dcY.push(0);for(let s=0;s<V;s++){const _=m.length>1?m[s]:m[0],w=S.length>1?S[s]:S[0],Y=A.length>1?A[s]:A[0];let h=(.005+w*.004*Math.sin(2*Math.PI*this.phase))*sampleRate;h<1?h=1:h>n-2&&(h=n-2);let l=this.writeIdx-h;l<0&&(l+=n);const o=l|0,v=l-o,L=o+1===n?0:o+1;for(let t=0;t<R;t++){const d=this.bufs[t],g=x[t]??x[0],b=d[o]+v*(d[L]-d[o]),y=b-this.dcX[t]+this.dcR*this.dcY[t];this.dcX[t]=b,this.dcY[t]=y;let u=(g?g[s]:0)+Y*y;u>-1e-20&&u<1e-20&&(u=0),d[this.writeIdx]=u,c[t][s]=b}this.writeIdx=this.writeIdx+1===n?0:this.writeIdx+1,this.phase+=_/sampleRate,this.phase>=1&&(this.phase-=1)}return!0}};a(p,"LEN",Math.ceil(M*sampleRate)+8);let I=p;registerProcessor("flanger",I);})();\n';
@@ -84,4 +84,4 @@ export {
84
84
  vca_default,
85
85
  waveshaper_default
86
86
  };
87
- //# sourceMappingURL=chunk-MEZE4P3U.js.map
87
+ //# sourceMappingURL=chunk-N7J25N5J.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lib-runtime/generated/worklet-src/adsr-envelope.ts", "../src/lib-runtime/generated/worklet-src/bitcrusher.ts", "../src/lib-runtime/generated/worklet-src/comb-filter.ts", "../src/lib-runtime/generated/worklet-src/env-follower.ts", "../src/lib-runtime/generated/worklet-src/fdn-reverb.ts", "../src/lib-runtime/generated/worklet-src/flanger.ts", "../src/lib-runtime/generated/worklet-src/formant-table.ts", "../src/lib-runtime/generated/worklet-src/freq-divider.ts", "../src/lib-runtime/generated/worklet-src/freq-shifter.ts", "../src/lib-runtime/generated/worklet-src/glide.ts", "../src/lib-runtime/generated/worklet-src/ladder-filter.ts", "../src/lib-runtime/generated/worklet-src/map-res.ts", "../src/lib-runtime/generated/worklet-src/map-voct-to-freq.ts", "../src/lib-runtime/generated/worklet-src/map-voct-to-period.ts", "../src/lib-runtime/generated/worklet-src/ping-pong.ts", "../src/lib-runtime/generated/worklet-src/pitch-shifter.ts", "../src/lib-runtime/generated/worklet-src/spring-reverb.ts", "../src/lib-runtime/generated/worklet-src/tape-delay.ts", "../src/lib-runtime/generated/worklet-src/tape-stop.ts", "../src/lib-runtime/generated/worklet-src/vca.ts", "../src/lib-runtime/generated/worklet-src/waveshaper.ts"],
4
+ "sourcesContent": ["export default \"(()=>{var x=Object.defineProperty;var R=(a,t,r)=>t in a?x(a,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[t]=r;var e=(a,t,r)=>R(a,typeof t!=\\\"symbol\\\"?t+\\\"\\\":t,r);const L=Math.log(1e3);class D extends AudioWorkletProcessor{constructor(){super(...arguments);e(this,\\\"_stage\\\",0);e(this,\\\"_level\\\",0);e(this,\\\"_prevGate\\\",0);e(this,\\\"_hold\\\",0);e(this,\\\"_prevEff\\\",!1);e(this,\\\"_dFor\\\",-1);e(this,\\\"_kd\\\",0);e(this,\\\"_rFor\\\",-1);e(this,\\\"_kr\\\",0)}static get parameterDescriptors(){return[{name:\\\"attack\\\",defaultValue:.01,minValue:.001,maxValue:2},{name:\\\"decay\\\",defaultValue:.46,minValue:.001,maxValue:10},{name:\\\"sustain\\\",defaultValue:.7,minValue:0,maxValue:1},{name:\\\"release\\\",defaultValue:2.1,minValue:.001,maxValue:20}]}process(r,V,i){const f=r[0]?.[0],n=V[0]?.[0];if(!n)return!0;const l=sampleRate,c=i.attack,_=i.decay,v=i.sustain,u=i.release;for(let s=0;s<n.length;s++){const p=f?f[s]:0,g=p>.5,F=this._prevGate>.5,k=c.length>1?c[s]:c[0],o=_.length>1?_[s]:_[0],d=v.length>1?v[s]:v[0],E=u.length>1?u[s]:u[0];g&&!F?(this._hold=Math.ceil((k+o)*l)+1,this._stage=1):this._hold>0&&this._hold--;const A=g||this._hold>0,m=this._prevEff;switch(A&&!m?this._stage=1:!A&&m&&(this._stage=4),this._stage){case 1:{const h=1/Math.max(k*l,1);this._level+=h,this._level>=1&&(this._level=1,this._stage=2);break}case 2:{o!==this._dFor&&(this._dFor=o,this._kd=Math.exp(-L/Math.max(o*l,1)));const h=(this._level-d)*this._kd;this._level=Math.abs(h)<1e-7?d:d+h;break}case 4:{E!==this._rFor&&(this._rFor=E,this._kr=Math.exp(-L/Math.max(E*l,1))),this._level*=this._kr,this._level<=1e-5&&(this._level=0,this._stage=0);break}case 0:default:this._level=0;break}this._prevGate=p,this._prevEff=A,n[s]=this._level}return!0}}registerProcessor(\\\"adsr-envelope\\\",D);})();\\n\";\n", "export default \"(()=>{var _=Object.defineProperty;var g=(e,t,r)=>t in e?_(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var l=(e,t,r)=>g(e,typeof t!=\\\"symbol\\\"?t+\\\"\\\":t,r);class m extends AudioWorkletProcessor{constructor(){super(...arguments);l(this,\\\"_held\\\",0);l(this,\\\"_phase\\\",0)}static get parameterDescriptors(){return[{name:\\\"bits\\\",defaultValue:8,minValue:1,maxValue:16},{name:\\\"rate\\\",defaultValue:1,minValue:.01,maxValue:1}]}process(r,c,n){const u=r[0]?.[0],a=c[0]?.[0];if(!u||!a)return!0;const o=n.bits,i=n.rate;for(let s=0;s<a.length;s++){const p=o.length>1?o[s]:o[0],d=i.length>1?i[s]:i[0];if(this._phase+=d,this._phase>=1){this._phase-=1;const h=Math.pow(2,p);this._held=Math.round(u[s]*h)/h}a[s]=this._held}return!0}}registerProcessor(\\\"bitcrusher\\\",m);})();\\n\";\n", "export default \"(()=>{var V=Object.defineProperty;var X=(a,e,r)=>e in a?V(a,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):a[e]=r;var o=(a,e,r)=>X(a,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,r);class w extends AudioWorkletProcessor{constructor(r){super();o(this,\\\"len\\\");o(this,\\\"bufs\\\",[]);o(this,\\\"dcX\\\",[]);o(this,\\\"dcY\\\",[]);o(this,\\\"writeIdx\\\",0);o(this,\\\"dcR\\\",1-2*Math.PI*5/sampleRate);const f=Math.min(5,r?.processorOptions?.maxPeriod??.1);this.len=Math.ceil(f*sampleRate)+4}static get parameterDescriptors(){return[{name:\\\"period\\\",defaultValue:.005,minValue:0,maxValue:5,automationRate:\\\"a-rate\\\"},{name:\\\"feedback\\\",defaultValue:.7,minValue:0,maxValue:.95,automationRate:\\\"a-rate\\\"}]}process(r,f,_){const g=r[0]??[],i=f[0];if(!i||!i.length)return!0;const h=_.period,I=_.feedback,s=this.len,A=i[0].length,E=this.writeIdx;for(let t=0;t<i.length;t++){const u=this.bufs[t]??(this.bufs[t]=new Float32Array(s));let P=this.dcX[t]??0,b=this.dcY[t]??0;const x=g[t],F=i[t];let c=E;for(let n=0;n<A;n++){const y=h.length>1?h[n]:h[0],O=I.length>1?I[n]:I[0];let l=y*sampleRate;l<1?l=1:l>s-2&&(l=s-2);let p=c-l;p<0&&(p+=s);const d=p|0,v=p-d,C=d+1===s?0:d+1,R=u[d]+v*(u[C]-u[d]),D=R-P+this.dcR*b;P=R,b=D;let m=(x?x[n]:0)+O*D;m>-1e-20&&m<1e-20&&(m=0),u[c]=m,c=c+1===s?0:c+1,F[n]=R}this.dcX[t]=P,this.dcY[t]=b}return this.writeIdx=(E+A)%s,!0}}registerProcessor(\\\"comb-filter\\\",w);})();\\n\";\n", "export default \"(()=>{var d=Object.defineProperty;var h=(t,e,a)=>e in t?d(t,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[e]=a;var u=(t,e,a)=>h(t,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,a);class V extends AudioWorkletProcessor{constructor(){super(...arguments);u(this,\\\"envelope\\\",0)}static get parameterDescriptors(){return[{name:\\\"attack\\\",defaultValue:.01,minValue:.001,maxValue:.5,automationRate:\\\"k-rate\\\"},{name:\\\"release\\\",defaultValue:.1,minValue:.001,maxValue:2,automationRate:\\\"k-rate\\\"}]}process(a,f,l){const s=a[0]?.[0],n=f[0]?.[0];if(!s||!n)return!0;const m=l.attack[0],p=l.release[0],k=Math.exp(-1/(m*sampleRate)),v=Math.exp(-1/(p*sampleRate));let o=this.envelope;for(let r=0;r<s.length;r++){const c=Math.abs(s[r]),i=c>o?k:v;o=i*o+(1-i)*c,n[r]=o}return this.envelope=o,!0}}registerProcessor(\\\"env-follower\\\",V);})();\\n\";\n", "export default \"(()=>{var at=Object.defineProperty;var ot=(h,c,a)=>c in h?at(h,c,{enumerable:!0,configurable:!0,writable:!0,value:a}):h[c]=a;var n=(h,c,a)=>ot(h,typeof c!=\\\"symbol\\\"?c+\\\"\\\":c,a);const rt=[29.7,37.1,41.1,43.7],it=[5,1.7],ct=[4.3,2.3],R=.5,lt=1e-20,pt=500;function ht(h,c){const a=1-h,m=2*Math.PI*c/sampleRate;return h/Math.sqrt(1-2*a*Math.cos(m)+a*a)}class ut extends AudioWorkletProcessor{constructor(a){super();n(this,\\\"combBuf\\\",[]);n(this,\\\"combLen\\\",[]);n(this,\\\"combIdx\\\",[0,0,0,0]);n(this,\\\"combDelaySec\\\",[]);n(this,\\\"lpState\\\",[0,0,0,0]);n(this,\\\"apBuf\\\",[]);n(this,\\\"apLen\\\",[]);n(this,\\\"apIdx\\\",[0,0]);n(this,\\\"sApBuf\\\",[]);n(this,\\\"sApLen\\\",[]);n(this,\\\"sApIdx\\\",[0,0]);n(this,\\\"ceiling\\\");n(this,\\\"g\\\",[0,0,0,0]);n(this,\\\"lpCoef\\\",0);n(this,\\\"primed\\\",!1);const m=a?.processorOptions?.size??1;this.ceiling=a?.processorOptions?.feedbackCeiling??.995;for(let r=0;r<4;r++){const i=rt[r]/1e3*m,l=Math.max(2,Math.round(i*sampleRate));this.combDelaySec.push(l/sampleRate),this.combLen.push(l),this.combBuf.push(new Float32Array(l))}for(let r=0;r<2;r++){const i=Math.max(2,Math.round(it[r]/1e3*sampleRate));this.apLen.push(i),this.apBuf.push(new Float32Array(i));const l=Math.max(2,Math.round(ct[r]/1e3*sampleRate));this.sApLen.push(l),this.sApBuf.push(new Float32Array(l))}}static get parameterDescriptors(){return[{name:\\\"rt60\\\",defaultValue:2,minValue:.05,maxValue:30,automationRate:\\\"k-rate\\\"},{name:\\\"damping\\\",defaultValue:.55,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"}]}targetGains(a,m){return this.combDelaySec.map(r=>Math.min(Math.pow(10,-3*r/Math.max(a,.05))/m,this.ceiling))}process(a,m,r){const i=m[0];if(!i||!i[0])return!0;const l=i[0],j=l.length,p=a[0],N=r.rt60[0],q=r.damping[0],H=800*Math.pow(20,Math.max(0,Math.min(1,q))),S=1-Math.exp(-2*Math.PI*H/sampleRate),F=this.targetGains(N,ht(S,pt));if(!this.primed){for(let t=0;t<4;t++)this.g[t]=F[t];this.lpCoef=S,this.primed=!0}const B=.15;for(let t=0;t<4;t++)this.g[t]+=(F[t]-this.g[t])*B;this.lpCoef+=(S-this.lpCoef)*B;const[L,_,C,P]=this.combBuf,[W,Z,J,K]=this.combLen,A=this.g,v=this.lpCoef,o=this.lpState,e=this.combIdx,O=i.length>1?i[1]:null,Q=!!(p&&p.length>1);for(let t=0;t<j;t++){let f=0,b=0;if(p&&p.length){for(let s=0;s<p.length;s++)f+=p[s][t];p.length>1&&(f/=p.length),Q&&(b=.5*(p[0][t]-p[1][t]))}const U=L[e[0]],X=_[e[1]],Y=C[e[2]],$=P[e[3]];o[0]+=(U-o[0])*v,o[1]+=(X-o[1])*v,o[2]+=(Y-o[2])*v,o[3]+=($-o[3])*v;const w=o[0],D=o[1],E=o[2],T=o[3],V=w*A[0],k=D*A[1],z=E*A[2],G=T*A[3],x=.5*(V+k+z+G),tt=x-k,et=x-V,st=x-z,nt=x-G;L[e[0]]=f+b+tt,_[e[1]]=f-b+et,C[e[2]]=f+b+st,P[e[3]]=f-b+nt,e[0]=e[0]+1===W?0:e[0]+1,e[1]=e[1]+1===Z?0:e[1]+1,e[2]=e[2]+1===J?0:e[2]+1,e[3]=e[3]+1===K?0:e[3]+1;let y=.5*(w+E),I=.5*(D+T);for(let s=0;s<2;s++){const d=this.apBuf[s],u=this.apIdx[s],g=d[u],M=y+g*R;d[u]=M,y=g-M*R,this.apIdx[s]=u+1===this.apLen[s]?0:u+1}for(let s=0;s<2;s++){const d=this.sApBuf[s],u=this.sApIdx[s],g=d[u],M=I+g*R;d[u]=M,I=g-M*R,this.sApIdx[s]=u+1===this.sApLen[s]?0:u+1}O?(l[t]=y,O[t]=I):l[t]=.5*(y+I)}for(let t=0;t<4;t++)Math.abs(o[t])<lt&&(o[t]=0);for(let t=2;t<i.length;t++)i[t].set(i[t&1]);return!0}}registerProcessor(\\\"fdn-reverb\\\",ut);})();\\n\";\n", "export default \"(()=>{var D=Object.defineProperty;var P=(r,e,i)=>e in r?D(r,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):r[e]=i;var a=(r,e,i)=>P(r,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,i);const M=.009000000000000001,p=class p extends AudioWorkletProcessor{constructor(){super(...arguments);a(this,\\\"bufs\\\",[]);a(this,\\\"writeIdx\\\",0);a(this,\\\"phase\\\",0);a(this,\\\"dcX\\\",[]);a(this,\\\"dcY\\\",[]);a(this,\\\"dcR\\\",1-2*Math.PI*5/sampleRate)}static get parameterDescriptors(){return[{name:\\\"rate\\\",defaultValue:.5,minValue:.05,maxValue:10,automationRate:\\\"a-rate\\\"},{name:\\\"depth\\\",defaultValue:.7,minValue:0,maxValue:1,automationRate:\\\"a-rate\\\"},{name:\\\"feedback\\\",defaultValue:.7,minValue:0,maxValue:.95,automationRate:\\\"a-rate\\\"}]}process(i,E,f){const x=i[0]??[],c=E[0]??[];if(!c.length)return!0;const V=c[0].length,m=f.rate,S=f.depth,A=f.feedback,n=p.LEN,R=c.length;for(;this.bufs.length<R;)this.bufs.push(new Float32Array(n)),this.dcX.push(0),this.dcY.push(0);for(let s=0;s<V;s++){const _=m.length>1?m[s]:m[0],w=S.length>1?S[s]:S[0],Y=A.length>1?A[s]:A[0];let h=(.005+w*.004*Math.sin(2*Math.PI*this.phase))*sampleRate;h<1?h=1:h>n-2&&(h=n-2);let l=this.writeIdx-h;l<0&&(l+=n);const o=l|0,v=l-o,L=o+1===n?0:o+1;for(let t=0;t<R;t++){const d=this.bufs[t],g=x[t]??x[0],b=d[o]+v*(d[L]-d[o]),y=b-this.dcX[t]+this.dcR*this.dcY[t];this.dcX[t]=b,this.dcY[t]=y;let u=(g?g[s]:0)+Y*y;u>-1e-20&&u<1e-20&&(u=0),d[this.writeIdx]=u,c[t][s]=b}this.writeIdx=this.writeIdx+1===n?0:this.writeIdx+1,this.phase+=_/sampleRate,this.phase>=1&&(this.phase-=1)}return!0}};a(p,\\\"LEN\\\",Math.ceil(M*sampleRate)+8);let I=p;registerProcessor(\\\"flanger\\\",I);})();\\n\";\n", "export default \"(()=>{const i=[[800,1200,2500,3300,3750],[400,2e3,2800,3500,4500],[300,2300,3e3,3500,4500],[500,900,2500,3300,3750],[350,700,2500,3300,3750]];class A extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:\\\"baseMorph\\\",defaultValue:0,automationRate:\\\"k-rate\\\"}]}process(m,h,b){const c=m[0],r=h[0],u=c.length>0?c[0]:null,O=b.baseMorph[0],s=r[0],d=r[1],g=r[2],l=r[3],f=r[4];if(!s)return!0;for(let o=0;o<s.length;o++){const F=u?u[o]:0,a=((O+F)%5+5)%5,p=Math.floor(a)%5,M=(p+1)%5,e=a-Math.floor(a),t=i[p],n=i[M];s[o]=t[0]+(n[0]-t[0])*e,d[o]=t[1]+(n[1]-t[1])*e,g[o]=t[2]+(n[2]-t[2])*e,l&&(l[o]=t[3]+(n[3]-t[3])*e),f&&(f[o]=t[4]+(n[4]-t[4])*e)}return!0}}registerProcessor(\\\"formant-table\\\",A);})();\\n\";\n", "export default \"(()=>{var F=Object.defineProperty;var b=(a,e,i)=>e in a?F(a,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):a[e]=i;var t=(a,e,i)=>b(a,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,i);class w extends AudioWorkletProcessor{constructor(){super(...arguments);t(this,\\\"prevSample\\\",0);t(this,\\\"div1State\\\",!1);t(this,\\\"div2Count\\\",0);t(this,\\\"div2State\\\",!1);t(this,\\\"envelope\\\",0);t(this,\\\"smoothGate\\\",0);t(this,\\\"samplesSinceCross\\\",0);t(this,\\\"freqEstimate\\\",0)}static get parameterDescriptors(){return[{name:\\\"oct1Level\\\",defaultValue:.5,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"},{name:\\\"oct2Level\\\",defaultValue:.3,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"}]}process(i,o,h){const r=i[0]?.[0],v=o[0]?.[0],p=o[1],m=o[2]?.[0];if(!r)return!0;const g=h.oct1Level[0],q=h.oct2Level[0],G=.01,V=.01,R=5e-4,A=.02,E=.002,f=p?.[0],u=p?.[1];for(let s=0;s<r.length;s++){const n=r[s],l=Math.abs(n);if(l>this.envelope?this.envelope+=V*(l-this.envelope):this.envelope+=R*(l-this.envelope),this.samplesSinceCross++,this.prevSample<=0&&n>0){if(this.div1State=!this.div1State,this.div2Count++,this.div2Count>=2&&(this.div2State=!this.div2State,this.div2Count=0),this.samplesSinceCross>4&&this.samplesSinceCross<sampleRate){const k=sampleRate/this.samplesSinceCross;this.freqEstimate+=.05*(k-this.freqEstimate)}this.samplesSinceCross=0}this.prevSample=n;const d=this.envelope>G?1:0,L=d>this.smoothGate?A:E;this.smoothGate+=L*(d-this.smoothGate);const S=this.div1State?1:-1,C=this.div2State?1:-1,c=this.smoothGate*this.envelope;v&&(v[s]=(S*g+C*q)*c),f&&(f[s]=S*c),u&&(u[s]=C*c),m&&(m[s]=this.freqEstimate*this.smoothGate)}return!0}}registerProcessor(\\\"freq-divider\\\",w);})();\\n\";\n", "export default \"(()=>{var q=Object.defineProperty;var B=(r,t,s)=>t in r?q(r,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):r[t]=s;var e=(r,t,s)=>B(r,typeof t!=\\\"symbol\\\"?t+\\\"\\\":t,s);const C=[.6923877778065,.9360654322959,.988229522686,.9987488452737],S=[.4021921162426,.856171088242,.9722909545651,.9952884791278];class m{constructor(t){e(this,\\\"a2\\\");e(this,\\\"x1\\\",0);e(this,\\\"x2\\\",0);e(this,\\\"y1\\\",0);e(this,\\\"y2\\\",0);this.a2=t}process(t){const s=this.a2*(t+this.y2)-this.x2;return this.x2=this.x1,this.x1=t,this.y2=this.y1,this.y1=s,s}}class w extends AudioWorkletProcessor{constructor(){super(...arguments);e(this,\\\"branchA\\\",C.map(s=>new m(s)));e(this,\\\"branchB\\\",S.map(s=>new m(s)));e(this,\\\"delayA\\\",0);e(this,\\\"phase\\\",0)}static get parameterDescriptors(){return[{name:\\\"shift\\\",defaultValue:0,minValue:-8e3,maxValue:8e3,automationRate:\\\"a-rate\\\"}]}process(s,y,A){const u=s[0]?.[0],n=y[0]?.[0];if(!n)return!0;if(!u)return n.fill(0),!0;const o=A.shift,c=2*Math.PI,b=c/sampleRate;for(let i=0;i<n.length;i++){const h=o.length>1?o[i]:o[0],v=h<0?-1:1,g=h<0?-h:h,f=u[i];let p=f;for(let a=0;a<this.branchA.length;a++)p=this.branchA[a].process(p);let l=f;for(let a=0;a<this.branchB.length;a++)l=this.branchB[a].process(l);const x=this.delayA,F=l;this.delayA=p,this.phase+=b*g,this.phase>=c&&(this.phase-=c);const d=Math.cos(this.phase),P=Math.sin(this.phase);n[i]=x*d+v*F*P}return!0}}registerProcessor(\\\"freq-shifter\\\",w);})();\\n\";\n", "export default \"(()=>{var m=Object.defineProperty;var v=(r,t,e)=>t in r?m(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var s=(r,t,e)=>v(r,typeof t!=\\\"symbol\\\"?t+\\\"\\\":t,e);class f extends AudioWorkletProcessor{constructor(){super(...arguments);s(this,\\\"y\\\",0);s(this,\\\"initialized\\\",!1);s(this,\\\"prevGate\\\",-1)}static get parameterDescriptors(){return[{name:\\\"time\\\",defaultValue:.1}]}process(e,p,u){const n=e[0]?.[0],l=e[1]?.[0],a=p[0]?.[0];if(!n||!a)return!0;const o=u.time;for(let i=0;i<a.length;i++){const c=n[i],d=o.length>1?o[i]:o[0],h=l?l[i]:-1,g=1-Math.exp(-3/(sampleRate*Math.max(d,1e-4))),y=h>0&&this.prevGate<=0;!this.initialized||y?(this.y=c,this.initialized=!0):this.y+=g*(c-this.y),this.prevGate=h,a[i]=this.y}return!0}}registerProcessor(\\\"glide\\\",f);})();\\n\";\n", "export default \"(()=>{var k=Object.defineProperty;var C=(a,e,n)=>e in a?k(a,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[e]=n;var y=(a,e,n)=>C(a,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,n);const V=Math.PI*2,W=()=>({y1:0,y2:0,y3:0,y4:0,dcIn:0,dcOut:0});class w extends AudioWorkletProcessor{constructor(){super(...arguments);y(this,\\\"states\\\",[]);y(this,\\\"noisePhase\\\",1)}static get parameterDescriptors(){return[{name:\\\"cutoff\\\",defaultValue:0,minValue:0,maxValue:24e3,automationRate:\\\"a-rate\\\"},{name:\\\"resonance\\\",defaultValue:.6,minValue:-2,maxValue:2,automationRate:\\\"a-rate\\\"},{name:\\\"drive\\\",defaultValue:.3,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"}]}process(n,M,f){const d=n[0]??[],c=M[0];if(!c||c.length===0)return!0;const i=f.cutoff,l=f.resonance,b=1+f.drive[0]*3,I=sampleRate*2,v=1-V*5/sampleRate,m=sampleRate*.45;for(let s=0;s<c.length;s++){const p=c[s],g=d[s]??d[0],t=this.states[s]??(this.states[s]=W());for(let o=0;o<p.length;o++){const O=g?g[o]:0,h=i.length>1?i[o]:i[0],A=h<8?8:h>m?m:h;let r=l.length>1?l[o]:l[0];r<0?r=0:r>1.15&&(r=1.15);const F=r*4,u=1-Math.exp(-V*A/I);this.noisePhase=this.noisePhase*1103515245+12345&2147483647;const L=(this.noisePhase/2147483647-.5)*2e-7;for(let R=0;R<2;R++){const S=Math.tanh(b*O-F*t.y4+L);t.y1+=u*(S-t.y1),t.y2+=u*(Math.tanh(t.y1)-t.y2),t.y3+=u*(Math.tanh(t.y2)-t.y3),t.y4+=u*(Math.tanh(t.y3)-t.y4)}const x=t.y4*(1+r),P=x-t.dcIn+v*t.dcOut;t.dcIn=x,t.dcOut=P,p[o]=P}Math.abs(t.y4)<1e-20&&(t.y1=t.y2=t.y3=t.y4=0)}return!0}}registerProcessor(\\\"ladder-filter\\\",w);})();\\n\";\n", "export default \"(()=>{class x extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:\\\"base\\\",defaultValue:1,minValue:.001,maxValue:1e3},{name:\\\"cvScale\\\",defaultValue:19.9,minValue:0,maxValue:1e3},{name:\\\"qMin\\\",defaultValue:.1,minValue:.001,maxValue:1e3},{name:\\\"qMax\\\",defaultValue:20,minValue:.001,maxValue:1e3},{name:\\\"dbOut\\\",defaultValue:1,minValue:0,maxValue:1}]}process(r,i,t){const s=r[0]?.[0],l=i[0]?.[0];if(!l)return!0;const n=t.base,u=t.cvScale,o=t.qMin[0],c=t.qMax[0],V=t.dbOut[0]>=.5;for(let e=0;e<l.length;e++){const m=n.length>1?n[e]:n[0],d=u.length>1?u[e]:u[0],f=s?s[e]:0;let a=m+f*d;a<o?a=o:a>c&&(a=c),l[e]=V?20*Math.log10(a):a}return!0}}registerProcessor(\\\"map-res\\\",x);})();\\n\";\n", "export default \"(()=>{class u extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:\\\"transpose\\\",defaultValue:0}]}process(s,a,n){const o=s[0]?.[0],r=a[0]?.[0];if(!r)return!0;const e=n.transpose;for(let t=0;t<r.length;t++){const c=e.length>1?e[t]:e[0],p=(o?o[t]:0)+c;r[t]=440*Math.pow(2,(p-69)/12)}return!0}}registerProcessor(\\\"map-voct-to-freq\\\",u);})();\\n\";\n", "export default \"(()=>{class i extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:\\\"transpose\\\",defaultValue:0}]}process(s,a,n){const e=s[0]?.[0],r=a[0]?.[0];if(!r)return!0;const o=n.transpose;for(let t=0;t<r.length;t++){const c=o.length>1?o[t]:o[0],p=(e?e[t]:0)+c,u=440*Math.pow(2,(p-69)/12);r[t]=1/u}return!0}}registerProcessor(\\\"map-voct-to-period\\\",i);})();\\n\";\n", "export default \"(()=>{var I=Object.defineProperty;var k=(s,e,n)=>e in s?I(s,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):s[e]=n;var r=(s,e,n)=>k(s,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,n);class x extends AudioWorkletProcessor{constructor(){super(...arguments);r(this,\\\"bufL\\\",new Float32Array(Math.ceil(2*sampleRate)+4));r(this,\\\"bufR\\\",new Float32Array(Math.ceil(2*2*sampleRate)+4));r(this,\\\"wL\\\",0);r(this,\\\"wR\\\",0);r(this,\\\"dcX\\\",0);r(this,\\\"dcY\\\",0);r(this,\\\"dcR\\\",1-2*Math.PI*5/sampleRate)}static get parameterDescriptors(){return[{name:\\\"time\\\",defaultValue:.3,minValue:.01,maxValue:2,automationRate:\\\"k-rate\\\"},{name:\\\"feedback\\\",defaultValue:.4,minValue:0,maxValue:.95,automationRate:\\\"a-rate\\\"}]}process(n,L,P){const X=n[0]?.[0],b=L[0]?.[0],_=L[1]?.[0];if(!b||!_)return!0;const v=P.time,M=P.feedback,g=this.bufL,A=this.bufR,f=g.length,R=A.length,F=this.dcR;let l=v[0]*sampleRate;l<1?l=1:l>f-3&&(l=f-3);let u=2*v[0]*sampleRate;u<1?u=1:u>R-3&&(u=R-3);let i=this.wL,o=this.wR,w=this.dcX,c=this.dcY;const y=(t,m,h,p)=>{let a=h-p;a<0&&(a+=m);const d=a|0,T=a-d,V=d+1===m?0:d+1;return t[d]+(t[V]-t[d])*T};for(let t=0;t<b.length;t++){const m=X?X[t]:0,h=M.length>1?M[t]:M[0],p=y(g,f,i,l),a=y(A,R,o,u);c=a-w+F*c,w=a,g[i]=m+h*c,A[o]=h*p,b[t]=p,_[t]=a,i++,i===f&&(i=0),o++,o===R&&(o=0)}return Math.abs(c)<1e-20&&(c=0),this.wL=i,this.wR=o,this.dcX=w,this.dcY=c,!0}}registerProcessor(\\\"ping-pong\\\",x);})();\\n\";\n", "export default \"(()=>{var R=Object.defineProperty;var y=(i,e,t)=>e in i?R(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var r=(i,e,t)=>y(i,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,t);class E extends AudioWorkletProcessor{constructor(t){super();r(this,\\\"ring\\\");r(this,\\\"ringLen\\\");r(this,\\\"writePos\\\",0);r(this,\\\"readPos\\\");r(this,\\\"grainPhase\\\");r(this,\\\"grainLen\\\");r(this,\\\"jitterLen\\\");r(this,\\\"rng\\\");this.rng=(t?.processorOptions?.seed??2654435769)>>>0||1,this.jitterLen=Math.round(sampleRate*.01),this.ringLen=Math.ceil(sampleRate*1),this.ring=new Float32Array(this.ringLen),this.grainLen=Math.floor(sampleRate*.08),this.readPos=new Float64Array([0,0]),this.grainPhase=new Float64Array([0,.5]),this.readPos[0]=this.readPos[1]=this.ringLen-this.grainLen}static get parameterDescriptors(){return[{name:\\\"semitones\\\",defaultValue:12,minValue:-24,maxValue:24,automationRate:\\\"k-rate\\\"}]}rand(){let t=this.rng;return t^=t<<13,t^=t>>>17,t^=t<<5,this.rng=t>>>0,this.rng/4294967296}process(t,P,p){const h=t[0]?.[0],o=P[0]?.[0];if(!o)return!0;const d=p.semitones[0],c=Math.pow(2,d/12),u=1/this.grainLen,L=2*Math.PI;for(let n=0;n<o.length;n++){const m=h?h[n]:0;this.ring[this.writePos]=m;let g=0;for(let s=0;s<2;s++){if(this.grainPhase[s]+=u,this.grainPhase[s]>=1){this.grainPhase[s]-=1;const f=Math.max(0,c-1)*this.grainLen+2+this.rand()*this.jitterLen;this.readPos[s]=(this.writePos-f+this.ringLen)%this.ringLen}else this.readPos[s]+=c,this.readPos[s]>=this.ringLen?this.readPos[s]-=this.ringLen:this.readPos[s]<0&&(this.readPos[s]+=this.ringLen);const l=this.readPos[s],a=l|0,A=l-a,S=(a+1)%this.ringLen,w=this.ring[a]+A*(this.ring[S]-this.ring[a]),N=.5-.5*Math.cos(L*this.grainPhase[s]);g+=w*N}o[n]=g,this.writePos=this.writePos+1===this.ringLen?0:this.writePos+1}return!0}}registerProcessor(\\\"pitch-shifter\\\",E);})();\\n\";\n", "export default \"(()=>{var $=Object.defineProperty;var tt=(n,o,e)=>o in n?$(n,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[o]=e;var s=(n,o,e)=>tt(n,typeof o!=\\\"symbol\\\"?o+\\\"\\\":o,e);const c=[{stages:76,delayMs:37.9,chan:0},{stages:90,delayMs:41.7,chan:1},{stages:82,delayMs:51.3,chan:0},{stages:96,delayMs:47.9,chan:1}],b=c.length,st=.7,N=.95,et=2.4,at=4,nt=150,ot=15,it=.98,rt=1e-20,ct=500;function ht(n){if(n>3)return 1;if(n<-3)return-1;const o=n*n;return n*(27+o)/(27+9*o)}class pt extends AudioWorkletProcessor{constructor(){super();s(this,\\\"apX\\\",[]);s(this,\\\"apY\\\",[]);s(this,\\\"dBuf\\\",[]);s(this,\\\"dLen\\\",[]);s(this,\\\"dIdx\\\",[]);s(this,\\\"fb\\\",[]);s(this,\\\"lp\\\",[]);s(this,\\\"dc\\\",[]);s(this,\\\"g\\\",[]);s(this,\\\"inHpState\\\",0);s(this,\\\"inHpCoef\\\");s(this,\\\"dcCoef\\\");s(this,\\\"a\\\",.56);s(this,\\\"lpCoef\\\",.4);s(this,\\\"knockPos\\\",-1);s(this,\\\"knockLen\\\");s(this,\\\"prevTrig\\\",0);for(let e=0;e<b;e++){this.apX.push(new Float32Array(c[e].stages)),this.apY.push(new Float32Array(c[e].stages));const p=Math.max(2,Math.round(c[e].delayMs/1e3*sampleRate));this.dLen.push(p),this.dBuf.push(new Float32Array(p)),this.dIdx.push(0),this.fb.push(0),this.lp.push(0),this.dc.push(0),this.g.push(0)}this.inHpCoef=1-Math.exp(-2*Math.PI*nt/sampleRate),this.dcCoef=1-Math.exp(-2*Math.PI*ot/sampleRate),this.knockLen=Math.max(8,Math.round(at/1e3*sampleRate))}static get parameterDescriptors(){return[{name:\\\"decay\\\",defaultValue:1.5,minValue:.3,maxValue:4,automationRate:\\\"k-rate\\\"},{name:\\\"tone\\\",defaultValue:.6,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"},{name:\\\"drip\\\",defaultValue:.5,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"}]}process(e,p,m){const h=p[0];if(!h||!h[0])return!0;const x=h[0],w=h[1]??h[0],O=x.length,M=e[0]?.[0],E=e[0]?.[1]??M,I=e[1]?.[0],B=m.decay[0],D=Math.max(0,Math.min(1,m.tone[0])),K=.35+.42*Math.max(0,Math.min(1,m.drip[0]));this.a+=(K-this.a)*.1;const i=this.a,X=1100*Math.pow(6500/1100,D),g=1-Math.exp(-2*Math.PI*X/sampleRate);this.lpCoef+=(g-this.lpCoef)*.15;const Y=this.lpCoef,L=2*Math.PI*ct/sampleRate,k=Math.cos(L),Z=(1-i*i)/(1-2*i*k+i*i),v=1-g,G=g/Math.sqrt(1-2*v*k+v*v),A=1-this.dcCoef,y=1-A*k,C=A*Math.sin(L),H=y*y+C*C,q=1-this.dcCoef*y/H,z=this.dcCoef*C/H,J=G*Math.hypot(q,z);for(let a=0;a<b;a++){const l=(this.dLen[a]+c[a].stages*Z)/sampleRate,u=Math.min(Math.pow(10,-3*l/Math.max(B,.05))/J,it);this.g[a]+=(u-this.g[a])*.15}const U=this.inHpCoef,W=this.dcCoef;for(let a=0;a<O;a++){if(I){const t=I[a];t>.5&&this.prevTrig<=.5&&(this.knockPos=0),this.prevTrig=t}const l=M?(M[a]+E[a])*.5:0;this.inHpState+=U*(l-this.inHpState);let u=(l-this.inHpState)*st;this.knockPos>=0&&(u+=Math.sin(Math.PI*this.knockPos/this.knockLen)*et,++this.knockPos>=this.knockLen&&(this.knockPos=-1));let F=0,S=0;for(let t=0;t<b;t++){let d=u+this.fb[t]+rt;const R=this.apX[t],T=this.apY[t],j=R.length;for(let r=0;r<j;r++){const V=-i*d+R[r]+i*T[r];R[r]=d,T[r]=V,d=V}const _=this.dBuf[t],f=this.dIdx[t],Q=_[f];_[f]=d,this.dIdx[t]=f+1>=this.dLen[t]?0:f+1,this.lp[t]+=Y*(Q-this.lp[t]),this.dc[t]+=W*(this.lp[t]-this.dc[t]);const P=ht(this.lp[t]-this.dc[t]);this.fb[t]=P*this.g[t],c[t].chan===0?F+=P:S+=P}x[a]=F*N,w[a]=S*N}return!0}}registerProcessor(\\\"spring-reverb\\\",pt);})();\\n\";\n", "export default \"(()=>{var L=Object.defineProperty;var Z=(s,e,t)=>e in s?L(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var a=(s,e,t)=>Z(s,typeof e!=\\\"symbol\\\"?e+\\\"\\\":e,t);function E(s){let e=s>>>0;return()=>{e=e+1831565813>>>0;let t=e;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}}class O extends AudioWorkletProcessor{constructor(){super(...arguments);a(this,\\\"buf\\\",new Float32Array(Math.ceil(1.5*1.03*sampleRate)+4));a(this,\\\"writeIdx\\\",0);a(this,\\\"tSlew\\\",-1);a(this,\\\"slewA\\\",1-Math.exp(-1/(.08*sampleRate)));a(this,\\\"phaseWow\\\",0);a(this,\\\"phaseFlut\\\",0);a(this,\\\"wowInc\\\",2*Math.PI*.85/sampleRate);a(this,\\\"rand\\\",E(2057179700));a(this,\\\"wander\\\",0);a(this,\\\"wanderTarget\\\",0);a(this,\\\"wanderCountdown\\\",0);a(this,\\\"damp\\\",0);a(this,\\\"dampD\\\",Math.exp(-2*Math.PI*6e3/sampleRate));a(this,\\\"dcX\\\",0);a(this,\\\"dcY\\\",0);a(this,\\\"dcR\\\",1-2*Math.PI*5/sampleRate)}static get parameterDescriptors(){return[{name:\\\"time\\\",defaultValue:.375,minValue:.05,maxValue:1.5,automationRate:\\\"k-rate\\\"},{name:\\\"feedback\\\",defaultValue:.5,minValue:0,maxValue:.95,automationRate:\\\"a-rate\\\"},{name:\\\"saturation\\\",defaultValue:.4,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"},{name:\\\"flutter\\\",defaultValue:.3,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"}]}process(t,S,u){const R=t[0]?.[0],p=S[0]?.[0];if(!p)return!0;const b=u.time,f=u.feedback,A=u.saturation,F=u.flutter,o=this.buf,l=o.length,V=this.dampD,g=this.dcR,T=b[0];this.tSlew<0&&(this.tSlew=T);const W=1+A[0]*4,x=F[0];this.wanderCountdown<=0&&(this.wanderTarget=this.rand()*2-1,this.wanderCountdown=Math.round(.5*sampleRate)),this.wanderCountdown-=p.length,this.wander+=.02*(this.wanderTarget-this.wander);const y=2*Math.PI*6.3*(1+.12*this.wander)/sampleRate;let m=this.tSlew,M=this.phaseWow,_=this.phaseFlut,n=this.damp,P=this.dcX,i=this.dcY,r=this.writeIdx;for(let h=0;h<p.length;h++){const C=R?R[h]:0,k=f.length>1?f[h]:f[0];m+=this.slewA*(T-m);let I=0;x>0&&(M+=this.wowInc,_+=y,I=x*(.008*Math.sin(M)+.0015*Math.sin(_)));let c=m*(1+I)*sampleRate;c<1?c=1:c>l-3&&(c=l-3);let w=r-c;w<0&&(w+=l);const d=w|0,D=w-d,X=d+1===l?0:d+1,H=o[d]+(o[X]-o[d])*D;n+=(1-V)*(H-n);const v=(Math.tanh(W*n)+Math.tanh(W*n*.3)*.1)/1.1;i=v-P+g*i,P=v,o[r]=C+k*i,p[h]=v,r++,r===l&&(r=0)}return Math.abs(n)<1e-20&&(n=0),Math.abs(i)<1e-20&&(i=0),this.tSlew=m,this.phaseWow=M,this.phaseFlut=_,this.damp=n,this.dcX=P,this.dcY=i,this.writeIdx=r,!0}}registerProcessor(\\\"tape-delay\\\",O);})();\\n\";\n", "export default \"(()=>{var O=Object.defineProperty;var w=(r,a,e)=>a in r?O(r,a,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[a]=e;var t=(r,a,e)=>w(r,typeof a!=\\\"symbol\\\"?a+\\\"\\\":a,e);class S extends AudioWorkletProcessor{constructor(){super();t(this,\\\"bufL\\\");t(this,\\\"bufR\\\");t(this,\\\"bufLen\\\");t(this,\\\"writePos\\\",0);t(this,\\\"readPos\\\",0);t(this,\\\"speed\\\",1);t(this,\\\"decayFactor\\\",1);t(this,\\\"ramping\\\",!1);t(this,\\\"prevTrig\\\",0);t(this,\\\"stopped\\\",!1);this.bufLen=Math.ceil(sampleRate*4),this.bufL=new Float32Array(this.bufLen),this.bufR=new Float32Array(this.bufLen)}static get parameterDescriptors(){return[{name:\\\"time\\\",defaultValue:.5,minValue:.005,maxValue:4},{name:\\\"mix\\\",defaultValue:1,minValue:0,maxValue:1}]}toggle(e){this.stopped=!this.stopped;const o=Math.max(1,Math.round(e*sampleRate));this.stopped?this.decayFactor=Math.pow(.001/Math.max(this.speed,.001),1/o):this.decayFactor=Math.pow(.001,1/o),this.ramping=!0,this.port.postMessage({type:\\\"state\\\",phase:\\\"ramping\\\"})}process(e,o,g){const L=e[0]?.[0],P=e[0]?.[1],F=e[1]?.[0],c=o[0]?.[0],b=o[0]?.[1];if(!c)return!0;const R=!!b,f=g.time,l=g.mix,E=c.length;for(let i=0;i<E;i++){const v=f.length>1?f[i]:f[0],h=l.length>1?l[i]:l[0];if(F){const s=F[i];s>.5&&this.prevTrig<=.5&&this.toggle(v),this.prevTrig=s}const n=L?L[i]:0,d=P?P[i]:R?n:0;if(this.bufL[this.writePos]=n,this.bufR[this.writePos]=d,this.ramping)if(this.stopped)this.speed*=this.decayFactor,this.speed<=.001&&(this.speed=0,this.ramping=!1,this.port.postMessage({type:\\\"state\\\",phase:\\\"stopped\\\"}));else{const p=(1-this.speed)*this.decayFactor;this.speed=1-p,p<=.001&&(this.speed=1,this.ramping=!1,this.port.postMessage({type:\\\"state\\\",phase:\\\"playing\\\"}))}let u=0,m=0;if(this.speed>=1&&!this.ramping)u=n,m=d,this.readPos=this.writePos;else if(this.speed>0){this.readPos=(this.readPos+this.speed)%this.bufLen;const s=Math.floor(this.readPos),p=this.readPos-s,y=(s+1)%this.bufLen;u=this.bufL[s]+p*(this.bufL[y]-this.bufL[s]),m=this.bufR[s]+p*(this.bufR[y]-this.bufR[s])}this.writePos=(this.writePos+1)%this.bufLen,c[i]=n*(1-h)+u*h,R&&(b[i]=d*(1-h)+m*h)}return!0}}registerProcessor(\\\"tape-stop\\\",S);})();\\n\";\n", "export default \"(()=>{class v extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:\\\"gain\\\",defaultValue:.5,minValue:0,maxValue:2,automationRate:\\\"a-rate\\\"},{name:\\\"cvAmount\\\",defaultValue:1,minValue:-1,maxValue:1,automationRate:\\\"a-rate\\\"},{name:\\\"cv\\\",defaultValue:0,minValue:-1e3,maxValue:1e3,automationRate:\\\"a-rate\\\"}]}process(i,m,o){const l=i[0],e=m[0];if(!e)return!0;const s=o.gain,c=o.cvAmount,r=o.cv,f=e.length,g=e[0]?.length??0;for(let t=0;t<g;t++){const V=s.length>1?s[t]:s[0],h=c.length>1?c[t]:c[0],d=r.length>1?r[t]:r[0];let a=V+h*d;a<0?a=0:a>2&&(a=2);for(let n=0;n<f;n++){const u=l?.[n]??l?.[0];e[n][t]=(u?u[t]:0)*a}}return!0}}registerProcessor(\\\"vca\\\",v);})();\\n\";\n", "export default \"(()=>{var J=Object.defineProperty;var X=(g,w,t)=>w in g?J(g,w,{enumerable:!0,configurable:!0,writable:!0,value:t}):g[w]=t;var r=(g,w,t)=>X(g,typeof w!=\\\"symbol\\\"?w+\\\"\\\":w,t);const F=new Float32Array([.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.109,.263,.453,.612,.701,.744,.773,.142,.333,.556,.731,.827,.873,.903,.188,.387,.59,.74,.821,.857,.882,.207,.422,.622,.756,.824,.855,.872,.217,.442,.642,.767,.827,.851,.868,.222,.452,.653,.774,.828,.852,.865,.224,.455,.657,.776,.829,.85,.862,.222,.452,.653,.774,.828,.852,.865,.217,.442,.642,.767,.827,.851,.868,.207,.422,.622,.756,.824,.855,.872,.187,.387,.59,.74,.821,.857,.882,.142,.333,.556,.731,.827,.873,.903,.152,.36,.61,.816,.935,.994,1.034,.27,.488,.689,.838,.924,.965,.994,.352,.592,.765,.874,.931,.958,.975,.401,.661,.819,.901,.939,.954,.966,.428,.7,.85,.917,.943,.954,.96,.437,.712,.861,.922,.945,.953,.957,.428,.7,.85,.917,.943,.954,.96,.401,.661,.819,.901,.939,.954,.966,.352,.592,.765,.874,.931,.958,.975,.27,.488,.689,.838,.924,.964,.995,.152,.36,.61,.816,.935,.994,1.034,.154,.369,.638,.876,1.028,1.108,1.165,.333,.551,.752,.912,1.012,1.063,1.103,.502,.721,.867,.967,1.025,1.053,1.074,.636,.849,.953,1.008,1.037,1.05,1.06,.724,.929,1.004,1.033,1.045,1.05,1.053,.754,.956,1.021,1.042,1.048,1.05,1.049,.724,.929,1.004,1.033,1.045,1.05,1.053,.636,.849,.953,1.008,1.037,1.05,1.06,.502,.721,.867,.967,1.025,1.053,1.073,.333,.551,.752,.912,1.012,1.063,1.103,.154,.369,.638,.876,1.028,1.108,1.165,.154,.372,.655,.923,1.11,1.216,1.296,.367,.586,.793,.969,1.09,1.154,1.208,.582,.79,.933,1.039,1.108,1.142,1.169,.77,.947,1.037,1.092,1.125,1.14,1.151,.901,1.047,1.1,1.124,1.135,1.14,1.144,.948,1.082,1.122,1.135,1.139,1.14,1.138,.901,1.047,1.1,1.124,1.135,1.14,1.144,.77,.947,1.037,1.092,1.125,1.14,1.151,.582,.79,.933,1.039,1.108,1.142,1.169,.367,.586,.793,.969,1.09,1.154,1.208,.154,.372,.655,.923,1.11,1.216,1.296,.154,.374,.668,.962,1.185,1.32,1.427,.377,.604,.821,1.016,1.159,1.24,1.31,.585,.811,.973,1.097,1.183,1.226,1.261,.753,.965,1.083,1.157,1.203,1.224,1.24,.862,1.061,1.15,1.194,1.216,1.225,1.232,.899,1.094,1.172,1.207,1.22,1.225,1.224,.862,1.061,1.15,1.194,1.216,1.225,1.232,.753,.965,1.083,1.157,1.203,1.224,1.24,.585,.811,.973,1.097,1.183,1.226,1.261,.377,.604,.821,1.016,1.159,1.24,1.31,.154,.374,.668,.962,1.185,1.32,1.427,.154,.372,.657,.934,1.137,1.257,1.35,.373,.594,.802,.985,1.116,1.188,1.249,.592,.801,.948,1.06,1.137,1.175,1.206,.781,.96,1.056,1.117,1.155,1.173,1.186,.911,1.06,1.121,1.152,1.167,1.173,1.178,.957,1.095,1.143,1.163,1.171,1.173,1.172,.911,1.06,1.121,1.152,1.167,1.173,1.178,.781,.96,1.056,1.117,1.155,1.173,1.186,.592,.801,.948,1.06,1.137,1.175,1.206,.373,.594,.802,.985,1.116,1.188,1.249,.154,.372,.657,.934,1.137,1.257,1.35,.154,.37,.647,.907,1.093,1.199,1.28,.367,.582,.784,.955,1.074,1.14,1.194,.592,.786,.922,1.025,1.093,1.128,1.155,.798,.946,1.026,1.077,1.11,1.125,1.137,.947,1.049,1.089,1.11,1.121,1.125,1.129,1.003,1.085,1.11,1.121,1.124,1.125,1.124,.947,1.049,1.089,1.11,1.121,1.125,1.129,.798,.946,1.026,1.077,1.11,1.125,1.137,.592,.786,.922,1.025,1.093,1.128,1.155,.367,.582,.784,.955,1.074,1.14,1.194,.154,.37,.647,.907,1.093,1.199,1.28,.153,.367,.636,.882,1.051,1.146,1.217,.358,.569,.764,.926,1.035,1.094,1.142,.583,.767,.896,.99,1.052,1.083,1.107,.799,.925,.994,1.039,1.067,1.081,1.091,.964,1.028,1.055,1.069,1.077,1.081,1.083,1.028,1.064,1.075,1.079,1.08,1.081,1.08,.964,1.028,1.055,1.069,1.077,1.081,1.084,.799,.925,.994,1.039,1.067,1.081,1.091,.583,.767,.896,.99,1.052,1.083,1.107,.358,.569,.764,.926,1.035,1.095,1.142,.153,.367,.636,.882,1.051,1.146,1.217,.153,.365,.625,.857,1.011,1.096,1.16,.348,.556,.745,.898,.999,1.052,1.095,.567,.746,.868,.957,1.014,1.042,1.064,.785,.899,.961,1.002,1.027,1.039,1.048,.958,1,1.018,1.029,1.036,1.039,1.041,1.027,1.035,1.038,1.039,1.039,1.039,1.038,.958,1,1.018,1.029,1.036,1.039,1.041,.785,.899,.961,1.002,1.027,1.039,1.048,.567,.746,.868,.957,1.014,1.042,1.064,.348,.556,.745,.898,.999,1.052,1.095,.153,.365,.625,.857,1.011,1.096,1.16,.153,.362,.615,.833,.975,1.051,1.107,.336,.541,.726,.871,.964,1.013,1.051,.546,.722,.841,.925,.977,1.003,1.023,.758,.869,.928,.966,.989,1.001,1.009,.931,.966,.982,.991,.997,1,1.002,1,1,1,1,1,1,1,.931,.966,.982,.991,.997,1,1.002,.758,.869,.928,.966,.989,1.001,1.009,.546,.722,.841,.925,.977,1.003,1.023,.336,.541,.726,.871,.964,1.013,1.051,.153,.362,.615,.833,.975,1.051,1.107]),K=11,D=11,T=7;const N=[5.7814,6.7814,7.7814,8.7814,9.7814,10.7814,11.7814],e=class e extends AudioWorkletProcessor{constructor(){super(...arguments);r(this,\\\"phase\\\",0);r(this,\\\"normGain\\\",1);r(this,\\\"normTarget\\\",1);r(this,\\\"osW1\\\",0);r(this,\\\"osW2\\\",0);r(this,\\\"stepPos\\\",new Float64Array(3));r(this,\\\"stepAmp\\\",new Float64Array(3));r(this,\\\"nSteps\\\",0)}static get parameterDescriptors(){return[{name:\\\"skew\\\",defaultValue:0,minValue:-34e37,maxValue:34e37,automationRate:\\\"a-rate\\\"},{name:\\\"shape\\\",defaultValue:0,minValue:-34e37,maxValue:34e37,automationRate:\\\"a-rate\\\"},{name:\\\"normalize\\\",defaultValue:0,minValue:0,maxValue:1,automationRate:\\\"k-rate\\\"}]}static awBilinear(t,o,n,a,i,s){const h=(y,c)=>(y*D+c)*T+i,u=h(t,n),A=h(t+1,n),S=h(t,n+1),E=h(t+1,n+1),f=F[u]*(1-s)+F[u+1]*s,b=F[A]*(1-s)+F[A+1]*s,m=F[S]*(1-s)+F[S+1]*s,d=F[E]*(1-s)+F[E+1]*s,l=f*(1-a)+m*a,p=b*(1-a)+d*a;return l*(1-o)+p*o}static awGainLookup(t,o,n){const a=Math.min(Math.max(t,0),1)*(K-1),i=Math.min(Math.max(o,0),1)*(D-1),h=(Math.log2(Math.max(n,20))-N[0])/(N[T-1]-N[0]),u=Math.min(Math.max(h*(T-1),0),T-1),A=Math.min(Math.floor(a),K-2),S=a-A,E=Math.min(Math.floor(i),D-2),f=i-E,b=Math.min(Math.floor(u),T-2),m=u-b,d=e.awBilinear(A,S,E,f,b,m),l=e.awBilinear(A,S,E,f,e.AW_REF_FI,0);return l<=1e-6?d:l*Math.pow(d/l,e.AW_TILT)}static shapeMap(t,o,n,a){let i;if(o<=.5){const s=Math.abs(t);i=(t>=0?1:-1)*Math.pow(s,n)}else{const s=(o-.5)*2,h=Math.sin(t*Math.PI*.5);i=t+(h-t)*s}return a>0&&(i=(1-a)*i+a*(t>=0?1:-1)),i}static blep(t){if(t>=0){if(t>=1)return 0;const n=t-1;return-.5*n*n}if(t<=-1)return 0;const o=t+1;return .5*o*o}static eval(t,o,n){const a=Math.min(Math.max(o,.001),.999);let i;t<a?i=t/a:i=1-(t-a)/(1-a);const s=2*i-1;if(n<=.5){const h=Math.max(n*2,.05),u=Math.abs(s);return(s>=0?1:-1)*Math.pow(u,h)}else{const h=(n-.5)*2,u=Math.sin(s*Math.PI*.5);return s+(u-s)*h}}cornerSample(t,o,n,a,i,s,h,u){let A;t<o?A=t/o:A=1-(t-o)/(1-o);let S=2*A-1;n>0&&(S=(1-n)*S+n*(a?2*t-1:1-2*t));let E=e.shapeMap(S,i,s,h);const f=u>=0?1:-1;for(let b=0;b<this.nSteps;b++){let m=t-this.stepPos[b];m-=Math.round(m);const d=m/u;d>-1&&d<1&&(E+=f*this.stepAmp[b]*e.blep(d))}return E}process(t,o,n){const a=t[0]?.[0],i=o[0]?.[0];if(!i)return!0;const s=n.skew,h=n.shape,u=n.normalize[0]>.5,A=1/sampleRate,S=e.SMOOTH_COEFF,E=e.UPDATE_INTERVAL,f=e.SKEW_EDGE,b=e.SHAPE_EDGE;for(let m=0;m<i.length;m++){const d=a&&a.length>m?a[m]:440;let l=s.length>1?s[m]:s[0],p=h.length>1?h[m]:h[0];l=(l+1)*.5,p=(p+1)*.5,l=1-Math.abs((l%2+2)%2-1),p=1-Math.abs((p%2+2)%2-1);const y=d*A*.5;let c=0,W=!1;l<f?c=1-l/f:l>1-f&&(c=1-(1-l)/f,W=!0);let v=0,R=1;if(p<=.5){const M=p*2;R=M>b?M:b,M<b&&(v=1-M/b)}let B,I;if(v===0&&c===0)this.phase+=y,this.phase>=1&&(this.phase-=1),this.phase<0&&(this.phase+=1),B=e.eval(this.phase,l,p),this.phase+=y,this.phase>=1&&(this.phase-=1),this.phase<0&&(this.phase+=1),I=e.eval(this.phase,l,p);else{const M=Math.min(Math.max(l,f),1-f),q=W?-1:1,C=W?2*M-1:1-2*M,j=W?1:-1,G=c>0?(1-c)*-1+c*q:-1,O=c>0?(1-c)*1+c*C:1,x=c>0?(1-c)*-1+c*j:-1;if(this.nSteps=0,c>0){const z=e.shapeMap(G,p,R,v)-e.shapeMap(x,p,R,v);z!==0&&(this.stepPos[this.nSteps]=0,this.stepAmp[this.nSteps++]=z)}v>0&&(G<0!=O<0&&(this.stepPos[this.nSteps]=M*(0-G)/(O-G),this.stepAmp[this.nSteps++]=O>G?2*v:-2*v),O<0!=x<0&&(this.stepPos[this.nSteps]=M+(1-M)*(0-O)/(x-O),this.stepAmp[this.nSteps++]=x>O?2*v:-2*v)),this.phase+=y,this.phase>=1&&(this.phase-=1),this.phase<0&&(this.phase+=1),B=this.cornerSample(this.phase,M,c,W,p,R,v,y),this.phase+=y,this.phase>=1&&(this.phase-=1),this.phase<0&&(this.phase+=1),I=this.cornerSample(this.phase,M,c,W,p,R,v,y)}const{OS_B0:P,OS_B1:Q,OS_B2:U,OS_A1:L,OS_A2:_}=e;let V=B-L*this.osW1-_*this.osW2;this.osW2=this.osW1,this.osW1=V,V=I-L*this.osW1-_*this.osW2;let H=P*V+Q*this.osW1+U*this.osW2;this.osW2=this.osW1,this.osW1=V,u&&((m&E-1)===0&&(this.normTarget=e.awGainLookup(p,l,d)),this.normGain+=S*(this.normTarget-this.normGain),H*=this.normGain),i[m]=H}return!0}};r(e,\\\"OS_B0\\\",.20657),r(e,\\\"OS_B1\\\",.41314),r(e,\\\"OS_B2\\\",.20657),r(e,\\\"OS_A1\\\",-.36953),r(e,\\\"OS_A2\\\",.19582),r(e,\\\"UPDATE_INTERVAL\\\",32),r(e,\\\"SMOOTH_COEFF\\\",1-Math.pow(.05,1/32)),r(e,\\\"AW_TILT\\\",.35),r(e,\\\"AW_REF_FI\\\",2),r(e,\\\"SKEW_EDGE\\\",.01),r(e,\\\"SHAPE_EDGE\\\",.05);let k=e;registerProcessor(\\\"waveshaper\\\",k);})();\\n\";\n"],
5
+ "mappings": ";AAAA,IAAO,wBAAQ;;;ACAf,IAAO,qBAAQ;;;ACAf,IAAO,sBAAQ;;;ACAf,IAAO,uBAAQ;;;ACAf,IAAO,qBAAQ;;;ACAf,IAAO,kBAAQ;;;ACAf,IAAO,wBAAQ;;;ACAf,IAAO,uBAAQ;;;ACAf,IAAO,uBAAQ;;;ACAf,IAAO,gBAAQ;;;ACAf,IAAO,wBAAQ;;;ACAf,IAAO,kBAAQ;;;ACAf,IAAO,2BAAQ;;;ACAf,IAAO,6BAAQ;;;ACAf,IAAO,oBAAQ;;;ACAf,IAAO,wBAAQ;;;ACAf,IAAO,wBAAQ;;;ACAf,IAAO,qBAAQ;;;ACAf,IAAO,oBAAQ;;;ACAf,IAAO,cAAQ;;;ACAf,IAAO,qBAAQ;",
6
+ "names": []
7
+ }
package/docs/GUIDE.md CHANGED
@@ -130,9 +130,26 @@ transport.start();
130
130
 
131
131
  ### Pattern steps
132
132
 
133
- - **Hits:** any value. `true` from `steps()`, a `Note` from `notes()`, or whatever your voice understands.
134
- - **Rests:** `null`, `undefined`, `false`, `0`, `'.'` and `'-'`.
135
- - **Per-step velocity and length:** `{ value, velocity, length }`, where `length` is in steps.
133
+ - **Hits:** any other value, `0` included. A `Note` from `notes()`, `true`, or whatever your voice understands.
134
+ - **Rests:** `null`, `undefined` (and array holes like `[60, , 64]`) and `false`. Inside the `steps()` and `notes()` strings, `'.'` and `'-'` become rests.
135
+ - **Per-step velocity and length:** `{ value, velocity, length }`, where `length` is in steps. Velocity defaults to 1.
136
+
137
+ A step's value means whatever the voice makes of it. Drums ignore it, and `NoteCv` and `SampleVoice` play it as a note. Loudness is always `velocity`, never the value, so `[1, 0, 0, 1]` is four equal hits, not a drum grid.
138
+
139
+ **Drum grids with accents.** In `steps()`, `X` is an accent, `x` a normal hit and `o` a ghost note. All three are velocities: 1, 0.75 and 0.4 by default, and you can change them. Any other character throws, so a typo can't quietly become a rest.
140
+
141
+ ```ts
142
+ import { createTransport, steps, Snare } from '@jpdutoit/squelchy';
143
+
144
+ const ctx = new AudioContext();
145
+ const transport = createTransport(ctx);
146
+ const snare = Snare.create(ctx);
147
+ snare.connect(ctx.destination);
148
+
149
+ transport.play(steps('....X..o .o..X..o'), snare); // backbeat with ghost notes
150
+ transport.play(steps('x.x.x.x.', { normal: 0.5, accent: 1, ghost: 0.2 }), snare); // your own levels
151
+ transport.start();
152
+ ```
136
153
 
137
154
  ```ts
138
155
  import { createTransport, notes, note, beats, NoteCv, type Step, type Note } from '@jpdutoit/squelchy';
@@ -266,6 +283,10 @@ transport.start();
266
283
 
267
284
  Actions like a tape stop or kicking the spring tank are **gate inputs**. They react to a rising edge, like a trigger cable on hardware. `pulse(input, time)` fires one at an exact time. It works the same whether it's called from a button, a pattern or `transport.at`, and it sums with anything else patched into that input.
268
285
 
286
+ **Timing.** A pulse lands exactly on the time you give it, as long as that time is still ahead when the call runs. Schedule timed actions ahead: `transport.at` and `transport.play` do this for you, a lookahead before the beat. A time that has already passed fires as soon as possible, so it's late. It's never dropped.
287
+
288
+ `pulse(input)` with no time is for buttons: it fires as soon as possible. A busy page can make it a few milliseconds late, but the press always registers. To land a button press on the beat, hand it to the transport so it fires on the next beat (or bar):
289
+
269
290
  ```ts
270
291
  import { preload, createTransport, steps, pulse, sec, TapeStop, SpringReverb, Kick } from '@jpdutoit/squelchy';
271
292
 
@@ -287,6 +308,8 @@ transport.at({ bar: 5 }, (t) => pulse(tape.trigger, t)); // …and back up a bar
287
308
 
288
309
  // From a button, right now:
289
310
  const onClick = () => pulse(tape.trigger);
311
+ // From a button, on the next beat ('bar' for the next bar line):
312
+ const onClickInTime = () => transport.at('beat', (t) => pulse(tape.trigger, t));
290
313
  transport.start();
291
314
  ```
292
315
 
@@ -309,7 +332,7 @@ Every kit is CC0 or public domain, and each one carries its own `license`. Each
309
332
  | `import { DeepAnalogue } from '@jpdutoit/squelchy/kits/deep-analogue'` | Deep Analogue | Acoustic | bd sd rim clap ch oh lt mt ht cym perc |
310
333
 
311
334
  ```ts
312
- import { createTransport, steps, loadSampleSet, SampleVoice, VOICE_KEYS } from '@jpdutoit/squelchy';
335
+ import { createTransport, steps, notes, note, loadSampleSet, SampleVoice, VOICE_KEYS } from '@jpdutoit/squelchy';
313
336
  import { Tr909 } from '@jpdutoit/squelchy/kits/tr-909';
314
337
 
315
338
  const ctx = new AudioContext();
@@ -319,17 +342,17 @@ const kit = await loadSampleSet(ctx, Tr909);
319
342
  console.log(VOICE_KEYS.filter((k) => !kit.buffers[k])); // voices this kit covers by fallback
320
343
 
321
344
  const bd = SampleVoice.create(ctx, kit, 'bd');
322
- const tom = SampleVoice.create(ctx, kit, 'lt');
345
+ const tom = SampleVoice.create(ctx, kit, 'lt', { root: note('C4') }); // C4 plays the sample as recorded (the default)
323
346
  bd.connect(ctx.destination);
324
347
  tom.connect(ctx.destination);
325
348
 
326
349
  const transport = createTransport(ctx);
327
350
  transport.play(steps('x...x...x...x...'), bd);
328
- transport.play([true, null, 3, null, 7, 12, null, null], tom); // numbers repitch in semitones
351
+ transport.play(notes('C4 . Eb4 . G4 C5 . .'), tom); // tom melody: notes, like NoteCv
329
352
  transport.start();
330
353
  ```
331
354
 
332
- A step value of `0` is a rest, so use `true` for an unshifted hit.
355
+ A sample voice is one-shot, like a drum machine: every hit plays the whole sample, whatever the step's gate length. Its step value is a note, so the same `notes()` melody plays on a sampler and on a synth voice.
333
356
 
334
357
  **How the audio gets into your build.** A kit's voice URLs are written as `new URL('./tr-909/bd.flac', import.meta.url)`. Vite (8.3 or newer, in dev and build), webpack 5 and Parcel all recognise that pattern: they copy each file of the kits you import into your output with a content hash and rewrite the URL. Loading the package unbundled, e.g. from a CDN like jsDelivr, resolves the files next to the kit module.
335
358
 
package/docs/MODULES.md CHANGED
@@ -79,7 +79,7 @@ Categories: Filters · Worklets: adsr-envelope, map-voct-to-freq
79
79
  | `resonance` | `8` | 0 – 15 (sqrt) | **Resonance** — Resonance amount, 0–100% of travel. Creates the characteristic 303 "wow" at high settings. Like the hardware, there is no resonance CV input — the knob is the only control. `set()` only. |
80
80
  | `envMod` | `0.7` | 0 – 1 | **Envelope Mod** — How much the triggered envelope sweeps the filter cutoff. `set()` only. |
81
81
  | `accent` | `0.5` | 0 – 1 | **Accent** — Intensifies the envelope sweep for more aggressive acid sounds. `set()` only. |
82
- | `decay` | `0.2` | 0.05 – 1 s (log) | **Decay Time** — How quickly the filter envelope falls. Short = plucky, long = sustained. Automatable: `params.decay` is a native AudioParam. |
82
+ | `decay` | `0.92` | 0.2 – 5 s (log) | **Decay Time** — Time for the exponential filter sweep to fall 60 dB after each trigger. Short = plucky squelch, long = slow, singing sweeps. Automatable: `params.decay` is a native AudioParam. |
83
83
 
84
84
  ## PAN
85
85
 
@@ -929,7 +929,7 @@ Categories: Time · Worklets: pitch-shifter, fdn-reverb
929
929
  | `decay` | `3` | 0.5 – 10 s (log) | **Reverb Decay** — RT60 of the reverb tank in seconds — the time to fall 60 dB, measured at 500 Hz. Treble dies faster, like a real hall. `set()` only. |
930
930
  | `pitch` | `12` | -12 – 24 semitones | **Pitch Shift** — Transposition applied by the granular pitch shifter on every trip round the feedback loop (12 = one octave). +12 = octave up, +7 = fifth up, -12 = octave down. `set()` only. |
931
931
  | `mix` | `0.5` | 0 – 1 | **Dry/Wet Mix** — Equal-power balance between dry signal and shimmer output — independent of the regen amount. Automatable: `params.mix` is a native AudioParam. |
932
- | `shimmer` | `0.5` | 0 – 0.95 | **Shimmer Regen** — Gain once round the pitch-shifted feedback loop, measured at 500 Hz: 0.5 = each new octave 6 dB quieter than the last, 0.95 = an almost endless rising choir. Means the same at every DECAY setting. Automatable: `params.shimmer` is a native AudioParam. |
932
+ | `shimmer` | `0.5` | 0 – 0.95 | **Shimmer Regen** — Gain once round the pitch-shifted feedback loop, measured at 500 Hz: 0.5 = each new octave 6 dB quieter than the last, 0.95 = an almost endless rising choir. Means the same at every DECAY setting. At PITCH 0 the loop is plain reverb feedback and the regen is held under its self-oscillation edge, so 0.95 is a near-frozen, slowly breathing tail that always dies away. Automatable: `params.shimmer` is a native AudioParam. |
933
933
 
934
934
  ## LIMIT
935
935
 
package/docs/modules.json CHANGED
@@ -80,12 +80,12 @@
80
80
  },
81
81
  "decay": {
82
82
  "name": "Decay Time",
83
- "description": "How quickly the filter envelope falls. Short = plucky, long = sustained.",
83
+ "description": "Time for the exponential filter sweep to fall 60 dB after each trigger. Short = plucky squelch, long = slow, singing sweeps.",
84
84
  "type": "Seconds",
85
85
  "unit": "s",
86
- "default": 0.2,
87
- "min": 0.05,
88
- "max": 1,
86
+ "default": 0.92,
87
+ "min": 0.2,
88
+ "max": 5,
89
89
  "scale": "log",
90
90
  "automatable": true
91
91
  }
@@ -2470,7 +2470,7 @@
2470
2470
  },
2471
2471
  "shimmer": {
2472
2472
  "name": "Shimmer Regen",
2473
- "description": "Gain once round the pitch-shifted feedback loop, measured at 500 Hz: 0.5 = each new octave 6 dB quieter than the last, 0.95 = an almost endless rising choir. Means the same at every DECAY setting.",
2473
+ "description": "Gain once round the pitch-shifted feedback loop, measured at 500 Hz: 0.5 = each new octave 6 dB quieter than the last, 0.95 = an almost endless rising choir. Means the same at every DECAY setting. At PITCH 0 the loop is plain reverb feedback and the regen is held under its self-oscillation edge, so 0.95 is a near-frozen, slowly breathing tail that always dies away.",
2474
2474
  "type": "number",
2475
2475
  "unit": "factor",
2476
2476
  "default": 0.5,
package/index.d.ts CHANGED
@@ -50,7 +50,7 @@ export declare function preload(ctx: BaseAudioContext, opts?: {
50
50
  export type ParamValue = number | string | boolean | number[] | boolean[][];
51
51
  /** Runtime metadata — only what code needs. Human-facing text (names,
52
52
  * descriptions, labels) is stripped from the bundle; it lives in the
53
- * generated docs/MODULES.md, meta.json and the .d.ts JSDoc instead. */
53
+ * generated docs/MODULES.md, docs/modules.json and the .d.ts JSDoc instead. */
54
54
  export interface ModuleMeta {
55
55
  type: string;
56
56
  ports: Record<string, Pick<PortDefinition, "type" | "signal">>;
@@ -139,7 +139,7 @@ export interface StepObject<V> {
139
139
  /** Gate length in steps, default = the playback's `gate`. */
140
140
  length?: number;
141
141
  }
142
- /** A pattern step: a value, a rest (null/undefined/false/0/'.'/'-'), or a StepObject. */
142
+ /** A pattern step: a value (0 included), a rest (null/undefined/false), or a StepObject. */
143
143
  export type Step<V> = V | StepObject<V> | null | undefined | false;
144
144
  /** What a voice receives per hit. */
145
145
  export interface Hit<V = unknown> {
@@ -151,7 +151,7 @@ export interface Hit<V = unknown> {
151
151
  step: number;
152
152
  /** Loop iteration, 0-based. */
153
153
  cycle: number;
154
- /** The step's value (true for `steps('x..x')`, a midi number for melodies, …). */
154
+ /** The step's value (true for `steps('x..x')`, a Note for melodies, …). */
155
155
  value: V;
156
156
  velocity: number;
157
157
  /** Gate length in seconds. */
@@ -219,10 +219,27 @@ export interface Transport {
219
219
  tick(): void;
220
220
  dispose(): void;
221
221
  }
222
- export declare function isRest(v: unknown): boolean;
222
+ /** Rests are exactly the "nothing" values in `Step`: null, undefined (array
223
+ * holes) and false. `0` is a real value (root note, 0 semitones, CV 0);
224
+ * `'.'`/`'-'` are only rest syntax inside steps()/notes() strings. */
225
+ export declare function isRest(v: unknown): v is null | undefined | false;
223
226
  export declare function createTransport(ctx: BaseAudioContext, opts?: TransportOptions): Transport;
224
- /** `steps('x... x... x..x x...')` → boolean[]. x/X = hit, anything else = rest; spaces/| ignored. */
225
- export declare function steps(s: string): boolean[];
227
+ /** Velocities for the hit letters in `steps()`. */
228
+ export interface StepsLevels {
229
+ /** `X`. Default 1. */
230
+ accent?: number;
231
+ /** `x`. Default 0.75. */
232
+ normal?: number;
233
+ /** `o`. Default 0.4. */
234
+ ghost?: number;
235
+ }
236
+ /**
237
+ * `steps('X..x o.x. x... x..x')` → one step per character, value `true`:
238
+ * `X` = accent, `x` = normal hit, `o` = ghost note (as velocity, see
239
+ * StepsLevels), `.`/`-` = rest. Spaces and `|` are ignored; any other
240
+ * character throws, so a typo can't silently become a rest.
241
+ */
242
+ export declare function steps(s: string, levels?: StepsLevels): (StepObject<true> | null)[];
226
243
  /** 'A4' → 69, 'C4' → 60, 'F#2' → 42; a number passes through typed. Midi numbers are the pitch unit everywhere (V/Oct = semitones). */
227
244
  export declare function note(name: string | number): Note;
228
245
  /** `notes('C3 . E3 G3 - C4')` → (Note | null)[]. '.'/'-' = rest. */
@@ -301,11 +318,17 @@ export interface LoadedSampleSet {
301
318
  export declare function loadSampleSet(ctx: BaseAudioContext, set: SampleSetInfo, opts?: {
302
319
  fetch?: typeof fetch;
303
320
  }): Promise<LoadedSampleSet>;
304
- /** A one-sample voice. velocity 0..1 scales level; a number `value`
305
- * repitches in semitones, anything else (e.g. `true` from steps()) plays it
306
- * unshifted. */
321
+ export interface SampleVoiceOptions {
322
+ /** The note that plays the sample unshifted. Default 60 (C4). */
323
+ root?: Note;
324
+ }
325
+ /** A one-shot sample voice, like a drum machine: every hit plays the whole
326
+ * sample, whatever the step's gate length. velocity 0..1 scales level. A
327
+ * `Note` value plays the sample at that note (`root` = unshifted), the same
328
+ * numbers `NoteCv` plays, so `notes()` melodies work on both; anything else
329
+ * (e.g. `true` from steps()) plays it unshifted. */
307
330
  export declare const SampleVoice: {
308
- create(ctx: BaseAudioContext, kit: LoadedSampleSet, key: VoiceKey): VoiceInstance<number | boolean>;
331
+ create(ctx: BaseAudioContext, kit: LoadedSampleSet, key: VoiceKey, opts?: SampleVoiceOptions): VoiceInstance<Note | boolean>;
309
332
  };
310
333
  export interface AcidFilterParams {
311
334
  /** Cutoff Note. Base cutoff as a note (67 ≈ 400 Hz, 69 = 440 Hz) for the iconic squelchy acid sound. Drives the V/OCT worklet 1:1 — the panel knob shows the equivalent Hz. Range 15–135 notes. Default 67. */
@@ -316,7 +339,7 @@ export interface AcidFilterParams {
316
339
  envMod?: number;
317
340
  /** Accent. Intensifies the envelope sweep for more aggressive acid sounds. Range 0–1. Default 0.5. */
318
341
  accent?: number;
319
- /** Decay Time. How quickly the filter envelope falls. Short = plucky, long = sustained. Range 0.05–1 s (log). Default 0.2. */
342
+ /** Decay Time. Time for the exponential filter sweep to fall 60 dB after each trigger. Short = plucky squelch, long = slow, singing sweeps. Range 0.2–5 s (log). Default 0.92. */
320
343
  decay?: Seconds;
321
344
  }
322
345
  export type AcidFilterInputs = {
@@ -1335,7 +1358,7 @@ export interface ShimmerParams {
1335
1358
  pitch?: Semitones;
1336
1359
  /** Dry/Wet Mix. Equal-power balance between dry signal and shimmer output — independent of the regen amount. Range 0–1. Default 0.5. */
1337
1360
  mix?: number;
1338
- /** Shimmer Regen. Gain once round the pitch-shifted feedback loop, measured at 500 Hz: 0.5 = each new octave 6 dB quieter than the last, 0.95 = an almost endless rising choir. Means the same at every DECAY setting. Range 0–0.95. Default 0.5. */
1361
+ /** Shimmer Regen. Gain once round the pitch-shifted feedback loop, measured at 500 Hz: 0.5 = each new octave 6 dB quieter than the last, 0.95 = an almost endless rising choir. Means the same at every DECAY setting. At PITCH 0 the loop is plain reverb feedback and the regen is held under its self-oscillation edge, so 0.95 is a near-frozen, slowly breathing tail that always dies away. Range 0–0.95. Default 0.5. */
1339
1362
  shimmer?: number;
1340
1363
  }
1341
1364
  export type ShimmerInputs = {
package/index.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  tape_stop_default,
21
21
  vca_default,
22
22
  waveshaper_default
23
- } from "./chunk-MEZE4P3U.js";
23
+ } from "./chunk-N7J25N5J.js";
24
24
 
25
25
  // src/lib-runtime/core.ts
26
26
  var pendingSources = {};
@@ -28,7 +28,7 @@ var registrations = /* @__PURE__ */ new WeakMap();
28
28
  function preload(ctx, opts) {
29
29
  const existing = registrations.get(ctx);
30
30
  if (existing) return existing;
31
- const sources = opts?.allWorklets ? import("./worklets-inline-DFWINMCS.js").then((m) => m.WORKLET_SOURCES) : Promise.resolve(pendingSources);
31
+ const sources = opts?.allWorklets ? import("./worklets-inline-EF3OTQ4D.js").then((m) => m.WORKLET_SOURCES) : Promise.resolve(pendingSources);
32
32
  const promise = sources.then(
33
33
  (map) => Promise.all(Object.entries(map).map(async ([name, src]) => {
34
34
  const url = URL.createObjectURL(new Blob([src], { type: "text/javascript" }));
@@ -141,7 +141,7 @@ var Instance = class {
141
141
  // src/lib-runtime/time/transport.ts
142
142
  var EPS = 1e-9;
143
143
  function isRest(v) {
144
- return v == null || v === false || v === 0 || v === "." || v === "-";
144
+ return v == null || v === false;
145
145
  }
146
146
  function normStep(s) {
147
147
  if (isRest(s)) return null;
@@ -356,8 +356,13 @@ function createTransport(ctx, opts = {}) {
356
356
  };
357
357
  return t;
358
358
  }
359
- function steps(s) {
360
- return [...s.replace(/[\s|]/g, "")].map((c) => c === "x" || c === "X");
359
+ function steps(s, levels = {}) {
360
+ const velocity = { X: levels.accent ?? 1, x: levels.normal ?? 0.75, o: levels.ghost ?? 0.4 };
361
+ return [...s.replace(/[\s|]/g, "")].map((c) => {
362
+ if (c === "." || c === "-") return null;
363
+ if (!(c in velocity)) throw new Error(`steps(): unknown character "${c}" in "${s}" (X accent, x hit, o ghost, . or - rest)`);
364
+ return { value: true, velocity: velocity[c] };
365
+ });
361
366
  }
362
367
  var NOTE_RE = /^([A-Ga-g])([#b]?)(-?\d+)$/;
363
368
  var PC = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };
@@ -526,16 +531,28 @@ var asPitch = (n) => n;
526
531
 
527
532
  // src/lib/dsp/pulse.ts
528
533
  var PULSE_S = 1e-3;
529
- function pulse(target, when) {
530
- const ctx = target.context;
531
- const at = Math.max(when ?? 0, ctx.currentTime);
532
- const src = ctx.createConstantSource();
533
- src.offset.value = 1;
534
+ var pulseBuffers = /* @__PURE__ */ new WeakMap();
535
+ function filled(ctx, samples, level) {
536
+ const buf = ctx.createBuffer(1, samples, ctx.sampleRate);
537
+ buf.getChannelData(0).fill(level);
538
+ return buf;
539
+ }
540
+ function play(ctx, buf, target, when) {
541
+ const src = ctx.createBufferSource();
542
+ src.buffer = buf;
534
543
  src.connect(target);
535
- src.start(at);
536
- src.stop(at + PULSE_S);
544
+ src.start(Math.max(0, when ?? 0));
537
545
  src.onended = () => src.disconnect();
538
546
  }
547
+ function pulse(target, when) {
548
+ const ctx = target.context;
549
+ let buf = pulseBuffers.get(ctx);
550
+ if (!buf) {
551
+ buf = filled(ctx, Math.max(1, Math.ceil(ctx.sampleRate * PULSE_S)), 1);
552
+ pulseBuffers.set(ctx, buf);
553
+ }
554
+ play(ctx, buf, target, when);
555
+ }
539
556
 
540
557
  // src/lib/samples/types.ts
541
558
  var VOICE_KEYS = [
@@ -585,19 +602,19 @@ async function loadSampleSet(ctx, set, opts = {}) {
585
602
  };
586
603
  }
587
604
  var SampleVoice = {
588
- create(ctx, kit, key) {
605
+ create(ctx, kit, key, opts = {}) {
589
606
  const out = ctx.createGain();
590
607
  const buf = kit.buffer(key);
608
+ const root = opts.root ?? 60;
591
609
  const trigger = (when, h) => {
592
610
  if (!buf) return;
593
611
  const src = ctx.createBufferSource();
594
612
  const g = ctx.createGain();
595
613
  src.buffer = buf;
596
- if (typeof h?.value === "number") src.playbackRate.value = 2 ** (h.value / 12);
614
+ if (typeof h?.value === "number") src.playbackRate.value = 2 ** ((h.value - root) / 12);
597
615
  g.gain.value = Math.max(0, Math.min(1, h?.velocity ?? 1));
598
616
  src.connect(g).connect(out);
599
617
  src.start(when);
600
- if (h?.duration) src.stop(when + h.duration);
601
618
  };
602
619
  return {
603
620
  output: out,
@@ -846,7 +863,7 @@ var params = {
846
863
  resonance: { unit: "factor", default: 8, min: 0, max: 15, scale: "sqrt" },
847
864
  envMod: { unit: "factor", default: 0.7, min: 0, max: 1 },
848
865
  accent: { unit: "factor", default: 0.5, min: 0, max: 1 },
849
- decay: { node: "envSmoother", field: "decay", unit: "s", default: 0.2, min: 0.05, max: 1, scale: "log" }
866
+ decay: { node: "envSmoother", field: "decay", unit: "s", default: 0.92, min: 0.2, max: 5, scale: "log" }
850
867
  };
851
868
  var filter303Descriptor = /* @__PURE__ */ defineDescriptor({
852
869
  type: "303-filter",
@@ -858,7 +875,7 @@ var filter303Descriptor = /* @__PURE__ */ defineDescriptor({
858
875
  "modFreq": { type: "modulation", signal: "modulation", node: "_cutoffVoct" }
859
876
  },
860
877
  createModule(id, position) {
861
- return { id, type: "303-filter", position, ...paramDefaults(params) };
878
+ return { id, type: "303-filter", position, timeUnit: "t60", ...paramDefaults(params) };
862
879
  },
863
880
  createNodes(ctx, module) {
864
881
  const input = ctx.createGain();
@@ -3283,7 +3300,8 @@ function tankEnergyGain500(rt60, size = 1) {
3283
3300
  let g2 = 0;
3284
3301
  for (const ms2 of COMB_TIMES_MS) g2 += Math.pow(10, -6 * (ms2 / 1e3) * size / Math.max(rt60, 0.05));
3285
3302
  g2 /= COMB_TIMES_MS.length;
3286
- return Math.max(0.05, 0.8006 / (1 - g2) - 0.531);
3303
+ const loss = 1 - g2;
3304
+ return Math.max(0.05, 0.6422 / loss - 0.2406 - 11e-4 * loss);
3287
3305
  }
3288
3306
  function createFdnTank(ctx, opts) {
3289
3307
  const input = ctx.createGain();
@@ -3658,14 +3676,47 @@ var saturatorDescriptor = /* @__PURE__ */ defineDescriptor({
3658
3676
  // src/lib-runtime/generated/modules/saturator.wrapper.ts
3659
3677
  var Saturator = /* @__PURE__ */ defineModule(saturatorDescriptor);
3660
3678
 
3661
- // src/lib-runtime/generated/modules/shimmer.tsx
3679
+ // src/lib/dsp/shimmerRegen.ts
3662
3680
  var REGEN_HP_HZ = 300;
3663
3681
  var REGEN_HP_Q_DB = 20 * Math.log10(Math.SQRT1_2);
3664
3682
  var HP_AT_500 = 1 / Math.sqrt(1 + Math.pow(REGEN_HP_HZ / 500, 4));
3665
3683
  var SHIFTER_ENERGY = 0.75;
3666
- function shimmerRegenNorm(decay) {
3667
- return 1 / (Math.sqrt(tankEnergyGain500(decay)) * HP_AT_500 * Math.sqrt(SHIFTER_ENERGY));
3684
+ var REGEN_DELAY_S = 0.02;
3685
+ var SHIFTER_SEEDS = [5370206, 739982445];
3686
+ var UNISON_FLOOR = [
3687
+ [0.5, 0.68],
3688
+ [1, 0.75],
3689
+ [2, 0.76],
3690
+ [3, 0.8],
3691
+ [5, 0.84],
3692
+ [7, 0.75],
3693
+ [10, 0.6]
3694
+ ];
3695
+ var UNISON_PITCH_SPAN = 0.75;
3696
+ function unisonFloor(decay) {
3697
+ const x = Math.log2(Math.max(0.05, decay));
3698
+ const first = UNISON_FLOOR[0], last = UNISON_FLOOR[UNISON_FLOOR.length - 1];
3699
+ if (x <= Math.log2(first[0])) return first[1];
3700
+ if (x >= Math.log2(last[0])) return last[1];
3701
+ for (let i = 1; i < UNISON_FLOOR.length; i++) {
3702
+ const [d1, k1] = UNISON_FLOOR[i];
3703
+ if (x <= Math.log2(d1)) {
3704
+ const [d0, k0] = UNISON_FLOOR[i - 1];
3705
+ const t = (x - Math.log2(d0)) / (Math.log2(d1) - Math.log2(d0));
3706
+ return k0 + (k1 - k0) * t;
3707
+ }
3708
+ }
3709
+ return last[1];
3668
3710
  }
3711
+ function unisonCoherence(decay, pitch) {
3712
+ const a = unisonFloor(decay);
3713
+ return Math.min(1, a + (1 - a) * (pitch / UNISON_PITCH_SPAN) ** 2);
3714
+ }
3715
+ function shimmerRegenNorm(decay, pitch) {
3716
+ return unisonCoherence(decay, pitch) / (Math.sqrt(tankEnergyGain500(decay)) * HP_AT_500 * Math.sqrt(SHIFTER_ENERGY));
3717
+ }
3718
+
3719
+ // src/lib-runtime/generated/modules/shimmer.tsx
3669
3720
  var params36 = {
3670
3721
  decay: { unit: "s", default: 3, min: 0.5, max: 10, scale: "log" },
3671
3722
  pitch: { unit: "semitone", default: 12, min: -12, max: 24 },
@@ -3699,14 +3750,14 @@ var shimmerDescriptor = /* @__PURE__ */ defineDescriptor({
3699
3750
  const shifter = createPitchShifterNode(ctx, module.pitch, seed);
3700
3751
  return { hp, shifter };
3701
3752
  };
3702
- const tapL = mkRegenTap(5370206);
3703
- const tapR = mkRegenTap(739982445);
3753
+ const tapL = mkRegenTap(SHIFTER_SEEDS[0]);
3754
+ const tapR = mkRegenTap(SHIFTER_SEEDS[1]);
3704
3755
  const regenNorm = ctx.createGain();
3705
- regenNorm.gain.value = shimmerRegenNorm(module.decay);
3756
+ regenNorm.gain.value = shimmerRegenNorm(module.decay, module.pitch);
3706
3757
  const regenGain = ctx.createGain();
3707
3758
  regenGain.gain.value = module.shimmer;
3708
3759
  const regenDelay = ctx.createDelay(0.1);
3709
- regenDelay.delayTime.value = 0.02;
3760
+ regenDelay.delayTime.value = REGEN_DELAY_S;
3710
3761
  tank.output.connect(splitter);
3711
3762
  splitter.connect(tapL.hp, 0);
3712
3763
  splitter.connect(tapR.hp, 1);
@@ -3753,9 +3804,10 @@ var shimmerDescriptor = /* @__PURE__ */ defineDescriptor({
3753
3804
  for (const key of ["pitchShifterL", "pitchShifterR"]) {
3754
3805
  nodes[key].parameters.get("semitones").setTargetAtTime(value, now2, 0.02);
3755
3806
  }
3807
+ nodes.regenNorm.gain.setTargetAtTime(shimmerRegenNorm(_m.decay, value), now2, 0.02);
3756
3808
  } else if (param === "decay") {
3757
3809
  setTankDecay({ node: nodes.tankNode }, value, now2);
3758
- nodes.regenNorm.gain.setTargetAtTime(shimmerRegenNorm(value), now2, 0.02);
3810
+ nodes.regenNorm.gain.setTargetAtTime(shimmerRegenNorm(value, _m.pitch), now2, 0.02);
3759
3811
  }
3760
3812
  }
3761
3813
  });