UNPKG

audio-inspect

Version:

Lightweight yet powerful audio analysis library

2 lines (1 loc) 7.54 kB
var A=class e extends Error{constructor(r,a,t,o){super(a,{cause:t});this.code=r;this.details=o;this.cause=t,Error.captureStackTrace&&Error.captureStackTrace(this,e)}name="AudioInspectError";timestamp=new Date;cause;toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,timestamp:this.timestamp,stack:this.stack,cause:this.cause}}};var C=new Map;function U(e){if(e<=0||!isFinite(e))throw new A("INVALID_INPUT","\u30B5\u30F3\u30D7\u30EB\u30EC\u30FC\u30C8\u306F\u6B63\u306E\u6709\u9650\u5024\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");if(e<8e3||e>384e3)throw new A("UNSUPPORTED_FORMAT",`\u30B5\u30F3\u30D7\u30EB\u30EC\u30FC\u30C8 ${e}Hz \u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093`)}function R(e){U(e);let n=C.get(e);if(n)return n;let r=20.598997,a=107.65265,t=737.86223,o=12194.217,i=1.9997,s=[],u=2*e*Math.tan(Math.PI*r/e),f=2*e*Math.tan(Math.PI*a/e),p=2*e*Math.tan(Math.PI*t/e),m=2*e*Math.tan(Math.PI*o/e),d=Math.pow(10,i/20);{let l=u,c=l*l,h=Math.SQRT2,b=4*e*e+2*h*l*e+c,F=2*(c-4*e*e)/b,M=(4*e*e-2*h*l*e+c)/b;s.push({b0:4*e*e*d/b,b1:-8*e*e*d/b,b2:4*e*e*d/b,a0:1,a1:F,a2:M})}{let l=f,c=2*e+l,h=(l-2*e)/c;s.push({b0:2*e/c,b1:-2*e/c,b2:0,a0:1,a1:h,a2:0})}{let l=p,c=2*e+l,h=(l-2*e)/c;s.push({b0:2*e/c,b1:-2*e/c,b2:0,a0:1,a1:h,a2:0})}{let l=m,c=l*l,h=Math.SQRT2,b=4*e*e+2*h*l*e+c,F=2*(c-4*e*e)/b,M=(4*e*e-2*h*l*e+c)/b;s.push({b0:c/b,b1:2*c/b,b2:c/b,a0:1,a1:F,a2:M})}let x=1/N(s,1e3,e).magnitude;return s.forEach(l=>{l.b0*=x,l.b1*=x,l.b2*=x}),C.set(e,s),s}function N(e,n,r){let a=2*Math.PI*n/r,t=1,o=0;for(let u of e){let f=Math.cos(a),p=Math.sin(a),m=Math.cos(2*a),d=Math.sin(2*a),y=u.b0+u.b1*f+u.b2*m,x=-u.b1*p-u.b2*d,l=u.a0+u.a1*f+u.a2*m,c=-u.a1*p-u.a2*d,h=l*l+c*c;if(h===0)throw new A("INVALID_INPUT","\u5468\u6CE2\u6570\u5FDC\u7B54\u8A08\u7B97\u3067\u30BC\u30ED\u9664\u7B97\u304C\u767A\u751F\u3057\u307E\u3057\u305F");let b=(y*l+x*c)/h,F=(x*l-y*c)/h,M=t*b-o*F,w=t*F+o*b;t=M,o=w}let i=Math.sqrt(t*t+o*o),s=Math.atan2(o,t);return{magnitude:i,phase:s}}function D(e,n=0){if(n===-1){if(e.numberOfChannels===0)throw new A("INVALID_INPUT","No channels available");for(let t=0;t<e.numberOfChannels;t++)if(!e.channelData[t])throw new A("INVALID_INPUT",`Channel ${t} data does not exist for averaging`);let a=new Float32Array(e.length);for(let t=0;t<e.length;t++){let o=0;for(let i=0;i<e.numberOfChannels;i++){let s=e.channelData[i];s&&t<s.length&&(o+=s[t]??0)}a[t]=o/e.numberOfChannels}return a}if(n<-1||n>=e.numberOfChannels)throw new A("INVALID_INPUT",`Invalid channel number: ${n}`);let r=e.channelData[n];if(!r)throw new A("INVALID_INPUT",`Channel ${n} data does not exist`);return r}function k(e){return e==null?!1:!isNaN(e)&&isFinite(e)}function g(e){return e==null||isNaN(e)||!isFinite(e)?0:e}function I(e,n=1){return e<=0||n<=0?-1/0:20*Math.log10(e/n)}function V(e,n,r={x1:0,x2:0,y1:0,y2:0}){let a=new Float32Array(e.length),{x1:t,x2:o,y1:i,y2:s}=r;for(let u=0;u<e.length;u++){let f=g(e[u]??0),p=n.b0*f+n.b1*t+n.b2*o-n.a1*i-n.a2*s;a[u]=p,o=t,t=f,s=i,i=p}return r.x1=t,r.x2=o,r.y1=i,r.y2=s,a}function S(e,n){let r=R(n),a=e;for(let t of r)a=V(a,t);return a}function E(e,n){let r=(e.length-1)*n+1,a=new Float32Array(r);for(let t=0;t<e.length-1;t++){let o=g(e[t]??0),s=(g(e[t+1]??0)-o)/n;for(let u=0;u<n;u++)a[t*n+u]=o+s*u}return e.length>0&&(a[r-1]=g(e[e.length-1]??0)),a}function T(e,n){if(e.length<4)return E(e,n);let r=(e.length-1)*n+1,a=new Float32Array(r);for(let t=0;t<e.length-1;t++){let o=g(e[Math.max(0,t-1)]??0),i=g(e[t]??0),s=g(e[Math.min(e.length-1,t+1)]??0),u=g(e[Math.min(e.length-1,t+2)]??0);for(let f=0;f<n;f++){let p=f/n,m=p*p,d=m*p,y=.5*(2*i+(-o+s)*p+(2*o-5*i+4*s-u)*m+(-o+3*i-3*s+u)*d);a[t*n+f]=g(y)}}return e.length>0&&(a[r-1]=g(e[e.length-1]??0)),a}function $(e,n){let r=(e.length-1)*n+1,a=new Float32Array(r),t=o=>{if(Math.abs(o)<1e-10)return 1;let i=Math.PI*o;return Math.abs(o)<3?3*Math.sin(i/3)*Math.sin(i)/(i*i):0};for(let o=0;o<r;o++){let i=o/n,s=0;for(let u=-3;u<=3;u++){let f=Math.floor(i)+u;if(f>=0&&f<e.length){let p=g(e[f]??0),m=t(i-f);s+=p*m}}a[o]=g(s)}return a}function j(e,n={}){let{factor:r=4,interpolation:a="cubic"}=n;if(r<=1)return e;if(e.length===0)return new Float32Array(0);switch(a){case"linear":return E(e,r);case"cubic":return T(e,r);case"sinc":return $(e,r);default:return T(e,r)}}function _(e,n={}){if(e.length===0)return 0;let r=j(e,n),a=0;for(let t=0;t<r.length;t++){let o=Math.abs(g(r[t]??0));a=Math.max(a,o)}return a}var O=-1/0;function q(e,n={}){let r=typeof n=="number"?{channel:n,asDB:!1,reference:1,truePeak:!1,oversamplingFactor:4,interpolation:"cubic"}:{channel:n.channel??0,asDB:n.asDB??!1,reference:n.reference??1,truePeak:n.truePeak??!1,oversamplingFactor:n.oversamplingFactor??4,interpolation:n.interpolation??"cubic"},a=D(e,r.channel);if(a.length===0)return r.asDB?O:0;let t=0,o=0;for(let s=0;s<a.length;s++){let u=a[s]??0;k(u)&&(t+=u*u,o++)}if(o===0)return r.asDB?O:0;let i=Math.sqrt(t/o);return r.asDB?I(i,r.reference):i}function B(e,n={}){let r={channel:n.channel??0,asDB:n.asDB??!1,reference:n.reference??1,truePeak:n.truePeak??!1,oversamplingFactor:n.oversamplingFactor??4,interpolation:n.interpolation??"cubic"},a=D(e,r.channel);if(a.length===0)return r.asDB?O:0;let t;if(r.truePeak)t=_(a,{factor:r.oversamplingFactor,interpolation:r.interpolation});else{t=0;for(let o=0;o<a.length;o++){let i=a[o]??0;k(i)&&(t=Math.max(t,Math.abs(i)))}}return r.asDB?I(t,r.reference):t}function L(e,n,r="simple"){if(e.length===0)return{peak:0,rms:0,cfDb:-1/0,cfLinear:0};let a=e;r==="weighted"&&(a=S(e,n));let t=0,o=0,i=0;for(let p=0;p<a.length;p++){let m=g(a[p]??0),d=Math.abs(m);t=Math.max(t,d),o+=m*m,i++}if(i===0)return{peak:0,rms:0,cfDb:-1/0,cfLinear:0};let s=Math.sqrt(o/i);if(s<1e-10)return{peak:t,rms:s,cfDb:1/0,cfLinear:1/0};let u=t/s,f=20*Math.log10(u);return{peak:t,rms:s,cfDb:f,cfLinear:u}}function de(e,n={}){let{channel:r=0,windowSize:a,hopSize:t,method:o="simple"}=n,i,s;if(o==="weighted"){let m=D(e,r),d=S(m,e.sampleRate),y=0,x=0,l=0;for(let c=0;c<d.length;c++){let h=g(d[c]??0),b=Math.abs(h);y=Math.max(y,b),x+=h*h,l++}i=y,s=l>0?Math.sqrt(x/l):0}else{let m={channel:r,asDB:!1};i=B(e,m),s=q(e,m)}let u=s>1e-10?i/s:1/0,f=s>1e-10?20*Math.log10(u):1/0,p;if(typeof a=="number"&&typeof t=="number"){if(a<=0||t<=0)throw new A("INVALID_INPUT","windowSize\u3068hopSize\u306F\u6B63\u306E\u5024\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");t>a&&console.warn("[audio-inspect] hopSize\u304CwindowSize\u3088\u308A\u5927\u304D\u3044\u305F\u3081\u3001\u5206\u6790\u7A93\u9593\u306B\u30AE\u30E3\u30C3\u30D7\u304C\u751F\u3058\u307E\u3059");let m=Math.floor(a*e.sampleRate),d=Math.floor(t*e.sampleRate);if(m===0||d===0)throw new A("INVALID_INPUT","\u30B5\u30F3\u30D7\u30EB\u30EC\u30FC\u30C8\u306B\u5BFE\u3057\u3066\u7A93\u30B5\u30A4\u30BA\u304C\u5C0F\u3055\u3059\u304E\u307E\u3059");let y=D(e,r),x=y.length;if(x<m){let l=L(y,e.sampleRate,o);p={times:new Float32Array([e.duration/2]),values:new Float32Array([l.cfDb]),valuesLinear:new Float32Array([l.cfLinear]),peaks:new Float32Array([l.peak]),rmsValues:new Float32Array([l.rms])}}else{let l=Math.floor((x-m)/d)+1,c=new Float32Array(l),h=new Float32Array(l),b=new Float32Array(l),F=new Float32Array(l),M=new Float32Array(l);for(let w=0;w<l;w++){let P=w*d,W=Math.min(P+m,x),z=y.subarray(P,W),v=L(z,e.sampleRate,o);c[w]=(P+m/2)/e.sampleRate,h[w]=v.cfDb,b[w]=v.cfLinear,F[w]=v.peak,M[w]=v.rms}p={times:c,values:h,valuesLinear:b,peaks:F,rmsValues:M}}}return{crestFactor:f,crestFactorLinear:u,peak:i,rms:s,timeVarying:p}}export{de as getCrestFactor};