UNPKG

audio-inspect

Version:

Lightweight yet powerful audio analysis library

2 lines (1 loc) 5.31 kB
"use strict";var E=Object.create;var h=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var k=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var D=(a,e)=>{for(var t in e)h(a,t,{get:e[t],enumerable:!0})},O=(a,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of M(e))!N.call(a,i)&&i!==t&&h(a,i,{get:()=>e[i],enumerable:!(r=S(e,i))||r.enumerable});return a};var C=(a,e,t)=>(t=a!=null?E(k(a)):{},O(e||!a||!a.__esModule?h(t,"default",{value:a,enumerable:!0}):t,a)),U=a=>O(h({},"__esModule",{value:!0}),a);var _={};D(_,{FFTProviderFactory:()=>A});module.exports=U(_);var l=class a extends Error{constructor(t,r,i,u){super(r,{cause:i});this.code=t;this.details=u;this.cause=i,Error.captureStackTrace&&Error.captureStackTrace(this,a)}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 F=class{constructor(e,t,r=!1){this.size=e;this.sampleRate=t;this.enableProfiling=r;this.initializationPromise=this.initializeWebFFT()}fftInstance=null;initializationPromise=null;get name(){return"WebFFT"}async waitForInitialization(){this.initializationPromise&&await this.initializationPromise}async initializeWebFFT(){try{let t=(await import("webfft")).default;this.fftInstance=new t(this.size),this.enableProfiling&&this.fftInstance?.profile&&await this.fftInstance.profile()}catch(e){throw new l("UNSUPPORTED_FORMAT",`WebFFT\u306E\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${e instanceof Error?e.message:String(e)}`)}}async fft(e){if(this.initializationPromise&&await this.initializationPromise,!this.fftInstance)throw new l("UNSUPPORTED_FORMAT","WebFFT initialization failed");if(e.length!==this.size)throw new l("INVALID_INPUT",`\u5165\u529B\u30B5\u30A4\u30BA\u304C\u4E0D\u6B63\u3067\u3059\u3002\u671F\u5F85\u5024: ${this.size}, \u5B9F\u969B: ${e.length}`);let t=new Float32Array(this.size*2);for(let s=0;s<this.size;s++)t[s*2]=e[s]||0,t[s*2+1]=0;let r=this.fftInstance.fft(t),i=new Float32Array(this.size/2+1),u=new Float32Array(this.size/2+1),m=new Float32Array(this.size/2+1);for(let s=0;s<i.length;s++){let n=r[s*2]||0,o=r[s*2+1]||0;i[s]=Math.sqrt(n*n+o*o),u[s]=Math.atan2(o,n),m[s]=s*this.sampleRate/this.size}return{complex:r,magnitude:i,phase:u,frequencies:m}}async profile(){if(this.initializationPromise&&await this.initializationPromise,!this.fftInstance||!this.fftInstance.profile)throw new l("UNSUPPORTED_FORMAT","WebFFT\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");await this.fftInstance.profile()}dispose(){if(this.fftInstance)try{this.fftInstance.dispose&&this.fftInstance.dispose()}catch(e){console.warn("FFT instance disposal failed:",e)}finally{this.fftInstance=null,this.initializationPromise=null}}},y=class{constructor(e,t){this.size=e;this.sampleRate=t;if(!this.isPowerOfTwo(e))throw new l("INVALID_INPUT","FFT\u30B5\u30A4\u30BA\u306F2\u306E\u51AA\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059");this.precomputeTables()}bitReversalTable;twiddleFactorsReal;twiddleFactorsImag;get name(){return"Native FFT (Cooley-Tukey)"}isPowerOfTwo(e){return e>0&&(e&e-1)===0}precomputeTables(){this.bitReversalTable=new Uint32Array(this.size);let e=Math.log2(this.size);for(let r=0;r<this.size;r++){let i=0;for(let u=0;u<e;u++)i=i<<1|r>>u&1;this.bitReversalTable[r]=i}let t=this.size/2;this.twiddleFactorsReal=new Float32Array(t),this.twiddleFactorsImag=new Float32Array(t);for(let r=0;r<t;r++){let i=-2*Math.PI*r/this.size;this.twiddleFactorsReal[r]=Math.cos(i),this.twiddleFactorsImag[r]=Math.sin(i)}}fft(e){if(e.length!==this.size)throw new l("INVALID_INPUT",`\u5165\u529B\u30B5\u30A4\u30BA\u304C\u4E0D\u6B63\u3067\u3059\u3002\u671F\u5F85\u5024: ${this.size}, \u5B9F\u969B: ${e.length}`);let t=new Float32Array(this.size),r=new Float32Array(this.size);for(let n=0;n<this.size;n++){let o=this.bitReversalTable[n];o!==void 0&&(t[o]=e[n]||0,r[o]=0)}for(let n=1;n<this.size;n*=2){let o=n*2,c=this.size/o;for(let f=0;f<this.size;f+=o)for(let p=0;p<n;p++){let w=p*c,R=this.twiddleFactorsReal[w]||0,g=this.twiddleFactorsImag[w]||0,d=f+p,b=f+p+n,v=t[d]||0,T=r[d]||0,P=t[b]||0,I=r[b]||0,z=P*R-I*g,x=P*g+I*R;t[d]=v+z,r[d]=T+x,t[b]=v-z,r[b]=T-x}}let i=new Float32Array(this.size*2),u=new Float32Array(this.size/2+1),m=new Float32Array(this.size/2+1),s=new Float32Array(this.size/2+1);for(let n=0;n<this.size;n++)if(i[n*2]=t[n]||0,i[n*2+1]=r[n]||0,n<=this.size/2){let o=t[n]||0,c=r[n]||0;u[n]=Math.sqrt(o*o+c*c),m[n]=Math.atan2(c,o),s[n]=n*this.sampleRate/this.size}return{complex:i,magnitude:u,phase:m,frequencies:s}}dispose(){}},A=class{static async createProvider(e){switch(e.type){case"webfft":{let t=new F(e.fftSize,e.sampleRate,e.enableProfiling);return await t.waitForInitialization(),t}case"native":return new y(e.fftSize,e.sampleRate);case"custom":if(!e.customProvider)throw new l("INVALID_INPUT","\u30AB\u30B9\u30BF\u30E0\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093");return e.customProvider;default:{let t=e.type;throw new l("UNSUPPORTED_FORMAT",`\u672A\u5BFE\u5FDC\u306EFFT\u30D7\u30ED\u30D0\u30A4\u30C0\u30FC: ${String(t)}`)}}}static getAvailableProviders(){return["webfft","native"]}};