diff --git a/.gitignore b/.gitignore index c5b5a11..ff9770e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ twistd.pid node_modules/ pvt/ - diff --git a/build/omnitone.js b/build/omnitone.js index 983bca5..32925ca 100644 --- a/build/omnitone.js +++ b/build/omnitone.js @@ -13,4 +13,118 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -!function(A,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e=t();for(var i in e)("object"==typeof exports?exports:A)[i]=e[i]}}(window,function(){return function(A){var t={};function e(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return A[i].call(n.exports,n,n.exports,e),n.l=!0,n.exports}return e.m=A,e.c=t,e.d=function(A,t,i){e.o(A,t)||Object.defineProperty(A,t,{configurable:!1,enumerable:!0,get:i})},e.r=function(A){Object.defineProperty(A,"__esModule",{value:!0})},e.n=function(A){var t=A&&A.__esModule?function(){return A.default}:function(){return A};return e.d(t,"a",t),t},e.o=function(A,t){return Object.prototype.hasOwnProperty.call(A,t)},e.p="",e(e.s=15)}([function(A,t){let e,i,n,o,r,s,a,f,c,h,g,w,D,v,P,B,u,l,Q,_,C,d,p,E,M,x,I,m,b;t.log=function(){let A="[Omnitone] "+Array.prototype.slice.call(arguments).join(" ")+" ("+performance.now().toFixed(2)+"ms)";window.console.log(A)},t.throw=function(){let A="[Omnitone] "+Array.prototype.slice.call(arguments).join(" ")+" ("+performance.now().toFixed(2)+"ms)";throw new Error(A)},t.invertMatrix4=function(A,t){return e=t[0],i=t[1],n=t[2],o=t[3],r=t[4],s=t[5],a=t[6],f=t[7],c=t[8],h=t[9],g=t[10],w=t[11],D=t[12],v=t[13],P=t[14],B=t[15],(b=(u=e*s-i*r)*(m=g*B-w*P)-(l=e*a-n*r)*(I=h*B-w*v)+(Q=e*f-o*r)*(x=h*P-g*v)+(_=i*a-n*s)*(M=c*B-w*D)-(C=i*f-o*s)*(E=c*P-g*D)+(d=n*f-o*a)*(p=c*v-h*D))?(b=1/b,A[0]=(s*m-a*I+f*x)*b,A[1]=(n*I-i*m-o*x)*b,A[2]=(v*d-P*C+B*_)*b,A[3]=(g*C-h*d-w*_)*b,A[4]=(a*M-r*m-f*E)*b,A[5]=(e*m-n*M+o*E)*b,A[6]=(P*Q-D*d-B*l)*b,A[7]=(c*d-g*Q+w*l)*b,A[8]=(r*I-s*M+f*p)*b,A[9]=(i*M-e*I-o*p)*b,A[10]=(D*C-v*Q+B*u)*b,A[11]=(h*Q-c*C-w*u)*b,A[12]=(s*E-r*x-a*p)*b,A[13]=(e*x-i*E+n*p)*b,A[14]=(v*l-D*_-P*u)*b,A[15]=(c*_-h*l+g*u)*b,A):null},t.isDefinedENUMEntry=function(A,t){for(let e in A)if(t===A[e])return!0;return!1},t.isAudioContext=function(A){return A instanceof AudioContext||A instanceof OfflineAudioContext},t.isAudioBuffer=function(A){return A instanceof AudioBuffer},t.mergeBufferListByChannel=function(A,e){const i=e[0].length,n=e[0].sampleRate;let o=0;for(let A=0;A32&&t.throw("Utils.mergeBuffer: Number of channels cannot exceed 32.(got "+o+")"),i!==e[A].length&&t.throw("Utils.mergeBuffer: AudioBuffer lengths are inconsistent. (expected "+i+" but got "+e[A].length+")"),n!==e[A].sampleRate&&t.throw("Utils.mergeBuffer: AudioBuffer sample rates are inconsistent. (expected "+n+" but got "+e[A].sampleRate+")"),o+=e[A].numberOfChannels;const r=A.createBuffer(o,i,n);let s=0;for(let A=0;Ae[i]=t.charCodeAt(i)),e.buffer}},function(A,t,e){"use strict";const i=e(0),n={BASE64:"base64",URL:"url"};function o(A,t,e){this._context=i.isAudioContext(A)?A:i.throw("BufferList: Invalid BaseAudioContext."),this._options={dataType:n.BASE64,verbose:!1},e&&(e.dataType&&i.isDefinedENUMEntry(n,e.dataType)&&(this._options.dataType=e.dataType),e.verbose&&(this._options.verbose=Boolean(e.verbose))),this._bufferList=[],this._bufferData=this._options.dataType===n.BASE64?t:t.slice(0),this._numberOfTasks=this._bufferData.length,this._resolveHandler=null,this._rejectHandler=new Function}o.prototype.load=function(){return new Promise(this._promiseGenerator.bind(this))},o.prototype._promiseGenerator=function(A,t){"function"!=typeof A?i.throw("BufferList: Invalid Promise resolver."):this._resolveHandler=A,"function"==typeof t&&(this._rejectHandler=t);for(let A=0;A0){const o=i(t,1);return r(A,1,t-1,e,n)*Math.sqrt(1+o)-r(A,-1,1-t,e,n)*(1-o)}{const o=i(t,-1);return r(A,1,t+1,e,n)*(1-o)+r(A,-1,-t-1,e,n)*Math.sqrt(1+o)}}function f(A,t,e,i){return 0===t?0:t>0?r(A,1,t+1,e,i)+r(A,-1,-t-1,e,i):r(A,1,t-1,e,i)-r(A,-1,1-t,e,i)}function c(A,t,e){const n=i(A,0),o=Math.abs(t)===e?1/(2*e*(2*e-1)):1/((e+t)*(e-t));return[Math.sqrt((e+A)*(e-A)*o),.5*(1-2*n)*Math.sqrt((1+n)*(e+Math.abs(A)-1)*(e+Math.abs(A))*o),-.5*(1-n)*Math.sqrt((e-Math.abs(A)-1)*(e-Math.abs(A)))*o]}function h(A,t){for(let e=-t;e<=t;e++)for(let i=-t;i<=t;i++){const o=c(e,i,t);Math.abs(o[0])>0&&(o[0]*=s(A,e,i,t)),Math.abs(o[1])>0&&(o[1]*=a(A,e,i,t)),Math.abs(o[2])>0&&(o[2]*=f(A,e,i,t)),n(A,t,e,i,o[0]+o[1]+o[2])}}function g(A){for(let t=2;t<=A.length;t++)h(A,t)}function w(A,t){this._context=A,this._ambisonicOrder=t;const e=(t+1)*(t+1);let i,n,o,r,s;this._splitter=this._context.createChannelSplitter(e),this._merger=this._context.createChannelMerger(e),this._gainNodeMatrix=[];for(let A=1;A<=t;A++){i=A*A,n=2*A+1,this._gainNodeMatrix[A-1]=[];for(let t=0;t=0?this._stereoSplitters[i].connect(this._positiveIndexSphericalHarmonics,e%2):this._stereoSplitters[i].connect(this._negativeIndexSphericalHarmonics,e%2)}this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,1),this._negativeIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._negativeIndexSphericalHarmonics.connect(this._inverter),this._inverter.connect(this._binauralMerger,0,1),this._inverter.gain.value=-1,this.input=this._inputSplitter,this.output=this._outputGain},i.prototype.setHRIRBufferList=function(A){if(!this._isBufferLoaded){for(let t=0;t ["+A.toString()+"])."),this._config.channelMap=A.slice(),this._foaRouter.setChannelMap(this._config.channelMap))},c.prototype.setRotationMatrix3=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix3(A)},c.prototype.setRotationMatrix4=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix4(A)},c.prototype.setRotationMatrixFromCamera=function(A){this._isRendererReady&&(a.invertMatrix4(this._tempMatrix4,A.elements),this._foaRotator.setRotationMatrix4(this._tempMatrix4))},c.prototype.setRenderingMode=function(A){if(A!==this._config.renderingMode){switch(A){case f.AMBISONIC:this._foaConvolver.enable(),this._bypass.disconnect();break;case f.BYPASS:this._foaConvolver.disable(),this._bypass.connect(this.output);break;case f.OFF:this._foaConvolver.disable(),this._bypass.disconnect();break;default:return void a.log('FOARenderer: Rendering mode "'+A+'" is not supported.')}this._config.renderingMode=A,a.log("FOARenderer: Rendering mode changed. ("+A+")")}},A.exports=c},function(A,t,e){"use strict";const i=e(1),n=e(6),o=e(13),r=e(5),s=e(4),a=e(3),f=e(11),c=e(2),h=e(8),g=e(0),w=e(7);let D={};D.browserInfo=h.getBrowserInfo(),D.createBufferList=function(A,t,e){return new i(A,t,e||{dataType:"url"}).load()},D.mergeBufferListByChannel=g.mergeBufferListByChannel,D.splitBufferbyChannel=g.splitBufferbyChannel,D.createFOAConvolver=function(A,t){return new n(A,t)},D.createFOARouter=function(A,t){return new s(A,t)},D.createFOARotator=function(A){return new r(A)},D.createHOARotator=function(A,t){return new c(A,t)},D.createHOAConvolver=function(A,t,e){return new a(A,t,e)},D.createFOARenderer=function(A,t){return new o(A,t)},D.createHOARenderer=function(A,t){return new f(A,t)},g.log("Version "+w+" (running "+D.browserInfo.name+" "+D.browserInfo.version+" on "+D.browserInfo.platform+")"),"safari"===D.browserInfo.name.toLowerCase()&&(h.patchSafari(),g.log(D.browserInfo.name+" detected. Polyfill applied.")),A.exports=D},function(A,t,e){"use strict";t.Omnitone=e(14)}])}); \ No newline at end of file + +(function n(e, A) { + if (typeof exports === "object" && typeof module === "object") module.exports = A(); else if (typeof define === "function" && define.amd) define([], A); else { + var t = A(); + for (var i in t) (typeof exports === "object" ? exports : e)[i] = t[i]; + } +})(window, function() { + return function(n) { + var e = {}; + function A(t) { + if (e[t]) { + return e[t].exports; + } + var i = e[t] = { + i: t, + l: false, + exports: {} + }; + n[t].call(i.exports, i, i.exports, A); + i.l = true; + return i.exports; + } + A.m = n; + A.c = e; + A.d = function(n, e, t) { + if (!A.o(n, e)) { + Object.defineProperty(n, e, { + configurable: false, + enumerable: true, + get: t + }); + } + }; + A.r = function(n) { + Object.defineProperty(n, "__esModule", { + value: true + }); + }; + A.n = function(n) { + var e = n && n.__esModule ? function e() { + return n["default"]; + } : function e() { + return n; + }; + A.d(e, "a", e); + return e; + }; + A.o = function(n, e) { + return Object.prototype.hasOwnProperty.call(n, e); + }; + A.p = ""; + return A(A.s = "./src/main.js"); + }({ + "./src/buffer-list.js": function(module, exports, __webpack_require__) { + "use strict"; + eval("/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Streamlined AudioBuffer loader.\n */\n\n\n\n\nconst Utils = __webpack_require__(/*! ./utils.js */ \"./src/utils.js\");\n\n/**\n * @typedef {string} BufferDataType\n */\n\n/**\n * Buffer data type for ENUM.\n * @enum {BufferDataType}\n */\nconst BufferDataType = {\n /** @type {string} The data contains Base64-encoded string.. */\n BASE64: 'base64',\n /** @type {string} The data is a URL for audio file. */\n URL: 'url',\n};\n\n\n/**\n * BufferList object mananges the async loading/decoding of multiple\n * AudioBuffers from multiple URLs.\n * @constructor\n * @param {BaseAudioContext} context - Associated BaseAudioContext.\n * @param {string[]} bufferData - An ordered list of URLs.\n * @param {Object} options - Options\n * @param {string} [options.dataType='base64'] - BufferDataType specifier.\n * @param {Boolean} [options.verbose=false] - Log verbosity. |true| prints the\n * individual message from each URL and AudioBuffer.\n */\nfunction BufferList(context, bufferData, options) {\n this._context = Utils.isAudioContext(context) ?\n context :\n Utils.throw('BufferList: Invalid BaseAudioContext.');\n\n this._options = {\n dataType: BufferDataType.BASE64,\n verbose: false,\n };\n\n if (options) {\n if (options.dataType &&\n Utils.isDefinedENUMEntry(BufferDataType, options.dataType)) {\n this._options.dataType = options.dataType;\n }\n if (options.verbose) {\n this._options.verbose = Boolean(options.verbose);\n }\n }\n\n this._bufferList = [];\n this._bufferData = this._options.dataType === BufferDataType.BASE64\n ? bufferData\n : bufferData.slice(0);\n this._numberOfTasks = this._bufferData.length;\n\n this._resolveHandler = null;\n this._rejectHandler = new Function();\n}\n\n\n/**\n * Starts AudioBuffer loading tasks.\n * @return {Promise} The promise resolves with an array of\n * AudioBuffer.\n */\nBufferList.prototype.load = function() {\n return new Promise(this._promiseGenerator.bind(this));\n};\n\n\n/**\n * Promise argument generator. Internally starts multiple async loading tasks.\n * @private\n * @param {function} resolve Promise resolver.\n * @param {function} reject Promise reject.\n */\nBufferList.prototype._promiseGenerator = function(resolve, reject) {\n if (typeof resolve !== 'function') {\n Utils.throw('BufferList: Invalid Promise resolver.');\n } else {\n this._resolveHandler = resolve;\n }\n\n if (typeof reject === 'function') {\n this._rejectHandler = reject;\n }\n\n for (let i = 0; i < this._bufferData.length; ++i) {\n this._options.dataType === BufferDataType.BASE64\n ? this._launchAsyncLoadTask(i)\n : this._launchAsyncLoadTaskXHR(i);\n }\n};\n\n\n/**\n * Run async loading task for Base64-encoded string.\n * @private\n * @param {Number} taskId Task ID number from the ordered list |bufferData|.\n */\nBufferList.prototype._launchAsyncLoadTask = function(taskId) {\n const that = this;\n this._context.decodeAudioData(\n Utils.getArrayBufferFromBase64String(this._bufferData[taskId]),\n function(audioBuffer) {\n that._updateProgress(taskId, audioBuffer);\n },\n function(errorMessage) {\n that._updateProgress(taskId, null);\n const message = 'BufferList: decoding ArrayByffer(\"' + taskId +\n '\" from Base64-encoded data failed. (' + errorMessage + ')';\n that._rejectHandler(message);\n Utils.throw(message);\n });\n};\n\n\n/**\n * Run async loading task via XHR for audio file URLs.\n * @private\n * @param {Number} taskId Task ID number from the ordered list |bufferData|.\n */\nBufferList.prototype._launchAsyncLoadTaskXHR = function(taskId) {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', this._bufferData[taskId]);\n xhr.responseType = 'arraybuffer';\n\n const that = this;\n xhr.onload = function() {\n if (xhr.status === 200) {\n that._context.decodeAudioData(\n xhr.response,\n function(audioBuffer) {\n that._updateProgress(taskId, audioBuffer);\n },\n function(errorMessage) {\n that._updateProgress(taskId, null);\n const message = 'BufferList: decoding \"' +\n that._bufferData[taskId] + '\" failed. (' + errorMessage + ')';\n that._rejectHandler(message);\n Utils.log(message);\n });\n } else {\n const message = 'BufferList: XHR error while loading \"' +\n that._bufferData[taskId] + '\". (' + xhr.status + ' ' +\n xhr.statusText + ')';\n that._rejectHandler(message);\n Utils.log(message);\n }\n };\n\n xhr.onerror = function(event) {\n that._updateProgress(taskId, null);\n that._rejectHandler();\n Utils.log(\n 'BufferList: XHR network failed on loading \"' +\n that._bufferData[taskId] + '\".');\n };\n\n xhr.send();\n};\n\n\n/**\n * Updates the overall progress on loading tasks.\n * @param {Number} taskId Task ID number.\n * @param {AudioBuffer} audioBuffer Decoded AudioBuffer object.\n */\nBufferList.prototype._updateProgress = function(taskId, audioBuffer) {\n this._bufferList[taskId] = audioBuffer;\n\n if (this._options.verbose) {\n let messageString = this._options.dataType === BufferDataType.BASE64\n ? 'ArrayBuffer(' + taskId + ') from Base64-encoded HRIR'\n : '\"' + this._bufferData[taskId] + '\"';\n Utils.log('BufferList: ' + messageString + ' successfully loaded.');\n }\n\n if (--this._numberOfTasks === 0) {\n let messageString = this._options.dataType === BufferDataType.BASE64\n ? this._bufferData.length + ' AudioBuffers from Base64-encoded HRIRs'\n : this._bufferData.length + ' files via XHR';\n Utils.log('BufferList: ' + messageString + ' loaded successfully.');\n this._resolveHandler(this._bufferList);\n }\n};\n\n\nmodule.exports = BufferList;\n\n\n//# sourceURL=webpack:///./src/buffer-list.js?"); + }, + "./src/foa-convolver.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/**\n * @file A collection of convolvers. Can be used for the optimized FOA binaural\n * rendering. (e.g. SH-MaxRe HRTFs)\n */\n\n\n\n\n/**\n * FOAConvolver. A collection of 2 stereo convolvers for 4-channel FOA stream.\n * @constructor\n * @param {BaseAudioContext} context The associated AudioContext.\n * @param {AudioBuffer[]} [hrirBufferList] - An ordered-list of stereo\n * AudioBuffers for convolution. (i.e. 2 stereo AudioBuffers for FOA)\n */\nfunction FOAConvolver(context, hrirBufferList) {\n this._context = context;\n\n this._active = false;\n this._isBufferLoaded = false;\n\n this._buildAudioGraph();\n\n if (hrirBufferList) {\n this.setHRIRBufferList(hrirBufferList);\n }\n\n this.enable();\n}\n\n\n/**\n * Build the internal audio graph.\n *\n * @private\n */\nFOAConvolver.prototype._buildAudioGraph = function() {\n this._splitterWYZX = this._context.createChannelSplitter(4);\n this._mergerWY = this._context.createChannelMerger(2);\n this._mergerZX = this._context.createChannelMerger(2);\n this._convolverWY = this._context.createConvolver();\n this._convolverZX = this._context.createConvolver();\n this._splitterWY = this._context.createChannelSplitter(2);\n this._splitterZX = this._context.createChannelSplitter(2);\n this._inverter = this._context.createGain();\n this._mergerBinaural = this._context.createChannelMerger(2);\n this._summingBus = this._context.createGain();\n\n // Group W and Y, then Z and X.\n this._splitterWYZX.connect(this._mergerWY, 0, 0);\n this._splitterWYZX.connect(this._mergerWY, 1, 1);\n this._splitterWYZX.connect(this._mergerZX, 2, 0);\n this._splitterWYZX.connect(this._mergerZX, 3, 1);\n\n // Create a network of convolvers using splitter/merger.\n this._mergerWY.connect(this._convolverWY);\n this._mergerZX.connect(this._convolverZX);\n this._convolverWY.connect(this._splitterWY);\n this._convolverZX.connect(this._splitterZX);\n this._splitterWY.connect(this._mergerBinaural, 0, 0);\n this._splitterWY.connect(this._mergerBinaural, 0, 1);\n this._splitterWY.connect(this._mergerBinaural, 1, 0);\n this._splitterWY.connect(this._inverter, 1, 0);\n this._inverter.connect(this._mergerBinaural, 0, 1);\n this._splitterZX.connect(this._mergerBinaural, 0, 0);\n this._splitterZX.connect(this._mergerBinaural, 0, 1);\n this._splitterZX.connect(this._mergerBinaural, 1, 0);\n this._splitterZX.connect(this._mergerBinaural, 1, 1);\n\n // By default, WebAudio\'s convolver does the normalization based on IR\'s\n // energy. For the precise convolution, it must be disabled before the buffer\n // assignment.\n this._convolverWY.normalize = false;\n this._convolverZX.normalize = false;\n\n // For asymmetric degree.\n this._inverter.gain.value = -1;\n\n // Input/output proxy.\n this.input = this._splitterWYZX;\n this.output = this._summingBus;\n};\n\n\n/**\n * Assigns 2 HRIR AudioBuffers to 2 convolvers: Note that we use 2 stereo\n * convolutions for 4-channel direct convolution. Using mono convolver or\n * 4-channel convolver is not viable because mono convolution wastefully\n * produces the stereo outputs, and the 4-ch convolver does cross-channel\n * convolution. (See Web Audio API spec)\n * @param {AudioBuffer[]} hrirBufferList - An array of stereo AudioBuffers for\n * convolvers.\n */\nFOAConvolver.prototype.setHRIRBufferList = function(hrirBufferList) {\n // After these assignments, the channel data in the buffer is immutable in\n // FireFox. (i.e. neutered) So we should avoid re-assigning buffers, otherwise\n // an exception will be thrown.\n if (this._isBufferLoaded) {\n return;\n }\n\n this._convolverWY.buffer = hrirBufferList[0];\n this._convolverZX.buffer = hrirBufferList[1];\n this._isBufferLoaded = true;\n};\n\n\n/**\n * Enable FOAConvolver instance. The audio graph will be activated and pulled by\n * the WebAudio engine. (i.e. consume CPU cycle)\n */\nFOAConvolver.prototype.enable = function() {\n this._mergerBinaural.connect(this._summingBus);\n this._active = true;\n};\n\n\n/**\n * Disable FOAConvolver instance. The inner graph will be disconnected from the\n * audio destination, thus no CPU cycle will be consumed.\n */\nFOAConvolver.prototype.disable = function() {\n this._mergerBinaural.disconnect();\n this._active = false;\n};\n\n\nmodule.exports = FOAConvolver;\n\n\n//# sourceURL=webpack:///./src/foa-convolver.js?'); + }, + "./src/foa-renderer.js": function(module, exports, __webpack_require__) { + "use strict"; + eval("/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/**\n * @file Omnitone FOARenderer. This is user-facing API for the first-order\n * ambisonic decoder and the optimized binaural renderer.\n */\n\n\n\nconst BufferList = __webpack_require__(/*! ./buffer-list.js */ \"./src/buffer-list.js\");\nconst FOAConvolver = __webpack_require__(/*! ./foa-convolver.js */ \"./src/foa-convolver.js\");\nconst FOAHrirBase64 = __webpack_require__(/*! ./resources/omnitone-foa-hrir-base64.js */ \"./src/resources/omnitone-foa-hrir-base64.js\");\nconst FOARotator = __webpack_require__(/*! ./foa-rotator.js */ \"./src/foa-rotator.js\");\nconst FOARouter = __webpack_require__(/*! ./foa-router.js */ \"./src/foa-router.js\");\nconst Utils = __webpack_require__(/*! ./utils.js */ \"./src/utils.js\");\n\n\n/**\n * @typedef {string} RenderingMode\n */\n\n/**\n * Rendering mode ENUM.\n * @enum {RenderingMode}\n */\nconst RenderingMode = {\n /** @type {string} Use ambisonic rendering. */\n AMBISONIC: 'ambisonic',\n /** @type {string} Bypass. No ambisonic rendering. */\n BYPASS: 'bypass',\n /** @type {string} Disable audio output. */\n OFF: 'off',\n};\n\n\n/**\n * Omnitone FOA renderer class. Uses the optimized convolution technique.\n * @constructor\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Object} config\n * @param {Array} [config.channelMap] - Custom channel routing map. Useful for\n * handling the inconsistency in browser's multichannel audio decoding.\n * @param {Array} [config.hrirPathList] - A list of paths to HRIR files. It\n * overrides the internal HRIR list if given.\n * @param {RenderingMode} [config.renderingMode='ambisonic'] - Rendering mode.\n */\nfunction FOARenderer(context, config) {\n this._context = Utils.isAudioContext(context) ?\n context :\n Utils.throw('FOARenderer: Invalid BaseAudioContext.');\n\n this._config = {\n channelMap: FOARouter.ChannelMap.DEFAULT,\n renderingMode: RenderingMode.AMBISONIC,\n };\n\n if (config) {\n if (config.channelMap) {\n if (Array.isArray(config.channelMap) && config.channelMap.length === 4) {\n this._config.channelMap = config.channelMap;\n } else {\n Utils.throw(\n 'FOARenderer: Invalid channel map. (got ' + config.channelMap\n + ')');\n }\n }\n\n if (config.hrirPathList) {\n if (Array.isArray(config.hrirPathList) &&\n config.hrirPathList.length === 2) {\n this._config.pathList = config.hrirPathList;\n } else {\n Utils.throw(\n 'FOARenderer: Invalid HRIR URLs. It must be an array with ' +\n '2 URLs to HRIR files. (got ' + config.hrirPathList + ')');\n }\n }\n\n if (config.renderingMode) {\n if (Object.values(RenderingMode).includes(config.renderingMode)) {\n this._config.renderingMode = config.renderingMode;\n } else {\n Utils.log(\n 'FOARenderer: Invalid rendering mode order. (got' +\n config.renderingMode + ') Fallbacks to the mode \"ambisonic\".');\n }\n }\n }\n\n this._buildAudioGraph();\n\n this._tempMatrix4 = new Float32Array(16);\n this._isRendererReady = false;\n}\n\n\n/**\n * Builds the internal audio graph.\n * @private\n */\nFOARenderer.prototype._buildAudioGraph = function() {\n this.input = this._context.createGain();\n this.output = this._context.createGain();\n this._bypass = this._context.createGain();\n this._foaRouter = new FOARouter(this._context, this._config.channelMap);\n this._foaRotator = new FOARotator(this._context);\n this._foaConvolver = new FOAConvolver(this._context);\n this.input.connect(this._foaRouter.input);\n this.input.connect(this._bypass);\n this._foaRouter.output.connect(this._foaRotator.input);\n this._foaRotator.output.connect(this._foaConvolver.input);\n this._foaConvolver.output.connect(this.output);\n\n this.input.channelCount = 4;\n this.input.channelCountMode = 'explicit';\n this.input.channelInterpretation = 'discrete';\n};\n\n\n/**\n * Internal callback handler for |initialize| method.\n * @private\n * @param {function} resolve - Resolution handler.\n * @param {function} reject - Rejection handler.\n */\nFOARenderer.prototype._initializeCallback = function(resolve, reject) {\n const bufferList = this._config.pathList\n ? new BufferList(this._context, this._config.pathList, {dataType: 'url'})\n : new BufferList(this._context, FOAHrirBase64);\n bufferList.load().then(\n function(hrirBufferList) {\n this._foaConvolver.setHRIRBufferList(hrirBufferList);\n this.setRenderingMode(this._config.renderingMode);\n this._isRendererReady = true;\n Utils.log('FOARenderer: HRIRs loaded successfully. Ready.');\n resolve();\n }.bind(this),\n function() {\n const errorMessage = 'FOARenderer: HRIR loading/decoding failed.';\n reject(errorMessage);\n Utils.throw(errorMessage);\n });\n};\n\n\n/**\n * Initializes and loads the resource for the renderer.\n * @return {Promise}\n */\nFOARenderer.prototype.initialize = function() {\n Utils.log(\n 'FOARenderer: Initializing... (mode: ' + this._config.renderingMode +\n ')');\n\n return new Promise(this._initializeCallback.bind(this));\n};\n\n\n/**\n * Set the channel map.\n * @param {Number[]} channelMap - Custom channel routing for FOA stream.\n */\nFOARenderer.prototype.setChannelMap = function(channelMap) {\n if (!this._isRendererReady) {\n return;\n }\n\n if (channelMap.toString() !== this._config.channelMap.toString()) {\n Utils.log(\n 'Remapping channels ([' + this._config.channelMap.toString() +\n '] -> [' + channelMap.toString() + ']).');\n this._config.channelMap = channelMap.slice();\n this._foaRouter.setChannelMap(this._config.channelMap);\n }\n};\n\n\n/**\n * Updates the rotation matrix with 3x3 matrix.\n * @param {Number[]} rotationMatrix3 - A 3x3 rotation matrix. (column-major)\n */\nFOARenderer.prototype.setRotationMatrix3 = function(rotationMatrix3) {\n if (!this._isRendererReady) {\n return;\n }\n\n this._foaRotator.setRotationMatrix3(rotationMatrix3);\n};\n\n\n/**\n * Updates the rotation matrix with 4x4 matrix.\n * @param {Number[]} rotationMatrix4 - A 4x4 rotation matrix. (column-major)\n */\nFOARenderer.prototype.setRotationMatrix4 = function(rotationMatrix4) {\n if (!this._isRendererReady) {\n return;\n }\n\n this._foaRotator.setRotationMatrix4(rotationMatrix4);\n};\n\n\n/**\n * Set the rotation matrix from a Three.js camera object. Depreated in V1, and\n * this exists only for the backward compatiblity. Instead, use\n * |setRotatationMatrix4()| with Three.js |camera.worldMatrix.elements|.\n * @deprecated\n * @param {Object} cameraMatrix - Matrix4 from Three.js |camera.matrix|.\n */\nFOARenderer.prototype.setRotationMatrixFromCamera = function(cameraMatrix) {\n if (!this._isRendererReady) {\n return;\n }\n\n // Extract the inner array elements and inverse. (The actual view rotation is\n // the opposite of the camera movement.)\n Utils.invertMatrix4(this._tempMatrix4, cameraMatrix.elements);\n this._foaRotator.setRotationMatrix4(this._tempMatrix4);\n};\n\n\n/**\n * Set the rendering mode.\n * @param {RenderingMode} mode - Rendering mode.\n * - 'ambisonic': activates the ambisonic decoding/binaurl rendering.\n * - 'bypass': bypasses the input stream directly to the output. No ambisonic\n * decoding or encoding.\n * - 'off': all the processing off saving the CPU power.\n */\nFOARenderer.prototype.setRenderingMode = function(mode) {\n if (mode === this._config.renderingMode) {\n return;\n }\n\n switch (mode) {\n case RenderingMode.AMBISONIC:\n this._foaConvolver.enable();\n this._bypass.disconnect();\n break;\n case RenderingMode.BYPASS:\n this._foaConvolver.disable();\n this._bypass.connect(this.output);\n break;\n case RenderingMode.OFF:\n this._foaConvolver.disable();\n this._bypass.disconnect();\n break;\n default:\n Utils.log(\n 'FOARenderer: Rendering mode \"' + mode + '\" is not ' +\n 'supported.');\n return;\n }\n\n this._config.renderingMode = mode;\n Utils.log('FOARenderer: Rendering mode changed. (' + mode + ')');\n};\n\n\nmodule.exports = FOARenderer;\n\n\n//# sourceURL=webpack:///./src/foa-renderer.js?"); + }, + "./src/foa-rotator.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Sound field rotator for first-order-ambisonics decoding.\n */\n\n\n\n\n/**\n * First-order-ambisonic decoder based on gain node network.\n * @constructor\n * @param {AudioContext} context - Associated AudioContext.\n */\nfunction FOARotator(context) {\n this._context = context;\n\n this._splitter = this._context.createChannelSplitter(4);\n this._inY = this._context.createGain();\n this._inZ = this._context.createGain();\n this._inX = this._context.createGain();\n this._m0 = this._context.createGain();\n this._m1 = this._context.createGain();\n this._m2 = this._context.createGain();\n this._m3 = this._context.createGain();\n this._m4 = this._context.createGain();\n this._m5 = this._context.createGain();\n this._m6 = this._context.createGain();\n this._m7 = this._context.createGain();\n this._m8 = this._context.createGain();\n this._outY = this._context.createGain();\n this._outZ = this._context.createGain();\n this._outX = this._context.createGain();\n this._merger = this._context.createChannelMerger(4);\n\n // ACN channel ordering: [1, 2, 3] => [-Y, Z, -X]\n // Y (from channel 1)\n this._splitter.connect(this._inY, 1);\n // Z (from channel 2)\n this._splitter.connect(this._inZ, 2);\n // X (from channel 3)\n this._splitter.connect(this._inX, 3);\n this._inY.gain.value = -1;\n this._inX.gain.value = -1;\n\n // Apply the rotation in the world space.\n // |Y| | m0 m3 m6 | | Y * m0 + Z * m3 + X * m6 | | Yr |\n // |Z| * | m1 m4 m7 | = | Y * m1 + Z * m4 + X * m7 | = | Zr |\n // |X| | m2 m5 m8 | | Y * m2 + Z * m5 + X * m8 | | Xr |\n this._inY.connect(this._m0);\n this._inY.connect(this._m1);\n this._inY.connect(this._m2);\n this._inZ.connect(this._m3);\n this._inZ.connect(this._m4);\n this._inZ.connect(this._m5);\n this._inX.connect(this._m6);\n this._inX.connect(this._m7);\n this._inX.connect(this._m8);\n this._m0.connect(this._outY);\n this._m1.connect(this._outZ);\n this._m2.connect(this._outX);\n this._m3.connect(this._outY);\n this._m4.connect(this._outZ);\n this._m5.connect(this._outX);\n this._m6.connect(this._outY);\n this._m7.connect(this._outZ);\n this._m8.connect(this._outX);\n\n // Transform 3: world space to audio space.\n // W -> W (to channel 0)\n this._splitter.connect(this._merger, 0, 0);\n // Y (to channel 1)\n this._outY.connect(this._merger, 0, 1);\n // Z (to channel 2)\n this._outZ.connect(this._merger, 0, 2);\n // X (to channel 3)\n this._outX.connect(this._merger, 0, 3);\n this._outY.gain.value = -1;\n this._outX.gain.value = -1;\n\n this.setRotationMatrix3(new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]));\n\n // input/output proxy.\n this.input = this._splitter;\n this.output = this._merger;\n}\n\n\n/**\n * Updates the rotation matrix with 3x3 matrix.\n * @param {Number[]} rotationMatrix3 - A 3x3 rotation matrix. (column-major)\n */\nFOARotator.prototype.setRotationMatrix3 = function(rotationMatrix3) {\n this._m0.gain.value = rotationMatrix3[0];\n this._m1.gain.value = rotationMatrix3[1];\n this._m2.gain.value = rotationMatrix3[2];\n this._m3.gain.value = rotationMatrix3[3];\n this._m4.gain.value = rotationMatrix3[4];\n this._m5.gain.value = rotationMatrix3[5];\n this._m6.gain.value = rotationMatrix3[6];\n this._m7.gain.value = rotationMatrix3[7];\n this._m8.gain.value = rotationMatrix3[8];\n};\n\n\n/**\n * Updates the rotation matrix with 4x4 matrix.\n * @param {Number[]} rotationMatrix4 - A 4x4 rotation matrix. (column-major)\n */\nFOARotator.prototype.setRotationMatrix4 = function(rotationMatrix4) {\n this._m0.gain.value = rotationMatrix4[0];\n this._m1.gain.value = rotationMatrix4[1];\n this._m2.gain.value = rotationMatrix4[2];\n this._m3.gain.value = rotationMatrix4[4];\n this._m4.gain.value = rotationMatrix4[5];\n this._m5.gain.value = rotationMatrix4[6];\n this._m6.gain.value = rotationMatrix4[8];\n this._m7.gain.value = rotationMatrix4[9];\n this._m8.gain.value = rotationMatrix4[10];\n};\n\n\n/**\n * Returns the current 3x3 rotation matrix.\n * @return {Number[]} - A 3x3 rotation matrix. (column-major)\n */\nFOARotator.prototype.getRotationMatrix3 = function() {\n return [\n this._m0.gain.value, this._m1.gain.value, this._m2.gain.value,\n this._m3.gain.value, this._m4.gain.value, this._m5.gain.value,\n this._m6.gain.value, this._m7.gain.value, this._m8.gain.value,\n ];\n};\n\n\n/**\n * Returns the current 4x4 rotation matrix.\n * @return {Number[]} - A 4x4 rotation matrix. (column-major)\n */\nFOARotator.prototype.getRotationMatrix4 = function() {\n let rotationMatrix4 = new Float32Array(16);\n rotationMatrix4[0] = this._m0.gain.value;\n rotationMatrix4[1] = this._m1.gain.value;\n rotationMatrix4[2] = this._m2.gain.value;\n rotationMatrix4[4] = this._m3.gain.value;\n rotationMatrix4[5] = this._m4.gain.value;\n rotationMatrix4[6] = this._m5.gain.value;\n rotationMatrix4[8] = this._m6.gain.value;\n rotationMatrix4[9] = this._m7.gain.value;\n rotationMatrix4[10] = this._m8.gain.value;\n return rotationMatrix4;\n};\n\n\nmodule.exports = FOARotator;\n\n\n//# sourceURL=webpack:///./src/foa-rotator.js?'); + }, + "./src/foa-router.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file An audio channel router to resolve different channel layouts between\n * browsers.\n */\n\n\n\n\n/**\n * @typedef {Number[]} ChannelMap\n */\n\n/**\n * Channel map dictionary ENUM.\n * @enum {ChannelMap}\n */\nconst ChannelMap = {\n /** @type {Number[]} - ACN channel map for Chrome and FireFox. (FFMPEG) */\n DEFAULT: [0, 1, 2, 3],\n /** @type {Number[]} - Safari\'s 4-channel map for AAC codec. */\n SAFARI: [2, 0, 1, 3],\n /** @type {Number[]} - ACN > FuMa conversion map. */\n FUMA: [0, 3, 1, 2],\n};\n\n\n/**\n * Channel router for FOA stream.\n * @constructor\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Number[]} channelMap - Routing destination array.\n */\nfunction FOARouter(context, channelMap) {\n this._context = context;\n\n this._splitter = this._context.createChannelSplitter(4);\n this._merger = this._context.createChannelMerger(4);\n\n // input/output proxy.\n this.input = this._splitter;\n this.output = this._merger;\n\n this.setChannelMap(channelMap || ChannelMap.DEFAULT);\n}\n\n\n/**\n * Sets channel map.\n * @param {Number[]} channelMap - A new channel map for FOA stream.\n */\nFOARouter.prototype.setChannelMap = function(channelMap) {\n if (!Array.isArray(channelMap)) {\n return;\n }\n\n this._channelMap = channelMap;\n this._splitter.disconnect();\n this._splitter.connect(this._merger, 0, this._channelMap[0]);\n this._splitter.connect(this._merger, 1, this._channelMap[1]);\n this._splitter.connect(this._merger, 2, this._channelMap[2]);\n this._splitter.connect(this._merger, 3, this._channelMap[3]);\n};\n\n\n/**\n * Static channel map ENUM.\n * @static\n * @type {ChannelMap}\n */\nFOARouter.ChannelMap = ChannelMap;\n\n\nmodule.exports = FOARouter;\n\n\n//# sourceURL=webpack:///./src/foa-router.js?'); + }, + "./src/hoa-convolver.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/**\n * @file A collection of convolvers. Can be used for the optimized HOA binaural\n * rendering. (e.g. SH-MaxRe HRTFs)\n */\n\n\n\n\n/**\n * A convolver network for N-channel HOA stream.\n * @constructor\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Number} ambisonicOrder - Ambisonic order. (2 or 3)\n * @param {AudioBuffer[]} [hrirBufferList] - An ordered-list of stereo\n * AudioBuffers for convolution. (SOA: 5 AudioBuffers, TOA: 8 AudioBuffers)\n */\nfunction HOAConvolver(context, ambisonicOrder, hrirBufferList) {\n this._context = context;\n\n this._active = false;\n this._isBufferLoaded = false;\n\n // The number of channels K based on the ambisonic order N where K = (N+1)^2.\n this._ambisonicOrder = ambisonicOrder;\n this._numberOfChannels =\n (this._ambisonicOrder + 1) * (this._ambisonicOrder + 1);\n\n this._buildAudioGraph();\n if (hrirBufferList) {\n this.setHRIRBufferList(hrirBufferList);\n }\n\n this.enable();\n}\n\n\n/**\n * Build the internal audio graph.\n * For TOA convolution:\n * input -> splitter(16) -[0,1]-> merger(2) -> convolver(2) -> splitter(2)\n * -[2,3]-> merger(2) -> convolver(2) -> splitter(2)\n * -[4,5]-> ... (6 more, 8 branches total)\n * @private\n */\nHOAConvolver.prototype._buildAudioGraph = function() {\n const numberOfStereoChannels = Math.ceil(this._numberOfChannels / 2);\n\n this._inputSplitter =\n this._context.createChannelSplitter(this._numberOfChannels);\n this._stereoMergers = [];\n this._convolvers = [];\n this._stereoSplitters = [];\n this._positiveIndexSphericalHarmonics = this._context.createGain();\n this._negativeIndexSphericalHarmonics = this._context.createGain();\n this._inverter = this._context.createGain();\n this._binauralMerger = this._context.createChannelMerger(2);\n this._outputGain = this._context.createGain();\n\n for (let i = 0; i < numberOfStereoChannels; ++i) {\n this._stereoMergers[i] = this._context.createChannelMerger(2);\n this._convolvers[i] = this._context.createConvolver();\n this._stereoSplitters[i] = this._context.createChannelSplitter(2);\n this._convolvers[i].normalize = false;\n }\n\n for (let l = 0; l <= this._ambisonicOrder; ++l) {\n for (let m = -l; m <= l; m++) {\n // We compute the ACN index (k) of ambisonics channel using the degree (l)\n // and index (m): k = l^2 + l + m\n const acnIndex = l * l + l + m;\n const stereoIndex = Math.floor(acnIndex / 2);\n\n // Split channels from input into array of stereo convolvers.\n // Then create a network of mergers that produces the stereo output.\n this._inputSplitter.connect(\n this._stereoMergers[stereoIndex], acnIndex, acnIndex % 2);\n this._stereoMergers[stereoIndex].connect(this._convolvers[stereoIndex]);\n this._convolvers[stereoIndex].connect(this._stereoSplitters[stereoIndex]);\n\n // Positive index (m >= 0) spherical harmonics are symmetrical around the\n // front axis, while negative index (m < 0) spherical harmonics are\n // anti-symmetrical around the front axis. We will exploit this symmetry\n // to reduce the number of convolutions required when rendering to a\n // symmetrical binaural renderer.\n if (m >= 0) {\n this._stereoSplitters[stereoIndex].connect(\n this._positiveIndexSphericalHarmonics, acnIndex % 2);\n } else {\n this._stereoSplitters[stereoIndex].connect(\n this._negativeIndexSphericalHarmonics, acnIndex % 2);\n }\n }\n }\n\n this._positiveIndexSphericalHarmonics.connect(this._binauralMerger, 0, 0);\n this._positiveIndexSphericalHarmonics.connect(this._binauralMerger, 0, 1);\n this._negativeIndexSphericalHarmonics.connect(this._binauralMerger, 0, 0);\n this._negativeIndexSphericalHarmonics.connect(this._inverter);\n this._inverter.connect(this._binauralMerger, 0, 1);\n\n // For asymmetric index.\n this._inverter.gain.value = -1;\n\n // Input/Output proxy.\n this.input = this._inputSplitter;\n this.output = this._outputGain;\n};\n\n\n/**\n * Assigns N HRIR AudioBuffers to N convolvers: Note that we use 2 stereo\n * convolutions for 4-channel direct convolution. Using mono convolver or\n * 4-channel convolver is not viable because mono convolution wastefully\n * produces the stereo outputs, and the 4-ch convolver does cross-channel\n * convolution. (See Web Audio API spec)\n * @param {AudioBuffer[]} hrirBufferList - An array of stereo AudioBuffers for\n * convolvers.\n */\nHOAConvolver.prototype.setHRIRBufferList = function(hrirBufferList) {\n // After these assignments, the channel data in the buffer is immutable in\n // FireFox. (i.e. neutered) So we should avoid re-assigning buffers, otherwise\n // an exception will be thrown.\n if (this._isBufferLoaded) {\n return;\n }\n\n for (let i = 0; i < hrirBufferList.length; ++i) {\n this._convolvers[i].buffer = hrirBufferList[i];\n }\n\n this._isBufferLoaded = true;\n};\n\n\n/**\n * Enable HOAConvolver instance. The audio graph will be activated and pulled by\n * the WebAudio engine. (i.e. consume CPU cycle)\n */\nHOAConvolver.prototype.enable = function() {\n this._binauralMerger.connect(this._outputGain);\n this._active = true;\n};\n\n\n/**\n * Disable HOAConvolver instance. The inner graph will be disconnected from the\n * audio destination, thus no CPU cycle will be consumed.\n */\nHOAConvolver.prototype.disable = function() {\n this._binauralMerger.disconnect();\n this._active = false;\n};\n\n\nmodule.exports = HOAConvolver;\n\n\n//# sourceURL=webpack:///./src/hoa-convolver.js?'); + }, + "./src/hoa-renderer.js": function(module, exports, __webpack_require__) { + "use strict"; + eval("/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/**\n * @file Omnitone HOARenderer. This is user-facing API for the higher-order\n * ambisonic decoder and the optimized binaural renderer.\n */\n\n\n\nconst BufferList = __webpack_require__(/*! ./buffer-list.js */ \"./src/buffer-list.js\");\nconst HOAConvolver = __webpack_require__(/*! ./hoa-convolver.js */ \"./src/hoa-convolver.js\");\nconst HOARotator = __webpack_require__(/*! ./hoa-rotator.js */ \"./src/hoa-rotator.js\");\nconst TOAHrirBase64 = __webpack_require__(/*! ./resources/omnitone-toa-hrir-base64.js */ \"./src/resources/omnitone-toa-hrir-base64.js\");\nconst SOAHrirBase64 = __webpack_require__(/*! ./resources/omnitone-soa-hrir-base64.js */ \"./src/resources/omnitone-soa-hrir-base64.js\");\nconst Utils = __webpack_require__(/*! ./utils.js */ \"./src/utils.js\");\n\n\n/**\n * @typedef {string} RenderingMode\n */\n\n/**\n * Rendering mode ENUM.\n * @enum {RenderingMode}\n */\nconst RenderingMode = {\n /** @type {string} Use ambisonic rendering. */\n AMBISONIC: 'ambisonic',\n /** @type {string} Bypass. No ambisonic rendering. */\n BYPASS: 'bypass',\n /** @type {string} Disable audio output. */\n OFF: 'off',\n};\n\n\n// Currently SOA and TOA are only supported.\nconst SupportedAmbisonicOrder = [2, 3];\n\n\n/**\n * Omnitone HOA renderer class. Uses the optimized convolution technique.\n * @constructor\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Object} config\n * @param {Number} [config.ambisonicOrder=3] - Ambisonic order.\n * @param {Array} [config.hrirPathList] - A list of paths to HRIR files. It\n * overrides the internal HRIR list if given.\n * @param {RenderingMode} [config.renderingMode='ambisonic'] - Rendering mode.\n */\nfunction HOARenderer(context, config) {\n this._context = Utils.isAudioContext(context) ?\n context :\n Utils.throw('HOARenderer: Invalid BaseAudioContext.');\n\n this._config = {\n ambisonicOrder: 3,\n renderingMode: RenderingMode.AMBISONIC,\n };\n\n if (config && config.ambisonicOrder) {\n if (SupportedAmbisonicOrder.includes(config.ambisonicOrder)) {\n this._config.ambisonicOrder = config.ambisonicOrder;\n } else {\n Utils.log(\n 'HOARenderer: Invalid ambisonic order. (got ' +\n config.ambisonicOrder + ') Fallbacks to 3rd-order ambisonic.');\n }\n }\n\n this._config.numberOfChannels =\n (this._config.ambisonicOrder + 1) * (this._config.ambisonicOrder + 1);\n this._config.numberOfStereoChannels =\n Math.ceil(this._config.numberOfChannels / 2);\n\n if (config && config.hrirPathList) {\n if (Array.isArray(config.hrirPathList) &&\n config.hrirPathList.length === this._config.numberOfStereoChannels) {\n this._config.pathList = config.hrirPathList;\n } else {\n Utils.throw(\n 'HOARenderer: Invalid HRIR URLs. It must be an array with ' +\n this._config.numberOfStereoChannels + ' URLs to HRIR files.' +\n ' (got ' + config.hrirPathList + ')');\n }\n }\n\n if (config && config.renderingMode) {\n if (Object.values(RenderingMode).includes(config.renderingMode)) {\n this._config.renderingMode = config.renderingMode;\n } else {\n Utils.log(\n 'HOARenderer: Invalid rendering mode. (got ' +\n config.renderingMode + ') Fallbacks to \"ambisonic\".');\n }\n }\n\n this._buildAudioGraph();\n\n this._isRendererReady = false;\n}\n\n\n/**\n * Builds the internal audio graph.\n * @private\n */\nHOARenderer.prototype._buildAudioGraph = function() {\n this.input = this._context.createGain();\n this.output = this._context.createGain();\n this._bypass = this._context.createGain();\n this._hoaRotator = new HOARotator(this._context, this._config.ambisonicOrder);\n this._hoaConvolver =\n new HOAConvolver(this._context, this._config.ambisonicOrder);\n this.input.connect(this._hoaRotator.input);\n this.input.connect(this._bypass);\n this._hoaRotator.output.connect(this._hoaConvolver.input);\n this._hoaConvolver.output.connect(this.output);\n\n this.input.channelCount = this._config.numberOfChannels;\n this.input.channelCountMode = 'explicit';\n this.input.channelInterpretation = 'discrete';\n};\n\n\n/**\n * Internal callback handler for |initialize| method.\n * @private\n * @param {function} resolve - Resolution handler.\n * @param {function} reject - Rejection handler.\n */\nHOARenderer.prototype._initializeCallback = function(resolve, reject) {\n let bufferList;\n if (this._config.pathList) {\n bufferList =\n new BufferList(this._context, this._config.pathList, {dataType: 'url'});\n } else {\n bufferList = this._config.ambisonicOrder === 2\n ? new BufferList(this._context, SOAHrirBase64)\n : new BufferList(this._context, TOAHrirBase64);\n }\n\n bufferList.load().then(\n function(hrirBufferList) {\n this._hoaConvolver.setHRIRBufferList(hrirBufferList);\n this.setRenderingMode(this._config.renderingMode);\n this._isRendererReady = true;\n Utils.log('HOARenderer: HRIRs loaded successfully. Ready.');\n resolve();\n }.bind(this),\n function() {\n const errorMessage = 'HOARenderer: HRIR loading/decoding failed.';\n reject(errorMessage);\n Utils.throw(errorMessage);\n });\n};\n\n\n/**\n * Initializes and loads the resource for the renderer.\n * @return {Promise}\n */\nHOARenderer.prototype.initialize = function() {\n Utils.log(\n 'HOARenderer: Initializing... (mode: ' + this._config.renderingMode +\n ', ambisonic order: ' + this._config.ambisonicOrder + ')');\n\n return new Promise(this._initializeCallback.bind(this));\n};\n\n\n/**\n * Updates the rotation matrix with 3x3 matrix.\n * @param {Number[]} rotationMatrix3 - A 3x3 rotation matrix. (column-major)\n */\nHOARenderer.prototype.setRotationMatrix3 = function(rotationMatrix3) {\n if (!this._isRendererReady) {\n return;\n }\n\n this._hoaRotator.setRotationMatrix3(rotationMatrix3);\n};\n\n\n/**\n * Updates the rotation matrix with 4x4 matrix.\n * @param {Number[]} rotationMatrix4 - A 4x4 rotation matrix. (column-major)\n */\nHOARenderer.prototype.setRotationMatrix4 = function(rotationMatrix4) {\n if (!this._isRendererReady) {\n return;\n }\n\n this._hoaRotator.setRotationMatrix4(rotationMatrix4);\n};\n\n\n/**\n * Set the decoding mode.\n * @param {RenderingMode} mode - Decoding mode.\n * - 'ambisonic': activates the ambisonic decoding/binaurl rendering.\n * - 'bypass': bypasses the input stream directly to the output. No ambisonic\n * decoding or encoding.\n * - 'off': all the processing off saving the CPU power.\n */\nHOARenderer.prototype.setRenderingMode = function(mode) {\n if (mode === this._config.renderingMode) {\n return;\n }\n\n switch (mode) {\n case RenderingMode.AMBISONIC:\n this._hoaConvolver.enable();\n this._bypass.disconnect();\n break;\n case RenderingMode.BYPASS:\n this._hoaConvolver.disable();\n this._bypass.connect(this.output);\n break;\n case RenderingMode.OFF:\n this._hoaConvolver.disable();\n this._bypass.disconnect();\n break;\n default:\n Utils.log(\n 'HOARenderer: Rendering mode \"' + mode + '\" is not ' +\n 'supported.');\n return;\n }\n\n this._config.renderingMode = mode;\n Utils.log('HOARenderer: Rendering mode changed. (' + mode + ')');\n};\n\n\nmodule.exports = HOARenderer;\n\n\n//# sourceURL=webpack:///./src/hoa-renderer.js?"); + }, + "./src/hoa-rotator.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Sound field rotator for higher-order-ambisonics decoding.\n */\n\n\n\n\n/**\n * Kronecker Delta function.\n * @param {Number} i\n * @param {Number} j\n * @return {Number}\n */\nfunction getKroneckerDelta(i, j) {\n return i === j ? 1 : 0;\n}\n\n\n/**\n * A helper function to allow us to access a matrix array in the same\n * manner, assuming it is a (2l+1)x(2l+1) matrix. [2] uses an odd convention of\n * referring to the rows and columns using centered indices, so the middle row\n * and column are (0, 0) and the upper left would have negative coordinates.\n * @param {Number[]} matrix - N matrices of gainNodes, each with (2n+1) x (2n+1)\n * elements, where n=1,2,...,N.\n * @param {Number} l\n * @param {Number} i\n * @param {Number} j\n * @param {Number} gainValue\n */\nfunction setCenteredElement(matrix, l, i, j, gainValue) {\n const index = (j + l) * (2 * l + 1) + (i + l);\n // Row-wise indexing.\n matrix[l - 1][index].gain.value = gainValue;\n}\n\n\n/**\n * This is a helper function to allow us to access a matrix array in the same\n * manner, assuming it is a (2l+1) x (2l+1) matrix.\n * @param {Number[]} matrix - N matrices of gainNodes, each with (2n+1) x (2n+1)\n * elements, where n=1,2,...,N.\n * @param {Number} l\n * @param {Number} i\n * @param {Number} j\n * @return {Number}\n */\nfunction getCenteredElement(matrix, l, i, j) {\n // Row-wise indexing.\n const index = (j + l) * (2 * l + 1) + (i + l);\n return matrix[l - 1][index].gain.value;\n}\n\n\n/**\n * Helper function defined in [2] that is used by the functions U, V, W.\n * This should not be called on its own, as U, V, and W (and their coefficients)\n * select the appropriate matrix elements to access arguments |a| and |b|.\n * @param {Number[]} matrix - N matrices of gainNodes, each with (2n+1) x (2n+1)\n * elements, where n=1,2,...,N.\n * @param {Number} i\n * @param {Number} a\n * @param {Number} b\n * @param {Number} l\n * @return {Number}\n */\nfunction getP(matrix, i, a, b, l) {\n if (b === l) {\n return getCenteredElement(matrix, 1, i, 1) *\n getCenteredElement(matrix, l - 1, a, l - 1) -\n getCenteredElement(matrix, 1, i, -1) *\n getCenteredElement(matrix, l - 1, a, -l + 1);\n } else if (b === -l) {\n return getCenteredElement(matrix, 1, i, 1) *\n getCenteredElement(matrix, l - 1, a, -l + 1) +\n getCenteredElement(matrix, 1, i, -1) *\n getCenteredElement(matrix, l - 1, a, l - 1);\n } else {\n return getCenteredElement(matrix, 1, i, 0) *\n getCenteredElement(matrix, l - 1, a, b);\n }\n}\n\n\n/**\n * The functions U, V, and W should only be called if the correspondingly\n * named coefficient u, v, w from the function ComputeUVWCoeff() is non-zero.\n * When the coefficient is 0, these would attempt to access matrix elements that\n * are out of bounds. The vector of rotations, |r|, must have the |l - 1|\n * previously completed band rotations. These functions are valid for |l >= 2|.\n * @param {Number[]} matrix - N matrices of gainNodes, each with (2n+1) x (2n+1)\n * elements, where n=1,2,...,N.\n * @param {Number} m\n * @param {Number} n\n * @param {Number} l\n * @return {Number}\n */\nfunction getU(matrix, m, n, l) {\n // Although [1, 2] split U into three cases for m == 0, m < 0, m > 0\n // the actual values are the same for all three cases.\n return getP(matrix, 0, m, n, l);\n}\n\n\n/**\n * The functions U, V, and W should only be called if the correspondingly\n * named coefficient u, v, w from the function ComputeUVWCoeff() is non-zero.\n * When the coefficient is 0, these would attempt to access matrix elements that\n * are out of bounds. The vector of rotations, |r|, must have the |l - 1|\n * previously completed band rotations. These functions are valid for |l >= 2|.\n * @param {Number[]} matrix - N matrices of gainNodes, each with (2n+1) x (2n+1)\n * elements, where n=1,2,...,N.\n * @param {Number} m\n * @param {Number} n\n * @param {Number} l\n * @return {Number}\n */\nfunction getV(matrix, m, n, l) {\n if (m === 0) {\n return getP(matrix, 1, 1, n, l) + getP(matrix, -1, -1, n, l);\n } else if (m > 0) {\n const d = getKroneckerDelta(m, 1);\n return getP(matrix, 1, m - 1, n, l) * Math.sqrt(1 + d) -\n getP(matrix, -1, -m + 1, n, l) * (1 - d);\n } else {\n // Note there is apparent errata in [1,2,2b] dealing with this particular\n // case. [2b] writes it should be P*(1-d)+P*(1-d)^0.5\n // [1] writes it as P*(1+d)+P*(1-d)^0.5, but going through the math by hand,\n // you must have it as P*(1-d)+P*(1+d)^0.5 to form a 2^.5 term, which\n // parallels the case where m > 0.\n const d = getKroneckerDelta(m, -1);\n return getP(matrix, 1, m + 1, n, l) * (1 - d) +\n getP(matrix, -1, -m - 1, n, l) * Math.sqrt(1 + d);\n }\n}\n\n\n/**\n * The functions U, V, and W should only be called if the correspondingly\n * named coefficient u, v, w from the function ComputeUVWCoeff() is non-zero.\n * When the coefficient is 0, these would attempt to access matrix elements that\n * are out of bounds. The vector of rotations, |r|, must have the |l - 1|\n * previously completed band rotations. These functions are valid for |l >= 2|.\n * @param {Number[]} matrix N matrices of gainNodes, each with (2n+1) x (2n+1)\n * elements, where n=1,2,...,N.\n * @param {Number} m\n * @param {Number} n\n * @param {Number} l\n * @return {Number}\n */\nfunction getW(matrix, m, n, l) {\n // Whenever this happens, w is also 0 so W can be anything.\n if (m === 0) {\n return 0;\n }\n\n return m > 0 ? getP(matrix, 1, m + 1, n, l) + getP(matrix, -1, -m - 1, n, l) :\n getP(matrix, 1, m - 1, n, l) - getP(matrix, -1, -m + 1, n, l);\n}\n\n\n/**\n * Calculates the coefficients applied to the U, V, and W functions. Because\n * their equations share many common terms they are computed simultaneously.\n * @param {Number} m\n * @param {Number} n\n * @param {Number} l\n * @return {Array} 3 coefficients for U, V and W functions.\n */\nfunction computeUVWCoeff(m, n, l) {\n const d = getKroneckerDelta(m, 0);\n const reciprocalDenominator =\n Math.abs(n) === l ? 1 / (2 * l * (2 * l - 1)) : 1 / ((l + n) * (l - n));\n\n return [\n Math.sqrt((l + m) * (l - m) * reciprocalDenominator),\n 0.5 * (1 - 2 * d) * Math.sqrt((1 + d) *\n (l + Math.abs(m) - 1) *\n (l + Math.abs(m)) *\n reciprocalDenominator),\n -0.5 * (1 - d) * Math.sqrt((l - Math.abs(m) - 1) * (l - Math.abs(m))) *\n reciprocalDenominator,\n ];\n}\n\n\n/**\n * Calculates the (2l+1) x (2l+1) rotation matrix for the band l.\n * This uses the matrices computed for band 1 and band l-1 to compute the\n * matrix for band l. |rotations| must contain the previously computed l-1\n * rotation matrices.\n * This implementation comes from p. 5 (6346), Table 1 and 2 in [2] taking\n * into account the corrections from [2b].\n * @param {Number[]} matrix - N matrices of gainNodes, each with where\n * n=1,2,...,N.\n * @param {Number} l\n */\nfunction computeBandRotation(matrix, l) {\n // The lth band rotation matrix has rows and columns equal to the number of\n // coefficients within that band (-l <= m <= l implies 2l + 1 coefficients).\n for (let m = -l; m <= l; m++) {\n for (let n = -l; n <= l; n++) {\n const uvwCoefficients = computeUVWCoeff(m, n, l);\n\n // The functions U, V, W are only safe to call if the coefficients\n // u, v, w are not zero.\n if (Math.abs(uvwCoefficients[0]) > 0) {\n uvwCoefficients[0] *= getU(matrix, m, n, l);\n }\n if (Math.abs(uvwCoefficients[1]) > 0) {\n uvwCoefficients[1] *= getV(matrix, m, n, l);\n }\n if (Math.abs(uvwCoefficients[2]) > 0) {\n uvwCoefficients[2] *= getW(matrix, m, n, l);\n }\n\n setCenteredElement(\n matrix, l, m, n,\n uvwCoefficients[0] + uvwCoefficients[1] + uvwCoefficients[2]);\n }\n }\n}\n\n\n/**\n * Compute the HOA rotation matrix after setting the transform matrix.\n * @param {Array} matrix - N matrices of gainNodes, each with (2n+1) x (2n+1)\n * elements, where n=1,2,...,N.\n */\nfunction computeHOAMatrices(matrix) {\n // We start by computing the 2nd-order matrix from the 1st-order matrix.\n for (let i = 2; i <= matrix.length; i++) {\n computeBandRotation(matrix, i);\n }\n}\n\n\n/**\n * Higher-order-ambisonic decoder based on gain node network. We expect\n * the order of the channels to conform to ACN ordering. Below are the helper\n * methods to compute SH rotation using recursion. The code uses maths described\n * in the following papers:\n * [1] R. Green, "Spherical Harmonic Lighting: The Gritty Details", GDC 2003,\n * http://www.research.scea.com/gdc2003/spherical-harmonic-lighting.pdf\n * [2] J. Ivanic and K. Ruedenberg, "Rotation Matrices for Real\n * Spherical Harmonics. Direct Determination by Recursion", J. Phys.\n * Chem., vol. 100, no. 15, pp. 6342-6347, 1996.\n * http://pubs.acs.org/doi/pdf/10.1021/jp953350u\n * [2b] Corrections to initial publication:\n * http://pubs.acs.org/doi/pdf/10.1021/jp9833350\n * @constructor\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Number} ambisonicOrder - Ambisonic order.\n */\nfunction HOARotator(context, ambisonicOrder) {\n this._context = context;\n this._ambisonicOrder = ambisonicOrder;\n\n // We need to determine the number of channels K based on the ambisonic order\n // N where K = (N + 1)^2.\n const numberOfChannels = (ambisonicOrder + 1) * (ambisonicOrder + 1);\n\n this._splitter = this._context.createChannelSplitter(numberOfChannels);\n this._merger = this._context.createChannelMerger(numberOfChannels);\n\n // Create a set of per-order rotation matrices using gain nodes.\n this._gainNodeMatrix = [];\n let orderOffset;\n let rows;\n let inputIndex;\n let outputIndex;\n let matrixIndex;\n for (let i = 1; i <= ambisonicOrder; i++) {\n // Each ambisonic order requires a separate (2l + 1) x (2l + 1) rotation\n // matrix. We compute the offset value as the first channel index of the\n // current order where\n // k_last = l^2 + l + m,\n // and m = -l\n // k_last = l^2\n orderOffset = i * i;\n\n // Uses row-major indexing.\n rows = (2 * i + 1);\n\n this._gainNodeMatrix[i - 1] = [];\n for (let j = 0; j < rows; j++) {\n inputIndex = orderOffset + j;\n for (let k = 0; k < rows; k++) {\n outputIndex = orderOffset + k;\n matrixIndex = j * rows + k;\n this._gainNodeMatrix[i - 1][matrixIndex] = this._context.createGain();\n this._splitter.connect(\n this._gainNodeMatrix[i - 1][matrixIndex], inputIndex);\n this._gainNodeMatrix[i - 1][matrixIndex].connect(\n this._merger, 0, outputIndex);\n }\n }\n }\n\n // W-channel is not involved in rotation, skip straight to ouput.\n this._splitter.connect(this._merger, 0, 0);\n\n // Default Identity matrix.\n this.setRotationMatrix3(new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]));\n\n // Input/Output proxy.\n this.input = this._splitter;\n this.output = this._merger;\n}\n\n\n/**\n * Updates the rotation matrix with 3x3 matrix.\n * @param {Number[]} rotationMatrix3 - A 3x3 rotation matrix. (column-major)\n */\nHOARotator.prototype.setRotationMatrix3 = function(rotationMatrix3) {\n this._gainNodeMatrix[0][0].gain.value = -rotationMatrix3[0];\n this._gainNodeMatrix[0][1].gain.value = rotationMatrix3[1];\n this._gainNodeMatrix[0][2].gain.value = -rotationMatrix3[2];\n this._gainNodeMatrix[0][3].gain.value = -rotationMatrix3[3];\n this._gainNodeMatrix[0][4].gain.value = rotationMatrix3[4];\n this._gainNodeMatrix[0][5].gain.value = -rotationMatrix3[5];\n this._gainNodeMatrix[0][6].gain.value = -rotationMatrix3[6];\n this._gainNodeMatrix[0][7].gain.value = rotationMatrix3[7];\n this._gainNodeMatrix[0][8].gain.value = -rotationMatrix3[8];\n computeHOAMatrices(this._gainNodeMatrix);\n};\n\n\n/**\n * Updates the rotation matrix with 4x4 matrix.\n * @param {Number[]} rotationMatrix4 - A 4x4 rotation matrix. (column-major)\n */\nHOARotator.prototype.setRotationMatrix4 = function(rotationMatrix4) {\n this._gainNodeMatrix[0][0].gain.value = -rotationMatrix4[0];\n this._gainNodeMatrix[0][1].gain.value = rotationMatrix4[1];\n this._gainNodeMatrix[0][2].gain.value = -rotationMatrix4[2];\n this._gainNodeMatrix[0][3].gain.value = -rotationMatrix4[4];\n this._gainNodeMatrix[0][4].gain.value = rotationMatrix4[5];\n this._gainNodeMatrix[0][5].gain.value = -rotationMatrix4[6];\n this._gainNodeMatrix[0][6].gain.value = -rotationMatrix4[8];\n this._gainNodeMatrix[0][7].gain.value = rotationMatrix4[9];\n this._gainNodeMatrix[0][8].gain.value = -rotationMatrix4[10];\n computeHOAMatrices(this._gainNodeMatrix);\n};\n\n\n/**\n * Returns the current 3x3 rotation matrix.\n * @return {Number[]} - A 3x3 rotation matrix. (column-major)\n */\nHOARotator.prototype.getRotationMatrix3 = function() {\n let rotationMatrix3 = new Float32Array(9);\n rotationMatrix3[0] = -this._gainNodeMatrix[0][0].gain.value;\n rotationMatrix3[1] = this._gainNodeMatrix[0][1].gain.value;\n rotationMatrix3[2] = -this._gainNodeMatrix[0][2].gain.value;\n rotationMatrix3[4] = -this._gainNodeMatrix[0][3].gain.value;\n rotationMatrix3[5] = this._gainNodeMatrix[0][4].gain.value;\n rotationMatrix3[6] = -this._gainNodeMatrix[0][5].gain.value;\n rotationMatrix3[8] = -this._gainNodeMatrix[0][6].gain.value;\n rotationMatrix3[9] = this._gainNodeMatrix[0][7].gain.value;\n rotationMatrix3[10] = -this._gainNodeMatrix[0][8].gain.value;\n return rotationMatrix3;\n};\n\n\n/**\n * Returns the current 4x4 rotation matrix.\n * @return {Number[]} - A 4x4 rotation matrix. (column-major)\n */\nHOARotator.prototype.getRotationMatrix4 = function() {\n let rotationMatrix4 = new Float32Array(16);\n rotationMatrix4[0] = -this._gainNodeMatrix[0][0].gain.value;\n rotationMatrix4[1] = this._gainNodeMatrix[0][1].gain.value;\n rotationMatrix4[2] = -this._gainNodeMatrix[0][2].gain.value;\n rotationMatrix4[4] = -this._gainNodeMatrix[0][3].gain.value;\n rotationMatrix4[5] = this._gainNodeMatrix[0][4].gain.value;\n rotationMatrix4[6] = -this._gainNodeMatrix[0][5].gain.value;\n rotationMatrix4[8] = -this._gainNodeMatrix[0][6].gain.value;\n rotationMatrix4[9] = this._gainNodeMatrix[0][7].gain.value;\n rotationMatrix4[10] = -this._gainNodeMatrix[0][8].gain.value;\n return rotationMatrix4;\n};\n\n\n/**\n * Get the current ambisonic order.\n * @return {Number}\n */\nHOARotator.prototype.getAmbisonicOrder = function() {\n return this._ambisonicOrder;\n};\n\n\nmodule.exports = HOARotator;\n\n\n//# sourceURL=webpack:///./src/hoa-rotator.js?'); + }, + "./src/main.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Namespace for Omnitone library.\n */\n\n\n\n\nexports.Omnitone = __webpack_require__(/*! ./omnitone.js */ "./src/omnitone.js");\n\n\n//# sourceURL=webpack:///./src/main.js?'); + }, + "./src/omnitone.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Omnitone library name space and user-facing APIs.\n */\n\n\n\n\nconst BufferList = __webpack_require__(/*! ./buffer-list.js */ "./src/buffer-list.js");\nconst FOAConvolver = __webpack_require__(/*! ./foa-convolver.js */ "./src/foa-convolver.js");\nconst FOARenderer = __webpack_require__(/*! ./foa-renderer.js */ "./src/foa-renderer.js");\nconst FOARotator = __webpack_require__(/*! ./foa-rotator.js */ "./src/foa-rotator.js");\nconst FOARouter = __webpack_require__(/*! ./foa-router.js */ "./src/foa-router.js");\nconst HOAConvolver = __webpack_require__(/*! ./hoa-convolver.js */ "./src/hoa-convolver.js");\nconst HOARenderer = __webpack_require__(/*! ./hoa-renderer.js */ "./src/hoa-renderer.js");\nconst HOARotator = __webpack_require__(/*! ./hoa-rotator.js */ "./src/hoa-rotator.js");\nconst Polyfill = __webpack_require__(/*! ./polyfill.js */ "./src/polyfill.js");\nconst Utils = __webpack_require__(/*! ./utils.js */ "./src/utils.js");\nconst Version = __webpack_require__(/*! ./version.js */ "./src/version.js");\n\n\n/**\n * Omnitone namespace.\n * @namespace\n */\nlet Omnitone = {};\n\n\n/**\n * @typedef {Object} BrowserInfo\n * @property {string} name - Browser name.\n * @property {string} version - Browser version.\n */\n\n/**\n * An object contains the detected browser name and version.\n * @memberOf Omnitone\n * @static {BrowserInfo}\n */\nOmnitone.browserInfo = Polyfill.getBrowserInfo();\n\n\n/**\n * Performs the async loading/decoding of multiple AudioBuffers from multiple\n * URLs.\n * @param {BaseAudioContext} context - Associated BaseAudioContext.\n * @param {string[]} bufferData - An ordered list of URLs.\n * @param {Object} [options] - BufferList options.\n * @param {String} [options.dataType=\'url\'] - BufferList data type.\n * @return {Promise} - The promise resolves with an array of\n * AudioBuffer.\n */\nOmnitone.createBufferList = function(context, bufferData, options) {\n const bufferList =\n new BufferList(context, bufferData, options || {dataType: \'url\'});\n return bufferList.load();\n};\n\n\n/**\n * Perform channel-wise merge on multiple AudioBuffers. The sample rate and\n * the length of buffers to be merged must be identical.\n * @static\n * @function\n * @param {BaseAudioContext} context - Associated BaseAudioContext.\n * @param {AudioBuffer[]} bufferList - An array of AudioBuffers to be merged\n * channel-wise.\n * @return {AudioBuffer} - A single merged AudioBuffer.\n */\nOmnitone.mergeBufferListByChannel = Utils.mergeBufferListByChannel;\n\n\n/**\n * Perform channel-wise split by the given channel count. For example,\n * 1 x AudioBuffer(8) -> splitBuffer(context, buffer, 2) -> 4 x AudioBuffer(2).\n * @static\n * @function\n * @param {BaseAudioContext} context - Associated BaseAudioContext.\n * @param {AudioBuffer} audioBuffer - An AudioBuffer to be splitted.\n * @param {Number} splitBy - Number of channels to be splitted.\n * @return {AudioBuffer[]} - An array of splitted AudioBuffers.\n */\nOmnitone.splitBufferbyChannel = Utils.splitBufferbyChannel;\n\n\n/**\n * Creates an instance of FOA Convolver.\n * @see FOAConvolver\n * @param {BaseAudioContext} context The associated AudioContext.\n * @param {AudioBuffer[]} [hrirBufferList] - An ordered-list of stereo\n * @return {FOAConvolver}\n */\nOmnitone.createFOAConvolver = function(context, hrirBufferList) {\n return new FOAConvolver(context, hrirBufferList);\n};\n\n\n/**\n * Create an instance of FOA Router.\n * @see FOARouter\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Number[]} channelMap - Routing destination array.\n * @return {FOARouter}\n */\nOmnitone.createFOARouter = function(context, channelMap) {\n return new FOARouter(context, channelMap);\n};\n\n\n/**\n * Create an instance of FOA Rotator.\n * @see FOARotator\n * @param {AudioContext} context - Associated AudioContext.\n * @return {FOARotator}\n */\nOmnitone.createFOARotator = function(context) {\n return new FOARotator(context);\n};\n\n\n/**\n * Creates HOARotator for higher-order ambisonics rotation.\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Number} ambisonicOrder - Ambisonic order.\n * @return {HOARotator}\n */\nOmnitone.createHOARotator = function(context, ambisonicOrder) {\n return new HOARotator(context, ambisonicOrder);\n};\n\n\n/**\n * Creates HOAConvolver performs the multi-channel convolution for the optmized\n * binaural rendering.\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Number} ambisonicOrder - Ambisonic order. (2 or 3)\n * @param {AudioBuffer[]} [hrirBufferList] - An ordered-list of stereo\n * AudioBuffers for convolution. (SOA: 5 AudioBuffers, TOA: 8 AudioBuffers)\n * @return {HOAConvovler}\n */\nOmnitone.createHOAConvolver = function(\n context, ambisonicOrder, hrirBufferList) {\n return new HOAConvolver(context, ambisonicOrder, hrirBufferList);\n};\n\n\n/**\n * Create a FOARenderer, the first-order ambisonic decoder and the optimized\n * binaural renderer.\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Object} config\n * @param {Array} [config.channelMap] - Custom channel routing map. Useful for\n * handling the inconsistency in browser\'s multichannel audio decoding.\n * @param {Array} [config.hrirPathList] - A list of paths to HRIR files. It\n * overrides the internal HRIR list if given.\n * @param {RenderingMode} [config.renderingMode=\'ambisonic\'] - Rendering mode.\n * @return {FOARenderer}\n */\nOmnitone.createFOARenderer = function(context, config) {\n return new FOARenderer(context, config);\n};\n\n\n/**\n * Creates HOARenderer for higher-order ambisonic decoding and the optimized\n * binaural rendering.\n * @param {AudioContext} context - Associated AudioContext.\n * @param {Object} config\n * @param {Number} [config.ambisonicOrder=3] - Ambisonic order.\n * @param {Array} [config.hrirPathList] - A list of paths to HRIR files. It\n * overrides the internal HRIR list if given.\n * @param {RenderingMode} [config.renderingMode=\'ambisonic\'] - Rendering mode.\n * @return {HOARenderer}\n */\nOmnitone.createHOARenderer = function(context, config) {\n return new HOARenderer(context, config);\n};\n\n\n// Handle Pre-load Tasks: detects the browser information and prints out the\n// version number. If the browser is Safari, patch prefixed interfaces.\n(function() {\n Utils.log(\'Version \' + Version + \' (running \' +\n Omnitone.browserInfo.name + \' \' + Omnitone.browserInfo.version +\n \' on \' + Omnitone.browserInfo.platform +\')\');\n if (Omnitone.browserInfo.name.toLowerCase() === \'safari\') {\n Polyfill.patchSafari();\n Utils.log(Omnitone.browserInfo.name + \' detected. Polyfill applied.\');\n }\n})();\n\n\nmodule.exports = Omnitone;\n\n\n//# sourceURL=webpack:///./src/omnitone.js?'); + }, + "./src/polyfill.js": function(module, exports, __webpack_require__) { + "use strict"; + eval("/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Cross-browser support polyfill for Omnitone library.\n */\n\n\n\n\n/**\n * Detects browser type and version.\n * @return {string[]} - An array contains the detected browser name and version.\n */\nexports.getBrowserInfo = function() {\n const ua = navigator.userAgent;\n let M = ua.match(\n /(opera|chrome|safari|firefox|msie|trident(?=\\/))\\/?\\s*([\\d\\.]+)/i) ||\n [];\n let tem;\n\n if (/trident/i.test(M[1])) {\n tem = /\\brv[ :]+(\\d+)/g.exec(ua) || [];\n return {name: 'IE', version: (tem[1] || '')};\n }\n\n if (M[1] === 'Chrome') {\n tem = ua.match(/\\bOPR|Edge\\/(\\d+)/);\n if (tem != null) {\n return {name: 'Opera', version: tem[1]};\n }\n }\n\n M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];\n if ((tem = ua.match(/version\\/([\\d.]+)/i)) != null) {\n M.splice(1, 1, tem[1]);\n }\n\n let platform = ua.match(/android|ipad|iphone/i);\n if (!platform) {\n platform = ua.match(/cros|linux|mac os x|windows/i);\n }\n\n return {\n name: M[0],\n version: M[1],\n platform: platform ? platform[0] : 'unknown',\n };\n};\n\n\n/**\n * Patches AudioContext if the prefixed API is found.\n */\nexports.patchSafari = function() {\n if (window.webkitAudioContext && window.webkitOfflineAudioContext) {\n window.AudioContext = window.webkitAudioContext;\n window.OfflineAudioContext = window.webkitOfflineAudioContext;\n }\n};\n\n\n//# sourceURL=webpack:///./src/polyfill.js?"); + }, + "./src/resources/omnitone-foa-hrir-base64.js": function(module, exports) { + eval('const OmnitoneFOAHrirBase64 = [\n"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",\n];\n\nmodule.exports = OmnitoneFOAHrirBase64;\n\n\n//# sourceURL=webpack:///./src/resources/omnitone-foa-hrir-base64.js?'); + }, + "./src/resources/omnitone-soa-hrir-base64.js": function(module, exports) { + eval('const OmnitoneSOAHrirBase64 = [\n"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/P////v//P8CAAQA+//+//3//f8CAAUA+v/9//////8AAAQA+v/8////AAD//wIA+//8/wAAAQD+/wEA+//8/wAAAgD9/////P/9/wEAAgD8//7//f/9/wAAAgD8//3//v/+////AQD8//z/////////AAD8//3///8AAP7/AAD9//7///8AAP7////+//////8AAP7////+////////////////////",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD//////v8AAP///////wAAAAAAAP7/AQABAAAABwD///X/BQAjAPL/CQDb/9D/GAAb/7sAYwCW/z0BcP/X/7T/2QDW+wH8yANCCCUJ5QT++UXmhPwhA78FuAxH+p78ifudBlAG9vmu/lAK2fdlB///cfjoCa0E7Akn9Yb/zvba+AkAHPywBGEBFwUNAL8AXAAGA20DFvmR/kz+F/06Ag/+GwHl/5EEKgJd/q0AP/ym/9n6EfxY/2H+/QFtAC4C6QBDAaMCo/20/+3/3f/p/fL9rv9V/6cBhQHuAX4AcwJYAaH/IP/P/gsApP0LAe7/sQBuAI0AAgGDAE4BzACe/5X//v+v/+f+Zf+gAOv/5QBhAOIApAANASYAuP+h/8b/HQBr/9//bACWAGEAFAB5AD0AWQDU/+D/Yf/p//D/s/+R/4QAMQBvABEAkQBfABQAJgDW/wwA8/8XALz/vf8zAFAAKwD1/zEAPwDJ/x0A7/8LAOX/FwDR//H/EQAdAO//6P8QAFEA2f8WABEAMgDy/xIA+f/s/xAALgDv////HQAvAPT/+f8iAAYAEgAFABoAGgD//w0A+f/0/xsAHgDx/9f/GAACAPH/8f8JAPf/GwALABEA7/8cAPT/CgD2//j/BQD8/+3/OgAgAAYA9f8PAN7/DgD9/9r/1//3/+3/9//1//b/8//5//f/AgAJAOf/+v8OAAMACwD9/+7/5f8eAAEA9//q//7/8P8WAP7/+//4/wIA+f8TAAIA9f/5/wcA+P8iAAgA9v/n/xoA//8gAAUABwDj/wAA9v8BAAUAFQDn/wMA7v8QABAAEQDm/wwA8f8aAAAABwDu/wcACgASAAEA7//w//f/BgARAAkA6P/3/wcADgAKAAYA4f/4/wYADgAAAPr/8P/9/xQACgAHAPn/7//9/xEAAgD+//L/8v/8/xUAAwDw//H/9f8CAAsA/v/q//L/+f8FAAYA/P/r//j///8GAAkA+//o//j/AQAIAP//+v/o//v/CAAIAPv/+P/w/wEACQAHAPj/+f/0/wIACwAFAPb/+f/4/wQACwACAPP/+f/+/wYACAD///L/+/8BAAYABQD9//P//P8FAAUAAgD7//T//f8HAAQA///7//f///8IAAMA/P/6//r/AQAIAAEA+v/6//3/AgAHAAAA+f/7/wAAAwAFAP7/+P/8/wIAAgACAP3/+f/9/wMAAwAAAPz/+v/+/wQAAgD+//z/+/8AAAQAAQD8//z//f8BAAQAAAD7//3///8BAAMA///7//3/AAACAAEA/v/7//7/AQABAAAA/v/9////AQAAAP///v/+////AAD/////////////////////////////",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD////////+//////8AAAAA/v/+/wAAAQD8//3/CQAJAP3/+v8PAAcApABlABkBkwCO/i//lfqa/HQAcf/3BdkCzwJcBCMC0wMN/9/9wgI7AaECYfxV/Tf83vhn/xrt8Owx/8n7cgHABYb43QcZDh4WugNrA7P74gHu/9z/zv0t/acCiQHY/iv4qQOl/ysCE/0//XT9Sf4O//j9xfupAn394gHO+rsCXAFIAxQC9wIXBgcD2AQuAnb/9gJh/6wAVfxEAI4Bvf7oAFv/bALsAMQBe/88/joAT/4dAH39/v9LAXn/gwDI//QBdABcAA0A7f4lAMn///+9/tv/iABp/13/pP/dALv/w/8MAHv//f+y/6////7U/5AAZP+Z/8r/nQDR/5r/DwDr/xAA4v+s/3z/+P9uAOv/t/82AGcAHgCb/yQAFQBGAM7/CgD3/xoAegAaAOz/CgBHAA8Adv8/AAAABQC2/xIAAAA7ABQAKgCj/z4AAQAXAJz/JAADAAcA8f/1/2AAAQAlAPD/NgDx/1wA7v/4/wMAZADv//3/HQAkAFoA8P9FAPv/FgBIAPf/WQAHAEUACQD0/xIAQwDu/wMAwP9VALn/XwCw/yEA5f8sAPj/FgDD/1YAyv8rAOX/HQDo//j/IQAQACAAHwD9/yQAHQBAABgABQAiAAUAKAD3/wkACwAKAAMABwAJAPb/+f8GAOr/JQAHABMA6P8TAA4AGgD//woA8/8ZAP//GADu/w0A9v8SAAMABwD4/wQA5P8XAAQACgDq/wUA+/8VAAcACADs/xIAAAATAPH/+v/1//T/7f///+z/+v/y/+//9/8KAAcACgAJAPT/BAAKAAAABgAIAPL/9v8KAAMABAACAPr/9v8OAAIA+P/x//v/+f8MAPb/+P/w/wQA9f8MAPn////7/woA/v8PAAEAAgD1/xAAAQAPAP//AwD//xQABwALAAAABgADABAAAgAHAAAACAABAA8ABQAFAAMABwAEAA4ABwADAAEACQAFAAoAAwD//wAACQADAAUAAQD/////CAABAAMAAAD/////BwACAAEAAAD/////BwACAP7///8BAAAABgABAP7///8CAAAABAAAAP7///8DAAAAAwAAAP3///8DAAAAAQAAAP3//v8EAAAAAAD+//////8EAP/////+/wAA/v8EAP/////+/wEA/v8EAP///v/+/wIA//8DAP///v/+/wIA//8BAP///v/+/wMA//8BAP/////+/wMA//8AAP//AAD+/wQA//8AAP7/AQD//wIA////////AQD//wIA////////AQAAAAEAAAAAAP//AQD//wEAAAAAAP//AQAAAAEAAAAAAAAA",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+/wAA+v8AAPz/AAD//wAA/f8AAAEAAAD+/wAACQAAAAQAAAAZAAAAtgAAAFsBAABW/gAAH/oAAGcBAABoBwAAlAAAAO3/AAARAQAA+wIAAEoEAACe/gAAiv4AALD0AADJ8wAAkQQAAF34AABi8QAAPQAAAAH2AAD19AAADAMAAJwGAACTEAAA0AwAAJkHAACOBwAAuQEAANcDAAC6AgAAHwUAAHEFAAB0AwAAbgEAADz+AADYAQAAGAAAAJwCAADgAAAA//0AAMn+AAAT/AAAwP8AAOn9AAAJAAAAewEAAOn+AACN/wAAOv0AAO3+AADN/gAAcP8AACj/AACq/gAA+f4AAML9AACa/wAA/f4AAN7/AABo/wAA6/4AAE//AAAC/wAAEQAAAHX/AAB0AAAA5f8AAEwAAAB3AAAA5/8AAMIAAABCAAAAzgAAAE8AAAB3AAAAKAAAADMAAACqAAAALwAAAK4AAAASAAAAVgAAACgAAAAtAAAATAAAAP3/AAA7AAAA2/8AACQAAADw/wAALQAAADEAAAAlAAAAbAAAADMAAABUAAAAEAAAACgAAAD1/wAA9v8AAPr/AADu/wAALgAAABIAAABUAAAARAAAAGUAAABGAAAAOAAAAGAAAAAuAAAARQAAACEAAAAfAAAAAAAAAAkAAAAQAAAAAwAAABIAAADs/wAAEAAAAAYAAAASAAAAIgAAABEAAAADAAAABAAAAA8AAAD4/wAAHQAAAAsAAAAIAAAADgAAAP//AAAcAAAADwAAAAYAAAASAAAAFwAAAAMAAAAYAAAAEgAAAPr/AAAQAAAADQAAAAoAAAD3/wAABgAAAPb/AADf/wAA/v8AAPL/AAD6/wAAFAAAAAQAAAAEAAAAGwAAAAEAAAAMAAAAIAAAAAIAAAAdAAAAGAAAAAIAAAAcAAAAEgAAAAcAAAAeAAAADwAAAAQAAAAeAAAABAAAAAYAAAAZAAAAAQAAAA4AAAATAAAA/v8AAAoAAAAOAAAA+/8AAAsAAAAJAAAA+f8AAAsAAAABAAAA+f8AAAoAAAD9/wAA+v8AAAcAAAD5/wAA+v8AAAUAAAD3/wAA/f8AAAQAAAD2/wAAAAAAAAEAAAD3/wAAAgAAAAAAAAD4/wAAAwAAAP7/AAD6/wAABAAAAP3/AAD8/wAABAAAAPv/AAD+/wAAAwAAAPv/AAD//wAAAQAAAPv/AAAAAAAAAAAAAPv/AAACAAAA//8AAPz/AAACAAAA/v8AAP3/AAACAAAA/f8AAP7/AAABAAAA/f8AAP//AAABAAAA/f8AAAAAAAAAAAAA/v8AAAEAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA",\n];\n\nmodule.exports = OmnitoneSOAHrirBase64;\n\n\n//# sourceURL=webpack:///./src/resources/omnitone-soa-hrir-base64.js?'); + }, + "./src/resources/omnitone-toa-hrir-base64.js": function(module, exports) { + eval('const OmnitoneTOAHrirBase64 = [\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+/wQA8/8YAP3/CgACAAAA//8CAAYA8/8AAPH/CgDv/97/e/+y/9P+UQDwAHUBEwV7/pP8P/y09bsDwAfNBGYIFf/Y+736+fP890Hv8AGcC3T/vwYy+S70AAICA3AD4AagBw0R4w3ZEAcN8RVYAV8Q8P2z+kECHwdK/jIG0QNKAYUElf8IClj7BgjX+/f8j/l3/5f/6fkK+xz8FP0v/nj/Mf/n/FcBPfvH/1H3+gBP/Hf8cfiCAR/54QBh+UQAcvkzAWL8TP13+iD/V/73+wv9Kv+Y/hv+xPz7/UL83//a/z/9AP6R/5L+jf26/P3+rP26/tD8nP7B/Pv+WP1V/sP9gv91/3P9xP3J/nv/GP5S/sb+IP8v/9j/dv7U/pr+6v+u/Z3/sv5cAOr9Q/83/+n/zP5x/57+2//k/nwA/v01//L+SACB/sD/Ff81AJT+TgDp/ocAm/5dAFT+MgD+/pMAW/7o/yH/xQDA/kkA9P6LAL3+pAC0/iQAz/5UALD+UwAt/3UAhf4UAA//pwC+/joAz/5aAAv/fwDY/iMAIf+uAPP+ZAAc/0QAy/4xAB7/TgDs/goADP8wAEL/NwDo/ub/Uf9BAC3/+v9F/y4ARP9HAFP/EQA3/xMATP81AG3/HQAu/wgAaP9FACb/9f9B/y0AUP8rAED/CwBV/z4AW/8TAGH/BQBK/xsAfv8eAFn/AgB3/zwAff8RAGj//v+E/yAAb//0/3n/FwBz/xcAiv8PAHn/FQCJ/xgAg//x/3j/EQCa/ycAff/w/47/HwCI//X/iv/7/43/JQCM/+n/kP8AAJb/JACj//7/oP8ZAML/SwCo/w4Atv8tAMb/PACr/xcAwP9HAMP/OADF/y4A0f9IANL/NwC//zEA0f9LAMb/MAC8/y4A3f9GAMH/FQDQ/yYA2/8sAMT/AwDX/xkA3v8SAM3/9v/c/w8A4f8LAMj/8f/h/xQA2P8CAMn/8//j/xQA0v/7/9H//P/i/xEA0v/1/9L//f/j/w0A0f/x/9f//v/k/wgAz//u/9z/AwDg/wMA0P/v/9//BQDf////0v/y/+D/CADc//3/0v/2/+L/CgDa//r/1v/5/+T/CgDY//j/2f/9/+T/CADY//f/3P8AAOT/BwDY//f/4P8EAOP/BADZ//j/4v8GAOL/AwDa//r/5f8IAOH/AQDc//3/5v8JAOD//v/f////5v8IAOD//v/h/wIA5/8HAOD//f/j/wMA5/8GAOD//f/l/wYA5v8EAOD//v/m/wYA5f8CAOL////n/wYA5P8BAOH/AADl/wUA4f///+H/AQDk/wMA4f///+T/AQDm/wEA5////+r/AADt/wAA7/////P/AAD1////",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD//////v///wAAAAAAAAAAAQAAAAAA///9/wAABAD+//n/AgAJAAAA+v/+//f/DAAdAPv/+v+l/8L+jf/4/vgAdwVPAQACLQBo+Qj/Ev7o/N3/VgCbA08Bxf+L+yn9J/2HCU8FmgBvDe30Rv5h/LT09gi5CxkA5gOi8/30kwEM+4YJMf2nBmkJJAQQBLoFtvvv+m4A7PF6/R0Bif3qAuf8WARAAf4GyABG/BIAwvr4Acv8U//c/yIC8AEn/B8Daf2CAgMBAf3MAN38vgLK/UT/QwCyAPYClPyvAW/+pQAoASD+zP+R/IYC1f7C/nEBQP96AZb+1QAIAM//yQE7/tkAZ/7TAXL/w/8+AIsAtwB7/24A4v9a/z4A7v4iADb/dwCj/23/kgBOANUAIv8lAKEAxP9gAK7/BwCP/5kA7/9v/0wAzv9DAGT/3/9vAHv/6P+q/xUA7P8XAO//uv/g/2UAEgCV/wEATADM/+7/+//j/+D/9v/i//j/IgD+/xoAxf/6/z4A5/+8/9D/QwDq/+3/OQDT/zUAIgA/APP/PgAjAPD/BwAGACAADAC3//b/HAA3AN//RgDN/w8AIAACAN//GQBDACEAIwA+ACoAJQAeAPz/KgAYAPr/DgAEABYAIgAcAMT/7f8OAOL/5P/2//L/9P8GAPT/7v/8/+7/6v/t//z/AgAUAOL//P8VAAMA4/8IAPb/+P8MAAoA5v8NAAsA9v///wEAAAD9//n/9/8JAAYA7v/6/wMA+f8GAAEA7f/7/xgACAD4/w8A///3/w0A+f8BAAIA/P/5/xIA///9//r/7v/+/xYACQD///H/CwDz/wEADgAHAPP/FADn/+3/AQD5//f/AgD7/wEABwAMAAEADQD8//n/8f8OAPX/BAD+//X/+v8WAAQA+f8CAAEA7/8QAAEA/P8DAAUA9f8KAAwA9v8DAAUA+f8OAAoA9f/7/w0A+v8EAAgA8P/6/woA+//8/wkA+P/3/woA+//8/wcA9//1/woAAwD5/wcA/P/3/w0AAwD3/wEABAD2/wkABgD3/wEABQD3/wUABQD3//v/BwD3/wMABQD3//r/CQD7////BQD6//n/CQD9//3/BAD9//j/BwAAAPv/AwD///j/BwABAPn/AQABAPn/BQACAPn///8DAPr/AwADAPr//v8EAPv/AQADAPv//P8FAP3///8DAPz/+/8FAP7//f8CAP7/+/8EAP///P8BAP//+/8DAAEA+/8AAAEA+/8CAAIA+////wIA/f8AAAIA/P/+/wIA/f8AAAIA/f/9/wMA/////wEA///+/wIA/////wAAAAD+/wAAAAD/////AAD//wAA//8AAP//AAD//wAA",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD////////+//////8AAP////8AAP//AAAAAPz//f8IAAMA9////w4AAQD6/wwA8//+/y8Afv/0/2H/UP5gAbH+2QG1B2cAVAIh/l32FPyM/nACPQDV/+UEo/Q6AQwCu/oLD9kF8QJA/Uz+Wf2KCOcC+wUKBsL5aQBQ97rwOPiPAvn5CAl8AHEDkQPcAA8Bn/lIAdz7HQF1+xz9cAM4/94E4gDKAun+cgPYAYr9JgJr/bf+ivxz/MoBgv5UA8EBSgAQAJ7/UgEk/cQB7f63/sD/vf4XAhT/BQFCADYAnQGI/9EBtv3hALD/vP+c/3H/TgIN/1sBpf8yAP3/4f8qABr+1f8OAJ3/dwAGADEBnv9JAPz/IQBwAIH/jgAS/4wAsACTAOn/DQDCALn/ZQCSAAIAAwD1/9//jv9aADQA/v9EAB0AfgA8AAQACgB9APr/IAARAPT/5v9xACAABAAHAGUAt/89AC4ACgAjAMP/+v/9/xYA7f/1/+D/7P87AC0Auv8RAAcA9/8FAC8A2//y/xIAEwAaADQAJADp/zoAAgAfABIA2f/e/zUA+P/6/w4A9//A/zcA4//P//T/5f/R////EwDb/w4A8/8BABkANADh/xEA+f/0/wIAHADc//j/GwD1//f/GADs/+v/EAAAAPz/EgD3/+r/FgAMAAkAGAD9/+z/IQAQAPH/GQD3//z/CgAfAOX/AgD8//H/BAATAOv/+v///wIABAAdAOj/BQAPAAcAAQATAOz/8/8JAAkA6f8VAOv/+f8QABUA/v8OAO3/+P8KABUA9f8FAPv/5/8TAA0A7f8XAAkAAQAJABYA4/8WAAcACgANABEA7v8EAP7/AAD+/wMA9//7/xAAAQD8/wQA+f/7/wMABgDq/wAA+v/3/wYACQD1//3/BAD9/wgADgDw//r/AgD6/wEACADv//j/BQD///X/BwDu//j/AgACAPP/BAD2//n/BAAGAPb/BAD8//3/BQAJAPL/AwD+//3/BAAIAPP//f8DAPz/AAAGAPP/+/8CAP7//f8FAPX/+f8DAAAA/P8EAPf/+v8GAAMA+/8EAPv/+/8GAAQA+v8CAP///P8EAAUA+f8AAP///f8CAAUA+P///wEA/v8BAAUA+f/+/wIAAAD//wUA+v/9/wMAAQD9/wQA+//9/wMAAgD8/wMA/P/9/wMAAwD7/wEA/v/+/wIAAwD6/wEA///+/wAABAD6/wAAAQD//wAAAwD7////AQAAAP//AwD8//7/AgABAP3/AgD9//7/AQABAP3/AQD+//7/AAACAPz/AAD+//////8BAP3/AAD//wAA//8BAP7/AAD//wAA/v8AAP7/AAD//wAA//8AAP//",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD//////P/9//3//////wAAAAAAAAIAAgACAP//CAAEAEEA//+cAAUAb/8HAAH9+P9eARkAogQUAJn8BwCd/gX/+QQNAKoC9gFdAtb/b/vd/936TP/6AsD/nfqn/un1W/0dA8IEsQLvAJv2bP72+WMAkP8dAcX+nQO2AIr6bP/EABX+NgK/Bdj2IQv2AE4EUAiD/xQAnwIm/B0B/wGNAoH7sQaP/b8CiQakAqD+R/9xA477KQL//6r75v/O/pcCgQCtAiMCBQAkANAARwHf//39hgBl/kUAJgEtAUEATgA/AgoASADK/zUAJv29/vL+l/9c/0cAUwBBAE8A6QE5/87/Wv9NAOf+5v7P/5P/4/9BAKYAQwDD/zYB5v+r/zYATwAp/1v/WQAEAB0AhwA0AA0AIAA3AAEAzv/u/+//5v9m/zwAIADQ/8T/SABiANb/SwAbAFf/MQDX/7L/hP8TAPr/AgAMAAsAHwAZAI3/VgDC/9v/5//x/6P/AwBlAMv/yf82AB4A+P9WAPj/NwDi/1EA0v9JANj/JwAcAAEADABYANj/4f8MAEwAmP82AN//3P8UADYA7//6/wIACADU/ygAyv82AN7/9v/2/ygAxv/9/+3/5//n/zUA6//g/y4ADgD5/wsABwDv/xIADwAGACoAJQD3/zIA+/8FABsAFgDO/zAAHAAIABQALADp/xcACAAAAPH/GADs/wkACQAFAAgAFQDp/wIAHAD1//P/EQDw/+3/GAD9/+f/HAD8//T/DAAQAPH/HwD4//r/DwAPAOj/EQACAOn/DAAXAOX/BAAOANH/9/8MAO//9f8LANT/9f8EAO//6f8NANb/+P8KAOz/5v8MAOD/7f8UAO//7//+//7/9v8YAPj/9f/z/wsA+v8SAPD/+v/x/xYA+f8SAPb/9//3/xEABQACAPn/9//y/xQACQD///b//v/7/xIACQD9//H/AAD7/xEAAgD5//P/AwD9/w8AAgD3//D/BAD//wUA/v/0//D/BgADAAMA/P/2//f/BwAGAP7/+//2//j/CAAFAPv/+f/5//v/BwAHAPn/9//7//7/BQAFAPf/9//+/wEABAACAPf/+P8BAAIAAgAAAPj/9/8CAAMAAAD+//n/+f8EAAQA/v/8//r/+/8EAAMA/P/7//z//P8EAAIA/P/5//7//v8DAAEA+//5//////8CAAAA+//5/wEAAAABAP//+//6/wIAAQD///3//P/7/wMAAQD///3//f/9/wIAAQD9//3//v/9/wMAAQD9//z/AAD//wEAAAD9//z/AAAAAAAA///9//3/AAD//wAA/v////7/AAD//wAA////////AAD//wAA//8AAP//",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAD+////+f////v//v///wAA/////wUAAQAIAAIABwACAHkATAAOAaMAAf9C/9X6QvwhArAAtghABW37nv/y+0wAWQNcAE8JRwSOC6AEJe8P8S/zrPWaBI/+LQA/+0L+P/4K8AgAb/8uCh78BQtC614GaQWfAin5UfzN8Tf+GQizAZ4MCQMbGJ4BoRS7AvcHyQARA6n9ZwHZ/z4DvwAZAlAB6gbNAS4GFADFATL7E/2K+j37C/xp/SD9Uv0VAOsDs//WAd3+bv7F/f79mP2X/KH+FwC0/1n+VgFcATABHQGaAET+nf8Y/hoAovpqAXj9CQKW/lsCl/4RApj+bAHk/RcAlv4BAG/+DgDi//3/GwAOAEIAq/+y/3z/8v8+/7T/Tv8//27/mgDZ/1sA+P+cAAAA/P/i/yMAi/85AMP/KgDM/9MA9P+QABoA4QAiACwACwBdAP7/TQDb/y0Ayf+SAA0AZwDg/4wA+/8/AAMAgQDp/w0ADAAQAAoANgAgAA4AKABIAB4A4v/3/+f/+v/c/+n/EADn/wgAFAAqAOz/IwDc/9//3f8XAND/2v/a/w0A5v8BANb/9P/m/wAA8P8ZAN3/RwAGAEsABgB/AP7/NAASAEgABAA3AP3/KgD9/1sA8P8lAOr/FgD1/xAA4/8kAOv/AwD4/xEA5f8NAPT/+v/3/x8A7f8PAPj/IwD5/yAA9/8ZAAEAGgD4/xoA9f8HAAMACAD0/xgA+P8AAPr/IQDp/w4A8v8HAPX/IgD1/wYA+P8GAPX/GgD3/woABQASAAcAGQDw/+v/9P8bAP3/HADs/+f/7/8LAPr//v/0//T/AgD2/wsA6P///+P/CADY//7/5v/3/wQA/v8LAPD/GgD1/yMA/P8QAOv/LADw/yQA+P8XAO7/MQD9/yEAAQAcAPD/IgD9/xMA+/8OAO//FQABAAoA+/8PAPP/FQABAAQA9/8PAPX/CAADAAEA+P8NAPv/CAAGAAUA9/8JAP//AAAFAPz/+f8HAAQA/f8FAP3//P8FAAYA+P8DAP7/+/8AAAcA9/8BAP///f///wgA9//+/wAA/v/8/wUA9//8/wIA///7/wUA+v/7/wIAAAD6/wMA/P/6/wEAAQD6/wEA/v/7/wIAAgD6////AAD7/wEAAgD7//7/AQD8/wAAAwD8//3/AwD9/wAAAgD9//z/AwD/////AgD+//z/AwAAAP7/AQD///3/AgABAP3/AAAAAP3/AgACAPz///8BAP3/AQACAP3//v8BAP7/AAABAP3//v8CAP7///8BAP7//f8CAP////8AAAAA/v8CAAAAAAAAAAAA/v8BAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAAAAP//AAD//wAA//8AAAAA/////wAAAQD+////AAAGAP3/OAABAIIAAwBv//f/E/0QAK0ADQCzA/7/8P4u/0cBDQCJA6ABbQDg/w7/z/9o+Vn/SPnL/1//Ef+2+jr9RfZgA5QFZwILDFj+PAb2/nEFKgKk/R0Dlv6b/FUDsP6YAoj9SgAT/iL/tAPwAv8A0P6zAr7/dwAnAf39uP22/skA2v///2YCoP4UAUsAZgF2AJH+4P70/rz9+f+U/Xv/8v7CAcb+TACS/kwAv/+x/tX9oP71/oL/1f8nAEUAZwGtAAgAIgC/AD4BaP8GAGH/dQDF/64Arf8nAakAhAH9/+kAQQD3AFb/q/8p/yIAR/8FAPD/ZAA/AIYA3v8tADQADQBp/3f/CwABAP3/Wf8OANj/WwDH/xoAe/8DAKz/zv96/z8A3f/J/5X/IAD5//j/q//c/+//RADq//D/vv8pADUAFQDI/y8ACAAbANb/OwD3/+3/9f/e/wcAIAAeAMH/8/8xAC0AEADW/+3/HAADAPv/8P8DAOL/OwD3/xcACQAHAM//5f8XAAcAz//T/9D/HgD9////yf/e//v/AgD//9H/6/////H/+/8hAAIA9//7/w0AFgAQAPL/2v/8/xsAGQABANz/9P8YAAQA/v/y/wMA5v8YAAkAAAAAAAMA7/8KABgADwDs//j/BwATABsA8P/1//z/BAAMAAAA9P/s/xAA/v8GAAkA/v/p/wMACwALAP7/9P/p/wcADQAFAPb/7//4/w0ACAD8//b//v/1/wMACwD1//T/8P/8/wAACQDz/+f/5P8GAAkABQD5//D/+v8FAA0AAwD///T/AgACABAA/v8CAPD/+/8FAAoA9f/3//f//v8GAP7/9v/t//z/+f8AAPj/+v/3/wEA+v8HAPr//P/5/wQA//8DAPr/+P/3/wYA///+//X/+//5/wQA/f/7//X/+//4/wMA/f/8//j//v/9/wYA///8//f/AgAAAAUA/f/6//n/AwACAAIA/f/7//z/AwACAAAA/f/6//3/AgADAP7//f/7/wAAAwAFAPz////8/wMAAgAEAPv//v/+/wMAAgADAPv//v///wMAAQABAPv//f8AAAIAAAD///v//f8BAAIA///+//z//v8CAAIA/v/9//3///8CAAEA/v/9//7/AAACAAAA/v/9////AAABAAAA/f/9/wAAAQABAP///f/+/wEAAQAAAP///v/+/wEAAQD///7//v///wEAAQD///7//v///wEAAAD+//7///8AAAAAAAD+//7///8AAAAA///+//7///8AAAAA////////AAAAAP////////////8AAP//////////",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAAAAAAAAAABAAAAAAD//////////////v////3/////////+//8////AQD9//z/9f8BAAIA+f8dACgAWQBxAJX/qv+Y/uz9aP9k/7UDUQQBAiQA4Pgi/AkB0gKaBsD/+fxp/vz9CQSp/I/+ywDO+vMD0fzK/PABcgBeBfoBv/+uAuH9Sf5gAy39awMmBWUBuP9fA9/9fgDj/2/+EACaACcCSv9Z/2j/rv7hAA0AWf55/7L84P7E/SIAT/67AMv/tf+FAA7/1v+7/gv/IP+E/sQA+P5aAXz/tP9XAFX/tP8o/4r/j//e/yQAMv9mAJT/rgCr/9X/EwCb//H/9f7F/6D/EAAoAK3//v+e/zsAh/+B/7r/if/C/2r/4P/z/6//HwCy/0IA7/9ZALT/y/80ACgA9v/J/9//DgA5ADUALQARADIACwAfAOf/NgArACMACQBBAEcAGAAjAC4AWQBUAHcAAAAfACEAIAAcAPj/CADk/yQA7v89AEEAFwD5/xYA6f8aAOX/AADF/zQADwAUAOT/BQDr/yUA6P8XAOf/HADR/0AA8P8nAAgACQDt/ycAKAAHAPH/IQDz/xsACADn//n/DgADAA4A8P///8z/GgDN/yMA/f8QANj/MwACAC0ACwAOAO3/JgAZAAUACgAAAA4AIgAaAAkADwACAAAAHQATAAUABQACAAgACwAjAO////8AAA8ABQAPAPL//f8GAAsABgAGAPD/8v8GAPz/CAD6//H/6v8PAAgABgD4//3/9v8aAAgABwD1//7//v8QAAoACAD//wUA9v8QAAoABAAFAAgAAgAJAAoAAwD//w0AAgD//wcA/v8DAAoABQAFABUABAAKAAYABwAHAA8ACgAGAAwADwAMAAkAEAAJAAgADwAMAAgADgAJAAUACQAPAAUACwAHAAEABgAIAAEABAAGAP//AgAJAAAAAgAEAP7///8IAAIA//8GAAEAAQAJAAIA/v8EAAMA//8JAAEA/v8DAAMA/v8HAAMA/f8BAAUA/v8FAAMA/v8BAAcA//8DAAMA/v8BAAYA//8CAAMA/////wcAAAAAAAMAAAD//wYAAQD+/wMAAQD//wUAAQD+/wIAAgD//wQAAgD+/wEAAwD//wMAAwD+/wEAAwD//wIAAwD//wEABAAAAAEABAD//wAABAABAAAAAwAAAAAABAABAP//AwABAAAAAwACAP//AgACAAAAAwACAP//AgACAAAAAgACAAAAAQADAAAAAQACAAAAAQADAAAAAQACAAAAAAACAAEAAAACAAEAAAACAAEAAAABAAEAAAABAAEAAAABAAEAAAABAAEAAAABAAEAAAABAAEAAAAAAAAAAAAAAAAA",\n"UklGRiQEAABXQVZFZm10IBAAAAABAAIAgLsAAADuAgAEABAAZGF0YQAEAAAAAP//AAD//wAA//8AAAAA//8AAP//AAACAAAA+f8BAAYA///4/wIA//8AAA8A/v/V/wEAEwA9AAEBRwA2AF7/kfog/3gBwv99CDYBU/qtAUX/AP7OAfkAX/o9B38FSfwaAuT14/60BAr8CQAI/tfyIQTzAXP+egdUBBwBof7TBMT8bAWi/5EEWwBRAAAKyfxE/8b88vp6ACP+PAF4/qD8MQNM/ygCJ/2XAPD9kP5gAVT/iP9I/lEB4P8qAD0BFAGa/+7/DgB2AOP98gFm/u/+Vv5/AG8ASP9gAM//qv9w//oAcv+2/jIBHgA7/6D/oAAGAKH/lADT/wAAggC8AAYAkP9yAEcAkf8BAOD/RAAr/zUANwDt/xQAJQAkAMT/zwA/AOH/xv9zAGsANQBTAIcALAAvACIATACy/xMADADg/xcAWABvAJL/7f9VAPb/EgDt/wcA4f8kAPP/5P+h/wgACQDy//r/LgAQAMn/8/9CAOX/5v/S/9//3P8pABYAuP/s/w8AFgDt/+3/7v/w/9j/5/8GAOf/2P/2//P//v8kABMAuf/m/xoADADZ/+r/3P8KAAUAKwDe/wsA3P8VAAAADgAfAB0ACAAMAF4AGgAhAPL/MwDz/0kABAAKAPX/LwAbAAkA9v/s/+3/8/8CABAAAADm//n/BQALAAUAAQDj//n/JQAVAPX/9v/+/wIAEQABAPP/8P/1/wAABgD6/+3/7//o//j/DAD8/+b/8P8IAAkABgD4//D/8P8UAAoAAwD4/wAA+f8OAAcAAAAFAPX/9v8TAAkA8v8EAPb/9/8dAA0A7/8CAPn/+f8SAAQA8/8CAOf/+v8DAAgA9P////H//P8IAAUA8//0/wIAAQAGAAgA9//7/wAA+/8EAP//+P/+////AgACAAsA8v/+/wIABQD7/wgA9v/7/wMABAD5/wAA/P/3/wEAAQD7//7//P/1/wQA///3//r////3/wMAAwD1//r/AwD6////AgD4//n/AwD8//7/AgD4//n/AwD+//3/AQD4//n/BQD///n/AAD6//j/BAABAPj/AAD9//v/AwADAPj//v/+//z/AwAEAPj//v8BAP7/AQADAPj//f8CAP////8EAPr//P8DAAAA/v8CAPv//P8DAAEA/f8BAP3//f8DAAIA/P8AAP7//f8DAAIA/P///wAA/f8BAAIA+//+/wEA//8AAAEA+//+/wEA/////wEA/P/+/wEA///+/wAA/f/9/wEAAAD9/wAA/f/+/wEAAQD8/////v/+/wAAAQD8////////////AQD9////AAD/////AAD+////AAAAAP//AAD///////8AAP//AAD//wAA//8AAP//",\n];\n\nmodule.exports = OmnitoneTOAHrirBase64;\n\n\n//# sourceURL=webpack:///./src/resources/omnitone-toa-hrir-base64.js?'); + }, + "./src/utils.js": function(module, exports) { + eval("/**\n * @license\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Omnitone library common utilities.\n */\n\n\n/**\n * Omnitone library logging function.\n * @param {any} Message to be printed out.\n */\nexports.log = function() {\n let message = '[Omnitone] ' + Array.prototype.slice.call(arguments).join(' ')\n + ' (' + performance.now().toFixed(2) + 'ms)';\n window.console.log(message);\n};\n\n\n/**\n * Omnitone library error-throwing function.\n * @param {any} Message to be printed out.\n */\nexports.throw = function() {\n let message = '[Omnitone] ' + Array.prototype.slice.call(arguments).join(' ')\n + ' (' + performance.now().toFixed(2) + 'ms)';\n throw new Error(message);\n};\n\n\n// Static temp storage for matrix inversion.\nlet a00;\nlet a01;\nlet a02;\nlet a03;\nlet a10;\nlet a11;\nlet a12;\nlet a13;\nlet a20;\nlet a21;\nlet a22;\nlet a23;\nlet a30;\nlet a31;\nlet a32;\nlet a33;\nlet b00;\nlet b01;\nlet b02;\nlet b03;\nlet b04;\nlet b05;\nlet b06;\nlet b07;\nlet b08;\nlet b09;\nlet b10;\nlet b11;\nlet det;\n\n\n/**\n * A 4x4 matrix inversion utility. This does not handle the case when the\n * arguments are not proper 4x4 matrices.\n * @param {Float32Array} out The inverted result.\n * @param {Float32Array} a The source matrix.\n * @return {Float32Array} out\n */\nexports.invertMatrix4 = function(out, a) {\n a00 = a[0];\n a01 = a[1];\n a02 = a[2];\n a03 = a[3];\n a10 = a[4];\n a11 = a[5];\n a12 = a[6];\n a13 = a[7];\n a20 = a[8];\n a21 = a[9];\n a22 = a[10];\n a23 = a[11];\n a30 = a[12];\n a31 = a[13];\n a32 = a[14];\n a33 = a[15];\n b00 = a00 * a11 - a01 * a10;\n b01 = a00 * a12 - a02 * a10;\n b02 = a00 * a13 - a03 * a10;\n b03 = a01 * a12 - a02 * a11;\n b04 = a01 * a13 - a03 * a11;\n b05 = a02 * a13 - a03 * a12;\n b06 = a20 * a31 - a21 * a30;\n b07 = a20 * a32 - a22 * a30;\n b08 = a20 * a33 - a23 * a30;\n b09 = a21 * a32 - a22 * a31;\n b10 = a21 * a33 - a23 * a31;\n b11 = a22 * a33 - a23 * a32;\n det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n\n det = 1.0 / det;\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n};\n\n\n/**\n * Check if a value is defined in the ENUM dictionary.\n * @param {Object} enumDictionary - ENUM dictionary.\n * @param {Number|String} entryValue - a value to probe.\n * @return {Boolean}\n */\nexports.isDefinedENUMEntry = function(enumDictionary, entryValue) {\n for (let enumKey in enumDictionary) {\n if (entryValue === enumDictionary[enumKey]) {\n return true;\n }\n }\n return false;\n};\n\n\n/**\n * Check if the given object is an instance of BaseAudioContext.\n * @param {AudioContext} context - A context object to be checked.\n * @return {Boolean}\n */\nexports.isAudioContext = function(context) {\n // TODO(hoch): Update this when BaseAudioContext is available for all\n // browsers.\n return context instanceof AudioContext ||\n context instanceof OfflineAudioContext;\n};\n\n\n/**\n * Check if the given object is a valid AudioBuffer.\n * @param {Object} audioBuffer An AudioBuffer object to be checked.\n * @return {Boolean}\n */\nexports.isAudioBuffer = function(audioBuffer) {\n return audioBuffer instanceof AudioBuffer;\n};\n\n\n/**\n * Perform channel-wise merge on multiple AudioBuffers. The sample rate and\n * the length of buffers to be merged must be identical.\n * @param {BaseAudioContext} context - Associated BaseAudioContext.\n * @param {AudioBuffer[]} bufferList - An array of AudioBuffers to be merged\n * channel-wise.\n * @return {AudioBuffer} - A single merged AudioBuffer.\n */\nexports.mergeBufferListByChannel = function(context, bufferList) {\n const bufferLength = bufferList[0].length;\n const bufferSampleRate = bufferList[0].sampleRate;\n let bufferNumberOfChannel = 0;\n\n for (let i = 0; i < bufferList.length; ++i) {\n if (bufferNumberOfChannel > 32) {\n exports.throw('Utils.mergeBuffer: Number of channels cannot exceed 32.' +\n '(got ' + bufferNumberOfChannel + ')');\n }\n if (bufferLength !== bufferList[i].length) {\n exports.throw('Utils.mergeBuffer: AudioBuffer lengths are ' +\n 'inconsistent. (expected ' + bufferLength + ' but got ' +\n bufferList[i].length + ')');\n }\n if (bufferSampleRate !== bufferList[i].sampleRate) {\n exports.throw('Utils.mergeBuffer: AudioBuffer sample rates are ' +\n 'inconsistent. (expected ' + bufferSampleRate + ' but got ' +\n bufferList[i].sampleRate + ')');\n }\n bufferNumberOfChannel += bufferList[i].numberOfChannels;\n }\n\n const buffer = context.createBuffer(bufferNumberOfChannel,\n bufferLength,\n bufferSampleRate);\n let destinationChannelIndex = 0;\n for (let i = 0; i < bufferList.length; ++i) {\n for (let j = 0; j < bufferList[i].numberOfChannels; ++j) {\n buffer.getChannelData(destinationChannelIndex++).set(\n bufferList[i].getChannelData(j));\n }\n }\n\n return buffer;\n};\n\n\n/**\n * Perform channel-wise split by the given channel count. For example,\n * 1 x AudioBuffer(8) -> splitBuffer(context, buffer, 2) -> 4 x AudioBuffer(2).\n * @param {BaseAudioContext} context - Associated BaseAudioContext.\n * @param {AudioBuffer} audioBuffer - An AudioBuffer to be splitted.\n * @param {Number} splitBy - Number of channels to be splitted.\n * @return {AudioBuffer[]} - An array of splitted AudioBuffers.\n */\nexports.splitBufferbyChannel = function(context, audioBuffer, splitBy) {\n if (audioBuffer.numberOfChannels <= splitBy) {\n exports.throw('Utils.splitBuffer: Insufficient number of channels. (' +\n audioBuffer.numberOfChannels + ' splitted by ' + splitBy + ')');\n }\n\n let bufflerList = [];\n let sourceChannelIndex = 0;\n const numberOfSplittedBuffer =\n Math.ceil(audioBuffer.numberOfChannels / splitBy);\n for (let i = 0; i < numberOfSplittedBuffer; ++i) {\n let buffer = context.createBuffer(splitBy,\n audioBuffer.length,\n audioBuffer.sampleRate);\n for (let j = 0; j < splitBy; ++j) {\n if (sourceChannelIndex < audioBuffer.numberOfChannels) {\n buffer.getChannelData(j).set(\n audioBuffer.getChannelData(sourceChannelIndex++));\n }\n }\n bufflerList.push(buffer);\n }\n\n return bufferList;\n};\n\n\n/**\n * Converts Base64-encoded string to ArrayBuffer.\n * @param {string} base64String - Base64-encdoed string.\n * @return {ArrayByuffer} Converted ArrayBuffer object.\n */\nexports.getArrayBufferFromBase64String = function(base64String) {\n let binaryString = window.atob(base64String);\n let byteArray = new Uint8Array(binaryString.length);\n byteArray.forEach(\n (value, index) => byteArray[index] = binaryString.charCodeAt(index));\n return byteArray.buffer;\n};\n\n\n//# sourceURL=webpack:///./src/utils.js?"); + }, + "./src/version.js": function(module, exports, __webpack_require__) { + "use strict"; + eval('/**\n * @license\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @file Omnitone version.\n */\n\n\n\n\n/**\n * Omnitone library version\n * @type {String}\n */\nmodule.exports = \'1.2.4\';\n\n\n//# sourceURL=webpack:///./src/version.js?'); + } + }); +}); \ No newline at end of file diff --git a/build/omnitone.min.js b/build/omnitone.min.js index 983bca5..fe510b3 100644 --- a/build/omnitone.min.js +++ b/build/omnitone.min.js @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -!function(A,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e=t();for(var i in e)("object"==typeof exports?exports:A)[i]=e[i]}}(window,function(){return function(A){var t={};function e(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return A[i].call(n.exports,n,n.exports,e),n.l=!0,n.exports}return e.m=A,e.c=t,e.d=function(A,t,i){e.o(A,t)||Object.defineProperty(A,t,{configurable:!1,enumerable:!0,get:i})},e.r=function(A){Object.defineProperty(A,"__esModule",{value:!0})},e.n=function(A){var t=A&&A.__esModule?function(){return A.default}:function(){return A};return e.d(t,"a",t),t},e.o=function(A,t){return Object.prototype.hasOwnProperty.call(A,t)},e.p="",e(e.s=15)}([function(A,t){let e,i,n,o,r,s,a,f,c,h,g,w,D,v,P,B,u,l,Q,_,C,d,p,E,M,x,I,m,b;t.log=function(){let A="[Omnitone] "+Array.prototype.slice.call(arguments).join(" ")+" ("+performance.now().toFixed(2)+"ms)";window.console.log(A)},t.throw=function(){let A="[Omnitone] "+Array.prototype.slice.call(arguments).join(" ")+" ("+performance.now().toFixed(2)+"ms)";throw new Error(A)},t.invertMatrix4=function(A,t){return e=t[0],i=t[1],n=t[2],o=t[3],r=t[4],s=t[5],a=t[6],f=t[7],c=t[8],h=t[9],g=t[10],w=t[11],D=t[12],v=t[13],P=t[14],B=t[15],(b=(u=e*s-i*r)*(m=g*B-w*P)-(l=e*a-n*r)*(I=h*B-w*v)+(Q=e*f-o*r)*(x=h*P-g*v)+(_=i*a-n*s)*(M=c*B-w*D)-(C=i*f-o*s)*(E=c*P-g*D)+(d=n*f-o*a)*(p=c*v-h*D))?(b=1/b,A[0]=(s*m-a*I+f*x)*b,A[1]=(n*I-i*m-o*x)*b,A[2]=(v*d-P*C+B*_)*b,A[3]=(g*C-h*d-w*_)*b,A[4]=(a*M-r*m-f*E)*b,A[5]=(e*m-n*M+o*E)*b,A[6]=(P*Q-D*d-B*l)*b,A[7]=(c*d-g*Q+w*l)*b,A[8]=(r*I-s*M+f*p)*b,A[9]=(i*M-e*I-o*p)*b,A[10]=(D*C-v*Q+B*u)*b,A[11]=(h*Q-c*C-w*u)*b,A[12]=(s*E-r*x-a*p)*b,A[13]=(e*x-i*E+n*p)*b,A[14]=(v*l-D*_-P*u)*b,A[15]=(c*_-h*l+g*u)*b,A):null},t.isDefinedENUMEntry=function(A,t){for(let e in A)if(t===A[e])return!0;return!1},t.isAudioContext=function(A){return A instanceof AudioContext||A instanceof OfflineAudioContext},t.isAudioBuffer=function(A){return A instanceof AudioBuffer},t.mergeBufferListByChannel=function(A,e){const i=e[0].length,n=e[0].sampleRate;let o=0;for(let A=0;A32&&t.throw("Utils.mergeBuffer: Number of channels cannot exceed 32.(got "+o+")"),i!==e[A].length&&t.throw("Utils.mergeBuffer: AudioBuffer lengths are inconsistent. (expected "+i+" but got "+e[A].length+")"),n!==e[A].sampleRate&&t.throw("Utils.mergeBuffer: AudioBuffer sample rates are inconsistent. (expected "+n+" but got "+e[A].sampleRate+")"),o+=e[A].numberOfChannels;const r=A.createBuffer(o,i,n);let s=0;for(let A=0;Ae[i]=t.charCodeAt(i)),e.buffer}},function(A,t,e){"use strict";const i=e(0),n={BASE64:"base64",URL:"url"};function o(A,t,e){this._context=i.isAudioContext(A)?A:i.throw("BufferList: Invalid BaseAudioContext."),this._options={dataType:n.BASE64,verbose:!1},e&&(e.dataType&&i.isDefinedENUMEntry(n,e.dataType)&&(this._options.dataType=e.dataType),e.verbose&&(this._options.verbose=Boolean(e.verbose))),this._bufferList=[],this._bufferData=this._options.dataType===n.BASE64?t:t.slice(0),this._numberOfTasks=this._bufferData.length,this._resolveHandler=null,this._rejectHandler=new Function}o.prototype.load=function(){return new Promise(this._promiseGenerator.bind(this))},o.prototype._promiseGenerator=function(A,t){"function"!=typeof A?i.throw("BufferList: Invalid Promise resolver."):this._resolveHandler=A,"function"==typeof t&&(this._rejectHandler=t);for(let A=0;A0){const o=i(t,1);return r(A,1,t-1,e,n)*Math.sqrt(1+o)-r(A,-1,1-t,e,n)*(1-o)}{const o=i(t,-1);return r(A,1,t+1,e,n)*(1-o)+r(A,-1,-t-1,e,n)*Math.sqrt(1+o)}}function f(A,t,e,i){return 0===t?0:t>0?r(A,1,t+1,e,i)+r(A,-1,-t-1,e,i):r(A,1,t-1,e,i)-r(A,-1,1-t,e,i)}function c(A,t,e){const n=i(A,0),o=Math.abs(t)===e?1/(2*e*(2*e-1)):1/((e+t)*(e-t));return[Math.sqrt((e+A)*(e-A)*o),.5*(1-2*n)*Math.sqrt((1+n)*(e+Math.abs(A)-1)*(e+Math.abs(A))*o),-.5*(1-n)*Math.sqrt((e-Math.abs(A)-1)*(e-Math.abs(A)))*o]}function h(A,t){for(let e=-t;e<=t;e++)for(let i=-t;i<=t;i++){const o=c(e,i,t);Math.abs(o[0])>0&&(o[0]*=s(A,e,i,t)),Math.abs(o[1])>0&&(o[1]*=a(A,e,i,t)),Math.abs(o[2])>0&&(o[2]*=f(A,e,i,t)),n(A,t,e,i,o[0]+o[1]+o[2])}}function g(A){for(let t=2;t<=A.length;t++)h(A,t)}function w(A,t){this._context=A,this._ambisonicOrder=t;const e=(t+1)*(t+1);let i,n,o,r,s;this._splitter=this._context.createChannelSplitter(e),this._merger=this._context.createChannelMerger(e),this._gainNodeMatrix=[];for(let A=1;A<=t;A++){i=A*A,n=2*A+1,this._gainNodeMatrix[A-1]=[];for(let t=0;t=0?this._stereoSplitters[i].connect(this._positiveIndexSphericalHarmonics,e%2):this._stereoSplitters[i].connect(this._negativeIndexSphericalHarmonics,e%2)}this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,1),this._negativeIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._negativeIndexSphericalHarmonics.connect(this._inverter),this._inverter.connect(this._binauralMerger,0,1),this._inverter.gain.value=-1,this.input=this._inputSplitter,this.output=this._outputGain},i.prototype.setHRIRBufferList=function(A){if(!this._isBufferLoaded){for(let t=0;t ["+A.toString()+"])."),this._config.channelMap=A.slice(),this._foaRouter.setChannelMap(this._config.channelMap))},c.prototype.setRotationMatrix3=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix3(A)},c.prototype.setRotationMatrix4=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix4(A)},c.prototype.setRotationMatrixFromCamera=function(A){this._isRendererReady&&(a.invertMatrix4(this._tempMatrix4,A.elements),this._foaRotator.setRotationMatrix4(this._tempMatrix4))},c.prototype.setRenderingMode=function(A){if(A!==this._config.renderingMode){switch(A){case f.AMBISONIC:this._foaConvolver.enable(),this._bypass.disconnect();break;case f.BYPASS:this._foaConvolver.disable(),this._bypass.connect(this.output);break;case f.OFF:this._foaConvolver.disable(),this._bypass.disconnect();break;default:return void a.log('FOARenderer: Rendering mode "'+A+'" is not supported.')}this._config.renderingMode=A,a.log("FOARenderer: Rendering mode changed. ("+A+")")}},A.exports=c},function(A,t,e){"use strict";const i=e(1),n=e(6),o=e(13),r=e(5),s=e(4),a=e(3),f=e(11),c=e(2),h=e(8),g=e(0),w=e(7);let D={};D.browserInfo=h.getBrowserInfo(),D.createBufferList=function(A,t,e){return new i(A,t,e||{dataType:"url"}).load()},D.mergeBufferListByChannel=g.mergeBufferListByChannel,D.splitBufferbyChannel=g.splitBufferbyChannel,D.createFOAConvolver=function(A,t){return new n(A,t)},D.createFOARouter=function(A,t){return new s(A,t)},D.createFOARotator=function(A){return new r(A)},D.createHOARotator=function(A,t){return new c(A,t)},D.createHOAConvolver=function(A,t,e){return new a(A,t,e)},D.createFOARenderer=function(A,t){return new o(A,t)},D.createHOARenderer=function(A,t){return new f(A,t)},g.log("Version "+w+" (running "+D.browserInfo.name+" "+D.browserInfo.version+" on "+D.browserInfo.platform+")"),"safari"===D.browserInfo.name.toLowerCase()&&(h.patchSafari(),g.log(D.browserInfo.name+" detected. Polyfill applied.")),A.exports=D},function(A,t,e){"use strict";t.Omnitone=e(14)}])}); \ No newline at end of file +!function(A,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e=t();for(var i in e)("object"==typeof exports?exports:A)[i]=e[i]}}(window,function(){return function(A){var t={};function e(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return A[i].call(n.exports,n,n.exports,e),n.l=!0,n.exports}return e.m=A,e.c=t,e.d=function(A,t,i){e.o(A,t)||Object.defineProperty(A,t,{configurable:!1,enumerable:!0,get:i})},e.r=function(A){Object.defineProperty(A,"__esModule",{value:!0})},e.n=function(A){var t=A&&A.__esModule?function(){return A.default}:function(){return A};return e.d(t,"a",t),t},e.o=function(A,t){return Object.prototype.hasOwnProperty.call(A,t)},e.p="",e(e.s=15)}([function(A,t){let e,i,n,o,r,s,a,f,c,h,g,w,D,v,P,B,u,l,Q,_,C,d,p,E,M,x,I,m,b;t.log=function(){let A="[Omnitone] "+Array.prototype.slice.call(arguments).join(" ")+" ("+performance.now().toFixed(2)+"ms)";window.console.log(A)},t.throw=function(){let A="[Omnitone] "+Array.prototype.slice.call(arguments).join(" ")+" ("+performance.now().toFixed(2)+"ms)";throw new Error(A)},t.invertMatrix4=function(A,t){return e=t[0],i=t[1],n=t[2],o=t[3],r=t[4],s=t[5],a=t[6],f=t[7],c=t[8],h=t[9],g=t[10],w=t[11],D=t[12],v=t[13],P=t[14],B=t[15],(b=(u=e*s-i*r)*(m=g*B-w*P)-(l=e*a-n*r)*(I=h*B-w*v)+(Q=e*f-o*r)*(x=h*P-g*v)+(_=i*a-n*s)*(M=c*B-w*D)-(C=i*f-o*s)*(E=c*P-g*D)+(d=n*f-o*a)*(p=c*v-h*D))?(b=1/b,A[0]=(s*m-a*I+f*x)*b,A[1]=(n*I-i*m-o*x)*b,A[2]=(v*d-P*C+B*_)*b,A[3]=(g*C-h*d-w*_)*b,A[4]=(a*M-r*m-f*E)*b,A[5]=(e*m-n*M+o*E)*b,A[6]=(P*Q-D*d-B*l)*b,A[7]=(c*d-g*Q+w*l)*b,A[8]=(r*I-s*M+f*p)*b,A[9]=(i*M-e*I-o*p)*b,A[10]=(D*C-v*Q+B*u)*b,A[11]=(h*Q-c*C-w*u)*b,A[12]=(s*E-r*x-a*p)*b,A[13]=(e*x-i*E+n*p)*b,A[14]=(v*l-D*_-P*u)*b,A[15]=(c*_-h*l+g*u)*b,A):null},t.isDefinedENUMEntry=function(A,t){for(let e in A)if(t===A[e])return!0;return!1},t.isAudioContext=function(A){return A instanceof AudioContext||A instanceof OfflineAudioContext},t.isAudioBuffer=function(A){return A instanceof AudioBuffer},t.mergeBufferListByChannel=function(A,e){const i=e[0].length,n=e[0].sampleRate;let o=0;for(let A=0;A32&&t.throw("Utils.mergeBuffer: Number of channels cannot exceed 32.(got "+o+")"),i!==e[A].length&&t.throw("Utils.mergeBuffer: AudioBuffer lengths are inconsistent. (expected "+i+" but got "+e[A].length+")"),n!==e[A].sampleRate&&t.throw("Utils.mergeBuffer: AudioBuffer sample rates are inconsistent. (expected "+n+" but got "+e[A].sampleRate+")"),o+=e[A].numberOfChannels;const r=A.createBuffer(o,i,n);let s=0;for(let A=0;Ae[i]=t.charCodeAt(i)),e.buffer}},function(A,t,e){"use strict";const i=e(0),n={BASE64:"base64",URL:"url"};function o(A,t,e){this._context=i.isAudioContext(A)?A:i.throw("BufferList: Invalid BaseAudioContext."),this._options={dataType:n.BASE64,verbose:!1},e&&(e.dataType&&i.isDefinedENUMEntry(n,e.dataType)&&(this._options.dataType=e.dataType),e.verbose&&(this._options.verbose=Boolean(e.verbose))),this._bufferList=[],this._bufferData=this._options.dataType===n.BASE64?t:t.slice(0),this._numberOfTasks=this._bufferData.length,this._resolveHandler=null,this._rejectHandler=new Function}o.prototype.load=function(){return new Promise(this._promiseGenerator.bind(this))},o.prototype._promiseGenerator=function(A,t){"function"!=typeof A?i.throw("BufferList: Invalid Promise resolver."):this._resolveHandler=A,"function"==typeof t&&(this._rejectHandler=t);for(let A=0;A0){const o=i(t,1);return r(A,1,t-1,e,n)*Math.sqrt(1+o)-r(A,-1,1-t,e,n)*(1-o)}{const o=i(t,-1);return r(A,1,t+1,e,n)*(1-o)+r(A,-1,-t-1,e,n)*Math.sqrt(1+o)}}function f(A,t,e,i){return 0===t?0:t>0?r(A,1,t+1,e,i)+r(A,-1,-t-1,e,i):r(A,1,t-1,e,i)-r(A,-1,1-t,e,i)}function c(A,t,e){const n=i(A,0),o=Math.abs(t)===e?1/(2*e*(2*e-1)):1/((e+t)*(e-t));return[Math.sqrt((e+A)*(e-A)*o),.5*(1-2*n)*Math.sqrt((1+n)*(e+Math.abs(A)-1)*(e+Math.abs(A))*o),-.5*(1-n)*Math.sqrt((e-Math.abs(A)-1)*(e-Math.abs(A)))*o]}function h(A,t){for(let e=-t;e<=t;e++)for(let i=-t;i<=t;i++){const o=c(e,i,t);Math.abs(o[0])>0&&(o[0]*=s(A,e,i,t)),Math.abs(o[1])>0&&(o[1]*=a(A,e,i,t)),Math.abs(o[2])>0&&(o[2]*=f(A,e,i,t)),n(A,t,e,i,o[0]+o[1]+o[2])}}function g(A){for(let t=2;t<=A.length;t++)h(A,t)}function w(A,t){this._context=A,this._ambisonicOrder=t;const e=(t+1)*(t+1);let i,n,o,r,s;this._splitter=this._context.createChannelSplitter(e),this._merger=this._context.createChannelMerger(e),this._gainNodeMatrix=[];for(let A=1;A<=t;A++){i=A*A,n=2*A+1,this._gainNodeMatrix[A-1]=[];for(let t=0;t=0?this._stereoSplitters[i].connect(this._positiveIndexSphericalHarmonics,e%2):this._stereoSplitters[i].connect(this._negativeIndexSphericalHarmonics,e%2)}this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._positiveIndexSphericalHarmonics.connect(this._binauralMerger,0,1),this._negativeIndexSphericalHarmonics.connect(this._binauralMerger,0,0),this._negativeIndexSphericalHarmonics.connect(this._inverter),this._inverter.connect(this._binauralMerger,0,1),this._inverter.gain.value=-1,this.input=this._inputSplitter,this.output=this._outputGain},i.prototype.setHRIRBufferList=function(A){if(!this._isBufferLoaded){for(let t=0;t ["+A.toString()+"])."),this._config.channelMap=A.slice(),this._foaRouter.setChannelMap(this._config.channelMap))},c.prototype.setRotationMatrix3=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix3(A)},c.prototype.setRotationMatrix4=function(A){this._isRendererReady&&this._foaRotator.setRotationMatrix4(A)},c.prototype.setRotationMatrixFromCamera=function(A){this._isRendererReady&&(a.invertMatrix4(this._tempMatrix4,A.elements),this._foaRotator.setRotationMatrix4(this._tempMatrix4))},c.prototype.setRenderingMode=function(A){if(A!==this._config.renderingMode){switch(A){case f.AMBISONIC:this._foaConvolver.enable(),this._bypass.disconnect();break;case f.BYPASS:this._foaConvolver.disable(),this._bypass.connect(this.output);break;case f.OFF:this._foaConvolver.disable(),this._bypass.disconnect();break;default:return void a.log('FOARenderer: Rendering mode "'+A+'" is not supported.')}this._config.renderingMode=A,a.log("FOARenderer: Rendering mode changed. ("+A+")")}},A.exports=c},function(A,t,e){"use strict";const i=e(1),n=e(6),o=e(13),r=e(5),s=e(4),a=e(3),f=e(11),c=e(2),h=e(8),g=e(0),w=e(7);let D={};D.browserInfo=h.getBrowserInfo(),D.createBufferList=function(A,t,e){return new i(A,t,e||{dataType:"url"}).load()},D.mergeBufferListByChannel=g.mergeBufferListByChannel,D.splitBufferbyChannel=g.splitBufferbyChannel,D.createFOAConvolver=function(A,t){return new n(A,t)},D.createFOARouter=function(A,t){return new s(A,t)},D.createFOARotator=function(A){return new r(A)},D.createHOARotator=function(A,t){return new c(A,t)},D.createHOAConvolver=function(A,t,e){return new a(A,t,e)},D.createFOARenderer=function(A,t){return new o(A,t)},D.createHOARenderer=function(A,t){return new f(A,t)},g.log("Version "+w+" (running "+D.browserInfo.name+" "+D.browserInfo.version+" on "+D.browserInfo.platform+")"),"safari"===D.browserInfo.name.toLowerCase()&&(h.patchSafari(),g.log(D.browserInfo.name+" detected. Polyfill applied.")),A.exports=D},function(A,t,e){"use strict";t.Omnitone=e(14)}])}); \ No newline at end of file diff --git a/package.json b/package.json index ca809e1..a6ccdd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "omnitone", - "version": "1.2.3", + "version": "1.2.4", "description": "Spatial Audio Decoder in Web Audio API", "main": "build/omnitone.js", "keywords": [ @@ -30,8 +30,8 @@ "fsevents": "1.1.3" }, "scripts": { - "build": "webpack --mode production --progress --color", - "build-all": "webpack --mode production --progress --color && webpack --mode production --config webpack.config.all.js --progress --color", + "build": "webpack --mode development --progress --color", + "build-all": "webpack --mode development --progress --color && webpack --mode production --config webpack.config.all.js --progress --color", "build-hrir": "node src/resources/build-hrir-base64.js", "build-doc": "node_modules/.bin/jsdoc src/omnitone.js -d doc/", "eslint": "./node_modules/.bin/eslint src/*", diff --git a/src/version.js b/src/version.js index 9142e4a..418680d 100644 --- a/src/version.js +++ b/src/version.js @@ -25,4 +25,4 @@ * Omnitone library version * @type {String} */ -module.exports = '1.2.3'; +module.exports = '1.2.4';