UNPKG

wavesurfer.js

Version:

Interactive navigable audio visualization using Web Audio and Canvas

7 lines 10.6 kB
/*! * wavesurfer.js spectrogram plugin 4.3.0 (2020-12-13) * https://wavesurfer-js.org * @license BSD-3-Clause */ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("spectrogram",[],t):"object"==typeof exports?exports.spectrogram=t():(e.WaveSurfer=e.WaveSurfer||{},e.WaveSurfer.spectrogram=t())}(this,(function(){return function(e){var t={};function r(a){if(t[a])return t[a].exports;var i=t[a]={i:a,l:!1,exports:{}};return e[a].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,a){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(r.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(a,i,function(t){return e[t]}.bind(null,i));return a},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="localhost:8080/dist/plugin/",r(r.s=7)}({7:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a,i=(a=r(8))&&a.__esModule?a:{default:a};function n(e,t){for(var r=0;r<t.length;r++){var a=t[r];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}function s(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}var o=function(){function e(t,r){var a=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.params=t,this.wavesurfer=r,this.util=r.util,this.frequenciesDataUrl=t.frequenciesDataUrl,this._onScroll=function(e){a.updateScroll(e)},this._onRender=function(){a.render()},this._onWrapperClick=function(e){a._wrapperClickHandler(e)},this._onReady=function(){var e=a.drawer=r.drawer;if(a.container="string"==typeof t.container?document.querySelector(t.container):t.container,!a.container)throw Error("No container for WaveSurfer spectrogram");if(t.colorMap){if(t.colorMap.length<256)throw new Error("Colormap must contain 256 elements");for(var i=0;i<t.colorMap.length;i++){if(4!==t.colorMap[i].length)throw new Error("ColorMap entries must contain 4 values")}a.colorMap=t.colorMap}else{a.colorMap=[];for(var n=0;n<256;n++){var s=(255-n)/256;a.colorMap.push([s,s,s,1])}}a.width=e.width,a.pixelRatio=a.params.pixelRatio||r.params.pixelRatio,a.fftSamples=a.params.fftSamples||r.params.fftSamples||512,a.height=a.fftSamples/2,a.noverlap=t.noverlap,a.windowFunc=t.windowFunc,a.alpha=t.alpha,a.createWrapper(),a.createCanvas(),a.render(),e.wrapper.addEventListener("scroll",a._onScroll),r.on("redraw",a._onRender)}}return s(e,null,[{key:"create",value:function(t){return{name:"spectrogram",deferInit:!(!t||!t.deferInit)&&t.deferInit,params:t,staticProps:{FFT:i.default},instance:e}}}]),s(e,[{key:"init",value:function(){this.wavesurfer.isReady?this._onReady():this.wavesurfer.once("ready",this._onReady)}},{key:"destroy",value:function(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("redraw",this._onRender),this.drawer&&this.drawer.wrapper.removeEventListener("scroll",this._onScroll),this.wavesurfer=null,this.util=null,this.params=null,this.wrapper&&(this.wrapper.removeEventListener("click",this._onWrapperClick),this.wrapper.parentNode.removeChild(this.wrapper),this.wrapper=null)}},{key:"createWrapper",value:function(){var e=this.container.querySelector("spectrogram");e&&this.container.removeChild(e);var t=this.wavesurfer.params;if(this.wrapper=document.createElement("spectrogram"),this.params.labels){var r=this.labelsEl=document.createElement("canvas");r.classList.add("spec-labels"),this.drawer.style(r,{left:0,position:"absolute",zIndex:9,height:"".concat(this.height/this.pixelRatio,"px"),width:"".concat(55/this.pixelRatio,"px")}),this.wrapper.appendChild(r),this.loadLabels("rgba(68,68,68,0.5)","12px","10px","","#fff","#f7f7f7","center","#specLabels")}this.drawer.style(this.wrapper,{display:"block",position:"relative",userSelect:"none",webkitUserSelect:"none",height:"".concat(this.height/this.pixelRatio,"px")}),(t.fillParent||t.scrollParent)&&this.drawer.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.container.appendChild(this.wrapper),this.wrapper.addEventListener("click",this._onWrapperClick)}},{key:"_wrapperClickHandler",value:function(e){e.preventDefault();var t="offsetX"in e?e.offsetX:e.layerX;this.fireEvent("click",t/this.width||0)}},{key:"createCanvas",value:function(){var e=this.canvas=this.wrapper.appendChild(document.createElement("canvas"));this.spectrCc=e.getContext("2d"),this.util.style(e,{position:"absolute",zIndex:4})}},{key:"render",value:function(){this.updateCanvasStyle(),this.frequenciesDataUrl?this.loadFrequenciesData(this.frequenciesDataUrl):this.getFrequencies(this.drawSpectrogram)}},{key:"updateCanvasStyle",value:function(){var e=Math.round(this.width/this.pixelRatio)+"px";this.canvas.width=this.width,this.canvas.height=this.height,this.canvas.style.width=e}},{key:"drawSpectrogram",value:function(e,t){var r,a,i,n=t.spectrCc,s=t.height,o=t.width,l=t.resample(e),h=t.buffer?2/t.buffer.numberOfChannels:1,f=n.createImageData(o,s);for(r=0;r<l.length;r++)for(a=0;a<l[r].length;a++){var u=t.colorMap[l[r][a]];for(i=0;i<h;i++){var c=s-a*h;2===h&&1===i&&c--;var p=c*(4*o)+4*r;f.data[p]=255*u[0],f.data[p+1]=255*u[1],f.data[p+2]=255*u[2],f.data[p+3]=255*u[3]}}n.putImageData(f,0,0)}},{key:"getFrequencies",value:function(e){var t=this.fftSamples,r=this.buffer=this.wavesurfer.backend.buffer,a=r.getChannelData(0),n=r.length,s=r.sampleRate,o=[];if(r){var l=this.noverlap;if(!l){var h=r.length/this.canvas.width;l=Math.max(0,Math.round(t-h))}for(var f=new i.default(t,s,this.windowFunc,this.alpha),u=(Math.floor(n/(t-l)),0);u+t<a.length;){var c=a.slice(u,u+t),p=f.calculateSpectrum(c),d=new Uint8Array(t/2),v=void 0;for(v=0;v<t/2;v++)d[v]=Math.max(-255,45*Math.log10(p[v]));o.push(d),u+=t-l}e(o,this)}else this.fireEvent("error","Web Audio buffer is not available")}},{key:"loadFrequenciesData",value:function(e){var t=this,r=this.util.fetchFile({url:e});return r.on("success",(function(e){return t.drawSpectrogram(JSON.parse(e),t)})),r.on("error",(function(e){return t.fireEvent("error",e)})),r}},{key:"freqType",value:function(e){return e>=1e3?(e/1e3).toFixed(1):Math.round(e)}},{key:"unitType",value:function(e){return e>=1e3?"KHz":"Hz"}},{key:"loadLabels",value:function(e,t,r,a,i,n,s,o){e=e||"rgba(68,68,68,0)",t=t||"12px",r=r||"10px",a=a||"Helvetica",i=i||"#fff",n=n||"#fff",s=s||"center",o=o||"#specLabels";var l,h=this.height||512,f=h/256*5,u=(this.wavesurfer.backend.ac.sampleRate/2-0)/f,c=this.labelsEl.getContext("2d");for(this.labelsEl.height=this.height,this.labelsEl.width=55,c.fillStyle=e,c.fillRect(0,0,55,h),c.fill(),l=0;l<=f;l++){c.textAlign=s,c.textBaseline="middle";var p=0+u*l,d=(Math.round(p/(this.sampleRate/2)*this.fftSamples),this.freqType(p)),v=this.unitType(p),w=void 0;0==l?(w=h+l-10,c.fillStyle=n,c.font=r+" "+a,c.fillText(v,40,w),c.fillStyle=i,c.font=t+" "+a,c.fillText(d,16,w)):(w=h-50*l+2,c.fillStyle=n,c.font=r+" "+a,c.fillText(v,40,w),c.fillStyle=i,c.font=t+" "+a,c.fillText(d,16,w))}}},{key:"updateScroll",value:function(e){this.wrapper&&(this.wrapper.scrollLeft=e.target.scrollLeft)}},{key:"resample",value:function(e){var t,r=this.width,a=[],i=1/e.length,n=1/r;for(t=0;t<r;t++){var s=new Array(e[0].length),o=void 0;for(o=0;o<e.length;o++){var l=o*i,h=l+i,f=t*n,u=f+n,c=h<=f||u<=l?0:Math.min(Math.max(h,f),Math.max(u,l))-Math.max(Math.min(h,f),Math.min(u,l)),p=void 0;if(c>0)for(p=0;p<e[0].length;p++)null==s[p]&&(s[p]=0),s[p]+=c/n*e[o][p]}var d=new Uint8Array(e[0].length),v=void 0;for(v=0;v<e[0].length;v++)d[v]=s[v];a.push(d)}return a}}]),e}();t.default=o,e.exports=t.default},8:function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,r,a){switch(this.bufferSize=e,this.sampleRate=t,this.bandwidth=2/e*(t/2),this.sinTable=new Float32Array(e),this.cosTable=new Float32Array(e),this.windowValues=new Float32Array(e),this.reverseTable=new Uint32Array(e),this.peakBand=0,this.peak=0,r){case"bartlett":for(i=0;i<e;i++)this.windowValues[i]=2/(e-1)*((e-1)/2-Math.abs(i-(e-1)/2));break;case"bartlettHann":for(i=0;i<e;i++)this.windowValues[i]=.62-.48*Math.abs(i/(e-1)-.5)-.38*Math.cos(2*Math.PI*i/(e-1));break;case"blackman":for(a=a||.16,i=0;i<e;i++)this.windowValues[i]=(1-a)/2-.5*Math.cos(2*Math.PI*i/(e-1))+a/2*Math.cos(4*Math.PI*i/(e-1));break;case"cosine":for(i=0;i<e;i++)this.windowValues[i]=Math.cos(Math.PI*i/(e-1)-Math.PI/2);break;case"gauss":for(a=a||.25,i=0;i<e;i++)this.windowValues[i]=Math.pow(Math.E,-.5*Math.pow((i-(e-1)/2)/(a*(e-1)/2),2));break;case"hamming":for(i=0;i<e;i++)this.windowValues[i]=.54-.46*Math.cos(2*Math.PI*i/(e-1));break;case"hann":case void 0:for(i=0;i<e;i++)this.windowValues[i]=.5*(1-Math.cos(2*Math.PI*i/(e-1)));break;case"lanczoz":for(i=0;i<e;i++)this.windowValues[i]=Math.sin(Math.PI*(2*i/(e-1)-1))/(Math.PI*(2*i/(e-1)-1));break;case"rectangular":for(i=0;i<e;i++)this.windowValues[i]=1;break;case"triangular":for(i=0;i<e;i++)this.windowValues[i]=2/e*(e/2-Math.abs(i-(e-1)/2));break;default:throw Error("No such window function '"+r+"'")}var i,n=1,s=e>>1;for(;n<e;){for(i=0;i<n;i++)this.reverseTable[i+n]=this.reverseTable[i]+s;n<<=1,s>>=1}for(i=0;i<e;i++)this.sinTable[i]=Math.sin(-Math.PI/i),this.cosTable[i]=Math.cos(-Math.PI/i);this.calculateSpectrum=function(e){var t,r,a,i=this.bufferSize,n=this.cosTable,s=this.sinTable,o=this.reverseTable,l=new Float32Array(i),h=new Float32Array(i),f=2/this.bufferSize,u=Math.sqrt,c=new Float32Array(i/2),p=Math.floor(Math.log(i)/Math.LN2);if(Math.pow(2,p)!==i)throw"Invalid buffer size, must be a power of 2.";if(i!==e.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+i+" Buffer Size: "+e.length;for(var d,v,w,b,m,y,g,M,k=1,S=0;S<i;S++)l[S]=e[o[S]]*this.windowValues[o[S]],h[S]=0;for(;k<i;){d=n[k],v=s[k],w=1,b=0;for(var x=0;x<k;x++){for(S=x;S<i;)y=w*l[m=S+k]-b*h[m],g=w*h[m]+b*l[m],l[m]=l[S]-y,h[m]=h[S]-g,l[S]+=y,h[S]+=g,S+=k<<1;w=(M=w)*d-b*v,b=M*v+b*d}k<<=1}S=0;for(var _=i/2;S<_;S++)(a=f*u((t=l[S])*t+(r=h[S])*r))>this.peak&&(this.peakBand=S,this.peak=a),c[S]=a;return c}},e.exports=t.default}})})); //# sourceMappingURL=wavesurfer.spectrogram.min.js.map