UNPKG

audio-inspect

Version:

Lightweight yet powerful audio analysis library

2 lines (1 loc) 10.2 kB
var A=class e extends Error{constructor(n,a,r,o){super(a,{cause:r});this.code=n;this.details=o;this.cause=r,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}}};function x(){if(typeof performance<"u"&&performance.now)return performance.now();if(typeof process<"u"&&process.hrtime){let[e,t]=process.hrtime();return e*1e3+t/1e6}return Date.now()}function M(e,t=0){if(t===-1){if(e.numberOfChannels===0)throw new A("INVALID_INPUT","No channels available");for(let r=0;r<e.numberOfChannels;r++)if(!e.channelData[r])throw new A("INVALID_INPUT",`Channel ${r} data does not exist for averaging`);let a=new Float32Array(e.length);for(let r=0;r<e.length;r++){let o=0;for(let s=0;s<e.numberOfChannels;s++){let i=e.channelData[s];i&&r<i.length&&(o+=i[r]??0)}a[r]=o/e.numberOfChannels}return a}if(t<-1||t>=e.numberOfChannels)throw new A("INVALID_INPUT",`Invalid channel number: ${t}`);let n=e.channelData[t];if(!n)throw new A("INVALID_INPUT",`Channel ${t} data does not exist`);return n}function R(e,t,n){return t<0||t>=e.length?n:e[t]??n}function O(e){return e==null?!1:!isNaN(e)&&isFinite(e)}function f(e){return e==null||isNaN(e)||!isFinite(e)?0:e}function I(e,t=1){return e<=0||t<=0?-1/0:20*Math.log10(e/t)}function N(e,t){let n=(e.length-1)*t+1,a=new Float32Array(n);for(let r=0;r<e.length-1;r++){let o=f(e[r]??0),i=(f(e[r+1]??0)-o)/t;for(let l=0;l<t;l++)a[r*t+l]=o+i*l}return e.length>0&&(a[n-1]=f(e[e.length-1]??0)),a}function C(e,t){if(e.length<4)return N(e,t);let n=(e.length-1)*t+1,a=new Float32Array(n);for(let r=0;r<e.length-1;r++){let o=f(e[Math.max(0,r-1)]??0),s=f(e[r]??0),i=f(e[Math.min(e.length-1,r+1)]??0),l=f(e[Math.min(e.length-1,r+2)]??0);for(let m=0;m<t;m++){let u=m/t,h=u*u,p=h*u,b=.5*(2*s+(-o+i)*u+(2*o-5*s+4*i-l)*h+(-o+3*s-3*i+l)*p);a[r*t+m]=f(b)}}return e.length>0&&(a[n-1]=f(e[e.length-1]??0)),a}function W(e,t){let n=(e.length-1)*t+1,a=new Float32Array(n),r=o=>{if(Math.abs(o)<1e-10)return 1;let s=Math.PI*o;return Math.abs(o)<3?3*Math.sin(s/3)*Math.sin(s)/(s*s):0};for(let o=0;o<n;o++){let s=o/t,i=0;for(let l=-3;l<=3;l++){let m=Math.floor(s)+l;if(m>=0&&m<e.length){let u=f(e[m]??0),h=r(s-m);i+=u*h}}a[o]=f(i)}return a}function L(e,t={}){let{factor:n=4,interpolation:a="cubic"}=t;if(n<=1)return e;if(e.length===0)return new Float32Array(0);switch(a){case"linear":return N(e,n);case"cubic":return C(e,n);case"sinc":return W(e,n);default:return C(e,n)}}function T(e,t={}){if(e.length===0)return 0;let n=L(e,t),a=0;for(let r=0;r<n.length;r++){let o=Math.abs(f(n[r]??0));a=Math.max(a,o)}return a}function E(e,t,n=!1){let a=[],r=e.length;if(r<3)return a;for(let o=1;o<r-1;o++){let s=Math.abs(f(e[o]??0)),i=Math.abs(f(e[o-1]??0)),l=Math.abs(f(e[o+1]??0));if(s>i&&s>l&&s>t){let m={position:o,amplitude:s};n&&(m.prominence=U(e,o,s)),a.push(m)}}return a}function U(e,t,n){let a=n;for(let o=t-1;o>=0;o--){let s=Math.abs(f(e[o]??0));if(s>n)break;a=Math.min(a,s)}let r=n;for(let o=t+1;o<e.length;o++){let s=Math.abs(f(e[o]??0));if(s>n)break;r=Math.min(r,s)}return n-Math.max(a,r)}function se(e,t={}){let{count:n=100,threshold:a=.1,channel:r=0,minDistance:o=Math.floor(e.sampleRate/100)}=t;if(n<=0)throw new A("INVALID_INPUT","\u30D4\u30FC\u30AF\u6570\u306F\u6B63\u306E\u6574\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");if(a<0||a>1)throw new A("INVALID_INPUT","\u95BE\u5024\u306F0\u304B\u30891\u306E\u7BC4\u56F2\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");let s=M(e,r);if(s.length===0)return{peaks:[],maxAmplitude:0,averageAmplitude:0};let i=E(s,a);if(i.length===0)return{peaks:[],maxAmplitude:0,averageAmplitude:0};i.sort((p,b)=>b.amplitude-p.amplitude);let l=[],m=[];for(let p of i){if(l.length>=n)break;let b=p.position-o,g=p.position+o;m.some(([F,w])=>!(g<F||b>w))||(l.push({position:p.position,time:p.position/e.sampleRate,amplitude:p.amplitude}),m.push([b,g]))}l.sort((p,b)=>p.position-b.position);let u=i.length>0?i[0]?.amplitude??0:0,h=i.length>0?i.reduce((p,b)=>p+b.amplitude,0)/i.length:0;return{peaks:l,maxAmplitude:u,averageAmplitude:h}}var S=-1/0;function ie(e,t={}){let n=typeof t=="number"?{channel:t,asDB:!1,reference:1,truePeak:!1,oversamplingFactor:4,interpolation:"cubic"}:{channel:t.channel??0,asDB:t.asDB??!1,reference:t.reference??1,truePeak:t.truePeak??!1,oversamplingFactor:t.oversamplingFactor??4,interpolation:t.interpolation??"cubic"},a=M(e,n.channel);if(a.length===0)return n.asDB?S:0;let r=0,o=0;for(let i=0;i<a.length;i++){let l=a[i]??0;O(l)&&(r+=l*l,o++)}if(o===0)return n.asDB?S:0;let s=Math.sqrt(r/o);return n.asDB?I(s,n.reference):s}function ue(e,t={}){let n={channel:t.channel??0,asDB:t.asDB??!1,reference:t.reference??1,truePeak:t.truePeak??!1,oversamplingFactor:t.oversamplingFactor??4,interpolation:t.interpolation??"cubic"},a=M(e,n.channel);if(a.length===0)return n.asDB?S:0;let r;if(n.truePeak)r=T(a,{factor:n.oversamplingFactor,interpolation:n.interpolation});else{r=0;for(let o=0;o<a.length;o++){let s=a[o]??0;O(s)&&(r=Math.max(r,Math.abs(s)))}}return n.asDB?I(r,n.reference):r}function le(e,t=0){let n=M(e,t);if(n.length<2)return 0;let a=0;for(let r=1;r<n.length;r++){let o=f(n[r-1]??0),s=f(n[r]??0);(o>=0&&s<0||o<0&&s>=0)&&a++}return a/(n.length-1)}function ce(e,t={}){let{framesPerSecond:n=60,channel:a=0,method:r="rms"}=t,o=M(e,a),s=Math.ceil(e.duration*n),i=e.length>0?e.length:s>0?1:0,l=Math.min(s,i),m=l>0?Math.max(1,Math.floor(e.length/l)):0,u=[],h=0,p=0;for(let g=0;g<l;g++){let y=g*m,F=Math.min(y+m,o.length);if(F<=y){let D=u.length>0?R(u,u.length-1,{time:0,amplitude:0}).amplitude:0;u.push({time:(y+m/2)/e.sampleRate,amplitude:D});continue}let w=o.subarray(y,F),c;switch(r){case"peak":c=q(w);break;case"average":c=B(w);break;case"rms":default:c=_(w);break}let d=(y+(F-y)/2)/e.sampleRate;u.push({time:d,amplitude:c}),h=Math.max(h,c),p+=c}let b=l>0?p/l:0;return{waveform:u,maxAmplitude:h,averageAmplitude:b,frameCount:l,samplesPerFrame:m}}function _(e){if(e.length===0)return 0;let t=0;for(let n=0;n<e.length;n++){let a=f(e[n]??0);t+=a*a}return Math.sqrt(t/e.length)}function q(e){let t=0;for(let n=0;n<e.length;n++){let a=Math.abs(f(e[n]??0));t=Math.max(t,a)}return t}function B(e){if(e.length===0)return 0;let t=0;for(let n=0;n<e.length;n++)t+=Math.abs(f(e[n]??0));return t/e.length}function me(e,t={}){let n=x(),{framesPerSecond:a=60,channel:r=0,method:o="rms",onProgress:s}=t;s?.(0,"Waveform\u89E3\u6790\u3092\u958B\u59CB");let i=M(e,r),l=Math.ceil(e.duration*a),m=e.length>0?e.length:l>0?1:0,u=Math.min(l,m),h=u>0?Math.max(1,Math.floor(e.length/u)):0;s?.(25,"\u30D5\u30EC\u30FC\u30E0\u8A2D\u5B9A\u5B8C\u4E86");let p=new Float32Array(u),b=new Float32Array(u),g=0,y=0;s?.(50,"\u632F\u5E45\u8A08\u7B97\u3092\u958B\u59CB");for(let c=0;c<u;c++){let d=c*h,D=Math.min(d+h,i.length);if(D<=d){let v=c>0?p[c-1]??0:0;p[c]=v,b[c]=(d+h/2)/e.sampleRate;continue}let k=i.subarray(d,D),P;switch(o){case"peak":P=q(k);break;case"average":P=B(k);break;case"rms":default:P=_(k);break}if(p[c]=P,b[c]=(d+(D-d)/2)/e.sampleRate,g=Math.max(g,P),y+=P,c%Math.max(1,Math.floor(u/20))===0){let v=50+c/u*45;s?.(Math.round(v),`\u30D5\u30EC\u30FC\u30E0 ${c+1}/${u} \u51E6\u7406\u4E2D`)}}let F=u>0?y/u:0,w=x()-n;return s?.(100,"\u51E6\u7406\u5B8C\u4E86"),{amplitudes:p,timestamps:b,frameCount:u,samplesPerFrame:h,framesPerSecond:a,maxAmplitude:g,averageAmplitude:F,sampleRate:e.sampleRate,duration:e.duration,processingTime:w}}function pe(e,t={}){let n=x(),{count:a=100,threshold:r=.1,channel:o=0,minDistance:s=Math.floor(e.sampleRate/100),onProgress:i}=t;if(i?.(0,"Peaks\u89E3\u6790\u3092\u958B\u59CB"),a<=0)throw new A("INVALID_INPUT","\u30D4\u30FC\u30AF\u6570\u306F\u6B63\u306E\u6574\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");if(r<0||r>1)throw new A("INVALID_INPUT","\u95BE\u5024\u306F0\u304B\u30891\u306E\u7BC4\u56F2\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");let l=M(e,o);if(l.length===0)return{positions:new Float32Array(0),amplitudes:new Float32Array(0),times:new Float32Array(0),maxAmplitude:0,averageAmplitude:0,count:0,sampleRate:e.sampleRate,duration:e.duration,processingTime:x()-n};i?.(25,"\u30D4\u30FC\u30AF\u5019\u88DC\u3092\u691C\u51FA\u4E2D");let m=E(l,r);if(m.length===0)return{positions:new Float32Array(0),amplitudes:new Float32Array(0),times:new Float32Array(0),maxAmplitude:0,averageAmplitude:0,count:0,sampleRate:e.sampleRate,duration:e.duration,processingTime:x()-n};i?.(50,"\u30D4\u30FC\u30AF\u3092\u30BD\u30FC\u30C8\u4E2D"),m.sort((c,d)=>d.amplitude-c.amplitude),i?.(75,"\u30D4\u30FC\u30AF\u3092\u9078\u629E\u4E2D");let u=[],h=[];for(let c of m){if(u.length>=a)break;let d=c.position-s,D=c.position+s;h.some(([P,v])=>!(D<P||d>v))||(u.push({position:c.position,time:c.position/e.sampleRate,amplitude:c.amplitude}),h.push([d,D]))}u.sort((c,d)=>c.position-d.position);let p=new Float32Array(u.length),b=new Float32Array(u.length),g=new Float32Array(u.length);for(let c=0;c<u.length;c++){let d=u[c];d&&(p[c]=d.position,b[c]=d.amplitude,g[c]=d.time)}let y=m.length>0?m[0]?.amplitude??0:0,F=m.length>0?m.reduce((c,d)=>c+d.amplitude,0)/m.length:0,w=x()-n;return i?.(100,"\u51E6\u7406\u5B8C\u4E86"),{positions:p,amplitudes:b,times:g,maxAmplitude:y,averageAmplitude:F,count:u.length,sampleRate:e.sampleRate,duration:e.duration,processingTime:w}}function fe(e,t={}){let n=x(),{channel:a=0,asDB:r=!1,reference:o=1,onProgress:s}=t;s?.(0,"RMS\u89E3\u6790\u3092\u958B\u59CB");let i=M(e,a);if(i.length===0)return{value:r?-1/0:0,channel:a,sampleRate:e.sampleRate,duration:e.duration,processingTime:x()-n};s?.(50,"RMS\u5024\u3092\u8A08\u7B97\u4E2D");let l=0;for(let h=0;h<i.length;h++){let p=i[h]??0;if(O(p)){let b=f(p);l+=b*b}}let m=Math.sqrt(l/i.length),u=x()-n;return s?.(100,"\u51E6\u7406\u5B8C\u4E86"),r?{value:I(m,o),channel:a,sampleRate:e.sampleRate,duration:e.duration,processingTime:u}:{value:m,valueDB:I(m,o),channel:a,sampleRate:e.sampleRate,duration:e.duration,processingTime:u}}export{ue as getPeak,ue as getPeakAmplitude,se as getPeaks,pe as getPeaksAnalysis,ie as getRMS,fe as getRMSAnalysis,ce as getWaveform,me as getWaveformAnalysis,le as getZeroCrossing};