Showing preview only (1,598K chars total). Download the full file or copy to clipboard to get everything.
Repository: resonance-audio/resonance-audio-web-sdk
Branch: master
Commit: c69e41dae836
Files: 51
Total size: 1.5 MB
Directory structure:
gitextract_qy9p2uoe/
├── .eslintrc.js
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── _config.yml
├── build/
│ └── resonance-audio.js
├── examples/
│ ├── benchmark.html
│ ├── birds.html
│ ├── hello-world.html
│ ├── index.html
│ ├── resources/
│ │ ├── examples.css
│ │ ├── js/
│ │ │ ├── benchmark.js
│ │ │ ├── birds.js
│ │ │ ├── canvas-control.js
│ │ │ ├── hello-world.js
│ │ │ ├── room-models.js
│ │ │ ├── treasure-hunt.js
│ │ │ └── vs-pannernode.js
│ │ └── three.js
│ ├── room-models.html
│ ├── treasure-hunt.html
│ └── vs-pannernode.html
├── karma.conf.js
├── package.json
├── src/
│ ├── attenuation.js
│ ├── directivity.js
│ ├── early-reflections.js
│ ├── encoder.js
│ ├── late-reflections.js
│ ├── listener.js
│ ├── main.js
│ ├── resonance-audio.js
│ ├── room.js
│ ├── source.js
│ ├── tables.js
│ ├── utils.js
│ └── version.js
├── test/
│ ├── test-attenuation.js
│ ├── test-directivity.js
│ ├── test-early-reflections.js
│ ├── test-encoder.js
│ ├── test-late-reflections.js
│ ├── test-listener.js
│ ├── test-resonance-audio.js
│ ├── test-room.js
│ ├── test-source.js
│ └── test-tables.js
├── webpack.config.all.js
└── webpack.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintrc.js
================================================
module.exports = {
"env": {
"es6": true,
},
"extends": "google",
"rules": {
// the 'rest' parameter for |arguments| might not be supported in some
// old version of browsers. See also:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters#Browser_compatibility
"prefer-rest-params": 0,
}
};
================================================
FILE: .gitignore
================================================
.DS_Store
npm-debug.log
node_modules/
pvt/
package-lock.json
doc/
.firebaserc
404.html
database.rules.json
firebase.json
./index.html
================================================
FILE: .travis.yml
================================================
dist: trusty
language: node_js
node_js:
- 7
addons:
apt:
packages:
- google-chrome-stable
install:
- npm install
before_script:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- sleep 3
script:
- npm run build-all
- npm test
================================================
FILE: CONTRIBUTING.md
================================================
# How to become a contributor and submit your own code
## Contributor License Agreements
We'd love to accept your sample apps and patches! Before we can take them, we have to jump a couple of legal hurdles.
Please fill out either the individual or corporate Contributor License Agreement (CLA).
* If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](https://developers.google.com/open-source/cla/individual).
* If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate).
Follow either of the two links above to access the appropriate CLA and instructions for how to sign and return it. Once we receive it, we'll be able to accept your pull requests.
## Contributing A Patch
1. Submit an issue describing your proposed change to the repo in question.
1. The repo owner will respond to your issue promptly.
1. If your proposed change is accepted, and you haven't already done so, sign a Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Ensure that your code adheres to the existing style in the sample to which you are contributing.
1. Submit a pull request.
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 Google, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# [Resonance Audio SDK](//developers.google.com/resonance-audio) for Web [](https://travis-ci.org/resonance-audio/resonance-audio-web-sdk)
Resonance Audio is a real-time JavaScript SDK that lets you add spatial audio to your web applications using [Web Audio](//developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API).
Copyright (c) 2017 Google Inc. All rights reserved.
## Getting Started
Consult our [online documentation](//developers.google.com/resonance-audio/develop/web/getting-started) for more information.
To learn more about how Resonance Audio works, see
[https://developers.google.com/resonance-audio/discover/concepts](https://developers.google.com/resonance-audio/discover/concepts)
================================================
FILE: _config.yml
================================================
theme: jekyll-theme-cayman
================================================
FILE: build/resonance-audio.js
================================================
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 10);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file ResonanceAudio library common utilities, mathematical constants,
* and default values.
* @author Andrew Allen <bitllama@google.com>
*/
/**
* @class Utils
* @description A set of defaults, constants and utility functions.
*/
function Utils() {};
/**
* Default input gain (linear).
* @type {Number}
*/
Utils.DEFAULT_SOURCE_GAIN = 1;
/**
* Maximum outside-the-room distance to attenuate far-field listener by.
* @type {Number}
*/
Utils.LISTENER_MAX_OUTSIDE_ROOM_DISTANCE = 1;
/**
* Maximum outside-the-room distance to attenuate far-field sources by.
* @type {Number}
*/
Utils.SOURCE_MAX_OUTSIDE_ROOM_DISTANCE = 1;
/**
* Default distance from listener when setting angle.
* @type {Number}
*/
Utils.DEFAULT_SOURCE_DISTANCE = 1;
/** @type {Float32Array} */
Utils.DEFAULT_POSITION = [0, 0, 0];
/** @type {Float32Array} */
Utils.DEFAULT_FORWARD = [0, 0, -1];
/** @type {Float32Array} */
Utils.DEFAULT_UP = [0, 1, 0];
/** @type {Float32Array} */
Utils.DEFAULT_RIGHT = [1, 0, 0];
/**
* @type {Number}
*/
Utils.DEFAULT_SPEED_OF_SOUND = 343;
/** Rolloff models (e.g. 'logarithmic', 'linear', or 'none').
* @type {Array}
*/
Utils.ATTENUATION_ROLLOFFS = ['logarithmic', 'linear', 'none'];
/** Default rolloff model ('logarithmic').
* @type {string}
*/
Utils.DEFAULT_ATTENUATION_ROLLOFF = 'logarithmic';
/** @type {Number} */
Utils.DEFAULT_MIN_DISTANCE = 1;
/** @type {Number} */
Utils.DEFAULT_MAX_DISTANCE = 1000;
/**
* The default alpha (i.e. microphone pattern).
* @type {Number}
*/
Utils.DEFAULT_DIRECTIVITY_ALPHA = 0;
/**
* The default pattern sharpness (i.e. pattern exponent).
* @type {Number}
*/
Utils.DEFAULT_DIRECTIVITY_SHARPNESS = 1;
/**
* Default azimuth (in degrees). Suitable range is 0 to 360.
* @type {Number}
*/
Utils.DEFAULT_AZIMUTH = 0;
/**
* Default elevation (in degres).
* Suitable range is from -90 (below) to 90 (above).
* @type {Number}
*/
Utils.DEFAULT_ELEVATION = 0;
/**
* The default ambisonic order.
* @type {Number}
*/
Utils.DEFAULT_AMBISONIC_ORDER = 1;
/**
* The default source width.
* @type {Number}
*/
Utils.DEFAULT_SOURCE_WIDTH = 0;
/**
* The maximum delay (in seconds) of a single wall reflection.
* @type {Number}
*/
Utils.DEFAULT_REFLECTION_MAX_DURATION = 0.5;
/**
* The -12dB cutoff frequency (in Hertz) for the lowpass filter applied to
* all reflections.
* @type {Number}
*/
Utils.DEFAULT_REFLECTION_CUTOFF_FREQUENCY = 6400; // Uses -12dB cutoff.
/**
* The default reflection coefficients (where 0 = no reflection, 1 = perfect
* reflection, -1 = mirrored reflection (180-degrees out of phase)).
* @type {Object}
*/
Utils.DEFAULT_REFLECTION_COEFFICIENTS = {
left: 0, right: 0, front: 0, back: 0, down: 0, up: 0,
};
/**
* The minimum distance we consider the listener to be to any given wall.
* @type {Number}
*/
Utils.DEFAULT_REFLECTION_MIN_DISTANCE = 1;
/**
* Default room dimensions (in meters).
* @type {Object}
*/
Utils.DEFAULT_ROOM_DIMENSIONS = {
width: 0, height: 0, depth: 0,
};
/**
* The multiplier to apply to distances from the listener to each wall.
* @type {Number}
*/
Utils.DEFAULT_REFLECTION_MULTIPLIER = 1;
/** The default bandwidth (in octaves) of the center frequencies.
* @type {Number}
*/
Utils.DEFAULT_REVERB_BANDWIDTH = 1;
/** The default multiplier applied when computing tail lengths.
* @type {Number}
*/
Utils.DEFAULT_REVERB_DURATION_MULTIPLIER = 1;
/**
* The late reflections pre-delay (in milliseconds).
* @type {Number}
*/
Utils.DEFAULT_REVERB_PREDELAY = 1.5;
/**
* The length of the beginning of the impulse response to apply a
* half-Hann window to.
* @type {Number}
*/
Utils.DEFAULT_REVERB_TAIL_ONSET = 3.8;
/**
* The default gain (linear).
* @type {Number}
*/
Utils.DEFAULT_REVERB_GAIN = 0.01;
/**
* The maximum impulse response length (in seconds).
* @type {Number}
*/
Utils.DEFAULT_REVERB_MAX_DURATION = 3;
/**
* Center frequencies of the multiband late reflections.
* Nine bands are computed by: 31.25 * 2^(0:8).
* @type {Array}
*/
Utils.DEFAULT_REVERB_FREQUENCY_BANDS = [
31.25, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000,
];
/**
* The number of frequency bands.
*/
Utils.NUMBER_REVERB_FREQUENCY_BANDS =
Utils.DEFAULT_REVERB_FREQUENCY_BANDS.length;
/**
* The default multiband RT60 durations (in seconds).
* @type {Float32Array}
*/
Utils.DEFAULT_REVERB_DURATIONS =
new Float32Array(Utils.NUMBER_REVERB_FREQUENCY_BANDS);
/**
* Pre-defined frequency-dependent absorption coefficients for listed materials.
* Currently supported materials are:
* <ul>
* <li>'transparent'</li>
* <li>'acoustic-ceiling-tiles'</li>
* <li>'brick-bare'</li>
* <li>'brick-painted'</li>
* <li>'concrete-block-coarse'</li>
* <li>'concrete-block-painted'</li>
* <li>'curtain-heavy'</li>
* <li>'fiber-glass-insulation'</li>
* <li>'glass-thin'</li>
* <li>'glass-thick'</li>
* <li>'grass'</li>
* <li>'linoleum-on-concrete'</li>
* <li>'marble'</li>
* <li>'metal'</li>
* <li>'parquet-on-concrete'</li>
* <li>'plaster-smooth'</li>
* <li>'plywood-panel'</li>
* <li>'polished-concrete-or-tile'</li>
* <li>'sheetrock'</li>
* <li>'water-or-ice-surface'</li>
* <li>'wood-ceiling'</li>
* <li>'wood-panel'</li>
* <li>'uniform'</li>
* </ul>
* @type {Object}
*/
Utils.ROOM_MATERIAL_COEFFICIENTS = {
'transparent':
[1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000, 1.000],
'acoustic-ceiling-tiles':
[0.672, 0.675, 0.700, 0.660, 0.720, 0.920, 0.880, 0.750, 1.000],
'brick-bare':
[0.030, 0.030, 0.030, 0.030, 0.030, 0.040, 0.050, 0.070, 0.140],
'brick-painted':
[0.006, 0.007, 0.010, 0.010, 0.020, 0.020, 0.020, 0.030, 0.060],
'concrete-block-coarse':
[0.360, 0.360, 0.360, 0.440, 0.310, 0.290, 0.390, 0.250, 0.500],
'concrete-block-painted':
[0.092, 0.090, 0.100, 0.050, 0.060, 0.070, 0.090, 0.080, 0.160],
'curtain-heavy':
[0.073, 0.106, 0.140, 0.350, 0.550, 0.720, 0.700, 0.650, 1.000],
'fiber-glass-insulation':
[0.193, 0.220, 0.220, 0.820, 0.990, 0.990, 0.990, 0.990, 1.000],
'glass-thin':
[0.180, 0.169, 0.180, 0.060, 0.040, 0.030, 0.020, 0.020, 0.040],
'glass-thick':
[0.350, 0.350, 0.350, 0.250, 0.180, 0.120, 0.070, 0.040, 0.080],
'grass':
[0.050, 0.050, 0.150, 0.250, 0.400, 0.550, 0.600, 0.600, 0.600],
'linoleum-on-concrete':
[0.020, 0.020, 0.020, 0.030, 0.030, 0.030, 0.030, 0.020, 0.040],
'marble':
[0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.020, 0.020, 0.040],
'metal':
[0.030, 0.035, 0.040, 0.040, 0.050, 0.050, 0.050, 0.070, 0.090],
'parquet-on-concrete':
[0.028, 0.030, 0.040, 0.040, 0.070, 0.060, 0.060, 0.070, 0.140],
'plaster-rough':
[0.017, 0.018, 0.020, 0.030, 0.040, 0.050, 0.040, 0.030, 0.060],
'plaster-smooth':
[0.011, 0.012, 0.013, 0.015, 0.020, 0.030, 0.040, 0.050, 0.100],
'plywood-panel':
[0.400, 0.340, 0.280, 0.220, 0.170, 0.090, 0.100, 0.110, 0.220],
'polished-concrete-or-tile':
[0.008, 0.008, 0.010, 0.010, 0.015, 0.020, 0.020, 0.020, 0.040],
'sheet-rock':
[0.290, 0.279, 0.290, 0.100, 0.050, 0.040, 0.070, 0.090, 0.180],
'water-or-ice-surface':
[0.006, 0.006, 0.008, 0.008, 0.013, 0.015, 0.020, 0.025, 0.050],
'wood-ceiling':
[0.150, 0.147, 0.150, 0.110, 0.100, 0.070, 0.060, 0.070, 0.140],
'wood-panel':
[0.280, 0.280, 0.280, 0.220, 0.170, 0.090, 0.100, 0.110, 0.220],
'uniform':
[0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500],
};
/**
* Default materials that use strings from
* {@linkcode Utils.MATERIAL_COEFFICIENTS MATERIAL_COEFFICIENTS}
* @type {Object}
*/
Utils.DEFAULT_ROOM_MATERIALS = {
left: 'transparent', right: 'transparent', front: 'transparent',
back: 'transparent', down: 'transparent', up: 'transparent',
};
/**
* The number of bands to average over when computing reflection coefficients.
* @type {Number}
*/
Utils.NUMBER_REFLECTION_AVERAGING_BANDS = 3;
/**
* The starting band to average over when computing reflection coefficients.
* @type {Number}
*/
Utils.ROOM_STARTING_AVERAGING_BAND = 4;
/**
* The minimum threshold for room volume.
* Room model is disabled if volume is below this value.
* @type {Number} */
Utils.ROOM_MIN_VOLUME = 1e-4;
/**
* Air absorption coefficients per frequency band.
* @type {Float32Array}
*/
Utils.ROOM_AIR_ABSORPTION_COEFFICIENTS =
[0.0006, 0.0006, 0.0007, 0.0008, 0.0010, 0.0015, 0.0026, 0.0060, 0.0207];
/**
* A scalar correction value to ensure Sabine and Eyring produce the same RT60
* value at the cross-over threshold.
* @type {Number}
*/
Utils.ROOM_EYRING_CORRECTION_COEFFICIENT = 1.38;
/**
* @type {Number}
* @private
*/
Utils.TWO_PI = 6.28318530717959;
/**
* @type {Number}
* @private
*/
Utils.TWENTY_FOUR_LOG10 = 55.2620422318571;
/**
* @type {Number}
* @private
*/
Utils.LOG1000 = 6.90775527898214;
/**
* @type {Number}
* @private
*/
Utils.LOG2_DIV2 = 0.346573590279973;
/**
* @type {Number}
* @private
*/
Utils.DEGREES_TO_RADIANS = 0.017453292519943;
/**
* @type {Number}
* @private
*/
Utils.RADIANS_TO_DEGREES = 57.295779513082323;
/**
* @type {Number}
* @private
*/
Utils.EPSILON_FLOAT = 1e-8;
/**
* ResonanceAudio library logging function.
* @type {Function}
* @param {any} Message to be printed out.
* @private
*/
Utils.log = function() {
window.console.log.apply(window.console, [
'%c[ResonanceAudio]%c '
+ Array.prototype.slice.call(arguments).join(' ') + ' %c(@'
+ performance.now().toFixed(2) + 'ms)',
'background: #BBDEFB; color: #FF5722; font-weight: 700',
'font-weight: 400',
'color: #AAA',
]);
};
/**
* Normalize a 3-d vector.
* @param {Float32Array} v 3-element vector.
* @return {Float32Array} 3-element vector.
* @private
*/
Utils.normalizeVector = function(v) {
let n = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (n > exports.EPSILON_FLOAT) {
n = 1 / n;
v[0] *= n;
v[1] *= n;
v[2] *= n;
}
return v;
};
/**
* Cross-product between two 3-d vectors.
* @param {Float32Array} a 3-element vector.
* @param {Float32Array} b 3-element vector.
* @return {Float32Array}
* @private
*/
Utils.crossProduct = function(a, b) {
return [
a[1] * b[2] - a[2] * b[1],
a[2] * b[0] - a[0] * b[2],
a[0] * b[1] - a[1] * b[0],
];
};
module.exports = Utils;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Spatially encodes input using weighted spherical harmonics.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Tables = __webpack_require__(3);
const Utils = __webpack_require__(0);
/**
* @class Encoder
* @description Spatially encodes input using weighted spherical harmonics.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Number} options.ambisonicOrder
* Desired ambisonic order. Defaults to
* {@linkcode Utils.DEFAULT_AMBISONIC_ORDER DEFAULT_AMBISONIC_ORDER}.
* @param {Number} options.azimuth
* Azimuth (in degrees). Defaults to
* {@linkcode Utils.DEFAULT_AZIMUTH DEFAULT_AZIMUTH}.
* @param {Number} options.elevation
* Elevation (in degrees). Defaults to
* {@linkcode Utils.DEFAULT_ELEVATION DEFAULT_ELEVATION}.
* @param {Number} options.sourceWidth
* Source width (in degrees). Where 0 degrees is a point source and 360 degrees
* is an omnidirectional source. Defaults to
* {@linkcode Utils.DEFAULT_SOURCE_WIDTH DEFAULT_SOURCE_WIDTH}.
*/
function Encoder(context, options) {
// Public variables.
/**
* Mono (1-channel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} input
* @memberof Encoder
* @instance
*/
/**
* Ambisonic (multichannel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof Encoder
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.ambisonicOrder == undefined) {
options.ambisonicOrder = Utils.DEFAULT_AMBISONIC_ORDER;
}
if (options.azimuth == undefined) {
options.azimuth = Utils.DEFAULT_AZIMUTH;
}
if (options.elevation == undefined) {
options.elevation = Utils.DEFAULT_ELEVATION;
}
if (options.sourceWidth == undefined) {
options.sourceWidth = Utils.DEFAULT_SOURCE_WIDTH;
}
this._context = context;
// Create I/O nodes.
this.input = context.createGain();
this._channelGain = [];
this._merger = undefined;
this.output = context.createGain();
// Set initial order, angle and source width.
this.setAmbisonicOrder(options.ambisonicOrder);
this._azimuth = options.azimuth;
this._elevation = options.elevation;
this.setSourceWidth(options.sourceWidth);
}
/**
* Set the desired ambisonic order.
* @param {Number} ambisonicOrder Desired ambisonic order.
*/
Encoder.prototype.setAmbisonicOrder = function(ambisonicOrder) {
this._ambisonicOrder = Encoder.validateAmbisonicOrder(ambisonicOrder);
this.input.disconnect();
for (let i = 0; i < this._channelGain.length; i++) {
this._channelGain[i].disconnect();
}
if (this._merger != undefined) {
this._merger.disconnect();
}
delete this._channelGain;
delete this._merger;
// Create audio graph.
let numChannels = (this._ambisonicOrder + 1) * (this._ambisonicOrder + 1);
this._merger = this._context.createChannelMerger(numChannels);
this._channelGain = new Array(numChannels);
for (let i = 0; i < numChannels; i++) {
this._channelGain[i] = this._context.createGain();
this.input.connect(this._channelGain[i]);
this._channelGain[i].connect(this._merger, 0, i);
}
this._merger.connect(this.output);
};
/**
* Set the direction of the encoded source signal.
* @param {Number} azimuth
* Azimuth (in degrees). Defaults to
* {@linkcode Utils.DEFAULT_AZIMUTH DEFAULT_AZIMUTH}.
* @param {Number} elevation
* Elevation (in degrees). Defaults to
* {@linkcode Utils.DEFAULT_ELEVATION DEFAULT_ELEVATION}.
*/
Encoder.prototype.setDirection = function(azimuth, elevation) {
// Format input direction to nearest indices.
if (azimuth == undefined || isNaN(azimuth)) {
azimuth = Utils.DEFAULT_AZIMUTH;
}
if (elevation == undefined || isNaN(elevation)) {
elevation = Utils.DEFAULT_ELEVATION;
}
// Store the formatted input (for updating source width).
this._azimuth = azimuth;
this._elevation = elevation;
// Format direction for index lookups.
azimuth = Math.round(azimuth % 360);
if (azimuth < 0) {
azimuth += 360;
}
elevation = Math.round(Math.min(90, Math.max(-90, elevation))) + 90;
// Assign gains to each output.
this._channelGain[0].gain.value = Tables.MAX_RE_WEIGHTS[this._spreadIndex][0];
for (let i = 1; i <= this._ambisonicOrder; i++) {
let degreeWeight = Tables.MAX_RE_WEIGHTS[this._spreadIndex][i];
for (let j = -i; j <= i; j++) {
let acnChannel = (i * i) + i + j;
let elevationIndex = i * (i + 1) / 2 + Math.abs(j) - 1;
let val = Tables.SPHERICAL_HARMONICS[1][elevation][elevationIndex];
if (j != 0) {
let azimuthIndex = Tables.SPHERICAL_HARMONICS_MAX_ORDER + j - 1;
if (j < 0) {
azimuthIndex = Tables.SPHERICAL_HARMONICS_MAX_ORDER + j;
}
val *= Tables.SPHERICAL_HARMONICS[0][azimuth][azimuthIndex];
}
this._channelGain[acnChannel].gain.value = val * degreeWeight;
}
}
};
/**
* Set the source width (in degrees). Where 0 degrees is a point source and 360
* degrees is an omnidirectional source.
* @param {Number} sourceWidth (in degrees).
*/
Encoder.prototype.setSourceWidth = function(sourceWidth) {
// The MAX_RE_WEIGHTS is a 360 x (Tables.SPHERICAL_HARMONICS_MAX_ORDER+1)
// size table.
this._spreadIndex = Math.min(359, Math.max(0, Math.round(sourceWidth)));
this.setDirection(this._azimuth, this._elevation);
};
/**
* Validate the provided ambisonic order.
* @param {Number} ambisonicOrder Desired ambisonic order.
* @return {Number} Validated/adjusted ambisonic order.
* @private
*/
Encoder.validateAmbisonicOrder = function(ambisonicOrder) {
if (isNaN(ambisonicOrder) || ambisonicOrder == undefined) {
Utils.log('Error: Invalid ambisonic order',
options.ambisonicOrder, '\nUsing ambisonicOrder=1 instead.');
ambisonicOrder = 1;
} else if (ambisonicOrder < 1) {
Utils.log('Error: Unable to render ambisonic order',
options.ambisonicOrder, '(Min order is 1)',
'\nUsing min order instead.');
ambisonicOrder = 1;
} else if (ambisonicOrder > Tables.SPHERICAL_HARMONICS_MAX_ORDER) {
Utils.log('Error: Unable to render ambisonic order',
options.ambisonicOrder, '(Max order is',
Tables.SPHERICAL_HARMONICS_MAX_ORDER, ')\nUsing max order instead.');
options.ambisonicOrder = Tables.SPHERICAL_HARMONICS_MAX_ORDER;
}
return ambisonicOrder;
};
module.exports = Encoder;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Listener model to spatialize sources in an environment.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Omnitone = __webpack_require__(12);
const Encoder = __webpack_require__(1);
const Utils = __webpack_require__(0);
/**
* @class Listener
* @description Listener model to spatialize sources in an environment.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Number} options.ambisonicOrder
* Desired ambisonic order. Defaults to
* {@linkcode Utils.DEFAULT_AMBISONIC_ORDER DEFAULT_AMBISONIC_ORDER}.
* @param {Float32Array} options.position
* Initial position (in meters), where origin is the center of
* the room. Defaults to
* {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
* @param {Float32Array} options.forward
* The listener's initial forward vector. Defaults to
* {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
* @param {Float32Array} options.up
* The listener's initial up vector. Defaults to
* {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
*/
function Listener(context, options) {
// Public variables.
/**
* Position (in meters).
* @member {Float32Array} position
* @memberof Listener
* @instance
*/
/**
* Ambisonic (multichannel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} input
* @memberof Listener
* @instance
*/
/**
* Binaurally-rendered stereo (2-channel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof Listener
* @instance
*/
/**
* Ambisonic (multichannel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} ambisonicOutput
* @memberof Listener
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.ambisonicOrder == undefined) {
options.ambisonicOrder = Utils.DEFAULT_AMBISONIC_ORDER;
}
if (options.position == undefined) {
options.position = Utils.DEFAULT_POSITION.slice();
}
if (options.forward == undefined) {
options.forward = Utils.DEFAULT_FORWARD.slice();
}
if (options.up == undefined) {
options.up = Utils.DEFAULT_UP.slice();
}
// Member variables.
this.position = new Float32Array(3);
this._tempMatrix3 = new Float32Array(9);
// Select the appropriate HRIR filters using 2-channel chunks since
// multichannel audio is not yet supported by a majority of browsers.
this._ambisonicOrder =
Encoder.validateAmbisonicOrder(options.ambisonicOrder);
// Create audio nodes.
this._context = context;
if (this._ambisonicOrder == 1) {
this._renderer = Omnitone.Omnitone.createFOARenderer(context, {});
} else if (this._ambisonicOrder > 1) {
this._renderer = Omnitone.Omnitone.createHOARenderer(context, {
ambisonicOrder: this._ambisonicOrder,
});
}
// These nodes are created in order to safely asynchronously load Omnitone
// while the rest of the scene is being created.
this.input = context.createGain();
this.output = context.createGain();
this.ambisonicOutput = context.createGain();
// Initialize Omnitone (async) and connect to audio graph when complete.
let that = this;
this._renderer.initialize().then(function() {
// Connect pre-rotated soundfield to renderer.
that.input.connect(that._renderer.input);
// Connect rotated soundfield to ambisonic output.
if (that._ambisonicOrder > 1) {
that._renderer._hoaRotator.output.connect(that.ambisonicOutput);
} else {
that._renderer._foaRotator.output.connect(that.ambisonicOutput);
}
// Connect binaurally-rendered soundfield to binaural output.
that._renderer.output.connect(that.output);
});
// Set orientation and update rotation matrix accordingly.
this.setOrientation(options.forward[0], options.forward[1],
options.forward[2], options.up[0], options.up[1], options.up[2]);
};
/**
* Set the source's orientation using forward and up vectors.
* @param {Number} forwardX
* @param {Number} forwardY
* @param {Number} forwardZ
* @param {Number} upX
* @param {Number} upY
* @param {Number} upZ
*/
Listener.prototype.setOrientation = function(forwardX, forwardY, forwardZ,
upX, upY, upZ) {
let right = Utils.crossProduct([forwardX, forwardY, forwardZ],
[upX, upY, upZ]);
this._tempMatrix3[0] = right[0];
this._tempMatrix3[1] = right[1];
this._tempMatrix3[2] = right[2];
this._tempMatrix3[3] = upX;
this._tempMatrix3[4] = upY;
this._tempMatrix3[5] = upZ;
this._tempMatrix3[6] = forwardX;
this._tempMatrix3[7] = forwardY;
this._tempMatrix3[8] = forwardZ;
this._renderer.setRotationMatrix3(this._tempMatrix3);
};
/**
* Set the listener's position and orientation using a Three.js Matrix4 object.
* @param {Object} matrix4
* The Three.js Matrix4 object representing the listener's world transform.
*/
Listener.prototype.setFromMatrix = function(matrix4) {
// Update ambisonic rotation matrix internally.
this._renderer.setRotationMatrix4(matrix4.elements);
// Extract position from matrix.
this.position[0] = matrix4.elements[12];
this.position[1] = matrix4.elements[13];
this.position[2] = matrix4.elements[14];
};
module.exports = Listener;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Pre-computed lookup tables for encoding ambisonic sources.
* @author Andrew Allen <bitllama@google.com>
*/
/**
* Pre-computed Spherical Harmonics Coefficients.
*
* This function generates an efficient lookup table of SH coefficients. It
* exploits the way SHs are generated (i.e. Ylm = Nlm * Plm * Em). Since Nlm
* & Plm coefficients only depend on theta, and Em only depends on phi, we
* can separate the equation along these lines. Em does not depend on
* degree, so we only need to compute (2 * l) per azimuth Em total and
* Nlm * Plm is symmetrical across indexes, so only positive indexes are
* computed ((l + 1) * (l + 2) / 2 - 1) per elevation.
* @type {Float32Array}
*/
exports.SPHERICAL_HARMONICS =
[
[
[0.000000, 0.000000, 0.000000, 1.000000, 1.000000, 1.000000],
[0.052336, 0.034899, 0.017452, 0.999848, 0.999391, 0.998630],
[0.104528, 0.069756, 0.034899, 0.999391, 0.997564, 0.994522],
[0.156434, 0.104528, 0.052336, 0.998630, 0.994522, 0.987688],
[0.207912, 0.139173, 0.069756, 0.997564, 0.990268, 0.978148],
[0.258819, 0.173648, 0.087156, 0.996195, 0.984808, 0.965926],
[0.309017, 0.207912, 0.104528, 0.994522, 0.978148, 0.951057],
[0.358368, 0.241922, 0.121869, 0.992546, 0.970296, 0.933580],
[0.406737, 0.275637, 0.139173, 0.990268, 0.961262, 0.913545],
[0.453990, 0.309017, 0.156434, 0.987688, 0.951057, 0.891007],
[0.500000, 0.342020, 0.173648, 0.984808, 0.939693, 0.866025],
[0.544639, 0.374607, 0.190809, 0.981627, 0.927184, 0.838671],
[0.587785, 0.406737, 0.207912, 0.978148, 0.913545, 0.809017],
[0.629320, 0.438371, 0.224951, 0.974370, 0.898794, 0.777146],
[0.669131, 0.469472, 0.241922, 0.970296, 0.882948, 0.743145],
[0.707107, 0.500000, 0.258819, 0.965926, 0.866025, 0.707107],
[0.743145, 0.529919, 0.275637, 0.961262, 0.848048, 0.669131],
[0.777146, 0.559193, 0.292372, 0.956305, 0.829038, 0.629320],
[0.809017, 0.587785, 0.309017, 0.951057, 0.809017, 0.587785],
[0.838671, 0.615661, 0.325568, 0.945519, 0.788011, 0.544639],
[0.866025, 0.642788, 0.342020, 0.939693, 0.766044, 0.500000],
[0.891007, 0.669131, 0.358368, 0.933580, 0.743145, 0.453990],
[0.913545, 0.694658, 0.374607, 0.927184, 0.719340, 0.406737],
[0.933580, 0.719340, 0.390731, 0.920505, 0.694658, 0.358368],
[0.951057, 0.743145, 0.406737, 0.913545, 0.669131, 0.309017],
[0.965926, 0.766044, 0.422618, 0.906308, 0.642788, 0.258819],
[0.978148, 0.788011, 0.438371, 0.898794, 0.615661, 0.207912],
[0.987688, 0.809017, 0.453990, 0.891007, 0.587785, 0.156434],
[0.994522, 0.829038, 0.469472, 0.882948, 0.559193, 0.104528],
[0.998630, 0.848048, 0.484810, 0.874620, 0.529919, 0.052336],
[1.000000, 0.866025, 0.500000, 0.866025, 0.500000, 0.000000],
[0.998630, 0.882948, 0.515038, 0.857167, 0.469472, -0.052336],
[0.994522, 0.898794, 0.529919, 0.848048, 0.438371, -0.104528],
[0.987688, 0.913545, 0.544639, 0.838671, 0.406737, -0.156434],
[0.978148, 0.927184, 0.559193, 0.829038, 0.374607, -0.207912],
[0.965926, 0.939693, 0.573576, 0.819152, 0.342020, -0.258819],
[0.951057, 0.951057, 0.587785, 0.809017, 0.309017, -0.309017],
[0.933580, 0.961262, 0.601815, 0.798636, 0.275637, -0.358368],
[0.913545, 0.970296, 0.615661, 0.788011, 0.241922, -0.406737],
[0.891007, 0.978148, 0.629320, 0.777146, 0.207912, -0.453990],
[0.866025, 0.984808, 0.642788, 0.766044, 0.173648, -0.500000],
[0.838671, 0.990268, 0.656059, 0.754710, 0.139173, -0.544639],
[0.809017, 0.994522, 0.669131, 0.743145, 0.104528, -0.587785],
[0.777146, 0.997564, 0.681998, 0.731354, 0.069756, -0.629320],
[0.743145, 0.999391, 0.694658, 0.719340, 0.034899, -0.669131],
[0.707107, 1.000000, 0.707107, 0.707107, 0.000000, -0.707107],
[0.669131, 0.999391, 0.719340, 0.694658, -0.034899, -0.743145],
[0.629320, 0.997564, 0.731354, 0.681998, -0.069756, -0.777146],
[0.587785, 0.994522, 0.743145, 0.669131, -0.104528, -0.809017],
[0.544639, 0.990268, 0.754710, 0.656059, -0.139173, -0.838671],
[0.500000, 0.984808, 0.766044, 0.642788, -0.173648, -0.866025],
[0.453990, 0.978148, 0.777146, 0.629320, -0.207912, -0.891007],
[0.406737, 0.970296, 0.788011, 0.615661, -0.241922, -0.913545],
[0.358368, 0.961262, 0.798636, 0.601815, -0.275637, -0.933580],
[0.309017, 0.951057, 0.809017, 0.587785, -0.309017, -0.951057],
[0.258819, 0.939693, 0.819152, 0.573576, -0.342020, -0.965926],
[0.207912, 0.927184, 0.829038, 0.559193, -0.374607, -0.978148],
[0.156434, 0.913545, 0.838671, 0.544639, -0.406737, -0.987688],
[0.104528, 0.898794, 0.848048, 0.529919, -0.438371, -0.994522],
[0.052336, 0.882948, 0.857167, 0.515038, -0.469472, -0.998630],
[0.000000, 0.866025, 0.866025, 0.500000, -0.500000, -1.000000],
[-0.052336, 0.848048, 0.874620, 0.484810, -0.529919, -0.998630],
[-0.104528, 0.829038, 0.882948, 0.469472, -0.559193, -0.994522],
[-0.156434, 0.809017, 0.891007, 0.453990, -0.587785, -0.987688],
[-0.207912, 0.788011, 0.898794, 0.438371, -0.615661, -0.978148],
[-0.258819, 0.766044, 0.906308, 0.422618, -0.642788, -0.965926],
[-0.309017, 0.743145, 0.913545, 0.406737, -0.669131, -0.951057],
[-0.358368, 0.719340, 0.920505, 0.390731, -0.694658, -0.933580],
[-0.406737, 0.694658, 0.927184, 0.374607, -0.719340, -0.913545],
[-0.453990, 0.669131, 0.933580, 0.358368, -0.743145, -0.891007],
[-0.500000, 0.642788, 0.939693, 0.342020, -0.766044, -0.866025],
[-0.544639, 0.615661, 0.945519, 0.325568, -0.788011, -0.838671],
[-0.587785, 0.587785, 0.951057, 0.309017, -0.809017, -0.809017],
[-0.629320, 0.559193, 0.956305, 0.292372, -0.829038, -0.777146],
[-0.669131, 0.529919, 0.961262, 0.275637, -0.848048, -0.743145],
[-0.707107, 0.500000, 0.965926, 0.258819, -0.866025, -0.707107],
[-0.743145, 0.469472, 0.970296, 0.241922, -0.882948, -0.669131],
[-0.777146, 0.438371, 0.974370, 0.224951, -0.898794, -0.629320],
[-0.809017, 0.406737, 0.978148, 0.207912, -0.913545, -0.587785],
[-0.838671, 0.374607, 0.981627, 0.190809, -0.927184, -0.544639],
[-0.866025, 0.342020, 0.984808, 0.173648, -0.939693, -0.500000],
[-0.891007, 0.309017, 0.987688, 0.156434, -0.951057, -0.453990],
[-0.913545, 0.275637, 0.990268, 0.139173, -0.961262, -0.406737],
[-0.933580, 0.241922, 0.992546, 0.121869, -0.970296, -0.358368],
[-0.951057, 0.207912, 0.994522, 0.104528, -0.978148, -0.309017],
[-0.965926, 0.173648, 0.996195, 0.087156, -0.984808, -0.258819],
[-0.978148, 0.139173, 0.997564, 0.069756, -0.990268, -0.207912],
[-0.987688, 0.104528, 0.998630, 0.052336, -0.994522, -0.156434],
[-0.994522, 0.069756, 0.999391, 0.034899, -0.997564, -0.104528],
[-0.998630, 0.034899, 0.999848, 0.017452, -0.999391, -0.052336],
[-1.000000, 0.000000, 1.000000, 0.000000, -1.000000, -0.000000],
[-0.998630, -0.034899, 0.999848, -0.017452, -0.999391, 0.052336],
[-0.994522, -0.069756, 0.999391, -0.034899, -0.997564, 0.104528],
[-0.987688, -0.104528, 0.998630, -0.052336, -0.994522, 0.156434],
[-0.978148, -0.139173, 0.997564, -0.069756, -0.990268, 0.207912],
[-0.965926, -0.173648, 0.996195, -0.087156, -0.984808, 0.258819],
[-0.951057, -0.207912, 0.994522, -0.104528, -0.978148, 0.309017],
[-0.933580, -0.241922, 0.992546, -0.121869, -0.970296, 0.358368],
[-0.913545, -0.275637, 0.990268, -0.139173, -0.961262, 0.406737],
[-0.891007, -0.309017, 0.987688, -0.156434, -0.951057, 0.453990],
[-0.866025, -0.342020, 0.984808, -0.173648, -0.939693, 0.500000],
[-0.838671, -0.374607, 0.981627, -0.190809, -0.927184, 0.544639],
[-0.809017, -0.406737, 0.978148, -0.207912, -0.913545, 0.587785],
[-0.777146, -0.438371, 0.974370, -0.224951, -0.898794, 0.629320],
[-0.743145, -0.469472, 0.970296, -0.241922, -0.882948, 0.669131],
[-0.707107, -0.500000, 0.965926, -0.258819, -0.866025, 0.707107],
[-0.669131, -0.529919, 0.961262, -0.275637, -0.848048, 0.743145],
[-0.629320, -0.559193, 0.956305, -0.292372, -0.829038, 0.777146],
[-0.587785, -0.587785, 0.951057, -0.309017, -0.809017, 0.809017],
[-0.544639, -0.615661, 0.945519, -0.325568, -0.788011, 0.838671],
[-0.500000, -0.642788, 0.939693, -0.342020, -0.766044, 0.866025],
[-0.453990, -0.669131, 0.933580, -0.358368, -0.743145, 0.891007],
[-0.406737, -0.694658, 0.927184, -0.374607, -0.719340, 0.913545],
[-0.358368, -0.719340, 0.920505, -0.390731, -0.694658, 0.933580],
[-0.309017, -0.743145, 0.913545, -0.406737, -0.669131, 0.951057],
[-0.258819, -0.766044, 0.906308, -0.422618, -0.642788, 0.965926],
[-0.207912, -0.788011, 0.898794, -0.438371, -0.615661, 0.978148],
[-0.156434, -0.809017, 0.891007, -0.453990, -0.587785, 0.987688],
[-0.104528, -0.829038, 0.882948, -0.469472, -0.559193, 0.994522],
[-0.052336, -0.848048, 0.874620, -0.484810, -0.529919, 0.998630],
[-0.000000, -0.866025, 0.866025, -0.500000, -0.500000, 1.000000],
[0.052336, -0.882948, 0.857167, -0.515038, -0.469472, 0.998630],
[0.104528, -0.898794, 0.848048, -0.529919, -0.438371, 0.994522],
[0.156434, -0.913545, 0.838671, -0.544639, -0.406737, 0.987688],
[0.207912, -0.927184, 0.829038, -0.559193, -0.374607, 0.978148],
[0.258819, -0.939693, 0.819152, -0.573576, -0.342020, 0.965926],
[0.309017, -0.951057, 0.809017, -0.587785, -0.309017, 0.951057],
[0.358368, -0.961262, 0.798636, -0.601815, -0.275637, 0.933580],
[0.406737, -0.970296, 0.788011, -0.615661, -0.241922, 0.913545],
[0.453990, -0.978148, 0.777146, -0.629320, -0.207912, 0.891007],
[0.500000, -0.984808, 0.766044, -0.642788, -0.173648, 0.866025],
[0.544639, -0.990268, 0.754710, -0.656059, -0.139173, 0.838671],
[0.587785, -0.994522, 0.743145, -0.669131, -0.104528, 0.809017],
[0.629320, -0.997564, 0.731354, -0.681998, -0.069756, 0.777146],
[0.669131, -0.999391, 0.719340, -0.694658, -0.034899, 0.743145],
[0.707107, -1.000000, 0.707107, -0.707107, -0.000000, 0.707107],
[0.743145, -0.999391, 0.694658, -0.719340, 0.034899, 0.669131],
[0.777146, -0.997564, 0.681998, -0.731354, 0.069756, 0.629320],
[0.809017, -0.994522, 0.669131, -0.743145, 0.104528, 0.587785],
[0.838671, -0.990268, 0.656059, -0.754710, 0.139173, 0.544639],
[0.866025, -0.984808, 0.642788, -0.766044, 0.173648, 0.500000],
[0.891007, -0.978148, 0.629320, -0.777146, 0.207912, 0.453990],
[0.913545, -0.970296, 0.615661, -0.788011, 0.241922, 0.406737],
[0.933580, -0.961262, 0.601815, -0.798636, 0.275637, 0.358368],
[0.951057, -0.951057, 0.587785, -0.809017, 0.309017, 0.309017],
[0.965926, -0.939693, 0.573576, -0.819152, 0.342020, 0.258819],
[0.978148, -0.927184, 0.559193, -0.829038, 0.374607, 0.207912],
[0.987688, -0.913545, 0.544639, -0.838671, 0.406737, 0.156434],
[0.994522, -0.898794, 0.529919, -0.848048, 0.438371, 0.104528],
[0.998630, -0.882948, 0.515038, -0.857167, 0.469472, 0.052336],
[1.000000, -0.866025, 0.500000, -0.866025, 0.500000, 0.000000],
[0.998630, -0.848048, 0.484810, -0.874620, 0.529919, -0.052336],
[0.994522, -0.829038, 0.469472, -0.882948, 0.559193, -0.104528],
[0.987688, -0.809017, 0.453990, -0.891007, 0.587785, -0.156434],
[0.978148, -0.788011, 0.438371, -0.898794, 0.615661, -0.207912],
[0.965926, -0.766044, 0.422618, -0.906308, 0.642788, -0.258819],
[0.951057, -0.743145, 0.406737, -0.913545, 0.669131, -0.309017],
[0.933580, -0.719340, 0.390731, -0.920505, 0.694658, -0.358368],
[0.913545, -0.694658, 0.374607, -0.927184, 0.719340, -0.406737],
[0.891007, -0.669131, 0.358368, -0.933580, 0.743145, -0.453990],
[0.866025, -0.642788, 0.342020, -0.939693, 0.766044, -0.500000],
[0.838671, -0.615661, 0.325568, -0.945519, 0.788011, -0.544639],
[0.809017, -0.587785, 0.309017, -0.951057, 0.809017, -0.587785],
[0.777146, -0.559193, 0.292372, -0.956305, 0.829038, -0.629320],
[0.743145, -0.529919, 0.275637, -0.961262, 0.848048, -0.669131],
[0.707107, -0.500000, 0.258819, -0.965926, 0.866025, -0.707107],
[0.669131, -0.469472, 0.241922, -0.970296, 0.882948, -0.743145],
[0.629320, -0.438371, 0.224951, -0.974370, 0.898794, -0.777146],
[0.587785, -0.406737, 0.207912, -0.978148, 0.913545, -0.809017],
[0.544639, -0.374607, 0.190809, -0.981627, 0.927184, -0.838671],
[0.500000, -0.342020, 0.173648, -0.984808, 0.939693, -0.866025],
[0.453990, -0.309017, 0.156434, -0.987688, 0.951057, -0.891007],
[0.406737, -0.275637, 0.139173, -0.990268, 0.961262, -0.913545],
[0.358368, -0.241922, 0.121869, -0.992546, 0.970296, -0.933580],
[0.309017, -0.207912, 0.104528, -0.994522, 0.978148, -0.951057],
[0.258819, -0.173648, 0.087156, -0.996195, 0.984808, -0.965926],
[0.207912, -0.139173, 0.069756, -0.997564, 0.990268, -0.978148],
[0.156434, -0.104528, 0.052336, -0.998630, 0.994522, -0.987688],
[0.104528, -0.069756, 0.034899, -0.999391, 0.997564, -0.994522],
[0.052336, -0.034899, 0.017452, -0.999848, 0.999391, -0.998630],
[0.000000, -0.000000, 0.000000, -1.000000, 1.000000, -1.000000],
[-0.052336, 0.034899, -0.017452, -0.999848, 0.999391, -0.998630],
[-0.104528, 0.069756, -0.034899, -0.999391, 0.997564, -0.994522],
[-0.156434, 0.104528, -0.052336, -0.998630, 0.994522, -0.987688],
[-0.207912, 0.139173, -0.069756, -0.997564, 0.990268, -0.978148],
[-0.258819, 0.173648, -0.087156, -0.996195, 0.984808, -0.965926],
[-0.309017, 0.207912, -0.104528, -0.994522, 0.978148, -0.951057],
[-0.358368, 0.241922, -0.121869, -0.992546, 0.970296, -0.933580],
[-0.406737, 0.275637, -0.139173, -0.990268, 0.961262, -0.913545],
[-0.453990, 0.309017, -0.156434, -0.987688, 0.951057, -0.891007],
[-0.500000, 0.342020, -0.173648, -0.984808, 0.939693, -0.866025],
[-0.544639, 0.374607, -0.190809, -0.981627, 0.927184, -0.838671],
[-0.587785, 0.406737, -0.207912, -0.978148, 0.913545, -0.809017],
[-0.629320, 0.438371, -0.224951, -0.974370, 0.898794, -0.777146],
[-0.669131, 0.469472, -0.241922, -0.970296, 0.882948, -0.743145],
[-0.707107, 0.500000, -0.258819, -0.965926, 0.866025, -0.707107],
[-0.743145, 0.529919, -0.275637, -0.961262, 0.848048, -0.669131],
[-0.777146, 0.559193, -0.292372, -0.956305, 0.829038, -0.629320],
[-0.809017, 0.587785, -0.309017, -0.951057, 0.809017, -0.587785],
[-0.838671, 0.615661, -0.325568, -0.945519, 0.788011, -0.544639],
[-0.866025, 0.642788, -0.342020, -0.939693, 0.766044, -0.500000],
[-0.891007, 0.669131, -0.358368, -0.933580, 0.743145, -0.453990],
[-0.913545, 0.694658, -0.374607, -0.927184, 0.719340, -0.406737],
[-0.933580, 0.719340, -0.390731, -0.920505, 0.694658, -0.358368],
[-0.951057, 0.743145, -0.406737, -0.913545, 0.669131, -0.309017],
[-0.965926, 0.766044, -0.422618, -0.906308, 0.642788, -0.258819],
[-0.978148, 0.788011, -0.438371, -0.898794, 0.615661, -0.207912],
[-0.987688, 0.809017, -0.453990, -0.891007, 0.587785, -0.156434],
[-0.994522, 0.829038, -0.469472, -0.882948, 0.559193, -0.104528],
[-0.998630, 0.848048, -0.484810, -0.874620, 0.529919, -0.052336],
[-1.000000, 0.866025, -0.500000, -0.866025, 0.500000, 0.000000],
[-0.998630, 0.882948, -0.515038, -0.857167, 0.469472, 0.052336],
[-0.994522, 0.898794, -0.529919, -0.848048, 0.438371, 0.104528],
[-0.987688, 0.913545, -0.544639, -0.838671, 0.406737, 0.156434],
[-0.978148, 0.927184, -0.559193, -0.829038, 0.374607, 0.207912],
[-0.965926, 0.939693, -0.573576, -0.819152, 0.342020, 0.258819],
[-0.951057, 0.951057, -0.587785, -0.809017, 0.309017, 0.309017],
[-0.933580, 0.961262, -0.601815, -0.798636, 0.275637, 0.358368],
[-0.913545, 0.970296, -0.615661, -0.788011, 0.241922, 0.406737],
[-0.891007, 0.978148, -0.629320, -0.777146, 0.207912, 0.453990],
[-0.866025, 0.984808, -0.642788, -0.766044, 0.173648, 0.500000],
[-0.838671, 0.990268, -0.656059, -0.754710, 0.139173, 0.544639],
[-0.809017, 0.994522, -0.669131, -0.743145, 0.104528, 0.587785],
[-0.777146, 0.997564, -0.681998, -0.731354, 0.069756, 0.629320],
[-0.743145, 0.999391, -0.694658, -0.719340, 0.034899, 0.669131],
[-0.707107, 1.000000, -0.707107, -0.707107, 0.000000, 0.707107],
[-0.669131, 0.999391, -0.719340, -0.694658, -0.034899, 0.743145],
[-0.629320, 0.997564, -0.731354, -0.681998, -0.069756, 0.777146],
[-0.587785, 0.994522, -0.743145, -0.669131, -0.104528, 0.809017],
[-0.544639, 0.990268, -0.754710, -0.656059, -0.139173, 0.838671],
[-0.500000, 0.984808, -0.766044, -0.642788, -0.173648, 0.866025],
[-0.453990, 0.978148, -0.777146, -0.629320, -0.207912, 0.891007],
[-0.406737, 0.970296, -0.788011, -0.615661, -0.241922, 0.913545],
[-0.358368, 0.961262, -0.798636, -0.601815, -0.275637, 0.933580],
[-0.309017, 0.951057, -0.809017, -0.587785, -0.309017, 0.951057],
[-0.258819, 0.939693, -0.819152, -0.573576, -0.342020, 0.965926],
[-0.207912, 0.927184, -0.829038, -0.559193, -0.374607, 0.978148],
[-0.156434, 0.913545, -0.838671, -0.544639, -0.406737, 0.987688],
[-0.104528, 0.898794, -0.848048, -0.529919, -0.438371, 0.994522],
[-0.052336, 0.882948, -0.857167, -0.515038, -0.469472, 0.998630],
[-0.000000, 0.866025, -0.866025, -0.500000, -0.500000, 1.000000],
[0.052336, 0.848048, -0.874620, -0.484810, -0.529919, 0.998630],
[0.104528, 0.829038, -0.882948, -0.469472, -0.559193, 0.994522],
[0.156434, 0.809017, -0.891007, -0.453990, -0.587785, 0.987688],
[0.207912, 0.788011, -0.898794, -0.438371, -0.615661, 0.978148],
[0.258819, 0.766044, -0.906308, -0.422618, -0.642788, 0.965926],
[0.309017, 0.743145, -0.913545, -0.406737, -0.669131, 0.951057],
[0.358368, 0.719340, -0.920505, -0.390731, -0.694658, 0.933580],
[0.406737, 0.694658, -0.927184, -0.374607, -0.719340, 0.913545],
[0.453990, 0.669131, -0.933580, -0.358368, -0.743145, 0.891007],
[0.500000, 0.642788, -0.939693, -0.342020, -0.766044, 0.866025],
[0.544639, 0.615661, -0.945519, -0.325568, -0.788011, 0.838671],
[0.587785, 0.587785, -0.951057, -0.309017, -0.809017, 0.809017],
[0.629320, 0.559193, -0.956305, -0.292372, -0.829038, 0.777146],
[0.669131, 0.529919, -0.961262, -0.275637, -0.848048, 0.743145],
[0.707107, 0.500000, -0.965926, -0.258819, -0.866025, 0.707107],
[0.743145, 0.469472, -0.970296, -0.241922, -0.882948, 0.669131],
[0.777146, 0.438371, -0.974370, -0.224951, -0.898794, 0.629320],
[0.809017, 0.406737, -0.978148, -0.207912, -0.913545, 0.587785],
[0.838671, 0.374607, -0.981627, -0.190809, -0.927184, 0.544639],
[0.866025, 0.342020, -0.984808, -0.173648, -0.939693, 0.500000],
[0.891007, 0.309017, -0.987688, -0.156434, -0.951057, 0.453990],
[0.913545, 0.275637, -0.990268, -0.139173, -0.961262, 0.406737],
[0.933580, 0.241922, -0.992546, -0.121869, -0.970296, 0.358368],
[0.951057, 0.207912, -0.994522, -0.104528, -0.978148, 0.309017],
[0.965926, 0.173648, -0.996195, -0.087156, -0.984808, 0.258819],
[0.978148, 0.139173, -0.997564, -0.069756, -0.990268, 0.207912],
[0.987688, 0.104528, -0.998630, -0.052336, -0.994522, 0.156434],
[0.994522, 0.069756, -0.999391, -0.034899, -0.997564, 0.104528],
[0.998630, 0.034899, -0.999848, -0.017452, -0.999391, 0.052336],
[1.000000, 0.000000, -1.000000, -0.000000, -1.000000, 0.000000],
[0.998630, -0.034899, -0.999848, 0.017452, -0.999391, -0.052336],
[0.994522, -0.069756, -0.999391, 0.034899, -0.997564, -0.104528],
[0.987688, -0.104528, -0.998630, 0.052336, -0.994522, -0.156434],
[0.978148, -0.139173, -0.997564, 0.069756, -0.990268, -0.207912],
[0.965926, -0.173648, -0.996195, 0.087156, -0.984808, -0.258819],
[0.951057, -0.207912, -0.994522, 0.104528, -0.978148, -0.309017],
[0.933580, -0.241922, -0.992546, 0.121869, -0.970296, -0.358368],
[0.913545, -0.275637, -0.990268, 0.139173, -0.961262, -0.406737],
[0.891007, -0.309017, -0.987688, 0.156434, -0.951057, -0.453990],
[0.866025, -0.342020, -0.984808, 0.173648, -0.939693, -0.500000],
[0.838671, -0.374607, -0.981627, 0.190809, -0.927184, -0.544639],
[0.809017, -0.406737, -0.978148, 0.207912, -0.913545, -0.587785],
[0.777146, -0.438371, -0.974370, 0.224951, -0.898794, -0.629320],
[0.743145, -0.469472, -0.970296, 0.241922, -0.882948, -0.669131],
[0.707107, -0.500000, -0.965926, 0.258819, -0.866025, -0.707107],
[0.669131, -0.529919, -0.961262, 0.275637, -0.848048, -0.743145],
[0.629320, -0.559193, -0.956305, 0.292372, -0.829038, -0.777146],
[0.587785, -0.587785, -0.951057, 0.309017, -0.809017, -0.809017],
[0.544639, -0.615661, -0.945519, 0.325568, -0.788011, -0.838671],
[0.500000, -0.642788, -0.939693, 0.342020, -0.766044, -0.866025],
[0.453990, -0.669131, -0.933580, 0.358368, -0.743145, -0.891007],
[0.406737, -0.694658, -0.927184, 0.374607, -0.719340, -0.913545],
[0.358368, -0.719340, -0.920505, 0.390731, -0.694658, -0.933580],
[0.309017, -0.743145, -0.913545, 0.406737, -0.669131, -0.951057],
[0.258819, -0.766044, -0.906308, 0.422618, -0.642788, -0.965926],
[0.207912, -0.788011, -0.898794, 0.438371, -0.615661, -0.978148],
[0.156434, -0.809017, -0.891007, 0.453990, -0.587785, -0.987688],
[0.104528, -0.829038, -0.882948, 0.469472, -0.559193, -0.994522],
[0.052336, -0.848048, -0.874620, 0.484810, -0.529919, -0.998630],
[0.000000, -0.866025, -0.866025, 0.500000, -0.500000, -1.000000],
[-0.052336, -0.882948, -0.857167, 0.515038, -0.469472, -0.998630],
[-0.104528, -0.898794, -0.848048, 0.529919, -0.438371, -0.994522],
[-0.156434, -0.913545, -0.838671, 0.544639, -0.406737, -0.987688],
[-0.207912, -0.927184, -0.829038, 0.559193, -0.374607, -0.978148],
[-0.258819, -0.939693, -0.819152, 0.573576, -0.342020, -0.965926],
[-0.309017, -0.951057, -0.809017, 0.587785, -0.309017, -0.951057],
[-0.358368, -0.961262, -0.798636, 0.601815, -0.275637, -0.933580],
[-0.406737, -0.970296, -0.788011, 0.615661, -0.241922, -0.913545],
[-0.453990, -0.978148, -0.777146, 0.629320, -0.207912, -0.891007],
[-0.500000, -0.984808, -0.766044, 0.642788, -0.173648, -0.866025],
[-0.544639, -0.990268, -0.754710, 0.656059, -0.139173, -0.838671],
[-0.587785, -0.994522, -0.743145, 0.669131, -0.104528, -0.809017],
[-0.629320, -0.997564, -0.731354, 0.681998, -0.069756, -0.777146],
[-0.669131, -0.999391, -0.719340, 0.694658, -0.034899, -0.743145],
[-0.707107, -1.000000, -0.707107, 0.707107, -0.000000, -0.707107],
[-0.743145, -0.999391, -0.694658, 0.719340, 0.034899, -0.669131],
[-0.777146, -0.997564, -0.681998, 0.731354, 0.069756, -0.629320],
[-0.809017, -0.994522, -0.669131, 0.743145, 0.104528, -0.587785],
[-0.838671, -0.990268, -0.656059, 0.754710, 0.139173, -0.544639],
[-0.866025, -0.984808, -0.642788, 0.766044, 0.173648, -0.500000],
[-0.891007, -0.978148, -0.629320, 0.777146, 0.207912, -0.453990],
[-0.913545, -0.970296, -0.615661, 0.788011, 0.241922, -0.406737],
[-0.933580, -0.961262, -0.601815, 0.798636, 0.275637, -0.358368],
[-0.951057, -0.951057, -0.587785, 0.809017, 0.309017, -0.309017],
[-0.965926, -0.939693, -0.573576, 0.819152, 0.342020, -0.258819],
[-0.978148, -0.927184, -0.559193, 0.829038, 0.374607, -0.207912],
[-0.987688, -0.913545, -0.544639, 0.838671, 0.406737, -0.156434],
[-0.994522, -0.898794, -0.529919, 0.848048, 0.438371, -0.104528],
[-0.998630, -0.882948, -0.515038, 0.857167, 0.469472, -0.052336],
[-1.000000, -0.866025, -0.500000, 0.866025, 0.500000, -0.000000],
[-0.998630, -0.848048, -0.484810, 0.874620, 0.529919, 0.052336],
[-0.994522, -0.829038, -0.469472, 0.882948, 0.559193, 0.104528],
[-0.987688, -0.809017, -0.453990, 0.891007, 0.587785, 0.156434],
[-0.978148, -0.788011, -0.438371, 0.898794, 0.615661, 0.207912],
[-0.965926, -0.766044, -0.422618, 0.906308, 0.642788, 0.258819],
[-0.951057, -0.743145, -0.406737, 0.913545, 0.669131, 0.309017],
[-0.933580, -0.719340, -0.390731, 0.920505, 0.694658, 0.358368],
[-0.913545, -0.694658, -0.374607, 0.927184, 0.719340, 0.406737],
[-0.891007, -0.669131, -0.358368, 0.933580, 0.743145, 0.453990],
[-0.866025, -0.642788, -0.342020, 0.939693, 0.766044, 0.500000],
[-0.838671, -0.615661, -0.325568, 0.945519, 0.788011, 0.544639],
[-0.809017, -0.587785, -0.309017, 0.951057, 0.809017, 0.587785],
[-0.777146, -0.559193, -0.292372, 0.956305, 0.829038, 0.629320],
[-0.743145, -0.529919, -0.275637, 0.961262, 0.848048, 0.669131],
[-0.707107, -0.500000, -0.258819, 0.965926, 0.866025, 0.707107],
[-0.669131, -0.469472, -0.241922, 0.970296, 0.882948, 0.743145],
[-0.629320, -0.438371, -0.224951, 0.974370, 0.898794, 0.777146],
[-0.587785, -0.406737, -0.207912, 0.978148, 0.913545, 0.809017],
[-0.544639, -0.374607, -0.190809, 0.981627, 0.927184, 0.838671],
[-0.500000, -0.342020, -0.173648, 0.984808, 0.939693, 0.866025],
[-0.453990, -0.309017, -0.156434, 0.987688, 0.951057, 0.891007],
[-0.406737, -0.275637, -0.139173, 0.990268, 0.961262, 0.913545],
[-0.358368, -0.241922, -0.121869, 0.992546, 0.970296, 0.933580],
[-0.309017, -0.207912, -0.104528, 0.994522, 0.978148, 0.951057],
[-0.258819, -0.173648, -0.087156, 0.996195, 0.984808, 0.965926],
[-0.207912, -0.139173, -0.069756, 0.997564, 0.990268, 0.978148],
[-0.156434, -0.104528, -0.052336, 0.998630, 0.994522, 0.987688],
[-0.104528, -0.069756, -0.034899, 0.999391, 0.997564, 0.994522],
[-0.052336, -0.034899, -0.017452, 0.999848, 0.999391, 0.998630],
],
[
[-1.000000, -0.000000, 1.000000, -0.000000, 0.000000,
-1.000000, -0.000000, 0.000000, -0.000000],
[-0.999848, 0.017452, 0.999543, -0.030224, 0.000264,
-0.999086, 0.042733, -0.000590, 0.000004],
[-0.999391, 0.034899, 0.998173, -0.060411, 0.001055,
-0.996348, 0.085356, -0.002357, 0.000034],
[-0.998630, 0.052336, 0.995891, -0.090524, 0.002372,
-0.991791, 0.127757, -0.005297, 0.000113],
[-0.997564, 0.069756, 0.992701, -0.120527, 0.004214,
-0.985429, 0.169828, -0.009400, 0.000268],
[-0.996195, 0.087156, 0.988606, -0.150384, 0.006578,
-0.977277, 0.211460, -0.014654, 0.000523],
[-0.994522, 0.104528, 0.983611, -0.180057, 0.009462,
-0.967356, 0.252544, -0.021043, 0.000903],
[-0.992546, 0.121869, 0.977722, -0.209511, 0.012862,
-0.955693, 0.292976, -0.028547, 0.001431],
[-0.990268, 0.139173, 0.970946, -0.238709, 0.016774,
-0.942316, 0.332649, -0.037143, 0.002131],
[-0.987688, 0.156434, 0.963292, -0.267617, 0.021193,
-0.927262, 0.371463, -0.046806, 0.003026],
[-0.984808, 0.173648, 0.954769, -0.296198, 0.026114,
-0.910569, 0.409317, -0.057505, 0.004140],
[-0.981627, 0.190809, 0.945388, -0.324419, 0.031530,
-0.892279, 0.446114, -0.069209, 0.005492],
[-0.978148, 0.207912, 0.935159, -0.352244, 0.037436,
-0.872441, 0.481759, -0.081880, 0.007105],
[-0.974370, 0.224951, 0.924096, -0.379641, 0.043823,
-0.851105, 0.516162, -0.095481, 0.008999],
[-0.970296, 0.241922, 0.912211, -0.406574, 0.050685,
-0.828326, 0.549233, -0.109969, 0.011193],
[-0.965926, 0.258819, 0.899519, -0.433013, 0.058013,
-0.804164, 0.580889, -0.125300, 0.013707],
[-0.961262, 0.275637, 0.886036, -0.458924, 0.065797,
-0.778680, 0.611050, -0.141427, 0.016556],
[-0.956305, 0.292372, 0.871778, -0.484275, 0.074029,
-0.751940, 0.639639, -0.158301, 0.019758],
[-0.951057, 0.309017, 0.856763, -0.509037, 0.082698,
-0.724012, 0.666583, -0.175868, 0.023329],
[-0.945519, 0.325568, 0.841008, -0.533178, 0.091794,
-0.694969, 0.691816, -0.194075, 0.027281],
[-0.939693, 0.342020, 0.824533, -0.556670, 0.101306,
-0.664885, 0.715274, -0.212865, 0.031630],
[-0.933580, 0.358368, 0.807359, -0.579484, 0.111222,
-0.633837, 0.736898, -0.232180, 0.036385],
[-0.927184, 0.374607, 0.789505, -0.601592, 0.121529,
-0.601904, 0.756637, -0.251960, 0.041559],
[-0.920505, 0.390731, 0.770994, -0.622967, 0.132217,
-0.569169, 0.774442, -0.272143, 0.047160],
[-0.913545, 0.406737, 0.751848, -0.643582, 0.143271,
-0.535715, 0.790270, -0.292666, 0.053196],
[-0.906308, 0.422618, 0.732091, -0.663414, 0.154678,
-0.501627, 0.804083, -0.313464, 0.059674],
[-0.898794, 0.438371, 0.711746, -0.682437, 0.166423,
-0.466993, 0.815850, -0.334472, 0.066599],
[-0.891007, 0.453990, 0.690839, -0.700629, 0.178494,
-0.431899, 0.825544, -0.355623, 0.073974],
[-0.882948, 0.469472, 0.669395, -0.717968, 0.190875,
-0.396436, 0.833145, -0.376851, 0.081803],
[-0.874620, 0.484810, 0.647439, -0.734431, 0.203551,
-0.360692, 0.838638, -0.398086, 0.090085],
[-0.866025, 0.500000, 0.625000, -0.750000, 0.216506,
-0.324760, 0.842012, -0.419263, 0.098821],
[-0.857167, 0.515038, 0.602104, -0.764655, 0.229726,
-0.288728, 0.843265, -0.440311, 0.108009],
[-0.848048, 0.529919, 0.578778, -0.778378, 0.243192,
-0.252688, 0.842399, -0.461164, 0.117644],
[-0.838671, 0.544639, 0.555052, -0.791154, 0.256891,
-0.216730, 0.839422, -0.481753, 0.127722],
[-0.829038, 0.559193, 0.530955, -0.802965, 0.270803,
-0.180944, 0.834347, -0.502011, 0.138237],
[-0.819152, 0.573576, 0.506515, -0.813798, 0.284914,
-0.145420, 0.827194, -0.521871, 0.149181],
[-0.809017, 0.587785, 0.481763, -0.823639, 0.299204,
-0.110246, 0.817987, -0.541266, 0.160545],
[-0.798636, 0.601815, 0.456728, -0.832477, 0.313658,
-0.075508, 0.806757, -0.560132, 0.172317],
[-0.788011, 0.615661, 0.431441, -0.840301, 0.328257,
-0.041294, 0.793541, -0.578405, 0.184487],
[-0.777146, 0.629320, 0.405934, -0.847101, 0.342984,
-0.007686, 0.778379, -0.596021, 0.197040],
[-0.766044, 0.642788, 0.380236, -0.852869, 0.357821,
0.025233, 0.761319, -0.612921, 0.209963],
[-0.754710, 0.656059, 0.354380, -0.857597, 0.372749,
0.057383, 0.742412, -0.629044, 0.223238],
[-0.743145, 0.669131, 0.328396, -0.861281, 0.387751,
0.088686, 0.721714, -0.644334, 0.236850],
[-0.731354, 0.681998, 0.302317, -0.863916, 0.402807,
0.119068, 0.699288, -0.658734, 0.250778],
[-0.719340, 0.694658, 0.276175, -0.865498, 0.417901,
0.148454, 0.675199, -0.672190, 0.265005],
[-0.707107, 0.707107, 0.250000, -0.866025, 0.433013,
0.176777, 0.649519, -0.684653, 0.279508],
[-0.694658, 0.719340, 0.223825, -0.865498, 0.448125,
0.203969, 0.622322, -0.696073, 0.294267],
[-0.681998, 0.731354, 0.197683, -0.863916, 0.463218,
0.229967, 0.593688, -0.706405, 0.309259],
[-0.669131, 0.743145, 0.171604, -0.861281, 0.478275,
0.254712, 0.563700, -0.715605, 0.324459],
[-0.656059, 0.754710, 0.145620, -0.857597, 0.493276,
0.278147, 0.532443, -0.723633, 0.339844],
[-0.642788, 0.766044, 0.119764, -0.852869, 0.508205,
0.300221, 0.500009, -0.730451, 0.355387],
[-0.629320, 0.777146, 0.094066, -0.847101, 0.523041,
0.320884, 0.466490, -0.736025, 0.371063],
[-0.615661, 0.788011, 0.068559, -0.840301, 0.537768,
0.340093, 0.431982, -0.740324, 0.386845],
[-0.601815, 0.798636, 0.043272, -0.832477, 0.552367,
0.357807, 0.396584, -0.743320, 0.402704],
[-0.587785, 0.809017, 0.018237, -0.823639, 0.566821,
0.373991, 0.360397, -0.744989, 0.418613],
[-0.573576, 0.819152, -0.006515, -0.813798, 0.581112,
0.388612, 0.323524, -0.745308, 0.434544],
[-0.559193, 0.829038, -0.030955, -0.802965, 0.595222,
0.401645, 0.286069, -0.744262, 0.450467],
[-0.544639, 0.838671, -0.055052, -0.791154, 0.609135,
0.413066, 0.248140, -0.741835, 0.466352],
[-0.529919, 0.848048, -0.078778, -0.778378, 0.622833,
0.422856, 0.209843, -0.738017, 0.482171],
[-0.515038, 0.857167, -0.102104, -0.764655, 0.636300,
0.431004, 0.171288, -0.732801, 0.497894],
[-0.500000, 0.866025, -0.125000, -0.750000, 0.649519,
0.437500, 0.132583, -0.726184, 0.513490],
[-0.484810, 0.874620, -0.147439, -0.734431, 0.662474,
0.442340, 0.093837, -0.718167, 0.528929],
[-0.469472, 0.882948, -0.169395, -0.717968, 0.675150,
0.445524, 0.055160, -0.708753, 0.544183],
[-0.453990, 0.891007, -0.190839, -0.700629, 0.687531,
0.447059, 0.016662, -0.697950, 0.559220],
[-0.438371, 0.898794, -0.211746, -0.682437, 0.699602,
0.446953, -0.021550, -0.685769, 0.574011],
[-0.422618, 0.906308, -0.232091, -0.663414, 0.711348,
0.445222, -0.059368, -0.672226, 0.588528],
[-0.406737, 0.913545, -0.251848, -0.643582, 0.722755,
0.441884, -0.096684, -0.657339, 0.602741],
[-0.390731, 0.920505, -0.270994, -0.622967, 0.733809,
0.436964, -0.133395, -0.641130, 0.616621],
[-0.374607, 0.927184, -0.289505, -0.601592, 0.744496,
0.430488, -0.169397, -0.623624, 0.630141],
[-0.358368, 0.933580, -0.307359, -0.579484, 0.754804,
0.422491, -0.204589, -0.604851, 0.643273],
[-0.342020, 0.939693, -0.324533, -0.556670, 0.764720,
0.413008, -0.238872, -0.584843, 0.655990],
[-0.325568, 0.945519, -0.341008, -0.533178, 0.774231,
0.402081, -0.272150, -0.563635, 0.668267],
[-0.309017, 0.951057, -0.356763, -0.509037, 0.783327,
0.389754, -0.304329, -0.541266, 0.680078],
[-0.292372, 0.956305, -0.371778, -0.484275, 0.791997,
0.376077, -0.335319, -0.517778, 0.691399],
[-0.275637, 0.961262, -0.386036, -0.458924, 0.800228,
0.361102, -0.365034, -0.493216, 0.702207],
[-0.258819, 0.965926, -0.399519, -0.433013, 0.808013,
0.344885, -0.393389, -0.467627, 0.712478],
[-0.241922, 0.970296, -0.412211, -0.406574, 0.815340,
0.327486, -0.420306, -0.441061, 0.722191],
[-0.224951, 0.974370, -0.424096, -0.379641, 0.822202,
0.308969, -0.445709, -0.413572, 0.731327],
[-0.207912, 0.978148, -0.435159, -0.352244, 0.828589,
0.289399, -0.469527, -0.385215, 0.739866],
[-0.190809, 0.981627, -0.445388, -0.324419, 0.834495,
0.268846, -0.491693, -0.356047, 0.747790],
[-0.173648, 0.984808, -0.454769, -0.296198, 0.839912,
0.247382, -0.512145, -0.326129, 0.755082],
[-0.156434, 0.987688, -0.463292, -0.267617, 0.844832,
0.225081, -0.530827, -0.295521, 0.761728],
[-0.139173, 0.990268, -0.470946, -0.238709, 0.849251,
0.202020, -0.547684, -0.264287, 0.767712],
[-0.121869, 0.992546, -0.477722, -0.209511, 0.853163,
0.178279, -0.562672, -0.232494, 0.773023],
[-0.104528, 0.994522, -0.483611, -0.180057, 0.856563,
0.153937, -0.575747, -0.200207, 0.777648],
[-0.087156, 0.996195, -0.488606, -0.150384, 0.859447,
0.129078, -0.586872, -0.167494, 0.781579],
[-0.069756, 0.997564, -0.492701, -0.120527, 0.861811,
0.103786, -0.596018, -0.134426, 0.784806],
[-0.052336, 0.998630, -0.495891, -0.090524, 0.863653,
0.078146, -0.603158, -0.101071, 0.787324],
[-0.034899, 0.999391, -0.498173, -0.060411, 0.864971,
0.052243, -0.608272, -0.067500, 0.789126],
[-0.017452, 0.999848, -0.499543, -0.030224, 0.865762,
0.026165, -0.611347, -0.033786, 0.790208],
[0.000000, 1.000000, -0.500000, 0.000000, 0.866025,
-0.000000, -0.612372, 0.000000, 0.790569],
[0.017452, 0.999848, -0.499543, 0.030224, 0.865762,
-0.026165, -0.611347, 0.033786, 0.790208],
[0.034899, 0.999391, -0.498173, 0.060411, 0.864971,
-0.052243, -0.608272, 0.067500, 0.789126],
[0.052336, 0.998630, -0.495891, 0.090524, 0.863653,
-0.078146, -0.603158, 0.101071, 0.787324],
[0.069756, 0.997564, -0.492701, 0.120527, 0.861811,
-0.103786, -0.596018, 0.134426, 0.784806],
[0.087156, 0.996195, -0.488606, 0.150384, 0.859447,
-0.129078, -0.586872, 0.167494, 0.781579],
[0.104528, 0.994522, -0.483611, 0.180057, 0.856563,
-0.153937, -0.575747, 0.200207, 0.777648],
[0.121869, 0.992546, -0.477722, 0.209511, 0.853163,
-0.178279, -0.562672, 0.232494, 0.773023],
[0.139173, 0.990268, -0.470946, 0.238709, 0.849251,
-0.202020, -0.547684, 0.264287, 0.767712],
[0.156434, 0.987688, -0.463292, 0.267617, 0.844832,
-0.225081, -0.530827, 0.295521, 0.761728],
[0.173648, 0.984808, -0.454769, 0.296198, 0.839912,
-0.247382, -0.512145, 0.326129, 0.755082],
[0.190809, 0.981627, -0.445388, 0.324419, 0.834495,
-0.268846, -0.491693, 0.356047, 0.747790],
[0.207912, 0.978148, -0.435159, 0.352244, 0.828589,
-0.289399, -0.469527, 0.385215, 0.739866],
[0.224951, 0.974370, -0.424096, 0.379641, 0.822202,
-0.308969, -0.445709, 0.413572, 0.731327],
[0.241922, 0.970296, -0.412211, 0.406574, 0.815340,
-0.327486, -0.420306, 0.441061, 0.722191],
[0.258819, 0.965926, -0.399519, 0.433013, 0.808013,
-0.344885, -0.393389, 0.467627, 0.712478],
[0.275637, 0.961262, -0.386036, 0.458924, 0.800228,
-0.361102, -0.365034, 0.493216, 0.702207],
[0.292372, 0.956305, -0.371778, 0.484275, 0.791997,
-0.376077, -0.335319, 0.517778, 0.691399],
[0.309017, 0.951057, -0.356763, 0.509037, 0.783327,
-0.389754, -0.304329, 0.541266, 0.680078],
[0.325568, 0.945519, -0.341008, 0.533178, 0.774231,
-0.402081, -0.272150, 0.563635, 0.668267],
[0.342020, 0.939693, -0.324533, 0.556670, 0.764720,
-0.413008, -0.238872, 0.584843, 0.655990],
[0.358368, 0.933580, -0.307359, 0.579484, 0.754804,
-0.422491, -0.204589, 0.604851, 0.643273],
[0.374607, 0.927184, -0.289505, 0.601592, 0.744496,
-0.430488, -0.169397, 0.623624, 0.630141],
[0.390731, 0.920505, -0.270994, 0.622967, 0.733809,
-0.436964, -0.133395, 0.641130, 0.616621],
[0.406737, 0.913545, -0.251848, 0.643582, 0.722755,
-0.441884, -0.096684, 0.657339, 0.602741],
[0.422618, 0.906308, -0.232091, 0.663414, 0.711348,
-0.445222, -0.059368, 0.672226, 0.588528],
[0.438371, 0.898794, -0.211746, 0.682437, 0.699602,
-0.446953, -0.021550, 0.685769, 0.574011],
[0.453990, 0.891007, -0.190839, 0.700629, 0.687531,
-0.447059, 0.016662, 0.697950, 0.559220],
[0.469472, 0.882948, -0.169395, 0.717968, 0.675150,
-0.445524, 0.055160, 0.708753, 0.544183],
[0.484810, 0.874620, -0.147439, 0.734431, 0.662474,
-0.442340, 0.093837, 0.718167, 0.528929],
[0.500000, 0.866025, -0.125000, 0.750000, 0.649519,
-0.437500, 0.132583, 0.726184, 0.513490],
[0.515038, 0.857167, -0.102104, 0.764655, 0.636300,
-0.431004, 0.171288, 0.732801, 0.497894],
[0.529919, 0.848048, -0.078778, 0.778378, 0.622833,
-0.422856, 0.209843, 0.738017, 0.482171],
[0.544639, 0.838671, -0.055052, 0.791154, 0.609135,
-0.413066, 0.248140, 0.741835, 0.466352],
[0.559193, 0.829038, -0.030955, 0.802965, 0.595222,
-0.401645, 0.286069, 0.744262, 0.450467],
[0.573576, 0.819152, -0.006515, 0.813798, 0.581112,
-0.388612, 0.323524, 0.745308, 0.434544],
[0.587785, 0.809017, 0.018237, 0.823639, 0.566821,
-0.373991, 0.360397, 0.744989, 0.418613],
[0.601815, 0.798636, 0.043272, 0.832477, 0.552367,
-0.357807, 0.396584, 0.743320, 0.402704],
[0.615661, 0.788011, 0.068559, 0.840301, 0.537768,
-0.340093, 0.431982, 0.740324, 0.386845],
[0.629320, 0.777146, 0.094066, 0.847101, 0.523041,
-0.320884, 0.466490, 0.736025, 0.371063],
[0.642788, 0.766044, 0.119764, 0.852869, 0.508205,
-0.300221, 0.500009, 0.730451, 0.355387],
[0.656059, 0.754710, 0.145620, 0.857597, 0.493276,
-0.278147, 0.532443, 0.723633, 0.339844],
[0.669131, 0.743145, 0.171604, 0.861281, 0.478275,
-0.254712, 0.563700, 0.715605, 0.324459],
[0.681998, 0.731354, 0.197683, 0.863916, 0.463218,
-0.229967, 0.593688, 0.706405, 0.309259],
[0.694658, 0.719340, 0.223825, 0.865498, 0.448125,
-0.203969, 0.622322, 0.696073, 0.294267],
[0.707107, 0.707107, 0.250000, 0.866025, 0.433013,
-0.176777, 0.649519, 0.684653, 0.279508],
[0.719340, 0.694658, 0.276175, 0.865498, 0.417901,
-0.148454, 0.675199, 0.672190, 0.265005],
[0.731354, 0.681998, 0.302317, 0.863916, 0.402807,
-0.119068, 0.699288, 0.658734, 0.250778],
[0.743145, 0.669131, 0.328396, 0.861281, 0.387751,
-0.088686, 0.721714, 0.644334, 0.236850],
[0.754710, 0.656059, 0.354380, 0.857597, 0.372749,
-0.057383, 0.742412, 0.629044, 0.223238],
[0.766044, 0.642788, 0.380236, 0.852869, 0.357821,
-0.025233, 0.761319, 0.612921, 0.209963],
[0.777146, 0.629320, 0.405934, 0.847101, 0.342984,
0.007686, 0.778379, 0.596021, 0.197040],
[0.788011, 0.615661, 0.431441, 0.840301, 0.328257,
0.041294, 0.793541, 0.578405, 0.184487],
[0.798636, 0.601815, 0.456728, 0.832477, 0.313658,
0.075508, 0.806757, 0.560132, 0.172317],
[0.809017, 0.587785, 0.481763, 0.823639, 0.299204,
0.110246, 0.817987, 0.541266, 0.160545],
[0.819152, 0.573576, 0.506515, 0.813798, 0.284914,
0.145420, 0.827194, 0.521871, 0.149181],
[0.829038, 0.559193, 0.530955, 0.802965, 0.270803,
0.180944, 0.834347, 0.502011, 0.138237],
[0.838671, 0.544639, 0.555052, 0.791154, 0.256891,
0.216730, 0.839422, 0.481753, 0.127722],
[0.848048, 0.529919, 0.578778, 0.778378, 0.243192,
0.252688, 0.842399, 0.461164, 0.117644],
[0.857167, 0.515038, 0.602104, 0.764655, 0.229726,
0.288728, 0.843265, 0.440311, 0.108009],
[0.866025, 0.500000, 0.625000, 0.750000, 0.216506,
0.324760, 0.842012, 0.419263, 0.098821],
[0.874620, 0.484810, 0.647439, 0.734431, 0.203551,
0.360692, 0.838638, 0.398086, 0.090085],
[0.882948, 0.469472, 0.669395, 0.717968, 0.190875,
0.396436, 0.833145, 0.376851, 0.081803],
[0.891007, 0.453990, 0.690839, 0.700629, 0.178494,
0.431899, 0.825544, 0.355623, 0.073974],
[0.898794, 0.438371, 0.711746, 0.682437, 0.166423,
0.466993, 0.815850, 0.334472, 0.066599],
[0.906308, 0.422618, 0.732091, 0.663414, 0.154678,
0.501627, 0.804083, 0.313464, 0.059674],
[0.913545, 0.406737, 0.751848, 0.643582, 0.143271,
0.535715, 0.790270, 0.292666, 0.053196],
[0.920505, 0.390731, 0.770994, 0.622967, 0.132217,
0.569169, 0.774442, 0.272143, 0.047160],
[0.927184, 0.374607, 0.789505, 0.601592, 0.121529,
0.601904, 0.756637, 0.251960, 0.041559],
[0.933580, 0.358368, 0.807359, 0.579484, 0.111222,
0.633837, 0.736898, 0.232180, 0.036385],
[0.939693, 0.342020, 0.824533, 0.556670, 0.101306,
0.664885, 0.715274, 0.212865, 0.031630],
[0.945519, 0.325568, 0.841008, 0.533178, 0.091794,
0.694969, 0.691816, 0.194075, 0.027281],
[0.951057, 0.309017, 0.856763, 0.509037, 0.082698,
0.724012, 0.666583, 0.175868, 0.023329],
[0.956305, 0.292372, 0.871778, 0.484275, 0.074029,
0.751940, 0.639639, 0.158301, 0.019758],
[0.961262, 0.275637, 0.886036, 0.458924, 0.065797,
0.778680, 0.611050, 0.141427, 0.016556],
[0.965926, 0.258819, 0.899519, 0.433013, 0.058013,
0.804164, 0.580889, 0.125300, 0.013707],
[0.970296, 0.241922, 0.912211, 0.406574, 0.050685,
0.828326, 0.549233, 0.109969, 0.011193],
[0.974370, 0.224951, 0.924096, 0.379641, 0.043823,
0.851105, 0.516162, 0.095481, 0.008999],
[0.978148, 0.207912, 0.935159, 0.352244, 0.037436,
0.872441, 0.481759, 0.081880, 0.007105],
[0.981627, 0.190809, 0.945388, 0.324419, 0.031530,
0.892279, 0.446114, 0.069209, 0.005492],
[0.984808, 0.173648, 0.954769, 0.296198, 0.026114,
0.910569, 0.409317, 0.057505, 0.004140],
[0.987688, 0.156434, 0.963292, 0.267617, 0.021193,
0.927262, 0.371463, 0.046806, 0.003026],
[0.990268, 0.139173, 0.970946, 0.238709, 0.016774,
0.942316, 0.332649, 0.037143, 0.002131],
[0.992546, 0.121869, 0.977722, 0.209511, 0.012862,
0.955693, 0.292976, 0.028547, 0.001431],
[0.994522, 0.104528, 0.983611, 0.180057, 0.009462,
0.967356, 0.252544, 0.021043, 0.000903],
[0.996195, 0.087156, 0.988606, 0.150384, 0.006578,
0.977277, 0.211460, 0.014654, 0.000523],
[0.997564, 0.069756, 0.992701, 0.120527, 0.004214,
0.985429, 0.169828, 0.009400, 0.000268],
[0.998630, 0.052336, 0.995891, 0.090524, 0.002372,
0.991791, 0.127757, 0.005297, 0.000113],
[0.999391, 0.034899, 0.998173, 0.060411, 0.001055,
0.996348, 0.085356, 0.002357, 0.000034],
[0.999848, 0.017452, 0.999543, 0.030224, 0.000264,
0.999086, 0.042733, 0.000590, 0.000004],
[1.000000, -0.000000, 1.000000, -0.000000, 0.000000,
1.000000, -0.000000, 0.000000, -0.000000],
],
];
/** @type {Number} */
exports.SPHERICAL_HARMONICS_AZIMUTH_RESOLUTION =
exports.SPHERICAL_HARMONICS[0].length;
/** @type {Number} */
exports.SPHERICAL_HARMONICS_ELEVATION_RESOLUTION =
exports.SPHERICAL_HARMONICS[1].length;
/**
* The maximum allowed ambisonic order.
* @type {Number}
*/
exports.SPHERICAL_HARMONICS_MAX_ORDER =
exports.SPHERICAL_HARMONICS[0][0].length / 2;
/**
* Pre-computed per-band weighting coefficients for producing energy-preserving
* Max-Re sources.
*/
exports.MAX_RE_WEIGHTS =
[
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.000000, 1.000000, 1.000000, 1.000000],
[1.003236, 1.002156, 0.999152, 0.990038],
[1.032370, 1.021194, 0.990433, 0.898572],
[1.062694, 1.040231, 0.979161, 0.799806],
[1.093999, 1.058954, 0.964976, 0.693603],
[1.126003, 1.077006, 0.947526, 0.579890],
[1.158345, 1.093982, 0.926474, 0.458690],
[1.190590, 1.109437, 0.901512, 0.330158],
[1.222228, 1.122890, 0.872370, 0.194621],
[1.252684, 1.133837, 0.838839, 0.052614],
[1.281987, 1.142358, 0.801199, 0.000000],
[1.312073, 1.150207, 0.760839, 0.000000],
[1.343011, 1.157424, 0.717799, 0.000000],
[1.374649, 1.163859, 0.671999, 0.000000],
[1.406809, 1.169354, 0.623371, 0.000000],
[1.439286, 1.173739, 0.571868, 0.000000],
[1.471846, 1.176837, 0.517465, 0.000000],
[1.504226, 1.178465, 0.460174, 0.000000],
[1.536133, 1.178438, 0.400043, 0.000000],
[1.567253, 1.176573, 0.337165, 0.000000],
[1.597247, 1.172695, 0.271688, 0.000000],
[1.625766, 1.166645, 0.203815, 0.000000],
[1.652455, 1.158285, 0.133806, 0.000000],
[1.676966, 1.147506, 0.061983, 0.000000],
[1.699006, 1.134261, 0.000000, 0.000000],
[1.720224, 1.119789, 0.000000, 0.000000],
[1.741631, 1.104810, 0.000000, 0.000000],
[1.763183, 1.089330, 0.000000, 0.000000],
[1.784837, 1.073356, 0.000000, 0.000000],
[1.806548, 1.056898, 0.000000, 0.000000],
[1.828269, 1.039968, 0.000000, 0.000000],
[1.849952, 1.022580, 0.000000, 0.000000],
[1.871552, 1.004752, 0.000000, 0.000000],
[1.893018, 0.986504, 0.000000, 0.000000],
[1.914305, 0.967857, 0.000000, 0.000000],
[1.935366, 0.948837, 0.000000, 0.000000],
[1.956154, 0.929471, 0.000000, 0.000000],
[1.976625, 0.909790, 0.000000, 0.000000],
[1.996736, 0.889823, 0.000000, 0.000000],
[2.016448, 0.869607, 0.000000, 0.000000],
[2.035721, 0.849175, 0.000000, 0.000000],
[2.054522, 0.828565, 0.000000, 0.000000],
[2.072818, 0.807816, 0.000000, 0.000000],
[2.090581, 0.786964, 0.000000, 0.000000],
[2.107785, 0.766051, 0.000000, 0.000000],
[2.124411, 0.745115, 0.000000, 0.000000],
[2.140439, 0.724196, 0.000000, 0.000000],
[2.155856, 0.703332, 0.000000, 0.000000],
[2.170653, 0.682561, 0.000000, 0.000000],
[2.184823, 0.661921, 0.000000, 0.000000],
[2.198364, 0.641445, 0.000000, 0.000000],
[2.211275, 0.621169, 0.000000, 0.000000],
[2.223562, 0.601125, 0.000000, 0.000000],
[2.235230, 0.581341, 0.000000, 0.000000],
[2.246289, 0.561847, 0.000000, 0.000000],
[2.256751, 0.542667, 0.000000, 0.000000],
[2.266631, 0.523826, 0.000000, 0.000000],
[2.275943, 0.505344, 0.000000, 0.000000],
[2.284707, 0.487239, 0.000000, 0.000000],
[2.292939, 0.469528, 0.000000, 0.000000],
[2.300661, 0.452225, 0.000000, 0.000000],
[2.307892, 0.435342, 0.000000, 0.000000],
[2.314654, 0.418888, 0.000000, 0.000000],
[2.320969, 0.402870, 0.000000, 0.000000],
[2.326858, 0.387294, 0.000000, 0.000000],
[2.332343, 0.372164, 0.000000, 0.000000],
[2.337445, 0.357481, 0.000000, 0.000000],
[2.342186, 0.343246, 0.000000, 0.000000],
[2.346585, 0.329458, 0.000000, 0.000000],
[2.350664, 0.316113, 0.000000, 0.000000],
[2.354442, 0.303208, 0.000000, 0.000000],
[2.357937, 0.290738, 0.000000, 0.000000],
[2.361168, 0.278698, 0.000000, 0.000000],
[2.364152, 0.267080, 0.000000, 0.000000],
[2.366906, 0.255878, 0.000000, 0.000000],
[2.369446, 0.245082, 0.000000, 0.000000],
[2.371786, 0.234685, 0.000000, 0.000000],
[2.373940, 0.224677, 0.000000, 0.000000],
[2.375923, 0.215048, 0.000000, 0.000000],
[2.377745, 0.205790, 0.000000, 0.000000],
[2.379421, 0.196891, 0.000000, 0.000000],
[2.380959, 0.188342, 0.000000, 0.000000],
[2.382372, 0.180132, 0.000000, 0.000000],
[2.383667, 0.172251, 0.000000, 0.000000],
[2.384856, 0.164689, 0.000000, 0.000000],
[2.385945, 0.157435, 0.000000, 0.000000],
[2.386943, 0.150479, 0.000000, 0.000000],
[2.387857, 0.143811, 0.000000, 0.000000],
[2.388694, 0.137421, 0.000000, 0.000000],
[2.389460, 0.131299, 0.000000, 0.000000],
[2.390160, 0.125435, 0.000000, 0.000000],
[2.390801, 0.119820, 0.000000, 0.000000],
[2.391386, 0.114445, 0.000000, 0.000000],
[2.391921, 0.109300, 0.000000, 0.000000],
[2.392410, 0.104376, 0.000000, 0.000000],
[2.392857, 0.099666, 0.000000, 0.000000],
[2.393265, 0.095160, 0.000000, 0.000000],
[2.393637, 0.090851, 0.000000, 0.000000],
[2.393977, 0.086731, 0.000000, 0.000000],
[2.394288, 0.082791, 0.000000, 0.000000],
[2.394571, 0.079025, 0.000000, 0.000000],
[2.394829, 0.075426, 0.000000, 0.000000],
[2.395064, 0.071986, 0.000000, 0.000000],
[2.395279, 0.068699, 0.000000, 0.000000],
[2.395475, 0.065558, 0.000000, 0.000000],
[2.395653, 0.062558, 0.000000, 0.000000],
[2.395816, 0.059693, 0.000000, 0.000000],
[2.395964, 0.056955, 0.000000, 0.000000],
[2.396099, 0.054341, 0.000000, 0.000000],
[2.396222, 0.051845, 0.000000, 0.000000],
[2.396334, 0.049462, 0.000000, 0.000000],
[2.396436, 0.047186, 0.000000, 0.000000],
[2.396529, 0.045013, 0.000000, 0.000000],
[2.396613, 0.042939, 0.000000, 0.000000],
[2.396691, 0.040959, 0.000000, 0.000000],
[2.396761, 0.039069, 0.000000, 0.000000],
[2.396825, 0.037266, 0.000000, 0.000000],
[2.396883, 0.035544, 0.000000, 0.000000],
[2.396936, 0.033901, 0.000000, 0.000000],
[2.396984, 0.032334, 0.000000, 0.000000],
[2.397028, 0.030838, 0.000000, 0.000000],
[2.397068, 0.029410, 0.000000, 0.000000],
[2.397104, 0.028048, 0.000000, 0.000000],
[2.397137, 0.026749, 0.000000, 0.000000],
[2.397167, 0.025509, 0.000000, 0.000000],
[2.397194, 0.024326, 0.000000, 0.000000],
[2.397219, 0.023198, 0.000000, 0.000000],
[2.397242, 0.022122, 0.000000, 0.000000],
[2.397262, 0.021095, 0.000000, 0.000000],
[2.397281, 0.020116, 0.000000, 0.000000],
[2.397298, 0.019181, 0.000000, 0.000000],
[2.397314, 0.018290, 0.000000, 0.000000],
[2.397328, 0.017441, 0.000000, 0.000000],
[2.397341, 0.016630, 0.000000, 0.000000],
[2.397352, 0.015857, 0.000000, 0.000000],
[2.397363, 0.015119, 0.000000, 0.000000],
[2.397372, 0.014416, 0.000000, 0.000000],
[2.397381, 0.013745, 0.000000, 0.000000],
[2.397389, 0.013106, 0.000000, 0.000000],
[2.397396, 0.012496, 0.000000, 0.000000],
[2.397403, 0.011914, 0.000000, 0.000000],
[2.397409, 0.011360, 0.000000, 0.000000],
[2.397414, 0.010831, 0.000000, 0.000000],
[2.397419, 0.010326, 0.000000, 0.000000],
[2.397424, 0.009845, 0.000000, 0.000000],
[2.397428, 0.009387, 0.000000, 0.000000],
[2.397432, 0.008949, 0.000000, 0.000000],
[2.397435, 0.008532, 0.000000, 0.000000],
[2.397438, 0.008135, 0.000000, 0.000000],
[2.397441, 0.007755, 0.000000, 0.000000],
[2.397443, 0.007394, 0.000000, 0.000000],
[2.397446, 0.007049, 0.000000, 0.000000],
[2.397448, 0.006721, 0.000000, 0.000000],
[2.397450, 0.006407, 0.000000, 0.000000],
[2.397451, 0.006108, 0.000000, 0.000000],
[2.397453, 0.005824, 0.000000, 0.000000],
[2.397454, 0.005552, 0.000000, 0.000000],
[2.397456, 0.005293, 0.000000, 0.000000],
[2.397457, 0.005046, 0.000000, 0.000000],
[2.397458, 0.004811, 0.000000, 0.000000],
[2.397459, 0.004586, 0.000000, 0.000000],
[2.397460, 0.004372, 0.000000, 0.000000],
[2.397461, 0.004168, 0.000000, 0.000000],
[2.397461, 0.003974, 0.000000, 0.000000],
[2.397462, 0.003788, 0.000000, 0.000000],
[2.397463, 0.003611, 0.000000, 0.000000],
[2.397463, 0.003443, 0.000000, 0.000000],
[2.397464, 0.003282, 0.000000, 0.000000],
[2.397464, 0.003129, 0.000000, 0.000000],
[2.397465, 0.002983, 0.000000, 0.000000],
[2.397465, 0.002844, 0.000000, 0.000000],
[2.397465, 0.002711, 0.000000, 0.000000],
[2.397466, 0.002584, 0.000000, 0.000000],
[2.397466, 0.002464, 0.000000, 0.000000],
[2.397466, 0.002349, 0.000000, 0.000000],
[2.397466, 0.002239, 0.000000, 0.000000],
[2.397467, 0.002135, 0.000000, 0.000000],
[2.397467, 0.002035, 0.000000, 0.000000],
[2.397467, 0.001940, 0.000000, 0.000000],
[2.397467, 0.001849, 0.000000, 0.000000],
[2.397467, 0.001763, 0.000000, 0.000000],
[2.397467, 0.001681, 0.000000, 0.000000],
[2.397468, 0.001602, 0.000000, 0.000000],
[2.397468, 0.001527, 0.000000, 0.000000],
[2.397468, 0.001456, 0.000000, 0.000000],
[2.397468, 0.001388, 0.000000, 0.000000],
[2.397468, 0.001323, 0.000000, 0.000000],
[2.397468, 0.001261, 0.000000, 0.000000],
[2.397468, 0.001202, 0.000000, 0.000000],
[2.397468, 0.001146, 0.000000, 0.000000],
[2.397468, 0.001093, 0.000000, 0.000000],
[2.397468, 0.001042, 0.000000, 0.000000],
[2.397468, 0.000993, 0.000000, 0.000000],
[2.397468, 0.000947, 0.000000, 0.000000],
[2.397468, 0.000902, 0.000000, 0.000000],
[2.397468, 0.000860, 0.000000, 0.000000],
[2.397468, 0.000820, 0.000000, 0.000000],
[2.397469, 0.000782, 0.000000, 0.000000],
[2.397469, 0.000745, 0.000000, 0.000000],
[2.397469, 0.000710, 0.000000, 0.000000],
[2.397469, 0.000677, 0.000000, 0.000000],
[2.397469, 0.000646, 0.000000, 0.000000],
[2.397469, 0.000616, 0.000000, 0.000000],
[2.397469, 0.000587, 0.000000, 0.000000],
[2.397469, 0.000559, 0.000000, 0.000000],
[2.397469, 0.000533, 0.000000, 0.000000],
[2.397469, 0.000508, 0.000000, 0.000000],
[2.397469, 0.000485, 0.000000, 0.000000],
[2.397469, 0.000462, 0.000000, 0.000000],
[2.397469, 0.000440, 0.000000, 0.000000],
[2.397469, 0.000420, 0.000000, 0.000000],
[2.397469, 0.000400, 0.000000, 0.000000],
[2.397469, 0.000381, 0.000000, 0.000000],
[2.397469, 0.000364, 0.000000, 0.000000],
[2.397469, 0.000347, 0.000000, 0.000000],
[2.397469, 0.000330, 0.000000, 0.000000],
[2.397469, 0.000315, 0.000000, 0.000000],
[2.397469, 0.000300, 0.000000, 0.000000],
[2.397469, 0.000286, 0.000000, 0.000000],
[2.397469, 0.000273, 0.000000, 0.000000],
[2.397469, 0.000260, 0.000000, 0.000000],
[2.397469, 0.000248, 0.000000, 0.000000],
[2.397469, 0.000236, 0.000000, 0.000000],
[2.397469, 0.000225, 0.000000, 0.000000],
[2.397469, 0.000215, 0.000000, 0.000000],
[2.397469, 0.000205, 0.000000, 0.000000],
[2.397469, 0.000195, 0.000000, 0.000000],
[2.397469, 0.000186, 0.000000, 0.000000],
[2.397469, 0.000177, 0.000000, 0.000000],
[2.397469, 0.000169, 0.000000, 0.000000],
[2.397469, 0.000161, 0.000000, 0.000000],
[2.397469, 0.000154, 0.000000, 0.000000],
[2.397469, 0.000147, 0.000000, 0.000000],
[2.397469, 0.000140, 0.000000, 0.000000],
[2.397469, 0.000133, 0.000000, 0.000000],
[2.397469, 0.000127, 0.000000, 0.000000],
[2.397469, 0.000121, 0.000000, 0.000000],
[2.397469, 0.000115, 0.000000, 0.000000],
[2.397469, 0.000110, 0.000000, 0.000000],
[2.397469, 0.000105, 0.000000, 0.000000],
[2.397469, 0.000100, 0.000000, 0.000000],
[2.397469, 0.000095, 0.000000, 0.000000],
[2.397469, 0.000091, 0.000000, 0.000000],
[2.397469, 0.000087, 0.000000, 0.000000],
[2.397469, 0.000083, 0.000000, 0.000000],
[2.397469, 0.000079, 0.000000, 0.000000],
[2.397469, 0.000075, 0.000000, 0.000000],
[2.397469, 0.000071, 0.000000, 0.000000],
[2.397469, 0.000068, 0.000000, 0.000000],
[2.397469, 0.000065, 0.000000, 0.000000],
[2.397469, 0.000062, 0.000000, 0.000000],
[2.397469, 0.000059, 0.000000, 0.000000],
[2.397469, 0.000056, 0.000000, 0.000000],
[2.397469, 0.000054, 0.000000, 0.000000],
[2.397469, 0.000051, 0.000000, 0.000000],
[2.397469, 0.000049, 0.000000, 0.000000],
[2.397469, 0.000046, 0.000000, 0.000000],
[2.397469, 0.000044, 0.000000, 0.000000],
[2.397469, 0.000042, 0.000000, 0.000000],
[2.397469, 0.000040, 0.000000, 0.000000],
[2.397469, 0.000038, 0.000000, 0.000000],
[2.397469, 0.000037, 0.000000, 0.000000],
[2.397469, 0.000035, 0.000000, 0.000000],
[2.397469, 0.000033, 0.000000, 0.000000],
[2.397469, 0.000032, 0.000000, 0.000000],
[2.397469, 0.000030, 0.000000, 0.000000],
[2.397469, 0.000029, 0.000000, 0.000000],
[2.397469, 0.000027, 0.000000, 0.000000],
[2.397469, 0.000026, 0.000000, 0.000000],
[2.397469, 0.000025, 0.000000, 0.000000],
[2.397469, 0.000024, 0.000000, 0.000000],
[2.397469, 0.000023, 0.000000, 0.000000],
[2.397469, 0.000022, 0.000000, 0.000000],
[2.397469, 0.000021, 0.000000, 0.000000],
[2.397469, 0.000020, 0.000000, 0.000000],
[2.397469, 0.000019, 0.000000, 0.000000],
[2.397469, 0.000018, 0.000000, 0.000000],
[2.397469, 0.000017, 0.000000, 0.000000],
[2.397469, 0.000016, 0.000000, 0.000000],
[2.397469, 0.000015, 0.000000, 0.000000],
[2.397469, 0.000015, 0.000000, 0.000000],
[2.397469, 0.000014, 0.000000, 0.000000],
[2.397469, 0.000013, 0.000000, 0.000000],
[2.397469, 0.000013, 0.000000, 0.000000],
[2.397469, 0.000012, 0.000000, 0.000000],
[2.397469, 0.000012, 0.000000, 0.000000],
[2.397469, 0.000011, 0.000000, 0.000000],
[2.397469, 0.000011, 0.000000, 0.000000],
[2.397469, 0.000010, 0.000000, 0.000000],
[2.397469, 0.000010, 0.000000, 0.000000],
[2.397469, 0.000009, 0.000000, 0.000000],
[2.397469, 0.000009, 0.000000, 0.000000],
[2.397469, 0.000008, 0.000000, 0.000000],
[2.397469, 0.000008, 0.000000, 0.000000],
[2.397469, 0.000008, 0.000000, 0.000000],
[2.397469, 0.000007, 0.000000, 0.000000],
[2.397469, 0.000007, 0.000000, 0.000000],
[2.397469, 0.000007, 0.000000, 0.000000],
[2.397469, 0.000006, 0.000000, 0.000000],
[2.397469, 0.000006, 0.000000, 0.000000],
[2.397469, 0.000006, 0.000000, 0.000000],
[2.397469, 0.000005, 0.000000, 0.000000],
[2.397469, 0.000005, 0.000000, 0.000000],
[2.397469, 0.000005, 0.000000, 0.000000],
[2.397469, 0.000005, 0.000000, 0.000000],
[2.397469, 0.000004, 0.000000, 0.000000],
[2.397469, 0.000004, 0.000000, 0.000000],
[2.397469, 0.000004, 0.000000, 0.000000],
[2.397469, 0.000004, 0.000000, 0.000000],
[2.397469, 0.000004, 0.000000, 0.000000],
[2.397469, 0.000004, 0.000000, 0.000000],
[2.397469, 0.000003, 0.000000, 0.000000],
[2.397469, 0.000003, 0.000000, 0.000000],
[2.397469, 0.000003, 0.000000, 0.000000],
[2.397469, 0.000003, 0.000000, 0.000000],
[2.397469, 0.000003, 0.000000, 0.000000],
[2.397469, 0.000003, 0.000000, 0.000000],
[2.397469, 0.000003, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000002, 0.000000, 0.000000],
[2.397469, 0.000001, 0.000000, 0.000000],
[2.397469, 0.000001, 0.000000, 0.000000],
[2.397469, 0.000001, 0.000000, 0.000000],
];
/** @type {Number} */
exports.MAX_RE_WEIGHTS_RESOLUTION = exports.MAX_RE_WEIGHTS.length;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Source model to spatialize an audio buffer.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Directivity = __webpack_require__(5);
const Attenuation = __webpack_require__(6);
const Encoder = __webpack_require__(1);
const Utils = __webpack_require__(0);
/**
* @class Source
* @description Source model to spatialize an audio buffer.
* @param {ResonanceAudio} scene Associated {@link ResonanceAudio
* ResonanceAudio} instance.
* @param {Object} options
* @param {Float32Array} options.position
* The source's initial position (in meters), where origin is the center of
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
* @param {Float32Array} options.forward
* The source's initial forward vector. Defaults to
* {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
* @param {Float32Array} options.up
* The source's initial up vector. Defaults to
* {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
* @param {Number} options.minDistance
* Min. distance (in meters). Defaults to
* {@linkcode Utils.DEFAULT_MIN_DISTANCE DEFAULT_MIN_DISTANCE}.
* @param {Number} options.maxDistance
* Max. distance (in meters). Defaults to
* {@linkcode Utils.DEFAULT_MAX_DISTANCE DEFAULT_MAX_DISTANCE}.
* @param {string} options.rolloff
* Rolloff model to use, chosen from options in
* {@linkcode Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}. Defaults to
* {@linkcode Utils.DEFAULT_ATTENUATION_ROLLOFF DEFAULT_ATTENUATION_ROLLOFF}.
* @param {Number} options.gain Input gain (linear). Defaults to
* {@linkcode Utils.DEFAULT_SOURCE_GAIN DEFAULT_SOURCE_GAIN}.
* @param {Number} options.alpha Directivity alpha. Defaults to
* {@linkcode Utils.DEFAULT_DIRECTIVITY_ALPHA DEFAULT_DIRECTIVITY_ALPHA}.
* @param {Number} options.sharpness Directivity sharpness. Defaults to
* {@linkcode Utils.DEFAULT_DIRECTIVITY_SHARPNESS
* DEFAULT_DIRECTIVITY_SHARPNESS}.
* @param {Number} options.sourceWidth
* Source width (in degrees). Where 0 degrees is a point source and 360 degrees
* is an omnidirectional source. Defaults to
* {@linkcode Utils.DEFAULT_SOURCE_WIDTH DEFAULT_SOURCE_WIDTH}.
*/
function Source(scene, options) {
// Public variables.
/**
* Mono (1-channel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} input
* @memberof Source
* @instance
*/
/**
*
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.position == undefined) {
options.position = Utils.DEFAULT_POSITION.slice();
}
if (options.forward == undefined) {
options.forward = Utils.DEFAULT_FORWARD.slice();
}
if (options.up == undefined) {
options.up = Utils.DEFAULT_UP.slice();
}
if (options.minDistance == undefined) {
options.minDistance = Utils.DEFAULT_MIN_DISTANCE;
}
if (options.maxDistance == undefined) {
options.maxDistance = Utils.DEFAULT_MAX_DISTANCE;
}
if (options.rolloff == undefined) {
options.rolloff = Utils.DEFAULT_ROLLOFF;
}
if (options.gain == undefined) {
options.gain = Utils.DEFAULT_SOURCE_GAIN;
}
if (options.alpha == undefined) {
options.alpha = Utils.DEFAULT_DIRECTIVITY_ALPHA;
}
if (options.sharpness == undefined) {
options.sharpness = Utils.DEFAULT_DIRECTIVITY_SHARPNESS;
}
if (options.sourceWidth == undefined) {
options.sourceWidth = Utils.DEFAULT_SOURCE_WIDTH;
}
// Member variables.
this._scene = scene;
this._position = options.position;
this._forward = options.forward;
this._up = options.up;
this._dx = new Float32Array(3);
this._right = Utils.crossProduct(this._forward, this._up);
// Create audio nodes.
let context = scene._context;
this.input = context.createGain();
this._directivity = new Directivity(context, {
alpha: options.alpha,
sharpness: options.sharpness,
});
this._toEarly = context.createGain();
this._toLate = context.createGain();
this._attenuation = new Attenuation(context, {
minDistance: options.minDistance,
maxDistance: options.maxDistance,
rolloff: options.rolloff,
});
this._encoder = new Encoder(context, {
ambisonicOrder: scene._ambisonicOrder,
sourceWidth: options.sourceWidth,
});
// Connect nodes.
this.input.connect(this._toLate);
this._toLate.connect(scene._room.late.input);
this.input.connect(this._attenuation.input);
this._attenuation.output.connect(this._toEarly);
this._toEarly.connect(scene._room.early.input);
this._attenuation.output.connect(this._directivity.input);
this._directivity.output.connect(this._encoder.input);
this._encoder.output.connect(scene._listener.input);
// Assign initial conditions.
this.setPosition(
options.position[0], options.position[1], options.position[2]);
this.input.gain.value = options.gain;
};
/**
* Set source's position (in meters), where origin is the center of
* the room.
* @param {Number} x
* @param {Number} y
* @param {Number} z
*/
Source.prototype.setPosition = function(x, y, z) {
// Assign new position.
this._position[0] = x;
this._position[1] = y;
this._position[2] = z;
// Handle far-field effect.
let distance = this._scene._room.getDistanceOutsideRoom(
this._position[0], this._position[1], this._position[2]);
let gain = _computeDistanceOutsideRoom(distance);
this._toLate.gain.value = gain;
this._toEarly.gain.value = gain;
this._update();
};
// Update the source when changing the listener's position.
Source.prototype._update = function() {
// Compute distance to listener.
for (let i = 0; i < 3; i++) {
this._dx[i] = this._position[i] - this._scene._listener.position[i];
}
let distance = Math.sqrt(this._dx[0] * this._dx[0] +
this._dx[1] * this._dx[1] + this._dx[2] * this._dx[2]);
if (distance > 0) {
// Normalize direction vector.
this._dx[0] /= distance;
this._dx[1] /= distance;
this._dx[2] /= distance;
}
// Compuete angle of direction vector.
let azimuth = Math.atan2(-this._dx[0], this._dx[2]) *
Utils.RADIANS_TO_DEGREES;
let elevation = Math.atan2(this._dx[1], Math.sqrt(this._dx[0] * this._dx[0] +
this._dx[2] * this._dx[2])) * Utils.RADIANS_TO_DEGREES;
// Set distance/directivity/direction values.
this._attenuation.setDistance(distance);
this._directivity.computeAngle(this._forward, this._dx);
this._encoder.setDirection(azimuth, elevation);
};
/**
* Set source's rolloff.
* @param {string} rolloff
* Rolloff model to use, chosen from options in
* {@linkcode Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}.
*/
Source.prototype.setRolloff = function(rolloff) {
this._attenuation.setRolloff(rolloff);
};
/**
* Set source's minimum distance (in meters).
* @param {Number} minDistance
*/
Source.prototype.setMinDistance = function(minDistance) {
this._attenuation.minDistance = minDistance;
};
/**
* Set source's maximum distance (in meters).
* @param {Number} maxDistance
*/
Source.prototype.setMaxDistance = function(maxDistance) {
this._attenuation.maxDistance = maxDistance;
};
/**
* Set source's gain (linear).
* @param {Number} gain
*/
Source.prototype.setGain = function(gain) {
this.input.gain.value = gain;
};
/**
* Set the source's orientation using forward and up vectors.
* @param {Number} forwardX
* @param {Number} forwardY
* @param {Number} forwardZ
* @param {Number} upX
* @param {Number} upY
* @param {Number} upZ
*/
Source.prototype.setOrientation = function(forwardX, forwardY, forwardZ,
upX, upY, upZ) {
this._forward[0] = forwardX;
this._forward[1] = forwardY;
this._forward[2] = forwardZ;
this._up[0] = upX;
this._up[1] = upY;
this._up[2] = upZ;
this._right = Utils.crossProduct(this._forward, this._up);
};
// TODO(bitllama): Make sure this works with Three.js as intended.
/**
* Set source's position and orientation using a
* Three.js modelViewMatrix object.
* @param {Float32Array} matrix4
* The Matrix4 representing the object position and rotation in world space.
*/
Source.prototype.setFromMatrix = function(matrix4) {
this._right[0] = matrix4.elements[0];
this._right[1] = matrix4.elements[1];
this._right[2] = matrix4.elements[2];
this._up[0] = matrix4.elements[4];
this._up[1] = matrix4.elements[5];
this._up[2] = matrix4.elements[6];
this._forward[0] = matrix4.elements[8];
this._forward[1] = matrix4.elements[9];
this._forward[2] = matrix4.elements[10];
// Normalize to remove scaling.
this._right = Utils.normalizeVector(this._right);
this._up = Utils.normalizeVector(this._up);
this._forward = Utils.normalizeVector(this._forward);
// Update position.
this.setPosition(
matrix4.elements[12], matrix4.elements[13], matrix4.elements[14]);
};
/**
* Set the source width (in degrees). Where 0 degrees is a point source and 360
* degrees is an omnidirectional source.
* @param {Number} sourceWidth (in degrees).
*/
Source.prototype.setSourceWidth = function(sourceWidth) {
this._encoder.setSourceWidth(sourceWidth);
this.setPosition(this._position[0], this._position[1], this._position[2]);
};
/**
* Set source's directivity pattern (defined by alpha), where 0 is an
* omnidirectional pattern, 1 is a bidirectional pattern, 0.5 is a cardiod
* pattern. The sharpness of the pattern is increased exponentially.
* @param {Number} alpha
* Determines directivity pattern (0 to 1).
* @param {Number} sharpness
* Determines the sharpness of the directivity pattern (1 to Inf).
*/
Source.prototype.setDirectivityPattern = function(alpha, sharpness) {
this._directivity.setPattern(alpha, sharpness);
this.setPosition(this._position[0], this._position[1], this._position[2]);
};
/**
* Determine the distance a source is outside of a room. Attenuate gain going
* to the reflections and reverb when the source is outside of the room.
* @param {Number} distance Distance in meters.
* @return {Number} Gain (linear) of source.
* @private
*/
function _computeDistanceOutsideRoom(distance) {
// We apply a linear ramp from 1 to 0 as the source is up to 1m outside.
let gain = 1;
if (distance > Utils.EPSILON_FLOAT) {
gain = 1 - distance / Utils.SOURCE_MAX_OUTSIDE_ROOM_DISTANCE;
// Clamp gain between 0 and 1.
gain = Math.max(0, Math.min(1, gain));
}
return gain;
}
module.exports = Source;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Directivity/occlusion filter.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Utils = __webpack_require__(0);
/**
* @class Directivity
* @description Directivity/occlusion filter.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Number} options.alpha
* Determines directivity pattern (0 to 1). See
* {@link Directivity#setPattern setPattern} for more details. Defaults to
* {@linkcode Utils.DEFAULT_DIRECTIVITY_ALPHA DEFAULT_DIRECTIVITY_ALPHA}.
* @param {Number} options.sharpness
* Determines the sharpness of the directivity pattern (1 to Inf). See
* {@link Directivity#setPattern setPattern} for more details. Defaults to
* {@linkcode Utils.DEFAULT_DIRECTIVITY_SHARPNESS
* DEFAULT_DIRECTIVITY_SHARPNESS}.
*/
function Directivity(context, options) {
// Public variables.
/**
* Mono (1-channel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} input
* @memberof Directivity
* @instance
*/
/**
* Mono (1-channel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof Directivity
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.alpha == undefined) {
options.alpha = Utils.DEFAULT_DIRECTIVITY_ALPHA;
}
if (options.sharpness == undefined) {
options.sharpness = Utils.DEFAULT_DIRECTIVITY_SHARPNESS;
}
// Create audio node.
this._context = context;
this._lowpass = context.createBiquadFilter();
// Initialize filter coefficients.
this._lowpass.type = 'lowpass';
this._lowpass.Q.value = 0;
this._lowpass.frequency.value = context.sampleRate * 0.5;
this._cosTheta = 0;
this.setPattern(options.alpha, options.sharpness);
// Input/Output proxy.
this.input = this._lowpass;
this.output = this._lowpass;
}
/**
* Compute the filter using the source's forward orientation and the listener's
* position.
* @param {Float32Array} forward The source's forward vector.
* @param {Float32Array} direction The direction from the source to the
* listener.
*/
Directivity.prototype.computeAngle = function(forward, direction) {
let forwardNorm = Utils.normalizeVector(forward);
let directionNorm = Utils.normalizeVector(direction);
let coeff = 1;
if (this._alpha > Utils.EPSILON_FLOAT) {
let cosTheta = forwardNorm[0] * directionNorm[0] +
forwardNorm[1] * directionNorm[1] + forwardNorm[2] * directionNorm[2];
coeff = (1 - this._alpha) + this._alpha * cosTheta;
coeff = Math.pow(Math.abs(coeff), this._sharpness);
}
this._lowpass.frequency.value = this._context.sampleRate * 0.5 * coeff;
};
/**
* Set source's directivity pattern (defined by alpha), where 0 is an
* omnidirectional pattern, 1 is a bidirectional pattern, 0.5 is a cardiod
* pattern. The sharpness of the pattern is increased exponenentially.
* @param {Number} alpha
* Determines directivity pattern (0 to 1).
* @param {Number} sharpness
* Determines the sharpness of the directivity pattern (1 to Inf).
* DEFAULT_DIRECTIVITY_SHARPNESS}.
*/
Directivity.prototype.setPattern = function(alpha, sharpness) {
// Clamp and set values.
this._alpha = Math.min(1, Math.max(0, alpha));
this._sharpness = Math.max(1, sharpness);
// Update angle calculation using new values.
this.computeAngle([this._cosTheta * this._cosTheta, 0, 0], [1, 0, 0]);
};
module.exports = Directivity;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Distance-based attenuation filter.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Utils = __webpack_require__(0);
/**
* @class Attenuation
* @description Distance-based attenuation filter.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Number} options.minDistance
* Min. distance (in meters). Defaults to
* {@linkcode Utils.DEFAULT_MIN_DISTANCE DEFAULT_MIN_DISTANCE}.
* @param {Number} options.maxDistance
* Max. distance (in meters). Defaults to
* {@linkcode Utils.DEFAULT_MAX_DISTANCE DEFAULT_MAX_DISTANCE}.
* @param {string} options.rolloff
* Rolloff model to use, chosen from options in
* {@linkcode Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}. Defaults to
* {@linkcode Utils.DEFAULT_ATTENUATION_ROLLOFF DEFAULT_ATTENUATION_ROLLOFF}.
*/
function Attenuation(context, options) {
// Public variables.
/**
* Min. distance (in meters).
* @member {Number} minDistance
* @memberof Attenuation
* @instance
*/
/**
* Max. distance (in meters).
* @member {Number} maxDistance
* @memberof Attenuation
* @instance
*/
/**
* Mono (1-channel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} input
* @memberof Attenuation
* @instance
*/
/**
* Mono (1-channel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof Attenuation
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.minDistance == undefined) {
options.minDistance = Utils.DEFAULT_MIN_DISTANCE;
}
if (options.maxDistance == undefined) {
options.maxDistance = Utils.DEFAULT_MAX_DISTANCE;
}
if (options.rolloff == undefined) {
options.rolloff = Utils.DEFAULT_ATTENUATION_ROLLOFF;
}
// Assign values.
this.minDistance = options.minDistance;
this.maxDistance = options.maxDistance;
this.setRolloff(options.rolloff);
// Create node.
this._gainNode = context.createGain();
// Initialize distance to max distance.
this.setDistance(options.maxDistance);
// Input/Output proxy.
this.input = this._gainNode;
this.output = this._gainNode;
}
/**
* Set distance from the listener.
* @param {Number} distance Distance (in meters).
*/
Attenuation.prototype.setDistance = function(distance) {
let gain = 1;
if (this._rolloff == 'logarithmic') {
if (distance > this.maxDistance) {
gain = 0;
} else if (distance > this.minDistance) {
let range = this.maxDistance - this.minDistance;
if (range > Utils.EPSILON_FLOAT) {
// Compute the distance attenuation value by the logarithmic curve
// "1 / (d + 1)" with an offset of |minDistance|.
let relativeDistance = distance - this.minDistance;
let attenuation = 1 / (relativeDistance + 1);
let attenuationMax = 1 / (range + 1);
gain = (attenuation - attenuationMax) / (1 - attenuationMax);
}
}
} else if (this._rolloff == 'linear') {
if (distance > this.maxDistance) {
gain = 0;
} else if (distance > this.minDistance) {
let range = this.maxDistance - this.minDistance;
if (range > Utils.EPSILON_FLOAT) {
gain = (this.maxDistance - distance) / range;
}
}
}
this._gainNode.gain.value = gain;
};
/**
* Set rolloff.
* @param {string} rolloff
* Rolloff model to use, chosen from options in
* {@linkcode Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}.
*/
Attenuation.prototype.setRolloff = function(rolloff) {
let isValidModel = ~Utils.ATTENUATION_ROLLOFFS.indexOf(rolloff);
if (rolloff == undefined || !isValidModel) {
if (!isValidModel) {
Utils.log('Invalid rolloff model (\"' + rolloff +
'\"). Using default: \"' + Utils.DEFAULT_ATTENUATION_ROLLOFF + '\".');
}
rolloff = Utils.DEFAULT_ATTENUATION_ROLLOFF;
} else {
rolloff = rolloff.toString().toLowerCase();
}
this._rolloff = rolloff;
};
module.exports = Attenuation;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Complete room model with early and late reflections.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const LateReflections = __webpack_require__(8);
const EarlyReflections = __webpack_require__(9);
const Utils = __webpack_require__(0);
/**
* Generate absorption coefficients from material names.
* @param {Object} materials
* @return {Object}
*/
function _getCoefficientsFromMaterials(materials) {
// Initialize coefficients to use defaults.
let coefficients = {};
for (let property in Utils.DEFAULT_ROOM_MATERIALS) {
if (Utils.DEFAULT_ROOM_MATERIALS.hasOwnProperty(property)) {
coefficients[property] = Utils.ROOM_MATERIAL_COEFFICIENTS[
Utils.DEFAULT_ROOM_MATERIALS[property]];
}
}
// Sanitize materials.
if (materials == undefined) {
materials = {};
Object.assign(materials, Utils.DEFAULT_ROOM_MATERIALS);
}
// Assign coefficients using provided materials.
for (let property in Utils.DEFAULT_ROOM_MATERIALS) {
if (Utils.DEFAULT_ROOM_MATERIALS.hasOwnProperty(property) &&
materials.hasOwnProperty(property)) {
if (materials[property] in Utils.ROOM_MATERIAL_COEFFICIENTS) {
coefficients[property] =
Utils.ROOM_MATERIAL_COEFFICIENTS[materials[property]];
} else {
Utils.log('Material \"' + materials[property] + '\" on wall \"' +
property + '\" not found. Using \"' +
Utils.DEFAULT_ROOM_MATERIALS[property] + '\".');
}
} else {
Utils.log('Wall \"' + property + '\" is not defined. Default used.');
}
}
return coefficients;
}
/**
* Sanitize coefficients.
* @param {Object} coefficients
* @return {Object}
*/
function _sanitizeCoefficients(coefficients) {
if (coefficients == undefined) {
coefficients = {};
}
for (let property in Utils.DEFAULT_ROOM_MATERIALS) {
if (!(coefficients.hasOwnProperty(property))) {
// If element is not present, use default coefficients.
coefficients[property] = Utils.ROOM_MATERIAL_COEFFICIENTS[
Utils.DEFAULT_ROOM_MATERIALS[property]];
}
}
return coefficients;
}
/**
* Sanitize dimensions.
* @param {Object} dimensions
* @return {Object}
*/
function _sanitizeDimensions(dimensions) {
if (dimensions == undefined) {
dimensions = {};
}
for (let property in Utils.DEFAULT_ROOM_DIMENSIONS) {
if (!(dimensions.hasOwnProperty(property))) {
dimensions[property] = Utils.DEFAULT_ROOM_DIMENSIONS[property];
}
}
return dimensions;
}
/**
* Compute frequency-dependent reverb durations.
* @param {Object} dimensions
* @param {Object} coefficients
* @param {Number} speedOfSound
* @return {Array}
*/
function _getDurationsFromProperties(dimensions, coefficients, speedOfSound) {
let durations = new Float32Array(Utils.NUMBER_REVERB_FREQUENCY_BANDS);
// Sanitize inputs.
dimensions = _sanitizeDimensions(dimensions);
coefficients = _sanitizeCoefficients(coefficients);
if (speedOfSound == undefined) {
speedOfSound = Utils.DEFAULT_SPEED_OF_SOUND;
}
// Acoustic constant.
let k = Utils.TWENTY_FOUR_LOG10 / speedOfSound;
// Compute volume, skip if room is not present.
let volume = dimensions.width * dimensions.height * dimensions.depth;
if (volume < Utils.ROOM_MIN_VOLUME) {
return durations;
}
// Room surface area.
let leftRightArea = dimensions.width * dimensions.height;
let floorCeilingArea = dimensions.width * dimensions.depth;
let frontBackArea = dimensions.depth * dimensions.height;
let totalArea = 2 * (leftRightArea + floorCeilingArea + frontBackArea);
for (let i = 0; i < Utils.NUMBER_REVERB_FREQUENCY_BANDS; i++) {
// Effective absorptive area.
let absorbtionArea =
(coefficients.left[i] + coefficients.right[i]) * leftRightArea +
(coefficients.down[i] + coefficients.up[i]) * floorCeilingArea +
(coefficients.front[i] + coefficients.back[i]) * frontBackArea;
let meanAbsorbtionArea = absorbtionArea / totalArea;
// Compute reverberation using Eyring equation [1].
// [1] Beranek, Leo L. "Analysis of Sabine and Eyring equations and their
// application to concert hall audience and chair absorption." The
// Journal of the Acoustical Society of America, Vol. 120, No. 3.
// (2006), pp. 1399-1399.
durations[i] = Utils.ROOM_EYRING_CORRECTION_COEFFICIENT * k * volume /
(-totalArea * Math.log(1 - meanAbsorbtionArea) + 4 *
Utils.ROOM_AIR_ABSORPTION_COEFFICIENTS[i] * volume);
}
return durations;
}
/**
* Compute reflection coefficients from absorption coefficients.
* @param {Object} absorptionCoefficients
* @return {Object}
*/
function _computeReflectionCoefficients(absorptionCoefficients) {
let reflectionCoefficients = [];
for (let property in Utils.DEFAULT_REFLECTION_COEFFICIENTS) {
if (Utils.DEFAULT_REFLECTION_COEFFICIENTS
.hasOwnProperty(property)) {
// Compute average absorption coefficient (per wall).
reflectionCoefficients[property] = 0;
for (let j = 0; j < Utils.NUMBER_REFLECTION_AVERAGING_BANDS; j++) {
let bandIndex = j + Utils.ROOM_STARTING_AVERAGING_BAND;
reflectionCoefficients[property] +=
absorptionCoefficients[property][bandIndex];
}
reflectionCoefficients[property] /=
Utils.NUMBER_REFLECTION_AVERAGING_BANDS;
// Convert absorption coefficient to reflection coefficient.
reflectionCoefficients[property] =
Math.sqrt(1 - reflectionCoefficients[property]);
}
}
return reflectionCoefficients;
}
/**
* @class Room
* @description Model that manages early and late reflections using acoustic
* properties and listener position relative to a rectangular room.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Float32Array} options.listenerPosition
* The listener's initial position (in meters), where origin is the center of
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
* @param {Object} options.dimensions Room dimensions (in meters). Defaults to
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
* @param {Object} options.materials Named acoustic materials per wall.
* Defaults to {@linkcode Utils.DEFAULT_ROOM_MATERIALS DEFAULT_ROOM_MATERIALS}.
* @param {Number} options.speedOfSound
* (in meters/second). Defaults to
* {@linkcode Utils.DEFAULT_SPEED_OF_SOUND DEFAULT_SPEED_OF_SOUND}.
*/
function Room(context, options) {
// Public variables.
/**
* EarlyReflections {@link EarlyReflections EarlyReflections} submodule.
* @member {AudioNode} early
* @memberof Room
* @instance
*/
/**
* LateReflections {@link LateReflections LateReflections} submodule.
* @member {AudioNode} late
* @memberof Room
* @instance
*/
/**
* Ambisonic (multichannel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof Room
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.listenerPosition == undefined) {
options.listenerPosition = Utils.DEFAULT_POSITION.slice();
}
if (options.dimensions == undefined) {
options.dimensions = {};
Object.assign(options.dimensions, Utils.DEFAULT_ROOM_DIMENSIONS);
}
if (options.materials == undefined) {
options.materials = {};
Object.assign(options.materials, Utils.DEFAULT_ROOM_MATERIALS);
}
if (options.speedOfSound == undefined) {
options.speedOfSound = Utils.DEFAULT_SPEED_OF_SOUND;
}
// Sanitize room-properties-related arguments.
options.dimensions = _sanitizeDimensions(options.dimensions);
let absorptionCoefficients = _getCoefficientsFromMaterials(options.materials);
let reflectionCoefficients =
_computeReflectionCoefficients(absorptionCoefficients);
let durations = _getDurationsFromProperties(options.dimensions,
absorptionCoefficients, options.speedOfSound);
// Construct submodules for early and late reflections.
this.early = new EarlyReflections(context, {
dimensions: options.dimensions,
coefficients: reflectionCoefficients,
speedOfSound: options.speedOfSound,
listenerPosition: options.listenerPosition,
});
this.late = new LateReflections(context, {
durations: durations,
});
this.speedOfSound = options.speedOfSound;
// Construct auxillary audio nodes.
this.output = context.createGain();
this.early.output.connect(this.output);
this._merger = context.createChannelMerger(4);
this.late.output.connect(this._merger, 0, 0);
this._merger.connect(this.output);
}
/**
* Set the room's dimensions and wall materials.
* @param {Object} dimensions Room dimensions (in meters). Defaults to
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
* @param {Object} materials Named acoustic materials per wall. Defaults to
* {@linkcode Utils.DEFAULT_ROOM_MATERIALS DEFAULT_ROOM_MATERIALS}.
*/
Room.prototype.setProperties = function(dimensions, materials) {
// Compute late response.
let absorptionCoefficients = _getCoefficientsFromMaterials(materials);
let durations = _getDurationsFromProperties(dimensions,
absorptionCoefficients, this.speedOfSound);
this.late.setDurations(durations);
// Compute early response.
this.early.speedOfSound = this.speedOfSound;
let reflectionCoefficients =
_computeReflectionCoefficients(absorptionCoefficients);
this.early.setRoomProperties(dimensions, reflectionCoefficients);
};
/**
* Set the listener's position (in meters), where origin is the center of
* the room.
* @param {Number} x
* @param {Number} y
* @param {Number} z
*/
Room.prototype.setListenerPosition = function(x, y, z) {
this.early.speedOfSound = this.speedOfSound;
this.early.setListenerPosition(x, y, z);
// Disable room effects if the listener is outside the room boundaries.
let distance = this.getDistanceOutsideRoom(x, y, z);
let gain = 1;
if (distance > Utils.EPSILON_FLOAT) {
gain = 1 - distance / Utils.LISTENER_MAX_OUTSIDE_ROOM_DISTANCE;
// Clamp gain between 0 and 1.
gain = Math.max(0, Math.min(1, gain));
}
this.output.gain.value = gain;
};
/**
* Compute distance outside room of provided position (in meters).
* @param {Number} x
* @param {Number} y
* @param {Number} z
* @return {Number}
* Distance outside room (in meters). Returns 0 if inside room.
*/
Room.prototype.getDistanceOutsideRoom = function(x, y, z) {
let dx = Math.max(0, -this.early._halfDimensions.width - x,
x - this.early._halfDimensions.width);
let dy = Math.max(0, -this.early._halfDimensions.height - y,
y - this.early._halfDimensions.height);
let dz = Math.max(0, -this.early._halfDimensions.depth - z,
z - this.early._halfDimensions.depth);
return Math.sqrt(dx * dx + dy * dy + dz * dz);
};
module.exports = Room;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Late reverberation filter for Ambisonic content.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Utils = __webpack_require__(0);
/**
* @class LateReflections
* @description Late-reflections reverberation filter for Ambisonic content.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Array} options.durations
* Multiband RT60 durations (in seconds) for each frequency band, listed as
* {@linkcode Utils.DEFAULT_REVERB_FREQUENCY_BANDS
* FREQUDEFAULT_REVERB_FREQUENCY_BANDSENCY_BANDS}. Defaults to
* {@linkcode Utils.DEFAULT_REVERB_DURATIONS DEFAULT_REVERB_DURATIONS}.
* @param {Number} options.predelay Pre-delay (in milliseconds). Defaults to
* {@linkcode Utils.DEFAULT_REVERB_PREDELAY DEFAULT_REVERB_PREDELAY}.
* @param {Number} options.gain Output gain (linear). Defaults to
* {@linkcode Utils.DEFAULT_REVERB_GAIN DEFAULT_REVERB_GAIN}.
* @param {Number} options.bandwidth Bandwidth (in octaves) for each frequency
* band. Defaults to
* {@linkcode Utils.DEFAULT_REVERB_BANDWIDTH DEFAULT_REVERB_BANDWIDTH}.
* @param {Number} options.tailonset Length (in milliseconds) of impulse
* response to apply a half-Hann window. Defaults to
* {@linkcode Utils.DEFAULT_REVERB_TAIL_ONSET DEFAULT_REVERB_TAIL_ONSET}.
*/
function LateReflections(context, options) {
// Public variables.
/**
* Mono (1-channel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} input
* @memberof LateReflections
* @instance
*/
/**
* Mono (1-channel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof LateReflections
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.durations == undefined) {
options.durations = Utils.DEFAULT_REVERB_DURATIONS.slice();
}
if (options.predelay == undefined) {
options.predelay = Utils.DEFAULT_REVERB_PREDELAY;
}
if (options.gain == undefined) {
options.gain = Utils.DEFAULT_REVERB_GAIN;
}
if (options.bandwidth == undefined) {
options.bandwidth = Utils.DEFAULT_REVERB_BANDWIDTH;
}
if (options.tailonset == undefined) {
options.tailonset = Utils.DEFAULT_REVERB_TAIL_ONSET;
}
// Assign pre-computed variables.
let delaySecs = options.predelay / 1000;
this._bandwidthCoeff = options.bandwidth * Utils.LOG2_DIV2;
this._tailonsetSamples = options.tailonset / 1000;
// Create nodes.
this._context = context;
this.input = context.createGain();
this._predelay = context.createDelay(delaySecs);
this._convolver = context.createConvolver();
this.output = context.createGain();
// Set reverb attenuation.
this.output.gain.value = options.gain;
// Disable normalization.
this._convolver.normalize = false;
// Connect nodes.
this.input.connect(this._predelay);
this._predelay.connect(this._convolver);
this._convolver.connect(this.output);
// Compute IR using RT60 values.
this.setDurations(options.durations);
}
/**
* Re-compute a new impulse response by providing Multiband RT60 durations.
* @param {Array} durations
* Multiband RT60 durations (in seconds) for each frequency band, listed as
* {@linkcode Utils.DEFAULT_REVERB_FREQUENCY_BANDS
* DEFAULT_REVERB_FREQUENCY_BANDS}.
*/
LateReflections.prototype.setDurations = function(durations) {
if (durations.length !== Utils.NUMBER_REVERB_FREQUENCY_BANDS) {
Utils.log('Warning: invalid number of RT60 values provided to reverb.');
return;
}
// Compute impulse response.
let durationsSamples =
new Float32Array(Utils.NUMBER_REVERB_FREQUENCY_BANDS);
let sampleRate = this._context.sampleRate;
for (let i = 0; i < durations.length; i++) {
// Clamp within suitable range.
durations[i] =
Math.max(0, Math.min(Utils.DEFAULT_REVERB_MAX_DURATION, durations[i]));
// Convert seconds to samples.
durationsSamples[i] = Math.round(durations[i] * sampleRate *
Utils.DEFAULT_REVERB_DURATION_MULTIPLIER);
};
// Determine max RT60 length in samples.
let durationsSamplesMax = 0;
for (let i = 0; i < durationsSamples.length; i++) {
if (durationsSamples[i] > durationsSamplesMax) {
durationsSamplesMax = durationsSamples[i];
}
}
// Skip this step if there is no reverberation to compute.
if (durationsSamplesMax < 1) {
durationsSamplesMax = 1;
}
// Create impulse response buffer.
let buffer = this._context.createBuffer(1, durationsSamplesMax, sampleRate);
let bufferData = buffer.getChannelData(0);
// Create noise signal (computed once, referenced in each band's routine).
let noiseSignal = new Float32Array(durationsSamplesMax);
for (let i = 0; i < durationsSamplesMax; i++) {
noiseSignal[i] = Math.random() * 2 - 1;
}
// Compute the decay rate per-band and filter the decaying noise signal.
for (let i = 0; i < Utils.NUMBER_REVERB_FREQUENCY_BANDS; i++) {
// Compute decay rate.
let decayRate = -Utils.LOG1000 / durationsSamples[i];
// Construct a standard one-zero, two-pole bandpass filter:
// H(z) = (b0 * z^0 + b1 * z^-1 + b2 * z^-2) / (1 + a1 * z^-1 + a2 * z^-2)
let omega = Utils.TWO_PI *
Utils.DEFAULT_REVERB_FREQUENCY_BANDS[i] / sampleRate;
let sinOmega = Math.sin(omega);
let alpha = sinOmega * Math.sinh(this._bandwidthCoeff * omega / sinOmega);
let a0CoeffReciprocal = 1 / (1 + alpha);
let b0Coeff = alpha * a0CoeffReciprocal;
let a1Coeff = -2 * Math.cos(omega) * a0CoeffReciprocal;
let a2Coeff = (1 - alpha) * a0CoeffReciprocal;
// We optimize since b2 = -b0, b1 = 0.
// Update equation for two-pole bandpass filter:
// u[n] = x[n] - a1 * x[n-1] - a2 * x[n-2]
// y[n] = b0 * (u[n] - u[n-2])
let um1 = 0;
let um2 = 0;
for (let j = 0; j < durationsSamples[i]; j++) {
// Exponentially-decaying white noise.
let x = noiseSignal[j] * Math.exp(decayRate * j);
// Filter signal with bandpass filter and add to output.
let u = x - a1Coeff * um1 - a2Coeff * um2;
bufferData[j] += b0Coeff * (u - um2);
// Update coefficients.
um2 = um1;
um1 = u;
}
}
// Create and apply half of a Hann window to the beginning of the
// impulse response.
let halfHannLength =
Math.round(this._tailonsetSamples);
for (let i = 0; i < Math.min(bufferData.length, halfHannLength); i++) {
let halfHann =
0.5 * (1 - Math.cos(Utils.TWO_PI * i / (2 * halfHannLength - 1)));
bufferData[i] *= halfHann;
}
this._convolver.buffer = buffer;
};
module.exports = LateReflections;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Ray-tracing-based early reflections model.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Utils = __webpack_require__(0);
/**
* @class EarlyReflections
* @description Ray-tracing-based early reflections model.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Object} options.dimensions
* Room dimensions (in meters). Defaults to
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
* @param {Object} options.coefficients
* Frequency-independent reflection coeffs per wall. Defaults to
* {@linkcode Utils.DEFAULT_REFLECTION_COEFFICIENTS
* DEFAULT_REFLECTION_COEFFICIENTS}.
* @param {Number} options.speedOfSound
* (in meters / second). Defaults to {@linkcode Utils.DEFAULT_SPEED_OF_SOUND
* DEFAULT_SPEED_OF_SOUND}.
* @param {Float32Array} options.listenerPosition
* (in meters). Defaults to
* {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
*/
function EarlyReflections(context, options) {
// Public variables.
/**
* The room's speed of sound (in meters/second).
* @member {Number} speedOfSound
* @memberof EarlyReflections
* @instance
*/
/**
* Mono (1-channel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} input
* @memberof EarlyReflections
* @instance
*/
/**
* First-order ambisonic (4-channel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof EarlyReflections
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.speedOfSound == undefined) {
options.speedOfSound = Utils.DEFAULT_SPEED_OF_SOUND;
}
if (options.listenerPosition == undefined) {
options.listenerPosition = Utils.DEFAULT_POSITION.slice();
}
if (options.coefficients == undefined) {
options.coefficients = {};
Object.assign(options.coefficients, Utils.DEFAULT_REFLECTION_COEFFICIENTS);
}
// Assign room's speed of sound.
this.speedOfSound = options.speedOfSound;
// Create nodes.
this.input = context.createGain();
this.output = context.createGain();
this._lowpass = context.createBiquadFilter();
this._delays = {};
this._gains = {}; // gainPerWall = (ReflectionCoeff / Attenuation)
this._inverters = {}; // 3 of these are needed for right/back/down walls.
this._merger = context.createChannelMerger(4); // First-order encoding only.
// Connect audio graph for each wall reflection.
for (let property in Utils.DEFAULT_REFLECTION_COEFFICIENTS) {
if (Utils.DEFAULT_REFLECTION_COEFFICIENTS
.hasOwnProperty(property)) {
this._delays[property] =
context.createDelay(Utils.MAX_DURATION);
this._gains[property] = context.createGain();
}
}
this._inverters.right = context.createGain();
this._inverters.down = context.createGain();
this._inverters.back = context.createGain();
// Initialize lowpass filter.
this._lowpass.type = 'lowpass';
this._lowpass.frequency.value = Utils.DEFAULT_REFLECTION_CUTOFF_FREQUENCY;
this._lowpass.Q.value = 0;
// Initialize encoder directions, set delay times and gains to 0.
for (let property in Utils.DEFAULT_REFLECTION_COEFFICIENTS) {
if (Utils.DEFAULT_REFLECTION_COEFFICIENTS
.hasOwnProperty(property)) {
this._delays[property].delayTime.value = 0;
this._gains[property].gain.value = 0;
}
}
// Initialize inverters for opposite walls ('right', 'down', 'back' only).
this._inverters.right.gain.value = -1;
this._inverters.down.gain.value = -1;
this._inverters.back.gain.value = -1;
// Connect nodes.
this.input.connect(this._lowpass);
for (let property in Utils.DEFAULT_REFLECTION_COEFFICIENTS) {
if (Utils.DEFAULT_REFLECTION_COEFFICIENTS
.hasOwnProperty(property)) {
this._lowpass.connect(this._delays[property]);
this._delays[property].connect(this._gains[property]);
this._gains[property].connect(this._merger, 0, 0);
}
}
// Connect gains to ambisonic channel output.
// Left: [1 1 0 0]
// Right: [1 -1 0 0]
// Up: [1 0 1 0]
// Down: [1 0 -1 0]
// Front: [1 0 0 1]
// Back: [1 0 0 -1]
this._gains.left.connect(this._merger, 0, 1);
this._gains.right.connect(this._inverters.right);
this._inverters.right.connect(this._merger, 0, 1);
this._gains.up.connect(this._merger, 0, 2);
this._gains.down.connect(this._inverters.down);
this._inverters.down.connect(this._merger, 0, 2);
this._gains.front.connect(this._merger, 0, 3);
this._gains.back.connect(this._inverters.back);
this._inverters.back.connect(this._merger, 0, 3);
this._merger.connect(this.output);
// Initialize.
this._listenerPosition = options.listenerPosition;
this.setRoomProperties(options.dimensions, options.coefficients);
}
/**
* Set the listener's position (in meters),
* where [0,0,0] is the center of the room.
* @param {Number} x
* @param {Number} y
* @param {Number} z
*/
EarlyReflections.prototype.setListenerPosition = function(x, y, z) {
// Assign listener position.
this._listenerPosition = [x, y, z];
// Determine distances to each wall.
let distances = {
left: Utils.DEFAULT_REFLECTION_MULTIPLIER * Math.max(0,
this._halfDimensions.width + x) + Utils.DEFAULT_REFLECTION_MIN_DISTANCE,
right: Utils.DEFAULT_REFLECTION_MULTIPLIER * Math.max(0,
this._halfDimensions.width - x) + Utils.DEFAULT_REFLECTION_MIN_DISTANCE,
front: Utils.DEFAULT_REFLECTION_MULTIPLIER * Math.max(0,
this._halfDimensions.depth + z) + Utils.DEFAULT_REFLECTION_MIN_DISTANCE,
back: Utils.DEFAULT_REFLECTION_MULTIPLIER * Math.max(0,
this._halfDimensions.depth - z) + Utils.DEFAULT_REFLECTION_MIN_DISTANCE,
down: Utils.DEFAULT_REFLECTION_MULTIPLIER * Math.max(0,
this._halfDimensions.height + y) + Utils.DEFAULT_REFLECTION_MIN_DISTANCE,
up: Utils.DEFAULT_REFLECTION_MULTIPLIER * Math.max(0,
this._halfDimensions.height - y) + Utils.DEFAULT_REFLECTION_MIN_DISTANCE,
};
// Assign delay & attenuation values using distances.
for (let property in Utils.DEFAULT_REFLECTION_COEFFICIENTS) {
if (Utils.DEFAULT_REFLECTION_COEFFICIENTS
.hasOwnProperty(property)) {
// Compute and assign delay (in seconds).
let delayInSecs = distances[property] / this.speedOfSound;
this._delays[property].delayTime.value = delayInSecs;
// Compute and assign gain, uses logarithmic rolloff: "g = R / (d + 1)"
let attenuation = this._coefficients[property] / distances[property];
this._gains[property].gain.value = attenuation;
}
}
};
/**
* Set the room's properties which determines the characteristics of
* reflections.
* @param {Object} dimensions
* Room dimensions (in meters). Defaults to
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
* @param {Object} coefficients
* Frequency-independent reflection coeffs per wall. Defaults to
* {@linkcode Utils.DEFAULT_REFLECTION_COEFFICIENTS
* DEFAULT_REFLECTION_COEFFICIENTS}.
*/
EarlyReflections.prototype.setRoomProperties = function(dimensions,
coefficients) {
if (dimensions == undefined) {
dimensions = {};
Object.assign(dimensions, Utils.DEFAULT_ROOM_DIMENSIONS);
}
if (coefficients == undefined) {
coefficients = {};
Object.assign(coefficients, Utils.DEFAULT_REFLECTION_COEFFICIENTS);
}
this._coefficients = coefficients;
// Sanitize dimensions and store half-dimensions.
this._halfDimensions = {};
this._halfDimensions.width = dimensions.width * 0.5;
this._halfDimensions.height = dimensions.height * 0.5;
this._halfDimensions.depth = dimensions.depth * 0.5;
// Update listener position with new room properties.
this.setListenerPosition(this._listenerPosition[0],
this._listenerPosition[1], this._listenerPosition[2]);
};
module.exports = EarlyReflections;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Primary namespace for ResonanceAudio library.
* @author Andrew Allen <bitllama@google.com>
*/
// Main module.
exports.ResonanceAudio = __webpack_require__(11);
// Testable Submodules.
exports.ResonanceAudio.Attenuation = __webpack_require__(6);
exports.ResonanceAudio.Directivity = __webpack_require__(5);
exports.ResonanceAudio.EarlyReflections = __webpack_require__(9);
exports.ResonanceAudio.Encoder = __webpack_require__(1);
exports.ResonanceAudio.LateReflections = __webpack_require__(8);
exports.ResonanceAudio.Listener = __webpack_require__(2);
exports.ResonanceAudio.Room = __webpack_require__(7);
exports.ResonanceAudio.Source = __webpack_require__(4);
exports.ResonanceAudio.Tables = __webpack_require__(3);
exports.ResonanceAudio.Utils = __webpack_require__(0);
exports.ResonanceAudio.Version = __webpack_require__(13);
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @license
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file ResonanceAudio library name space and common utilities.
* @author Andrew Allen <bitllama@google.com>
*/
// Internal dependencies.
const Listener = __webpack_require__(2);
const Source = __webpack_require__(4);
const Room = __webpack_require__(7);
const Encoder = __webpack_require__(1);
const Utils = __webpack_require__(0);
/**
* @class ResonanceAudio
* @description Main class for managing sources, room and listener models.
* @param {AudioContext} context
* Associated {@link
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext AudioContext}.
* @param {Object} options
* @param {Number} options.ambisonicOrder
* Desired ambisonic Order. Defaults to
* {@linkcode Utils.DEFAULT_AMBISONIC_ORDER DEFAULT_AMBISONIC_ORDER}.
* @param {Float32Array} options.listenerPosition
* The listener's initial position (in meters), where origin is the center of
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
* @param {Float32Array} options.listenerForward
* The listener's initial forward vector.
* Defaults to {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
* @param {Float32Array} options.listenerUp
* The listener's initial up vector.
* Defaults to {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
* @param {Object} options.dimensions Room dimensions (in meters). Defaults to
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
* @param {Object} options.materials Named acoustic materials per wall.
* Defaults to {@linkcode Utils.DEFAULT_ROOM_MATERIALS DEFAULT_ROOM_MATERIALS}.
* @param {Number} options.speedOfSound
* (in meters/second). Defaults to
* {@linkcode Utils.DEFAULT_SPEED_OF_SOUND DEFAULT_SPEED_OF_SOUND}.
*/
function ResonanceAudio(context, options) {
// Public variables.
/**
* Binaurally-rendered stereo (2-channel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}.
* @member {AudioNode} output
* @memberof ResonanceAudio
* @instance
*/
/**
* Ambisonic (multichannel) input {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}
* (For rendering input soundfields).
* @member {AudioNode} ambisonicInput
* @memberof ResonanceAudio
* @instance
*/
/**
* Ambisonic (multichannel) output {@link
* https://developer.mozilla.org/en-US/docs/Web/API/AudioNode AudioNode}
* (For allowing external rendering / post-processing).
* @member {AudioNode} ambisonicOutput
* @memberof ResonanceAudio
* @instance
*/
// Use defaults for undefined arguments.
if (options == undefined) {
options = {};
}
if (options.ambisonicOrder == undefined) {
options.ambisonicOrder = Utils.DEFAULT_AMBISONIC_ORDER;
}
if (options.listenerPosition == undefined) {
options.listenerPosition = Utils.DEFAULT_POSITION.slice();
}
if (options.listenerForward == undefined) {
options.listenerForward = Utils.DEFAULT_FORWARD.slice();
}
if (options.listenerUp == undefined) {
options.listenerUp = Utils.DEFAULT_UP.slice();
}
if (options.dimensions == undefined) {
options.dimensions = {};
Object.assign(options.dimensions, Utils.DEFAULT_ROOM_DIMENSIONS);
}
if (options.materials == undefined) {
options.materials = {};
Object.assign(options.materials, Utils.DEFAULT_ROOM_MATERIALS);
}
if (options.speedOfSound == undefined) {
options.speedOfSound = Utils.DEFAULT_SPEED_OF_SOUND;
}
// Create member submodules.
this._ambisonicOrder = Encoder.validateAmbisonicOrder(options.ambisonicOrder);
this._sources = [];
this._room = new Room(context, {
listenerPosition: options.listenerPosition,
dimensions: options.dimensions,
materials: options.materials,
speedOfSound: options.speedOfSound,
});
this._listener = new Listener(context, {
ambisonicOrder: options.ambisonicOrder,
position: options.listenerPosition,
forward: options.listenerForward,
up: options.listenerUp,
});
// Create auxillary audio nodes.
this._context = context;
this.output = context.createGain();
this.ambisonicOutput = context.createGain();
this.ambisonicInput = this._listener.input;
// Connect audio graph.
this._room.output.connect(this._listener.input);
this._listener.output.connect(this.output);
this._listener.ambisonicOutput.connect(this.ambisonicOutput);
}
/**
* Create a new source for the scene.
* @param {Object} options
* @param {Float32Array} options.position
* The source's initial position (in meters), where origin is the center of
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
* @param {Float32Array} options.forward
* The source's initial forward vector. Defaults to
* {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
* @param {Float32Array} options.up
* The source's initial up vector. Defaults to
* {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
* @param {Number} options.minDistance
* Min. distance (in meters). Defaults to
* {@linkcode Utils.DEFAULT_MIN_DISTANCE DEFAULT_MIN_DISTANCE}.
* @param {Number} options.maxDistance
* Max. distance (in meters). Defaults to
* {@linkcode Utils.DEFAULT_MAX_DISTANCE DEFAULT_MAX_DISTANCE}.
* @param {string} options.rolloff
* Rolloff model to use, chosen from options in
* {@linkcode Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}. Defaults to
* {@linkcode Utils.DEFAULT_ATTENUATION_ROLLOFF DEFAULT_ATTENUATION_ROLLOFF}.
* @param {Number} options.gain Input gain (linear). Defaults to
* {@linkcode Utils.DEFAULT_SOURCE_GAIN DEFAULT_SOURCE_GAIN}.
* @param {Number} options.alpha Directivity alpha. Defaults to
* {@linkcode Utils.DEFAULT_DIRECTIVITY_ALPHA DEFAULT_DIRECTIVITY_ALPHA}.
* @param {Number} options.sharpness Directivity sharpness. Defaults to
* {@linkcode Utils.DEFAULT_DIRECTIVITY_SHARPNESS
* DEFAULT_DIRECTIVITY_SHARPNESS}.
* @param {Number} options.sourceWidth
* Source width (in degrees). Where 0 degrees is a point source and 360 degrees
* is an omnidirectional source. Defaults to
* {@linkcode Utils.DEFAULT_SOURCE_WIDTH DEFAULT_SOURCE_WIDTH}.
* @return {Source}
*/
ResonanceAudio.prototype.createSource = function(options) {
// Create a source and push it to the internal sources array, returning
// the object's reference to the user.
let source = new Source(this, options);
this._sources[this._sources.length] = source;
return source;
};
/**
* Set the scene's desired ambisonic order.
* @param {Number} ambisonicOrder Desired ambisonic order.
*/
ResonanceAudio.prototype.setAmbisonicOrder = function(ambisonicOrder) {
this._ambisonicOrder = Encoder.validateAmbisonicOrder(ambisonicOrder);
};
/**
* Set the room's dimensions and wall materials.
* @param {Object} dimensions Room dimensions (in meters).
* @param {Object} materials Named acoustic materials per wall.
*/
ResonanceAudio.prototype.setRoomProperties = function(dimensions, materials) {
this._room.setProperties(dimensions, materials);
};
/**
* Set the listener's position (in meters), where origin is the center of
* the room.
* @param {Number} x
* @param {Number} y
* @param {Number} z
*/
ResonanceAudio.prototype.setListenerPosition = function(x, y, z) {
// Update listener position.
this._listener.position[0] = x;
this._listener.position[1] = y;
this._listener.position[2] = z;
this._room.setListenerPosition(x, y, z);
// Update sources with new listener position.
this._sources.forEach(function(element) {
element._update();
});
};
/**
* Set the source's orientation using forward and up vectors.
* @param {Number} forwardX
* @param {Number} forwardY
* @param {Number} forwardZ
* @param {Number} upX
* @param {Number} upY
* @param {Number} upZ
*/
ResonanceAudio.prototype.setListenerOrientation = function(forwardX, forwardY,
forwardZ, upX, upY, upZ) {
this._listener.setOrientation(forwardX, forwardY, forwardZ, upX, upY, upZ);
};
/**
* Set the listener's position and orientation using a Three.js Matrix4 object.
* @param {Object} matrix
* The Three.js Matrix4 object representing the listener's world transform.
*/
ResonanceAudio.prototype.setListenerFromMatrix = function(matrix) {
this._listener.setFromMatrix(matrix);
// Update the rest of the scene using new listener position.
this.setListenerPosition(this._listener.position[0],
this._listener.position[1], this._listener.position[2]);
};
/**
* Set the speed of sound.
* @param {Number} speedOfSound
*/
ResonanceAudio.prototype.setSpeedOfSound = function(speedOfSound) {
this._room.speedOfSound = speedOfSound;
};
module.exports = ResonanceAudio;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
(function webpackUniversalModuleDefinition(root, factory) {
if(true)
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 10);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
/**
* Copyright 2016 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Omnitone library common utilities.
*/
/**
* Omnitone library logging function.
* @param {any} Message to be printed out.
*/
exports.log = function() {
window.console.log.apply(window.console, [
'%c[Omnitone]%c ' + Array.prototype.slice.call(arguments).join(' ') +
' %c(@' + performance.now().toFixed(2) + 'ms)',
'background: #BBDEFB; color: #FF5722; font-weight: 500', 'font-weight: 300',
'color: #AAA',
]);
};
/**
* Omnitone library error-throwing function.
* @param {any} Message to be printed out.
*/
exports.throw = function() {
window.console.error.apply(window.console, [
'%c[Omnitone]%c ' + Array.prototype.slice.call(arguments).join(' ') +
' %c(@' + performance.now().toFixed(2) + 'ms)',
'background: #C62828; color: #FFEBEE; font-weight: 800', 'font-weight: 400',
'color: #AAA',
]);
throw new Error(false);
};
// Static temp storage for matrix inversion.
let a00;
let a01;
let a02;
let a03;
let a10;
let a11;
let a12;
let a13;
let a20;
let a21;
let a22;
let a23;
let a30;
let a31;
let a32;
let a33;
let b00;
let b01;
let b02;
let b03;
let b04;
let b05;
let b06;
let b07;
let b08;
let b09;
let b10;
let b11;
let det;
/**
* A 4x4 matrix inversion utility. This does not handle the case when the
* arguments are not proper 4x4 matrices.
* @param {Float32Array} out The inverted result.
* @param {Float32Array} a The source matrix.
* @return {Float32Array} out
*/
exports.invertMatrix4 = function(out, a) {
a00 = a[0];
a01 = a[1];
a02 = a[2];
a03 = a[3];
a10 = a[4];
a11 = a[5];
a12 = a[6];
a13 = a[7];
a20 = a[8];
a21 = a[9];
a22 = a[10];
a23 = a[11];
a30 = a[12];
a31 = a[13];
a32 = a[14];
a33 = a[15];
b00 = a00 * a11 - a01 * a10;
b01 = a00 * a12 - a02 * a10;
b02 = a00 * a13 - a03 * a10;
b03 = a01 * a12 - a02 * a11;
b04 = a01 * a13 - a03 * a11;
b05 = a02 * a13 - a03 * a12;
b06 = a20 * a31 - a21 * a30;
b07 = a20 * a32 - a22 * a30;
b08 = a20 * a33 - a23 * a30;
b09 = a21 * a32 - a22 * a31;
b10 = a21 * a33 - a23 * a31;
b11 = a22 * a33 - a23 * a32;
det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (!det) {
return null;
}
det = 1.0 / det;
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
return out;
};
/**
* Check if a value is defined in the ENUM dictionary.
* @param {Object} enumDictionary - ENUM dictionary.
* @param {Number|String} entryValue - a value to probe.
* @return {Boolean}
*/
exports.isDefinedENUMEntry = function(enumDictionary, entryValue) {
for (let enumKey in enumDictionary) {
if (entryValue === enumDictionary[enumKey]) {
return true;
}
}
return false;
};
/**
* Check if the given object is an instance of BaseAudioContext.
* @param {AudioContext} context - A context object to be checked.
* @return {Boolean}
*/
exports.isAudioContext = function(context) {
// TODO(hoch): Update this when BaseAudioContext is available for all
// browsers.
return context instanceof AudioContext ||
context instanceof OfflineAudioContext;
};
/**
* Check if the given object is a valid AudioBuffer.
* @param {Object} audioBuffer An AudioBuffer object to be checked.
* @return {Boolean}
*/
exports.isAudioBuffer = function(audioBuffer) {
return audioBuffer instanceof AudioBuffer;
};
/**
* Perform channel-wise merge on multiple AudioBuffers. The sample rate and
* the length of buffers to be merged must be identical.
* @param {BaseAudioContext} context - Associated BaseAudioContext.
* @param {AudioBuffer[]} bufferList - An array of AudioBuffers to be merged
* channel-wise.
* @return {AudioBuffer} - A single merged AudioBuffer.
*/
exports.mergeBufferListByChannel = function(context, bufferList) {
const bufferLength = bufferList[0].length;
const bufferSampleRate = bufferList[0].sampleRate;
let bufferNumberOfChannel = 0;
for (let i = 0; i < bufferList.length; ++i) {
if (bufferNumberOfChannel > 32) {
exports.throw('Utils.mergeBuffer: Number of channels cannot exceed 32.' +
'(got ' + bufferNumberOfChannel + ')');
}
if (bufferLength !== bufferList[i].length) {
exports.throw('Utils.mergeBuffer: AudioBuffer lengths are ' +
'inconsistent. (expected ' + bufferLength + ' but got ' +
bufferList[i].length + ')');
}
if (bufferSampleRate !== bufferList[i].sampleRate) {
exports.throw('Utils.mergeBuffer: AudioBuffer sample rates are ' +
'inconsistent. (expected ' + bufferSampleRate + ' but got ' +
bufferList[i].sampleRate + ')');
}
bufferNumberOfChannel += bufferList[i].numberOfChannels;
}
const buffer = context.createBuffer(bufferNumberOfChannel,
bufferLength,
bufferSampleRate);
let destinationChannelIndex = 0;
for (let i = 0; i < bufferList.length; ++i) {
for (let j = 0; j < bufferList[i].numberOfChannels; ++j) {
buffer.getChannelData(destinationChannelIndex++).set(
bufferList[i].getChannelData(j));
}
}
return buffer;
};
/**
* Perform channel-wise split by the given channel count. For example,
* 1 x AudioBuffer(8) -> splitBuffer(context, buffer, 2) -> 4 x AudioBuffer(2).
* @param {BaseAudioContext} context - Associated BaseAudioContext.
* @param {AudioBuffer} audioBuffer - An AudioBuffer to be splitted.
* @param {Number} splitBy - Number of channels to be splitted.
* @return {AudioBuffer[]} - An array of splitted AudioBuffers.
*/
exports.splitBufferbyChannel = function(context, audioBuffer, splitBy) {
if (audioBuffer.numberOfChannels <= splitBy) {
exports.throw('Utils.splitBuffer: Insufficient number of channels. (' +
audioBuffer.numberOfChannels + ' splitted by ' + splitBy + ')');
}
let bufflerList = [];
let sourceChannelIndex = 0;
const numberOfSplittedBuffer =
Math.ceil(audioBuffer.numberOfChannels / splitBy);
for (let i = 0; i < numberOfSplittedBuffer; ++i) {
let buffer = context.createBuffer(splitBy,
audioBuffer.length,
audioBuffer.sampleRate);
for (let j = 0; j < splitBy; ++j) {
if (sourceChannelIndex < audioBuffer.numberOfChannels) {
buffer.getChannelData(j).set(
audioBuffer.getChannelData(sourceChannelIndex++));
}
}
bufflerList.push(buffer);
}
return bufferList;
};
/**
* Converts Base64-encoded string to ArrayBuffer.
* @param {string} base64String - Base64-encdoed string.
* @return {ArrayByuffer} Converted ArrayBuffer object.
*/
exports.getArrayBufferFromBase64String = function(base64String) {
let binaryString = window.atob(base64String);
let byteArray = new Uint8Array(binaryString.length);
byteArray.forEach(
(value, index) => byteArray[index] = binaryString.charCodeAt(index));
return byteArray.buffer;
};
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Streamlined AudioBuffer loader.
*/
const Utils = __webpack_require__(0);
/**
* @typedef {string} BufferDataType
*/
/**
* Buffer data type for ENUM.
* @enum {BufferDataType}
*/
const BufferDataType = {
/** @type {string} The data contains Base64-encoded string.. */
BASE64: 'base64',
/** @type {string} The data is a URL for audio file. */
URL: 'url',
};
/**
* BufferList object mananges the async loading/decoding of multiple
* AudioBuffers from multiple URLs.
* @constructor
* @param {BaseAudioContext} context - Associated BaseAudioContext.
* @param {string[]} bufferData - An ordered list of URLs.
* @param {Object} options - Options
* @param {string} [options.dataType='base64'] - BufferDataType specifier.
* @param {Boolean} [options.verbose=false] - Log verbosity. |true| prints the
* individual message from each URL and AudioBuffer.
*/
function BufferList(context, bufferData, options) {
this._context = Utils.isAudioContext(context) ?
context :
Utils.throw('BufferList: Invalid BaseAudioContext.');
this._options = {
dataType: BufferDataType.BASE64,
verbose: false,
};
if (options) {
if (options.dataType &&
Utils.isDefinedENUMEntry(BufferDataType, options.dataType)) {
this._options.dataType = options.dataType;
}
if (options.verbose) {
this._options.verbose = Boolean(options.verbose);
}
}
this._bufferList = [];
this._bufferData = this._options.dataType === BufferDataType.BASE64
? bufferData
: bufferData.slice(0);
this._numberOfTasks = this._bufferData.length;
this._resolveHandler = null;
this._rejectHandler = new Function();
}
/**
* Starts AudioBuffer loading tasks.
* @return {Promise<AudioBuffer[]>} The promise resolves with an array of
* AudioBuffer.
*/
BufferList.prototype.load = function() {
return new Promise(this._promiseGenerator.bind(this));
};
/**
* Promise argument generator. Internally starts multiple async loading tasks.
* @private
* @param {function} resolve Promise resolver.
* @param {function} reject Promise reject.
*/
BufferList.prototype._promiseGenerator = function(resolve, reject) {
if (typeof resolve !== 'function') {
Utils.throw('BufferList: Invalid Promise resolver.');
} else {
this._resolveHandler = resolve;
}
if (typeof reject === 'function') {
this._rejectHandler = reject;
}
for (let i = 0; i < this._bufferData.length; ++i) {
this._options.dataType === BufferDataType.BASE64
? this._launchAsyncLoadTask(i)
: this._launchAsyncLoadTaskXHR(i);
}
};
/**
* Run async loading task for Base64-encoded string.
* @private
* @param {Number} taskId Task ID number from the ordered list |bufferData|.
*/
BufferList.prototype._launchAsyncLoadTask = function(taskId) {
const that = this;
this._context.decodeAudioData(
Utils.getArrayBufferFromBase64String(this._bufferData[taskId]),
function(audioBuffer) {
that._updateProgress(taskId, audioBuffer);
},
function(errorMessage) {
that._updateProgress(taskId, null);
const message = 'BufferList: decoding ArrayByffer("' + taskId +
'" from Base64-encoded data failed. (' + errorMessage + ')';
Utils.throw(message);
that._rejectHandler(message);
});
};
/**
* Run async loading task via XHR for audio file URLs.
* @private
* @param {Number} taskId Task ID number from the ordered list |bufferData|.
*/
BufferList.prototype._launchAsyncLoadTaskXHR = function(taskId) {
const xhr = new XMLHttpRequest();
xhr.open('GET', this._bufferData[taskId]);
xhr.responseType = 'arraybuffer';
const that = this;
xhr.onload = function() {
if (xhr.status === 200) {
that._context.decodeAudioData(
xhr.response,
function(audioBuffer) {
that._updateProgress(taskId, audioBuffer);
},
function(errorMessage) {
that._updateProgress(taskId, null);
const message = 'BufferList: decoding "' +
that._bufferData[taskId] + '" failed. (' + errorMessage + ')';
Utils.throw(message);
that._rejectHandler(message);
});
} else {
const message = 'BufferList: XHR error while loading "' +
that._bufferData[taskId] + '(' + xhr.statusText + ')';
Utils.throw(message);
that._rejectHandler(message);
}
};
xhr.onerror = function(event) {
Utils.throw(
'BufferList: XHR network failed on loading "' +
that._bufferData[taskId] + '".');
that._updateProgress(taskId, null);
that._rejectHandler();
};
xhr.send();
};
/**
* Updates the overall progress on loading tasks.
* @param {Number} taskId Task ID number.
* @param {AudioBuffer} audioBuffer Decoded AudioBuffer object.
*/
BufferList.prototype._updateProgress = function(taskId, audioBuffer) {
this._bufferList[taskId] = audioBuffer;
if (this._options.verbose) {
let messageString = this._options.dataType === BufferDataType.BASE64
? 'ArrayBuffer(' + taskId + ') from Base64-encoded HRIR'
: '"' + this._bufferData[taskId] + '"';
Utils.log('BufferList: ' + messageString + ' successfully loaded.');
}
if (--this._numberOfTasks === 0) {
let messageString = this._options.dataType === BufferDataType.BASE64
? this._bufferData.length + ' AudioBuffers from Base64-encoded HRIRs'
: this._bufferData.length + ' files via XHR';
Utils.log('BufferList: ' + messageString + ' loaded successfully.');
this._resolveHandler(this._bufferList);
}
};
module.exports = BufferList;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright 2016 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file An audio channel router to resolve different channel layouts between
* browsers.
*/
/**
* @typedef {Number[]} ChannelMap
*/
/**
* Channel map dictionary ENUM.
* @enum {ChannelMap}
*/
const ChannelMap = {
/** @type {Number[]} - ACN channel map for Chrome and FireFox. (FFMPEG) */
DEFAULT: [0, 1, 2, 3],
/** @type {Number[]} - Safari's 4-channel map for AAC codec. */
SAFARI: [2, 0, 1, 3],
/** @type {Number[]} - ACN > FuMa conversion map. */
FUMA: [0, 3, 1, 2],
};
/**
* Channel router for FOA stream.
* @constructor
* @param {AudioContext} context - Associated AudioContext.
* @param {Number[]} channelMap - Routing destination array.
*/
function FOARouter(context, channelMap) {
this._context = context;
this._splitter = this._context.createChannelSplitter(4);
this._merger = this._context.createChannelMerger(4);
// input/output proxy.
this.input = this._splitter;
this.output = this._merger;
this.setChannelMap(channelMap || ChannelMap.DEFAULT);
}
/**
* Sets channel map.
* @param {Number[]} channelMap - A new channel map for FOA stream.
*/
FOARouter.prototype.setChannelMap = function(channelMap) {
if (!Array.isArray(channelMap)) {
return;
}
this._channelMap = channelMap;
this._splitter.disconnect();
this._splitter.connect(this._merger, 0, this._channelMap[0]);
this._splitter.connect(this._merger, 1, this._channelMap[1]);
this._splitter.connect(this._merger, 2, this._channelMap[2]);
this._splitter.connect(this._merger, 3, this._channelMap[3]);
};
/**
* Static channel map ENUM.
* @static
* @type {ChannelMap}
*/
FOARouter.ChannelMap = ChannelMap;
module.exports = FOARouter;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright 2016 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Sound field rotator for first-order-ambisonics decoding.
*/
/**
* First-order-ambisonic decoder based on gain node network.
* @constructor
* @param {AudioContext} context - Associated AudioContext.
*/
function FOARotator(context) {
this._context = context;
this._splitter = this._context.createChannelSplitter(4);
this._inY = this._context.createGain();
this._inZ = this._context.createGain();
this._inX = this._context.createGain();
this._m0 = this._context.createGain();
this._m1 = this._context.createGain();
this._m2 = this._context.createGain();
this._m3 = this._context.createGain();
this._m4 = this._context.createGain();
this._m5 = this._context.createGain();
this._m6 = this._context.createGain();
this._m7 = this._context.createGain();
this._m8 = this._context.createGain();
this._outY = this._context.createGain();
this._outZ = this._context.createGain();
this._outX = this._context.createGain();
this._merger = this._context.createChannelMerger(4);
// ACN channel ordering: [1, 2, 3] => [-Y, Z, -X]
// Y (from channel 1)
this._splitter.connect(this._inY, 1);
// Z (from channel 2)
this._splitter.connect(this._inZ, 2);
// X (from channel 3)
this._splitter.connect(this._inX, 3);
this._inY.gain.value = -1;
this._inX.gain.value = -1;
// Apply the rotation in the world space.
// |Y| | m0 m3 m6 | | Y * m0 + Z * m3 + X * m6 | | Yr |
// |Z| * | m1 m4 m7 | = | Y * m1 + Z * m4 + X * m7 | = | Zr |
// |X| | m2 m5 m8 | | Y * m2 + Z * m5 + X * m8 | | Xr |
this._inY.connect(this._m0);
this._inY.connect(this._m1);
this._inY.connect(this._m2);
this._inZ.connect(this._m3);
this._inZ.connect(this._m4);
this._inZ.connect(this._m5);
this._inX.connect(this._m6);
this._inX.connect(this._m7);
this._inX.connect(this._m8);
this._m0.connect(this._outY);
this._m1.connect(this._outZ);
this._m2.connect(this._outX);
this._m3.connect(this._outY);
this._m4.connect(this._outZ);
this._m5.connect(this._outX);
this._m6.connect(this._outY);
this._m7.connect(this._outZ);
this._m8.connect(this._outX);
// Transform 3: world space to audio space.
// W -> W (to channel 0)
this._splitter.connect(this._merger, 0, 0);
// Y (to channel 1)
this._outY.connect(this._merger, 0, 1);
// Z (to channel 2)
this._outZ.connect(this._merger, 0, 2);
// X (to channel 3)
this._outX.connect(this._merger, 0, 3);
this._outY.gain.value = -1;
this._outX.gain.value = -1;
this.setRotationMatrix3(new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]));
// input/output proxy.
this.input = this._splitter;
this.output = this._merger;
}
/**
* Updates the rotation matrix with 3x3 matrix.
* @param {Number[]} rotationMatrix3 - A 3x3 rotation matrix. (column-major)
*/
FOARotator.prototype.setRotationMatrix3 = function(rotationMatrix3) {
this._m0.gain.value = rotationMatrix3[0];
this._m1.gain.value = rotationMatrix3[1];
this._m2.gain.value = rotationMatrix3[2];
this._m3.gain.value = rotationMatrix3[3];
this._m4.gain.value = rotationMatrix3[4];
this._m5.gain.value = rotationMatrix3[5];
this._m6.gain.value = rotationMatrix3[6];
this._m7.gain.value = rotationMatrix3[7];
this._m8.gain.value = rotationMatrix3[8];
};
/**
* Updates the rotation matrix with 4x4 matrix.
* @param {Number[]} rotationMatrix4 - A 4x4 rotation matrix. (column-major)
*/
FOARotator.prototype.setRotationMatrix4 = function(rotationMatrix4) {
this._m0.gain.value = rotationMatrix4[0];
this._m1.gain.value = rotationMatrix4[1];
this._m2.gain.value = rotationMatrix4[2];
this._m3.gain.value = rotationMatrix4[4];
this._m4.gain.value = rotationMatrix4[5];
this._m5.gain.value = rotationMatrix4[6];
this._m6.gain.value = rotationMatrix4[8];
this._m7.gain.value = rotationMatrix4[9];
this._m8.gain.value = rotationMatrix4[10];
};
/**
* Returns the current 3x3 rotation matrix.
* @return {Number[]} - A 3x3 rotation matrix. (column-major)
*/
FOARotator.prototype.getRotationMatrix3 = function() {
return [
this._m0.gain.value, this._m1.gain.value, this._m2.gain.value,
this._m3.gain.value, this._m4.gain.value, this._m5.gain.value,
this._m6.gain.value, this._m7.gain.value, this._m8.gain.value,
];
};
/**
* Returns the current 4x4 rotation matrix.
* @return {Number[]} - A 4x4 rotation matrix. (column-major)
*/
FOARotator.prototype.getRotationMatrix4 = function() {
let rotationMatrix4 = new Float32Array(16);
rotationMatrix4[0] = this._m0.gain.value;
rotationMatrix4[1] = this._m1.gain.value;
rotationMatrix4[2] = this._m2.gain.value;
rotationMatrix4[4] = this._m3.gain.value;
rotationMatrix4[5] = this._m4.gain.value;
rotationMatrix4[6] = this._m5.gain.value;
rotationMatrix4[8] = this._m6.gain.value;
rotationMatrix4[9] = this._m7.gain.value;
rotationMatrix4[10] = this._m8.gain.value;
return rotationMatrix4;
};
module.exports = FOARotator;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file A collection of convolvers. Can be used for the optimized FOA binaural
* rendering. (e.g. SH-MaxRe HRTFs)
*/
/**
* FOAConvolver. A collection of 2 stereo convolvers for 4-channel FOA stream.
* @constructor
* @param {BaseAudioContext} context The associated AudioContext.
* @param {AudioBuffer[]} [hrirBufferList] - An ordered-list of stereo
* AudioBuffers for convolution. (i.e. 2 stereo AudioBuffers for FOA)
*/
function FOAConvolver(context, hrirBufferList) {
this._context = context;
this._active = false;
this._isBufferLoaded = false;
this._buildAudioGraph();
if (hrirBufferList) {
this.setHRIRBufferList(hrirBufferList);
}
this.enable();
}
/**
* Build the internal audio graph.
*
* @private
*/
FOAConvolver.prototype._buildAudioGraph = function() {
this._splitterWYZX = this._context.createChannelSplitter(4);
this._mergerWY = this._context.createChannelMerger(2);
this._mergerZX = this._context.createChannelMerger(2);
this._convolverWY = this._context.createConvolver();
this._convolverZX = this._context.createConvolver();
this._splitterWY = this._context.createChannelSplitter(2);
this._splitterZX = this._context.createChannelSplitter(2);
this._inverter = this._context.createGain();
this._mergerBinaural = this._context.createChannelMerger(2);
this._summingBus = this._context.createGain();
// Group W and Y, then Z and X.
this._splitterWYZX.connect(this._mergerWY, 0, 0);
this._splitterWYZX.connect(this._mergerWY, 1, 1);
this._splitterWYZX.connect(this._mergerZX, 2, 0);
this._splitterWYZX.connect(this._mergerZX, 3, 1);
// Create a network of convolvers using splitter/merger.
this._mergerWY.connect(this._convolverWY);
this._mergerZX.connect(this._convolverZX);
this._convolverWY.connect(this._splitterWY);
this._convolverZX.connect(this._splitterZX);
this._splitterWY.connect(this._mergerBinaural, 0, 0);
this._splitterWY.connect(this._mergerBinaural, 0, 1);
this._splitterWY.connect(this._mergerBinaural, 1, 0);
this._splitterWY.connect(this._inverter, 1, 0);
this._inverter.connect(this._mergerBinaural, 0, 1);
this._splitterZX.connect(this._mergerBinaural, 0, 0);
this._splitterZX.connect(this._mergerBinaural, 0, 1);
this._splitterZX.connect(this._mergerBinaural, 1, 0);
this._splitterZX.connect(this._mergerBinaural, 1, 1);
// By default, WebAudio's convolver does the normalization based on IR's
// energy. For the precise convolution, it must be disabled before the buffer
// assignment.
this._convolverWY.normalize = false;
this._convolverZX.normalize = false;
// For asymmetric degree.
this._inverter.gain.value = -1;
// Input/output proxy.
this.input = this._splitterWYZX;
this.output = this._summingBus;
};
/**
* Assigns 2 HRIR AudioBuffers to 2 convolvers: Note that we use 2 stereo
* convolutions for 4-channel direct convolution. Using mono convolver or
* 4-channel convolver is not viable because mono convolution wastefully
* produces the stereo outputs, and the 4-ch convolver does cross-channel
* convolution. (See Web Audio API spec)
* @param {AudioBuffer[]} hrirBufferList - An array of stereo AudioBuffers for
* convolvers.
*/
FOAConvolver.prototype.setHRIRBufferList = function(hrirBufferList) {
// After these assignments, the channel data in the buffer is immutable in
// FireFox. (i.e. neutered) So we should avoid re-assigning buffers, otherwise
// an exception will be thrown.
if (this._isBufferLoaded) {
return;
}
this._convolverWY.buffer = hrirBufferList[0];
this._convolverZX.buffer = hrirBufferList[1];
this._isBufferLoaded = true;
};
/**
* Enable FOAConvolver instance. The audio graph will be activated and pulled by
* the WebAudio engine. (i.e. consume CPU cycle)
*/
FOAConvolver.prototype.enable = function() {
this._mergerBinaural.connect(this._summingBus);
this._active = true;
};
/**
* Disable FOAConvolver instance. The inner graph will be disconnected from the
* audio destination, thus no CPU cycle will be consumed.
*/
FOAConvolver.prototype.disable = function() {
this._mergerBinaural.disconnect();
this._active = false;
};
module.exports = FOAConvolver;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright 2016 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileOverview DEPRECATED at V1. Audio buffer loading utility.
*/
const Utils = __webpack_require__(0);
/**
* Streamlined audio file loader supports Promise.
* @param {Object} context AudioContext
* @param {Object} audioFileData Audio file info as [{name, url}]
* @param {Function} resolve Resolution handler for promise.
* @param {Function} reject Rejection handler for promise.
* @param {Function} progress Progress event handler.
*/
function AudioBufferManager(context, audioFileData, resolve, reject, progress) {
this._context = context;
this._buffers = new Map();
this._loadingTasks = {};
this._resolve = resolve;
this._reject = reject;
this._progress = progress;
// Iterating file loading.
for (let i = 0; i < audioFileData.length; i++) {
const fileInfo = audioFileData[i];
// Check for duplicates filename and quit if it happens.
if (this._loadingTasks.hasOwnProperty(fileInfo.name)) {
Utils.log('Duplicated filename when loading: ' + fileInfo.name);
return;
}
// Mark it as pending (0)
this._loadingTasks[fileInfo.name] = 0;
this._loadAudioFile(fileInfo);
}
}
AudioBufferManager.prototype._loadAudioFile = function(fileInfo) {
const xhr = new XMLHttpRequest();
xhr.open('GET', fileInfo.url);
xhr.responseType = 'arraybuffer';
const that = this;
xhr.onload = function() {
if (xhr.status === 200) {
that._context.decodeAudioData(xhr.response,
function(buffer) {
// Utils.log('File loaded: ' + fileInfo.url);
that._done(fileInfo.name, buffer);
},
function(message) {
Utils.log('Decoding failure: '
+ fileInfo.url + ' (' + message + ')');
that._done(fileInfo.name, null);
});
} else {
Utils.log('XHR Error: ' + fileInfo.url + ' (' + xhr.statusText
+ ')');
that._done(fileInfo.name, null);
}
};
// TODO: fetch local resources if XHR fails.
xhr.onerror = function(event) {
Utils.log('XHR Network failure: ' + fileInfo.url);
that._done(fileInfo.name, null);
};
xhr.send();
};
AudioBufferManager.prototype._done = function(filename, buffer) {
// Label the loading task.
this._loadingTasks[filename] = buffer !== null ? 'loaded' : 'failed';
// A failed task will be a null buffer.
this._buffers.set(filename, buffer);
this._updateProgress(filename);
};
AudioBufferManager.prototype._updateProgress = function(filename) {
let numberOfFinishedTasks = 0;
let numberOfFailedTask = 0;
let numberOfTasks = 0;
for (const task in this._loadingTasks) {
if (Object.prototype.hasOwnProperty.call(this._loadingTasks, task)) {
numberOfTasks++;
if (this._loadingTasks[task] === 'loaded') {
numberOfFinishedTasks++;
} else if (this._loadingTasks[task] === 'failed') {
numberOfFailedTask++;
}
}
}
if (typeof this._progress === 'function') {
this._progress(filename, numberOfFinishedTasks, numberOfTasks);
return;
}
if (numberOfFinishedTasks === numberOfTasks) {
this._resolve(this._buffers);
return;
}
if (numberOfFinishedTasks + numberOfFailedTask === numberOfTasks) {
this._reject(this._buffers);
return;
}
};
module.exports = AudioBufferManager;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright 2016 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file Phase matched filter for first-order-ambisonics decoding.
*/
const Utils = __webpack_require__(0);
// Static parameters.
const CROSSOVER_FREQUENCY = 690;
const GAIN_COEFFICIENTS = [1.4142, 0.8166, 0.8166, 0.8166];
/**
* Generate the coefficients for dual band filter.
* @param {Number} crossoverFrequency
* @param {Number} sampleRate
* @return {Object} Filter coefficients.
*/
function generateDualBandCoefficients(crossoverFrequency, sampleRate) {
const k = Math.tan(Math.PI * crossoverFrequency / sampleRate);
const k2 = k * k;
const denominator = k2 + 2 * k + 1;
return {
lowpassA: [1, 2 * (k2 - 1) / denominator, (k2 - 2 * k + 1) / denominator],
lowpassB: [k2 / denominator, 2 * k2 / denominator, k2 / denominator],
hipassA: [1, 2 * (k2 - 1) / denominator, (k2 - 2 * k + 1) / denominator],
hipassB: [1 / denominator, -2 * 1 / denominator, 1 / denominator],
};
}
/**
* FOAPhaseMatchedFilter: A set of filters (LP/HP) with a crossover frequency to
* compensate the gain of high frequency contents without a phase difference.
* @constructor
* @param {AudioContext} context - Associated AudioContext.
*/
function FOAPhaseMatchedFilter(context) {
this._context = context;
this._input = this._context.createGain();
if (!this._context.createIIRFilter) {
Utils.log('IIR fi
gitextract_qy9p2uoe/ ├── .eslintrc.js ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── _config.yml ├── build/ │ └── resonance-audio.js ├── examples/ │ ├── benchmark.html │ ├── birds.html │ ├── hello-world.html │ ├── index.html │ ├── resources/ │ │ ├── examples.css │ │ ├── js/ │ │ │ ├── benchmark.js │ │ │ ├── birds.js │ │ │ ├── canvas-control.js │ │ │ ├── hello-world.js │ │ │ ├── room-models.js │ │ │ ├── treasure-hunt.js │ │ │ └── vs-pannernode.js │ │ └── three.js │ ├── room-models.html │ ├── treasure-hunt.html │ └── vs-pannernode.html ├── karma.conf.js ├── package.json ├── src/ │ ├── attenuation.js │ ├── directivity.js │ ├── early-reflections.js │ ├── encoder.js │ ├── late-reflections.js │ ├── listener.js │ ├── main.js │ ├── resonance-audio.js │ ├── room.js │ ├── source.js │ ├── tables.js │ ├── utils.js │ └── version.js ├── test/ │ ├── test-attenuation.js │ ├── test-directivity.js │ ├── test-early-reflections.js │ ├── test-encoder.js │ ├── test-late-reflections.js │ ├── test-listener.js │ ├── test-resonance-audio.js │ ├── test-room.js │ ├── test-source.js │ └── test-tables.js ├── webpack.config.all.js └── webpack.config.js
SYMBOL INDEX (469 symbols across 19 files)
FILE: build/resonance-audio.js
function __webpack_require__ (line 16) | function __webpack_require__(moduleId) {
function Utils (line 110) | function Utils() {}
function Encoder (line 627) | function Encoder(context, options) {
function Listener (line 854) | function Listener(context, options) {
function Source (line 2228) | function Source(scene, options) {
function _computeDistanceOutsideRoom (line 2496) | function _computeDistanceOutsideRoom(distance) {
function Directivity (line 2561) | function Directivity(context, options) {
function Attenuation (line 2702) | function Attenuation(context, options) {
function _getCoefficientsFromMaterials (line 2860) | function _getCoefficientsFromMaterials(materials) {
function _sanitizeCoefficients (line 2900) | function _sanitizeCoefficients(coefficients) {
function _sanitizeDimensions (line 2919) | function _sanitizeDimensions(dimensions) {
function _getDurationsFromProperties (line 2938) | function _getDurationsFromProperties(dimensions, coefficients, speedOfSo...
function _computeReflectionCoefficients (line 2988) | function _computeReflectionCoefficients(absorptionCoefficients) {
function Room (line 3031) | function Room(context, options) {
function LateReflections (line 3226) | function LateReflections(context, options) {
function EarlyReflections (line 3447) | function EarlyReflections(context, options) {
function ResonanceAudio (line 3761) | function ResonanceAudio(context, options) {
function __webpack_require__ (line 3988) | function __webpack_require__(moduleId) {
function BufferList (line 4388) | function BufferList(context, bufferData, options) {
function FOARouter (line 4601) | function FOARouter(context, channelMap) {
function FOARotator (line 4676) | function FOARotator(context) {
function FOAConvolver (line 4855) | function FOAConvolver(context, hrirBufferList) {
function AudioBufferManager (line 5006) | function AudioBufferManager(context, audioFileData, resolve, reject, pro...
function generateDualBandCoefficients (line 5152) | function generateDualBandCoefficients(crossoverFrequency, sampleRate) {
function FOAPhaseMatchedFilter (line 5172) | function FOAPhaseMatchedFilter(context) {
function FOAVirtualSpeaker (line 5274) | function FOAVirtualSpeaker(context, options) {
function HOAConvolver (line 5370) | function HOAConvolver(context, ambisonicOrder, hrirBufferList) {
function getKroneckerDelta (line 5544) | function getKroneckerDelta(i, j) {
function setCenteredElement (line 5561) | function setCenteredElement(matrix, l, i, j, gainValue) {
function getCenteredElement (line 5578) | function getCenteredElement(matrix, l, i, j) {
function getP (line 5597) | function getP(matrix, i, a, b, l) {
function getU (line 5628) | function getU(matrix, m, n, l) {
function getV (line 5648) | function getV(matrix, m, n, l) {
function getW (line 5681) | function getW(matrix, m, n, l) {
function computeUVWCoeff (line 5700) | function computeUVWCoeff(m, n, l) {
function computeBandRotation (line 5728) | function computeBandRotation(matrix, l) {
function computeHOAMatrices (line 5760) | function computeHOAMatrices(matrix) {
function HOARotator (line 5785) | function HOARotator(context, ambisonicOrder) {
function FOADecoder (line 6274) | function FOADecoder(context, videoElement, options) {
function FOARenderer (line 6579) | function FOARenderer(context, config) {
function HOARenderer (line 6878) | function HOARenderer(context, config) {
FILE: examples/resources/js/benchmark.js
function selectDimensionsAndMaterials (line 12) | function selectDimensionsAndMaterials() {
function startBenchmark (line 99) | function startBenchmark() {
FILE: examples/resources/js/birds.js
function updatePositions (line 24) | function updatePositions(elements) {
function integrateBirdPaths (line 42) | function integrateBirdPaths(elements) {
function initAudio (line 135) | function initAudio() {
FILE: examples/resources/js/canvas-control.js
function CanvasControl (line 7) | function CanvasControl(canvas, elements, callbackFunc) {
FILE: examples/resources/js/hello-world.js
function initAudio (line 11) | function initAudio() {
FILE: examples/resources/js/room-models.js
function selectRoomProperties (line 50) | function selectRoomProperties() {
function updatePositions (line 67) | function updatePositions(elements) {
function initAudio (line 86) | function initAudio() {
FILE: examples/resources/js/treasure-hunt.js
function updateAngles (line 41) | function updateAngles(xAngle, yAngle, zAngle) {
function getCursorPosition (line 64) | function getCursorPosition(event) {
function cursorDownFunc (line 85) | function cursorDownFunc(event) {
function cursorMoveFunc (line 96) | function cursorMoveFunc(event) {
function cursorUpFunc (line 124) | function cursorUpFunc(event) {
function moveSource (line 145) | function moveSource() {
function animate (line 165) | function animate() {
function resize (line 184) | function resize() {
function initAudio (line 199) | function initAudio() {
FILE: examples/resources/js/vs-pannernode.js
function selectRenderingMode (line 21) | function selectRenderingMode(event) {
function updatePositions (line 67) | function updatePositions(elements) {
function initAudio (line 90) | function initAudio() {
FILE: examples/resources/three.js
function EventDispatcher (line 110) | function EventDispatcher() {}
function Vector2 (line 489) | function Vector2( x, y ) {
function Texture (line 969) | function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, fo...
function getDataURL (line 1078) | function getDataURL( image ) {
function Vector4 (line 1265) | function Vector4( x, y, z, w ) {
function WebGLRenderTarget (line 1895) | function WebGLRenderTarget( width, height, options ) {
function WebGLRenderTargetCube (line 1974) | function WebGLRenderTargetCube( width, height, options ) {
function Quaternion (line 1995) | function Quaternion( x, y, z, w ) {
function Vector3 (line 2603) | function Vector3( x, y, z ) {
function Matrix4 (line 3337) | function Matrix4() {
function DataTexture (line 4250) | function DataTexture( data, width, height, format, type, mapping, wrapS,...
function CubeTexture (line 4274) | function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilte...
function UniformContainer (line 4360) | function UniformContainer() {
function flatten (line 4381) | function flatten( array, nBlocks, blockSize ) {
function allocTexUnits (line 4418) | function allocTexUnits( renderer, n ) {
function setValue1f (line 4443) | function setValue1f( gl, v ) { gl.uniform1f( this.addr, v ); }
function setValue1i (line 4444) | function setValue1i( gl, v ) { gl.uniform1i( this.addr, v ); }
function setValue2fv (line 4448) | function setValue2fv( gl, v ) {
function setValue3fv (line 4455) | function setValue3fv( gl, v ) {
function setValue4fv (line 4466) | function setValue4fv( gl, v ) {
function setValue2fm (line 4475) | function setValue2fm( gl, v ) {
function setValue3fm (line 4481) | function setValue3fm( gl, v ) {
function setValue4fm (line 4496) | function setValue4fm( gl, v ) {
function setValueT1 (line 4513) | function setValueT1( gl, v, renderer ) {
function setValueT6 (line 4521) | function setValueT6( gl, v, renderer ) {
function setValue2iv (line 4531) | function setValue2iv( gl, v ) { gl.uniform2iv( this.addr, v ); }
function setValue3iv (line 4532) | function setValue3iv( gl, v ) { gl.uniform3iv( this.addr, v ); }
function setValue4iv (line 4533) | function setValue4iv( gl, v ) { gl.uniform4iv( this.addr, v ); }
function getSingularSetter (line 4537) | function getSingularSetter( type ) {
function setValue1fv (line 4564) | function setValue1fv( gl, v ) { gl.uniform1fv( this.addr, v ); }
function setValue1iv (line 4565) | function setValue1iv( gl, v ) { gl.uniform1iv( this.addr, v ); }
function setValueV2a (line 4569) | function setValueV2a( gl, v ) {
function setValueV3a (line 4575) | function setValueV3a( gl, v ) {
function setValueV4a (line 4581) | function setValueV4a( gl, v ) {
function setValueM2a (line 4589) | function setValueM2a( gl, v ) {
function setValueM3a (line 4595) | function setValueM3a( gl, v ) {
function setValueM4a (line 4601) | function setValueM4a( gl, v ) {
function setValueT1a (line 4609) | function setValueT1a( gl, v, renderer ) {
function setValueT6a (line 4624) | function setValueT6a( gl, v, renderer ) {
function getPureArraySetter (line 4641) | function getPureArraySetter( type ) {
function SingleUniform (line 4668) | function SingleUniform( id, activeInfo, addr ) {
function PureArrayUniform (line 4678) | function PureArrayUniform( id, activeInfo, addr ) {
function StructuredUniform (line 4689) | function StructuredUniform( id ) {
function addUniform (line 4728) | function addUniform( container, uniformObject ) {
function parseUniform (line 4735) | function parseUniform( activeInfo, addr, container ) {
function WebGLUniforms (line 4787) | function WebGLUniforms( gl, program, renderer ) {
function Color (line 4888) | function Color( r, g, b ) {
function hue2rgb (line 4961) | function hue2rgb( p, q, t ) {
function handleAlpha (line 5002) | function handleAlpha( string ) {
function Box2 (line 6196) | function Box2( min, max ) {
function WebGLFlareRenderer (line 6414) | function WebGLFlareRenderer( renderer, gl, state, textures, capabilities...
function CanvasTexture (line 6794) | function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFil...
function WebGLSpriteRenderer (line 6810) | function WebGLSpriteRenderer( renderer, gl, state, textures, capabilitie...
function Material (line 7182) | function Material() {
function extractFromCache (line 7408) | function extractFromCache( cache ) {
function ShaderMaterial (line 7538) | function ShaderMaterial( parameters ) {
function MeshDepthMaterial (line 7662) | function MeshDepthMaterial( parameters ) {
function MeshDistanceMaterial (line 7743) | function MeshDistanceMaterial( parameters ) {
function Box3 (line 7804) | function Box3( min, max ) {
function Sphere (line 8284) | function Sphere( center, radius ) {
function Matrix3 (line 8451) | function Matrix3() {
function Plane (line 8775) | function Plane( normal, constant ) {
function Frustum (line 9002) | function Frustum( p0, p1, p2, p3, p4, p5 ) {
function WebGLShadowMap (line 9196) | function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
function WebGLAttributes (line 9629) | function WebGLAttributes( gl ) {
function Euler (line 9784) | function Euler( x, y, z, order ) {
function Layers (line 10127) | function Layers() {
function Object3D (line 10177) | function Object3D() {
function serialize (line 10782) | function serialize( library, element ) {
function extractFromCache (line 10857) | function extractFromCache( cache ) {
function Camera (line 10931) | function Camera() {
function OrthographicCamera (line 10996) | function OrthographicCamera( left, right, top, bottom, near, far ) {
function PerspectiveCamera (line 11120) | function PerspectiveCamera( fov, aspect, near, far ) {
function Face3 (line 11337) | function Face3( a, b, c, normal, color, materialIndex ) {
function GeometryIdCount (line 11400) | function GeometryIdCount() { return count++; }
function Geometry (line 11402) | function Geometry() {
function addFace (line 11641) | function addFace( a, b, c, materialIndex ) {
function materialIndexSort (line 12317) | function materialIndexSort( a, b ) {
function setBit (line 12473) | function setBit( value, position, enabled ) {
function getNormalIndex (line 12479) | function getNormalIndex( normal ) {
function getColorIndex (line 12496) | function getColorIndex( color ) {
function getUvIndex (line 12513) | function getUvIndex( uv ) {
function BufferAttribute (line 12818) | function BufferAttribute( array, itemSize, normalized ) {
function Int8BufferAttribute (line 13152) | function Int8BufferAttribute( array, itemSize ) {
function Uint8BufferAttribute (line 13162) | function Uint8BufferAttribute( array, itemSize ) {
function Uint8ClampedBufferAttribute (line 13172) | function Uint8ClampedBufferAttribute( array, itemSize ) {
function Int16BufferAttribute (line 13182) | function Int16BufferAttribute( array, itemSize ) {
function Uint16BufferAttribute (line 13192) | function Uint16BufferAttribute( array, itemSize ) {
function Int32BufferAttribute (line 13202) | function Int32BufferAttribute( array, itemSize ) {
function Uint32BufferAttribute (line 13212) | function Uint32BufferAttribute( array, itemSize ) {
function Float32BufferAttribute (line 13222) | function Float32BufferAttribute( array, itemSize ) {
function Float64BufferAttribute (line 13232) | function Float64BufferAttribute( array, itemSize ) {
function DirectGeometry (line 13245) | function DirectGeometry() {
function arrayMax (line 13504) | function arrayMax( array ) {
function BufferGeometry (line 13525) | function BufferGeometry() {
function BoxGeometry (line 14617) | function BoxGeometry( width, height, depth, widthSegments, heightSegment...
function BoxBufferGeometry (line 14642) | function BoxBufferGeometry( width, height, depth, widthSegments, heightS...
function PlaneGeometry (line 14809) | function PlaneGeometry( width, height, widthSegments, heightSegments ) {
function PlaneBufferGeometry (line 14832) | function PlaneBufferGeometry( width, height, widthSegments, heightSegmen...
function MeshBasicMaterial (line 14954) | function MeshBasicMaterial( parameters ) {
function Ray (line 15037) | function Ray( origin, direction ) {
function Line3 (line 15567) | function Line3( start, end ) {
function Triangle (line 15693) | function Triangle( a, b, c ) {
function Mesh (line 15947) | function Mesh( geometry, material ) {
function uvIntersection (line 16063) | function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) {
function checkIntersection (line 16077) | function checkIntersection( object, material, raycaster, ray, pA, pB, pC...
function checkBufferGeometryIntersection (line 16108) | function checkBufferGeometryIntersection( object, raycaster, ray, positi...
function WebGLBackground (line 16318) | function WebGLBackground( renderer, state, geometries, premultipliedAlph...
function painterSortStable (line 16453) | function painterSortStable( a, b ) {
function reversePainterSortStable (line 16479) | function reversePainterSortStable( a, b ) {
function WebGLRenderList (line 16497) | function WebGLRenderList() {
function WebGLRenderLists (line 16571) | function WebGLRenderLists() {
function absNumericalSort (line 16610) | function absNumericalSort( a, b ) {
function WebGLMorphtargets (line 16616) | function WebGLMorphtargets( gl ) {
function WebGLIndexedBufferRenderer (line 16719) | function WebGLIndexedBufferRenderer( gl, extensions, infoRender ) {
function WebGLBufferRenderer (line 16784) | function WebGLBufferRenderer( gl, extensions, infoRender ) {
function WebGLGeometries (line 16851) | function WebGLGeometries( gl, attributes, infoMemory ) {
function UniformsCache (line 17040) | function UniformsCache() {
function WebGLLights (line 17133) | function WebGLLights() {
function WebGLObjects (line 17363) | function WebGLObjects( geometries, infoRender ) {
function addLineNumbers (line 17413) | function addLineNumbers( string ) {
function WebGLShader (line 17427) | function WebGLShader( gl, type, string ) {
function getEncodingComponents (line 17459) | function getEncodingComponents( encoding ) {
function getTexelDecodingFunction (line 17484) | function getTexelDecodingFunction( functionName, encoding ) {
function getTexelEncodingFunction (line 17491) | function getTexelEncodingFunction( functionName, encoding ) {
function getToneMappingFunction (line 17498) | function getToneMappingFunction( functionName, toneMapping ) {
function generateExtensions (line 17529) | function generateExtensions( extensions, parameters, rendererExtensions ) {
function generateDefines (line 17544) | function generateDefines( defines ) {
function fetchAttributeLocations (line 17562) | function fetchAttributeLocations( gl, program, identifiers ) {
function filterEmptyLine (line 17583) | function filterEmptyLine( string ) {
function replaceLightNums (line 17589) | function replaceLightNums( string, parameters ) {
function parseIncludes (line 17600) | function parseIncludes( string ) {
function unrollLoops (line 17622) | function unrollLoops( string ) {
function WebGLProgram (line 17644) | function WebGLProgram( renderer, extensions, code, material, shader, par...
function WebGLPrograms (line 18123) | function WebGLPrograms( renderer, extensions, capabilities ) {
function WebGLTextures (line 18423) | function WebGLTextures( _gl, extensions, state, properties, capabilities...
function WebGLProperties (line 19214) | function WebGLProperties() {
function WebGLState (line 19258) | function WebGLState( gl, extensions, utils ) {
function WebGLCapabilities (line 20213) | function WebGLCapabilities( gl, extensions, parameters ) {
function ArrayCamera (line 20323) | function ArrayCamera( array ) {
function WebVRManager (line 20343) | function WebVRManager( renderer ) {
function WebGLExtensions (line 20557) | function WebGLExtensions( gl ) {
function WebGLClipping (line 20620) | function WebGLClipping() {
function WebGLUtils (line 20780) | function WebGLUtils ( gl, extensions ) {
function WebGLRenderer (line 20921) | function WebGLRenderer( parameters ) {
function FogExp2 (line 23376) | function FogExp2 ( color, density ) {
function Fog (line 23408) | function Fog ( color, near, far ) {
function Scene (line 23442) | function Scene () {
function LensFlare (line 23493) | function LensFlare( texture, size, distance, blending, color ) {
function SpriteMaterial (line 23598) | function SpriteMaterial( parameters ) {
function Sprite (line 23638) | function Sprite( material ) {
function LOD (line 23701) | function LOD() {
function Skeleton (line 23873) | function Skeleton( bones, boneInverses ) {
function Bone (line 24028) | function Bone() {
function SkinnedMesh (line 24050) | function SkinnedMesh( geometry, material ) {
function LineBasicMaterial (line 24259) | function LineBasicMaterial( parameters ) {
function Line (line 24300) | function Line( geometry, material, mode ) {
function LineSegments (line 24485) | function LineSegments( geometry, material ) {
function LineLoop (line 24505) | function LineLoop( geometry, material ) {
function PointsMaterial (line 24535) | function PointsMaterial( parameters ) {
function Points (line 24578) | function Points( geometry, material ) {
function testPoint (line 24627) | function testPoint( point, index ) {
function Group (line 24715) | function Group() {
function VideoTexture (line 24733) | function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilte...
function CompressedTexture (line 24764) | function CompressedTexture( mipmaps, width, height, format, type, mappin...
function DepthTexture (line 24793) | function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFi...
function WireframeGeometry (line 24827) | function WireframeGeometry( geometry ) {
function ParametricGeometry (line 25005) | function ParametricGeometry( func, slices, stacks ) {
function ParametricBufferGeometry (line 25027) | function ParametricBufferGeometry( func, slices, stacks ) {
function PolyhedronGeometry (line 25154) | function PolyhedronGeometry( vertices, indices, radius, detail ) {
function PolyhedronBufferGeometry (line 25177) | function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
function TetrahedronGeometry (line 25485) | function TetrahedronGeometry( radius, detail ) {
function TetrahedronBufferGeometry (line 25506) | function TetrahedronBufferGeometry( radius, detail ) {
function OctahedronGeometry (line 25537) | function OctahedronGeometry( radius, detail ) {
function OctahedronBufferGeometry (line 25558) | function OctahedronBufferGeometry( radius, detail ) {
function IcosahedronGeometry (line 25589) | function IcosahedronGeometry( radius, detail ) {
function IcosahedronBufferGeometry (line 25610) | function IcosahedronBufferGeometry( radius, detail ) {
function DodecahedronGeometry (line 25648) | function DodecahedronGeometry( radius, detail ) {
function DodecahedronBufferGeometry (line 25669) | function DodecahedronBufferGeometry( radius, detail ) {
function TubeGeometry (line 25736) | function TubeGeometry( path, tubularSegments, radius, radialSegments, cl...
function TubeBufferGeometry (line 25772) | function TubeBufferGeometry( path, tubularSegments, radius, radialSegmen...
function TorusKnotGeometry (line 25947) | function TorusKnotGeometry( radius, tube, tubularSegments, radialSegment...
function TorusKnotBufferGeometry (line 25974) | function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialS...
function TorusGeometry (line 26133) | function TorusGeometry( radius, tube, radialSegments, tubularSegments, a...
function TorusBufferGeometry (line 26157) | function TorusBufferGeometry( radius, tube, radialSegments, tubularSegme...
function snip (line 26299) | function snip( contour, u, v, w, n, verts ) {
function removeDupEndPts (line 26453) | function removeDupEndPts(points) {
function point_in_segment_2D_colin (line 26468) | function point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {
function intersect_segments_2D (line 26499) | function intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2P...
function isPointInsideAngle (line 26672) | function isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt...
function removeHoles (line 26715) | function removeHoles( contour, holes ) {
function ExtrudeGeometry (line 26979) | function ExtrudeGeometry( shapes, options ) {
function ExtrudeBufferGeometry (line 27000) | function ExtrudeBufferGeometry( shapes, options ) {
function scalePt2 (line 27176) | function scalePt2( pt, vec, size ) {
function getBevelVec (line 27192) | function getBevelVec( inPt, inPrev, inNext ) {
function buildLidFaces (line 27511) | function buildLidFaces() {
function buildSideFaces (line 27569) | function buildSideFaces() {
function sidewalls (line 27592) | function sidewalls( contour, layeroffset ) {
function v (line 27626) | function v( x, y, z ) {
function f3 (line 27635) | function f3( a, b, c ) {
function f4 (line 27650) | function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourInd...
function addVertex (line 27674) | function addVertex( index ) {
function addUV (line 27684) | function addUV( vector2 ) {
function TextGeometry (line 27779) | function TextGeometry( text, parameters ) {
function TextBufferGeometry (line 27800) | function TextBufferGeometry( text, parameters ) {
function SphereGeometry (line 27842) | function SphereGeometry( radius, widthSegments, heightSegments, phiStart...
function SphereBufferGeometry (line 27868) | function SphereBufferGeometry( radius, widthSegments, heightSegments, ph...
function RingGeometry (line 27986) | function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegme...
function RingBufferGeometry (line 28011) | function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, ph...
function LatheGeometry (line 28132) | function LatheGeometry( points, segments, phiStart, phiLength ) {
function LatheBufferGeometry (line 28155) | function LatheBufferGeometry( points, segments, phiStart, phiLength ) {
function ShapeGeometry (line 28308) | function ShapeGeometry( shapes, curveSegments ) {
function ShapeBufferGeometry (line 28337) | function ShapeBufferGeometry( shapes, curveSegments ) {
function EdgesGeometry (line 28475) | function EdgesGeometry( geometry, thresholdAngle ) {
function CylinderGeometry (line 28583) | function CylinderGeometry( radiusTop, radiusBottom, height, radialSegmen...
function CylinderBufferGeometry (line 28610) | function CylinderBufferGeometry( radiusTop, radiusBottom, height, radial...
function ConeGeometry (line 28890) | function ConeGeometry( radius, height, radialSegments, heightSegments, o...
function ConeBufferGeometry (line 28913) | function ConeBufferGeometry( radius, height, radialSegments, heightSegme...
function CircleGeometry (line 28942) | function CircleGeometry( radius, segments, thetaStart, thetaLength ) {
function CircleBufferGeometry (line 28965) | function CircleBufferGeometry( radius, segments, thetaStart, thetaLength...
function ShadowMaterial (line 29103) | function ShadowMaterial( parameters ) {
function RawShaderMaterial (line 29128) | function RawShaderMaterial( parameters ) {
function MeshStandardMaterial (line 29192) | function MeshStandardMaterial( parameters ) {
function MeshPhysicalMaterial (line 29319) | function MeshPhysicalMaterial( parameters ) {
function MeshPhongMaterial (line 29406) | function MeshPhongMaterial( parameters ) {
function MeshToonMaterial (line 29525) | function MeshToonMaterial( parameters ) {
function MeshNormalMaterial (line 29580) | function MeshNormalMaterial( parameters ) {
function MeshLambertMaterial (line 29678) | function MeshLambertMaterial( parameters ) {
function LineDashedMaterial (line 29780) | function LineDashedMaterial( parameters ) {
function LoadingManager (line 29881) | function LoadingManager( onLoad, onProgress, onError ) {
function FileLoader (line 29952) | function FileLoader( manager ) {
function CompressedTextureLoader (line 30195) | function CompressedTextureLoader( manager ) {
function loadTexture (line 30219) | function loadTexture( i ) {
function DataTextureLoader (line 30329) | function DataTextureLoader( manager ) {
function ImageLoader (line 30415) | function ImageLoader( manager ) {
function CubeTextureLoader (line 30514) | function CubeTextureLoader( manager ) {
function loadTexture (line 30534) | function loadTexture( i ) {
function TextureLoader (line 30584) | function TextureLoader( manager ) {
function Light (line 30642) | function Light( color, intensity ) {
function HemisphereLight (line 30698) | function HemisphereLight( skyColor, groundColor, intensity ) {
function LightShadow (line 30735) | function LightShadow( camera ) {
function SpotLightShadow (line 30791) | function SpotLightShadow() {
function SpotLight (line 30828) | function SpotLight( color, intensity, distance, angle, penumbra, decay ) {
function PointLight (line 30891) | function PointLight( color, intensity, distance, decay ) {
function DirectionalLightShadow (line 30943) | function DirectionalLightShadow( ) {
function DirectionalLight (line 30960) | function DirectionalLight( color, intensity ) {
function AmbientLight (line 30999) | function AmbientLight( color, intensity ) {
function RectAreaLight (line 31021) | function RectAreaLight( color, intensity, width, height ) {
function compareTime (line 31121) | function compareTime( i, j ) {
function Interpolant (line 31258) | function Interpolant( parameterPositions, sampleValues, sampleSize, resu...
function CubicInterpolant (line 31502) | function CubicInterpolant( parameterPositions, sampleValues, sampleSize,...
function LinearInterpolant (line 31647) | function LinearInterpolant( parameterPositions, sampleValues, sampleSize...
function DiscreteInterpolant (line 31691) | function DiscreteInterpolant( parameterPositions, sampleValues, sampleSi...
function KeyframeTrackConstructor (line 32065) | function KeyframeTrackConstructor( name, times, values, interpolation ) {
function VectorKeyframeTrack (line 32097) | function VectorKeyframeTrack( name, times, values, interpolation ) {
function QuaternionLinearInterpolant (line 32122) | function QuaternionLinearInterpolant( parameterPositions, sampleValues, ...
function QuaternionKeyframeTrack (line 32164) | function QuaternionKeyframeTrack( name, times, values, interpolation ) {
function NumberKeyframeTrack (line 32201) | function NumberKeyframeTrack( name, times, values, interpolation ) {
function StringKeyframeTrack (line 32230) | function StringKeyframeTrack( name, times, values, interpolation ) {
function BooleanKeyframeTrack (line 32262) | function BooleanKeyframeTrack( name, times, values ) {
function ColorKeyframeTrack (line 32297) | function ColorKeyframeTrack( name, times, values, interpolation ) {
function KeyframeTrack (line 32330) | function KeyframeTrack( name, times, values, interpolation ) {
function AnimationClip (line 32472) | function AnimationClip( name, duration, tracks ) {
function MaterialLoader (line 32817) | function MaterialLoader( manager ) {
function getTexture (line 32849) | function getTexture( name ) {
function BufferGeometryLoader (line 32968) | function BufferGeometryLoader( manager ) {
function Loader (line 33066) | function Loader() {
function loadTexture (line 33158) | function loadTexture( path, repeat, offset, wrap, anisotropy ) {
function JSONLoader (line 33398) | function JSONLoader( manager ) {
function parseModel (line 33467) | function parseModel( json, geometry ) {
function parseSkin (line 33769) | function parseSkin( json, geometry ) {
function parseMorphing (line 33814) | function parseMorphing( json, geometry ) {
function parseAnimations (line 33861) | function parseAnimations( json, geometry ) {
function ObjectLoader (line 33959) | function ObjectLoader( manager ) {
function loadImage (line 34317) | function loadImage( url ) {
function parseConstant (line 34358) | function parseConstant( value, type ) {
function getGeometry (line 34430) | function getGeometry( name ) {
function getMaterial (line 34442) | function getMaterial( name ) {
function CatmullRom (line 34738) | function CatmullRom( t, p0, p1, p2, p3 ) {
function QuadraticBezierP0 (line 34750) | function QuadraticBezierP0( t, p ) {
function QuadraticBezierP1 (line 34757) | function QuadraticBezierP1( t, p ) {
function QuadraticBezierP2 (line 34763) | function QuadraticBezierP2( t, p ) {
function QuadraticBezier (line 34769) | function QuadraticBezier( t, p0, p1, p2 ) {
function CubicBezierP0 (line 34778) | function CubicBezierP0( t, p ) {
function CubicBezierP1 (line 34785) | function CubicBezierP1( t, p ) {
function CubicBezierP2 (line 34792) | function CubicBezierP2( t, p ) {
function CubicBezierP3 (line 34798) | function CubicBezierP3( t, p ) {
function CubicBezier (line 34804) | function CubicBezier( t, p0, p1, p2, p3 ) {
function Curve (line 34846) | function Curve() {
function LineCurve (line 35189) | function LineCurve( v1, v2 ) {
function CurvePath (line 35244) | function CurvePath() {
function EllipseCurve (line 35470) | function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle,...
function SplineCurve (line 35554) | function SplineCurve( points /* array of Vector2 */ ) {
function CubicBezierCurve (line 35587) | function CubicBezierCurve( v0, v1, v2, v3 ) {
function QuadraticBezierCurve (line 35612) | function QuadraticBezierCurve( v0, v1, v2 ) {
function Path (line 35761) | function Path( points ) {
function Shape (line 35788) | function Shape() {
function ShapePath (line 35840) | function ShapePath() {
function toShapesNoHoles (line 35883) | function toShapesNoHoles( inSubpaths ) {
function isPointInsidePolygon (line 35902) | function isPointInsidePolygon( inPt, inPolygon ) {
function Font (line 36115) | function Font( data ) {
function createPaths (line 36127) | function createPaths( text ) {
function createPath (line 36160) | function createPath( c, scale, offsetX, offsetY ) {
function FontLoader (line 36293) | function FontLoader( manager ) {
function AudioLoader (line 36365) | function AudioLoader( manager ) {
function StereoCamera (line 36397) | function StereoCamera() {
function CubeCamera (line 36492) | function CubeCamera( near, far, cubeResolution ) {
function AudioListener (line 36594) | function AudioListener() {
function Audio (line 36718) | function Audio( listener ) {
function PositionalAudio (line 37014) | function PositionalAudio( listener ) {
function AudioAnalyser (line 37104) | function AudioAnalyser( audio, fftSize ) {
function PropertyMixer (line 37151) | function PropertyMixer( binding, typeName, valueSize ) {
function Composite (line 37356) | function Composite( targetGroup, path, optionalParsedPath ) {
function PropertyBinding (line 37421) | function PropertyBinding( rootNode, path, parsedPath ) {
function AnimationObjectGroup (line 38106) | function AnimationObjectGroup( var_args ) {
function AnimationAction (line 38454) | function AnimationAction( mixer, clip, localRoot ) {
function AnimationMixer (line 39114) | function AnimationMixer( root ) {
method total (line 39292) | get total() { return scope._actions.length; }
method inUse (line 39293) | get inUse() { return scope._nActiveActions; }
method total (line 39296) | get total() { return scope._bindings.length; }
method inUse (line 39297) | get inUse() { return scope._nActiveBindings; }
method total (line 39300) | get total() { return scope._controlInterpolants.length; }
method inUse (line 39301) | get inUse() { return scope._nActiveControlInterpolants; }
function Uniform (line 39834) | function Uniform( value ) {
function InstancedBufferGeometry (line 39857) | function InstancedBufferGeometry() {
function InterleavedBufferAttribute (line 39922) | function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset...
function InterleavedBuffer (line 40060) | function InterleavedBuffer( array, stride ) {
function InstancedInterleavedBuffer (line 40168) | function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {
function InstancedBufferAttribute (line 40198) | function InstancedBufferAttribute( array, itemSize, meshPerAttribute ) {
function Raycaster (line 40230) | function Raycaster( origin, direction, near, far ) {
function ascSort (line 40257) | function ascSort( a, b ) {
function intersectObject (line 40263) | function intersectObject( object, raycaster, intersects, recursive ) {
function Clock (line 40356) | function Clock( autoStart ) {
function Spherical (line 40433) | function Spherical( radius, phi, theta ) {
function Cylindrical (line 40510) | function Cylindrical( radius, theta, y ) {
function ImmediateRenderObject (line 40564) | function ImmediateRenderObject( material ) {
function VertexNormalsHelper (line 40583) | function VertexNormalsHelper( object, size, hex, linewidth ) {
function SpotLightHelper (line 40728) | function SpotLightHelper( light, color ) {
function getBoneList (line 40824) | function getBoneList( object ) {
function SkeletonHelper (line 40844) | function SkeletonHelper( object ) {
function PointLightHelper (line 40938) | function PointLightHelper( light, sphereSize, color ) {
function RectAreaLightHelper (line 41025) | function RectAreaLightHelper( light, color ) {
function HemisphereLightHelper (line 41099) | function HemisphereLightHelper( light, size, color ) {
function GridHelper (line 41182) | function GridHelper( size, divisions, color1, color2 ) {
function PolarGridHelper (line 41228) | function PolarGridHelper( radius, radials, circles, divisions, color1, c...
function FaceNormalsHelper (line 41314) | function FaceNormalsHelper( object, size, hex, linewidth ) {
function DirectionalLightHelper (line 41424) | function DirectionalLightHelper( light, size, color ) {
function CameraHelper (line 41517) | function CameraHelper( camera ) {
function setPoint (line 41631) | function setPoint( point, x, y, z ) {
function BoxHelper (line 41711) | function BoxHelper( object, color ) {
function Box3Helper (line 41807) | function Box3Helper( box, hex ) {
function PlaneHelper (line 41854) | function PlaneHelper( plane, size, hex ) {
function ArrowHelper (line 41924) | function ArrowHelper( dir, origin, length, color, headLength, headWidth ) {
function AxisHelper (line 42020) | function AxisHelper( size ) {
function CubicPoly (line 42071) | function CubicPoly() {
function CatmullRomCurve3 (line 42133) | function CatmullRomCurve3( points ) {
function CubicBezierCurve3 (line 42226) | function CubicBezierCurve3( v0, v1, v2, v3 ) {
function QuadraticBezierCurve3 (line 42252) | function QuadraticBezierCurve3( v0, v1, v2 ) {
function LineCurve3 (line 42277) | function LineCurve3( v1, v2 ) {
function ArcCurve (line 42307) | function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
function Face4 (line 42359) | function Face4( a, b, c, d, normal, color, materialIndex ) {
function MeshFaceMaterial (line 42370) | function MeshFaceMaterial( materials ) {
function MultiMaterial (line 42377) | function MultiMaterial( materials ) {
function PointCloud (line 42393) | function PointCloud( geometry, material ) {
function Particle (line 42400) | function Particle( material ) {
function ParticleSystem (line 42407) | function ParticleSystem( geometry, material ) {
function PointCloudMaterial (line 42414) | function PointCloudMaterial( parameters ) {
function ParticleBasicMaterial (line 42421) | function ParticleBasicMaterial( parameters ) {
function ParticleSystemMaterial (line 42428) | function ParticleSystemMaterial( parameters ) {
function Vertex (line 42435) | function Vertex( x, y, z ) {
function DynamicBufferAttribute (line 42444) | function DynamicBufferAttribute( array, itemSize ) {
function Int8Attribute (line 42451) | function Int8Attribute( array, itemSize ) {
function Uint8Attribute (line 42458) | function Uint8Attribute( array, itemSize ) {
function Uint8ClampedAttribute (line 42465) | function Uint8ClampedAttribute( array, itemSize ) {
function Int16Attribute (line 42472) | function Int16Attribute( array, itemSize ) {
function Uint16Attribute (line 42479) | function Uint16Attribute( array, itemSize ) {
function Int32Attribute (line 42486) | function Int32Attribute( array, itemSize ) {
function Uint32Attribute (line 42493) | function Uint32Attribute( array, itemSize ) {
function Float32Attribute (line 42500) | function Float32Attribute( array, itemSize ) {
function Float64Attribute (line 42507) | function Float64Attribute( array, itemSize ) {
function ClosedSplineCurve3 (line 42530) | function ClosedSplineCurve3( points ) {
function SplineCurve3 (line 42544) | function SplineCurve3( points ) {
function Spline (line 42557) | function Spline( points ) {
function BoundingBoxHelper (line 42589) | function BoundingBoxHelper( object, color ) {
function EdgesHelper (line 42596) | function EdgesHelper( object, hex ) {
function WireframeHelper (line 42615) | function WireframeHelper( object, hex ) {
function XHRLoader (line 42624) | function XHRLoader( manager ) {
function BinaryTextureLoader (line 42631) | function BinaryTextureLoader( manager ) {
function Projector (line 43804) | function Projector() {
function CanvasRenderer (line 43832) | function CanvasRenderer() {
FILE: src/attenuation.js
function Attenuation (line 47) | function Attenuation(context, options) {
FILE: src/directivity.js
function Directivity (line 45) | function Directivity(context, options) {
FILE: src/early-reflections.js
function EarlyReflections (line 49) | function EarlyReflections(context, options) {
FILE: src/encoder.js
function Encoder (line 50) | function Encoder(context, options) {
FILE: src/late-reflections.js
function LateReflections (line 51) | function LateReflections(context, options) {
FILE: src/listener.js
function Listener (line 52) | function Listener(context, options) {
FILE: src/resonance-audio.js
function ResonanceAudio (line 67) | function ResonanceAudio(context, options) {
FILE: src/room.js
function _getCoefficientsFromMaterials (line 36) | function _getCoefficientsFromMaterials(materials) {
function _sanitizeCoefficients (line 76) | function _sanitizeCoefficients(coefficients) {
function _sanitizeDimensions (line 95) | function _sanitizeDimensions(dimensions) {
function _getDurationsFromProperties (line 114) | function _getDurationsFromProperties(dimensions, coefficients, speedOfSo...
function _computeReflectionCoefficients (line 164) | function _computeReflectionCoefficients(absorptionCoefficients) {
function Room (line 207) | function Room(context, options) {
FILE: src/source.js
function Source (line 76) | function Source(scene, options) {
function _computeDistanceOutsideRoom (line 344) | function _computeDistanceOutsideRoom(distance) {
FILE: src/utils.js
function Utils (line 30) | function Utils() {}
Condensed preview — 51 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,743K chars).
[
{
"path": ".eslintrc.js",
"chars": 362,
"preview": "module.exports = {\n \"env\": {\n \"es6\": true,\n },\n \"extends\": \"google\",\n \"rules\": {\n // the 'rest' parameter for "
},
{
"path": ".gitignore",
"chars": 135,
"preview": ".DS_Store\nnpm-debug.log\nnode_modules/\npvt/\npackage-lock.json\ndoc/\n\n.firebaserc\n404.html\ndatabase.rules.json\nfirebase.jso"
},
{
"path": ".travis.yml",
"chars": 301,
"preview": "dist: trusty\n\nlanguage: node_js\n\nnode_js:\n - 7\n\naddons:\n apt:\n packages:\n - google-chrome-stable\n\ninstall:\n -"
},
{
"path": "CONTRIBUTING.md",
"chars": 1347,
"preview": "# How to become a contributor and submit your own code\n\n## Contributor License Agreements\n\nWe'd love to accept your samp"
},
{
"path": "LICENSE",
"chars": 11343,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 796,
"preview": "# [Resonance Audio SDK](//developers.google.com/resonance-audio) for Web [ {\n\tif(typeof exports === 'object' && typeof module === 'object"
},
{
"path": "examples/benchmark.html",
"chars": 5682,
"preview": "<!--\n Copyright 2017 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "examples/birds.html",
"chars": 4519,
"preview": "<!--\n Copyright 2017 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "examples/hello-world.html",
"chars": 4535,
"preview": "<!--\n Copyright 2017 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "examples/index.html",
"chars": 4173,
"preview": "<!--\n Copyright 2017 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "examples/resources/examples.css",
"chars": 1433,
"preview": "* {\n font-family: 'Open Sans', sans-serif;\n}\n\n.icon {\n width: 24px;\n height: 24px;\n border: 1px black solid;\n paddi"
},
{
"path": "examples/resources/js/benchmark.js",
"chars": 5985,
"preview": "const sampleRate = 48000;\nconst numberOutputChannels = 2;\nconst durationSeconds = 1;\n\nlet playback;\n\n/**\n * Select appro"
},
{
"path": "examples/resources/js/birds.js",
"chars": 7698,
"preview": "let numberOfBirds = 8;\nlet elements;\nlet canvasControl;\nlet deltaTimeMilliseconds = 33;\nlet areaSize = 10;\nlet speedRang"
},
{
"path": "examples/resources/js/canvas-control.js",
"chars": 5457,
"preview": "/**\n * Class for managing 2D visualization/interaction for audio demos.\n * @param {Object} canvas\n * @param {Object} ele"
},
{
"path": "examples/resources/js/hello-world.js",
"chars": 2309,
"preview": "let audioContext;\nlet scene;\nlet audioElement;\nlet audioElementSource;\nlet source;\nlet audioReady = false;\n\n/**\n * @priv"
},
{
"path": "examples/resources/js/room-models.js",
"chars": 4573,
"preview": "let audioContext;\nlet canvasControl;\nlet scene;\nlet audioElements = [];\nlet soundSources = [];\nlet sourceIds = ['sourceA"
},
{
"path": "examples/resources/js/treasure-hunt.js",
"chars": 9066,
"preview": "let audioContext;\nlet audioElement;\nlet htmlElement;\nlet renderer;\nlet visualScene;\nlet camera;\nlet mesh;\nlet isCursorDo"
},
{
"path": "examples/resources/js/vs-pannernode.js",
"chars": 4663,
"preview": "let audioContext;\nlet audioElement;\nlet audioElementSource;\nlet foaSource;\nlet toaSource;\nlet pannerNode;\nlet foaScene;\n"
},
{
"path": "examples/resources/three.js",
"chars": 1043505,
"preview": "(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof"
},
{
"path": "examples/room-models.html",
"chars": 6836,
"preview": "<!--\n Copyright 2017 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "examples/treasure-hunt.html",
"chars": 4668,
"preview": "<!--\n Copyright 2017 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "examples/vs-pannernode.html",
"chars": 5151,
"preview": "<!--\n Copyright 2017 Google Inc. All Rights Reserved.\n Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "karma.conf.js",
"chars": 641,
"preview": "module.exports = function(config) {\n const configuration = {\n basePath: '',\n frameworks: ['mocha', 'chai'],\n f"
},
{
"path": "package.json",
"chars": 1553,
"preview": "{\n \"name\": \"resonance-audio\",\n \"version\": \"1.0.0\",\n \"description\": \"Resonance Audio library: Spatial Audio for the We"
},
{
"path": "src/attenuation.js",
"chars": 4848,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/directivity.js",
"chars": 4289,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/early-reflections.js",
"chars": 8782,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/encoder.js",
"chars": 7240,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/late-reflections.js",
"chars": 7437,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/listener.js",
"chars": 6134,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/main.js",
"chars": 1532,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/resonance-audio.js",
"chars": 7856,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/room.js",
"chars": 11777,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/source.js",
"chars": 11124,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/tables.js",
"chars": 61453,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "src/utils.js",
"chars": 11646,
"preview": "/**\n * @license\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/version.js",
"chars": 805,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-attenuation.js",
"chars": 3776,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-directivity.js",
"chars": 3428,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-early-reflections.js",
"chars": 2100,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-encoder.js",
"chars": 13239,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-late-reflections.js",
"chars": 1962,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-listener.js",
"chars": 1914,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-resonance-audio.js",
"chars": 1914,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-room.js",
"chars": 2103,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-source.js",
"chars": 2059,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "test/test-tables.js",
"chars": 2193,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "webpack.config.all.js",
"chars": 1147,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "webpack.config.js",
"chars": 772,
"preview": "/**\n * Copyright 2017 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\")"
}
]
About this extraction
This page contains the full source code of the resonance-audio/resonance-audio-web-sdk GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 51 files (1.5 MB), approximately 489.9k tokens, and a symbol index with 469 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.