UNPKG

modern-audio

Version:
2 lines (1 loc) 8.02 kB
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const H=({context:e})=>{const o=e.createAnalyser();return o.fftSize=2048,{name:"analyser",node:o}},V=({context:e})=>({name:"destination",node:e.destination}),F=({source:e})=>({name:"loop",props:{loop:{value:!1,getter(){return this.value},setter(o){this.value=o=Boolean(o),e instanceof MediaElementAudioSourceNode?e.mediaElement.loop=o:e instanceof AudioBufferSourceNode&&(e.loop=o)}}}}),W=e=>{const{context:o}=e;let t=!1;const n=o.createBiquadFilter();n.Q.value=8.3,n.frequency.value=355,n.gain.value=3,n.type="bandpass";const r=o.createDynamicsCompressor();return r.attack.value=0,r.knee.value=40,r.ratio.value=12,r.release.value=.25,r.threshold.value=-50,{name:"noise-reduction",node:()=>t?n:void 0,connect:s=>n.connect(r).connect(s),disconnect:()=>{n.disconnect(),r.disconnect()},props:{noiseReduction:{value:t,getter(){return this.value},setter(s){s===""&&(s=!0),t!==s&&(this.value=t=s,e.reconnect())}}}}},j=({context:e})=>{const o=e.createStereoPanner();return{name:"panner",node:o,props:{pan:{value:o.pan.value,getter(){return this.value},setter(t){this.value=o.pan.value=Number(t)}}}}},q=({source:e})=>({name:"playbackRate",props:{playbackRate:{value:1,getter(){return this.value},setter(o){this.value=o=Number(o),e instanceof MediaElementAudioSourceNode?e.mediaElement.playbackRate=o:e instanceof AudioBufferSourceNode&&(e.playbackRate.value=o)}}}}),z=({source:e})=>({name:"source",node:e});function $(e){return e instanceof MediaElementAudioSourceNode?e.mediaElement.playbackRate:e instanceof AudioBufferSourceNode?e.playbackRate.value:0}function G(e){var o,t;return e instanceof MediaElementAudioSourceNode?e.mediaElement.duration:e instanceof AudioBufferSourceNode&&(t=(o=e.buffer)==null?void 0:o.duration)!=null?t:0}const Q=({context:e,source:o})=>{const t=e.createGain();return{name:"volume",node:t,props:{db:{value:1,getter(){return this.value},setter(n){this.value=n=Number(n),t.gain.value=Math.pow(10,n/20)}},fadeIn:{value:0,getter(){return this.value},setter(n){this.value=n;const{at:r,duration:s}=typeof n=="object"?n:{at:e.currentTime,duration:Number(n)};t.gain.setValueAtTime(.01,r),t.gain.exponentialRampToValueAtTime(t.gain.value,r+s)}},fadeOut:{value:0,getter(){return this.value},setter(n){this.value=n;const{at:r,duration:s}=typeof n=="object"?n:{at:e.currentTime+G(o)/$(o)-Number(n),duration:Number(n)};t.gain.setValueAtTime(t.gain.value,r),t.gain.exponentialRampToValueAtTime(.01,r+s)}}}}};function _(e){return e=e||[],[z,q,F,W,Q,j,...e,H,V]}function J(e){return e}function K(e,o){return _(o).map(t=>t(e))}function M({node:e}){return typeof e=="function"?e():e}function N(e){e.slice(1).reduce((o,t)=>{var r;const n=M(t);return n?(o.connect?o.connect(n):(r=M(o))==null||r.connect(n),t):o},e[0])}function v(e){e.forEach(o=>{var t;o.disconnect?o.disconnect():(t=M(o))==null||t.disconnect()})}function X(e){const o=new Map;for(const t of e)if(!!t.props)for(const n in t.props)o.set(n,t.props[n]);return o}function C(e){return e.replace(/-(\w)/g,(o,t)=>t.toLocaleUpperCase())}function T(e,o){const t=o in e?e[o]:void 0;return t instanceof Function?t.bind(e):t}function U(e,o){return fetch(e).then(t=>t.arrayBuffer()).then(t=>o.decodeAudioData(t))}function Y(e,o,t=0,n){t=t||0,n=n||o-1;const r=e.length/o,s=~~(r/10)||1,i=e.numberOfChannels,c=[],a=[];for(let u=0;u<i;u++){c[u]=c[u]||[];const l=c[u],d=e.getChannelData(u);let f;for(f=t;f<=n;f++){const g=~~(f*r),y=~~(g+r);let h=d[g],p=h;for(let A=g;A<y;A+=s){const b=d[A];b>p&&(p=b),b<h&&(h=b)}l[2*f]=p,l[2*f+1]=h,(u===0||p>a[2*f])&&(a[2*f]=p),(u===0||h<a[2*f+1])&&(a[2*f+1]=h)}}return{splitPeaks:c,mergedPeaks:a}}async function Z(e,o="#364356",t,n){const{width:r,height:s}=e,i=e.getContext("2d"),c=typeof t=="string"?await U(t,n):t.buffer,{mergedPeaks:a}=Y(c,r),u=window.devicePixelRatio||1,l=a.some(m=>m<0)?2:1,f=a.length/l/r,g=s/2,y=.5/u,h=2,p=1,b=1/1,S=h*u,L=Math.max(u,~~(S/2)),R=S+L;i.clearRect(0,0,r,s);for(let m=0;m<a.length;m+=R){let x=0,B=Math.floor(m*f)*l;const I=Math.floor((m+R)*f)*l;do{const E=Math.abs(a[B]);E>x&&(x=E),B+=l}while(B<I);const P=Math.max(Math.round(x/b*g),p);i.fillStyle=o,i.fillRect(m+y,g-P,S+y,P*2)}}function ee(e,o="#364356",t){const{width:n,height:r}=e,s=e.getContext("2d"),i=t.frequencyBinCount,c=new Uint8Array(i);s.clearRect(0,0,n,r),function a(){requestAnimationFrame(a),t.getByteTimeDomainData(c);const u=n/i*1.5;s.clearRect(0,0,n,r);for(let l=0,d=0;l<i;l++){const f=c[l];s.fillStyle=o,s.fillRect(d,r-f,u,f),d+=u+1}}()}function te(e,o){const t=o!=null?o:new AudioContext;if(typeof e=="string"){const n=t.createBufferSource();return{context:t,source:n,src:e,load:async()=>{n.buffer=await U(e,t)},clone:()=>{const r=n.buffer,s=t.createBufferSource();return s.buffer=r,s}}}else if(e instanceof AudioBuffer){const n=t.createBufferSource();return n.buffer=e,{context:t,source:n,clone:()=>{const r=n.buffer,s=t.createBufferSource();return s.buffer=r,s}}}else return t instanceof AudioContext&&e instanceof HTMLMediaElement?{context:t,source:t.createMediaElementSource(e),src:e.src}:{context:t,source:e}}function D(e,o){const{load:t,clone:n,...r}=te(e,o),s={...r,processors:[],props:new Map,setup(){v(this.processors),this.processors=K(this),this.props=X(this.processors),N(this.processors)},reconnect(){v(this.processors),N(this.processors)},get(i){var c,a;if(i)return(a=(c=this.props.get(C(i)))==null?void 0:c.getter)==null?void 0:a.call(c);{const u={};return this.props.forEach((l,d)=>{u[d]=this.get(d)}),u}},set(i,c){var a,u;if(typeof i=="string")(u=(a=this.props.get(C(i)))==null?void 0:a.setter)==null||u.call(a,c);else for(const l in i)this.set(l,i[l])},renderBarChart(i,c){return Z(i,c,this.source instanceof MediaElementAudioSourceNode?this.source.mediaElement.src:this.source,this.context)},renderTimeDomainBarChart(i,c){return ee(i,c,this.processors.find(a=>a.name==="analyser").node)}};return t&&(s.load=async function(){await t(),this.setup()}),n&&(s.reset=function(){this.source=n();const i=this.get();this.setup(),this.set(i)},s.resetAndStart=function(i,c,a){var u;(u=this.reset)==null||u.call(this),this.source.start(i,c,a)}),s.source instanceof AudioBufferSourceNode||s.setup(),new Proxy(s,{get(i,c){var a;return(a=T(i,c))!=null?a:T(i.source,c)},set(i,c,a){return c in i?i[c]=a:i.source[c]=a,!0}})}class k extends HTMLAudioElement{constructor(){super(),this.source=D(this),this.setup()}static install(){customElements.define("modern-audio",k,{extends:"audio"})}async setup(){this.setupListeners();for(let o=0;o<this.attributes.length;o++){const t=this.attributes.item(o);t&&this.source.set(t.name,t.value)}}setupListeners(){this.addEventListener("play",()=>this.source.context.resume())}}function ne(e){return new Blob([re(oe(e),e.sampleRate)],{type:"audio/wav"})}function oe(e){const o=e.getChannelData(0),t=o.length*2,n=new Float32Array(t);let r=0,s=0;for(;r<t;)n[r++]=o[s],n[r++]=o[s],s++;return n}function re(e,o){const t=new ArrayBuffer(44+e.length*2),n=new DataView(t);return w(n,0,"RIFF"),n.setUint32(4,32+e.length*2,!0),w(n,8,"WAVE"),w(n,12,"fmt "),n.setUint32(16,16,!0),n.setUint16(20,1,!0),n.setUint16(22,2,!0),n.setUint32(24,o,!0),n.setUint32(28,o*4,!0),n.setUint16(32,4,!0),n.setUint16(34,16,!0),w(n,36,"data"),n.setUint32(40,e.length*2,!0),se(n,e,44)}function se(e,o,t){for(let n=0;n<o.length;n++,t+=2){const r=Math.max(-1,Math.min(1,o[n]));e.setInt16(t,r<0?r*32768:r*32767,!0)}return e}function w(e,o,t){for(let n=0;n<t.length;n++)e.setUint8(o+n,t.charCodeAt(n))}function ie(e,o=2,t=44100){return new OfflineAudioContext({length:t*e,numberOfChannels:o,sampleRate:t})}async function O(e){return ne(await e.startRendering())}async function ae(e,o="audio"){const t=await O(e),n=document.createElement("a");n.style.display="none",n.href=URL.createObjectURL(t),n.download=`${o}.${t.type.split("/")[1]}`,n.click()}exports.ModernAudio=k;exports.createAudio=D;exports.createOfflineAudioContext=ie;exports.defineProcessor=J;exports.downloadOfflineAudio=ae;exports.exportOfflineAudio=O;