UNPKG

wavesurfer.js

Version:

Interactive navigable audio visualization using Web Audio and Canvas

7 lines 9.45 kB
/*! * wavesurfer.js 2.0.5 (Sun Mar 04 2018 20:10:16 GMT+0100 (CET)) * https://github.com/katspaugh/wavesurfer.js * @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())}("undefined"!=typeof self?self:this,function(){return function(e){function t(r){if(a[r])return a[r].exports;var i=a[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var a={};return t.m=e,t.c=a,t.d=function(e,a,r){t.o(e,a)||Object.defineProperty(e,a,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var a=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(a,"a",a),a},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="localhost:8080/dist/plugin/",t(t.s=3)}({3:function(e,t,a){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var a=0;a<t.length;a++){var r=t[a];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,a,r){return a&&e(t.prototype,a),r&&e(t,r),t}}(),n=function(e,t,a,r){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,a){case"bartlett":for(var i=0;i<e;i++)this.windowValues[i]=2/(e-1)*((e-1)/2-Math.abs(i-(e-1)/2));break;case"bartlettHann":for(var 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":r=r||.16;for(var i=0;i<e;i++)this.windowValues[i]=(1-r)/2-.5*Math.cos(2*Math.PI*i/(e-1))+r/2*Math.cos(4*Math.PI*i/(e-1));break;case"cosine":for(var i=0;i<e;i++)this.windowValues[i]=Math.cos(Math.PI*i/(e-1)-Math.PI/2);break;case"gauss":r=r||.25;for(var i=0;i<e;i++)this.windowValues[i]=Math.pow(Math.E,-.5*Math.pow((i-(e-1)/2)/(r*(e-1)/2),2));break;case"hamming":for(var 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(var i=0;i<e;i++)this.windowValues[i]=.5*(1-Math.cos(2*Math.PI*i/(e-1)));break;case"lanczoz":for(var 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(var i=0;i<e;i++)this.windowValues[i]=1;break;case"triangular":for(var 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 '"+a+"'")}for(var i,n=1,s=e>>1;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,a,r,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,y,m,g,M,x=1,k=0;k<i;k++)l[k]=e[o[k]]*this.windowValues[o[k]],h[k]=0;for(;x<i;){d=n[x],v=s[x],w=1,b=0;for(var S=0;S<x;S++){for(var k=S;k<i;)y=k+x,m=w*l[y]-b*h[y],g=w*h[y]+b*l[y],l[y]=l[k]-m,h[y]=h[k]-g,l[k]+=m,h[k]+=g,k+=x<<1;M=w,w=M*d-b*v,b=M*v+b*d}x<<=1}for(var k=0,T=i/2;k<T;k++)t=l[k],a=h[k],r=f*u(t*t+a*a),r>this.peak&&(this.peakBand=k,this.peak=r),c[k]=r;return c}},s=function(){function e(t,a){var i=this;r(this,e),this.params=t,this.wavesurfer=a,this.util=a.util,this.frequenciesDataUrl=t.frequenciesDataUrl,this._onScroll=function(e){i.updateScroll(e)},this._onReady=function(){var e=i.drawer=a.drawer;if(i.container="string"==typeof t.container?document.querySelector(t.container):t.container,!i.container)throw Error("No container for WaveSurfer spectrogram");i.width=e.width,i.pixelRatio=i.params.pixelRatio||a.params.pixelRatio,i.fftSamples=i.params.fftSamples||a.params.fftSamples||512,i.height=i.fftSamples/2,i.noverlap=t.noverlap,i.windowFunc=t.windowFunc,i.alpha=t.alpha,i.createWrapper(),i.createCanvas(),i.render(),e.wrapper.addEventListener("scroll",i._onScroll),a.on("redraw",function(){return i.render()})}}return i(e,null,[{key:"create",value:function(t){return{name:"spectrogram",deferInit:!(!t||!t.deferInit)&&t.deferInit,params:t,staticProps:{FFT:n},instance:e}}}]),i(e,[{key:"init",value:function(){this.wavesurfer.isReady&&this._onReady(),this.wavesurfer.on("ready",this._onReady)}},{key:"destroy",value:function(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.drawer.wrapper.removeEventListener("scroll",this._onScroll),this.wavesurfer=null,this.util=null,this.params=null,this.wrapper&&(this.wrapper.parentNode.removeChild(this.wrapper),this.wrapper=null)}},{key:"createWrapper",value:function(){var e=this,t=this.container.querySelector("spectrogram");t&&this.container.removeChild(t);var a=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:this.height/this.pixelRatio+"px",width: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:this.height/this.pixelRatio+"px"}),(a.fillParent||a.scrollParent)&&this.drawer.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.container.appendChild(this.wrapper),this.wrapper.addEventListener("click",function(t){t.preventDefault();var a="offsetX"in t?t.offsetX:t.layerX;e.fireEvent("click",a/e.scrollWidth||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 a=(t.spectrCc,t.wavesurfer.backend.getDuration(),t.height),r=t.resample(e),i=t.buffer?2/t.buffer.numberOfChannels:1,n=void 0,s=void 0;for(n=0;n<r.length;n++)for(s=0;s<r[n].length;s++){var o=255-r[n][s];t.spectrCc.fillStyle="rgb("+o+", "+o+", "+o+")",t.spectrCc.fillRect(n,a-s*i,1,i)}}},{key:"getFrequencies",value:function(e){var t=this.fftSamples,a=this.buffer=this.wavesurfer.backend.buffer,r=a.getChannelData(0),i=a.length,s=a.sampleRate,o=[];if(!a)return void this.fireEvent("error","Web Audio buffer is not available");var l=this.noverlap;if(!l){var h=a.length/this.canvas.width;l=Math.max(0,Math.round(t-h))}for(var f=new n(t,s,this.windowFunc,this.alpha),u=(Math.floor(i/(t-l)),0);u+t<r.length;){var c=r.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)}},{key:"loadFrequenciesData",value:function(e){var t=this,a=this.util.ajax({url:e});return a.on("success",function(e){return t.drawSpectrogram(JSON.parse(e),t)}),a.on("error",function(e){return t.fireEvent("error","XHR error: "+e.target.statusText)}),a}},{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,a,r,i,n,s,o){var l=this.height;e=e||"rgba(68,68,68,0)",t=t||"12px",a=a||"10px",r=r||"Helvetica",i=i||"#fff",n=n||"#fff",s=s||"center",o=o||"#specLabels";var h=l||512,f=h/256*5,u=(this.wavesurfer.backend.ac.sampleRate/2-0)/f,c=this.labelsEl.getContext("2d");this.labelsEl.height=this.height,this.labelsEl.width=55,c.fillStyle=e,c.fillRect(0,0,55,h),c.fill();var p=void 0;for(p=0;p<=f;p++){c.textAlign=s,c.textBaseline="middle";var d=0+u*p,v=(Math.round(d/(this.sampleRate/2)*this.fftSamples),this.freqType(d)),w=this.unitType(d);0==p?(c.fillStyle=n,c.font=a+" "+r,c.fillText(w,40,h+p-10),c.fillStyle=i,c.font=t+" "+r,c.fillText(v,16,h+p-10)):(c.fillStyle=n,c.font=a+" "+r,c.fillText(w,40,h-50*p+2),c.fillStyle=i,c.font=t+" "+r,c.fillText(v,16,h-50*p+2))}}},{key:"updateScroll",value:function(e){this.wrapper&&(this.wrapper.scrollLeft=e.target.scrollLeft)}},{key:"resample",value:function(e){var t=this.width,a=[],r=1/e.length,i=1/t,n=void 0;for(n=0;n<t;n++){var s=new Array(e[0].length),o=void 0;for(o=0;o<e.length;o++){var l=o*r,h=l+r,f=n*i,u=f+i,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/i*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=s,e.exports=t.default}})}); //# sourceMappingURL=wavesurfer.spectrogram.min.js.map