Update framework
This commit is contained in:
40
framework/resonator/vendor/resonance-es6/attenuation.d.ts
vendored
Normal file
40
framework/resonator/vendor/resonance-es6/attenuation.d.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
export default Attenuation;
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
declare class Attenuation {
|
||||
constructor(context: any, options: any);
|
||||
minDistance: any;
|
||||
maxDistance: any;
|
||||
_gainNode: any;
|
||||
input: any;
|
||||
output: any;
|
||||
/**
|
||||
* Set distance from the listener.
|
||||
* @param {Number} distance Distance (in meters).
|
||||
*/
|
||||
setDistance(distance: number): void;
|
||||
/**
|
||||
* Set rolloff.
|
||||
* @param {string} rolloff
|
||||
* Rolloff model to use, chosen from options in
|
||||
* {@linkcode Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}.
|
||||
*/
|
||||
setRolloff(rolloff: string): void;
|
||||
_rolloff: string;
|
||||
}
|
151
framework/resonator/vendor/resonance-es6/attenuation.js
vendored
Normal file
151
framework/resonator/vendor/resonance-es6/attenuation.js
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
class Attenuation {
|
||||
constructor(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).
|
||||
*/
|
||||
setDistance(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}.
|
||||
*/
|
||||
setRolloff(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;
|
||||
}
|
||||
}
|
||||
export default Attenuation;
|
217
framework/resonator/vendor/resonance-es6/d.d.ts
vendored
Normal file
217
framework/resonator/vendor/resonance-es6/d.d.ts
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
declare module 'resonance-audio' {
|
||||
namespace ResonanceAudio {
|
||||
/** Options for constructing a new ResonanceAudio scene */
|
||||
interface Options {
|
||||
/** Desired ambisonic Order */
|
||||
ambisonicOrder?: number;
|
||||
/** The listener's initial position (in meters), where origin is the center of
|
||||
* the room */
|
||||
listenerPosition?: Float32Array;
|
||||
/** The listener's initial forward vector */
|
||||
listenerForward?: Float32Array;
|
||||
/** The listener's initial up vector */
|
||||
listenerUp?: Float32Array;
|
||||
/** Room dimensions (in meters) */
|
||||
dimensions?: Utils.RoomDimensions;
|
||||
/** Named acoustic materials per wall */
|
||||
materials?: Utils.RoomMaterials;
|
||||
/** (in meters/second) */
|
||||
speedOfSound?: number;
|
||||
}
|
||||
}
|
||||
/** Main class for managing sources, room and listener models */
|
||||
class ResonanceAudio {
|
||||
/** Binaurally-rendered stereo (2-channel) output */
|
||||
output: AudioNode;
|
||||
/** Ambisonic (multichannel) input */
|
||||
ambisonicInput: AudioNode;
|
||||
/** Ambisonic (multichannel) output */
|
||||
ambisonicOutput: AudioNode;
|
||||
constructor(context: AudioContext, options?: ResonanceAudio.Options);
|
||||
/**
|
||||
* Create a new source for the scene.
|
||||
* @param options
|
||||
* Options for constructing a new Source.
|
||||
*/
|
||||
createSource(options?: Source.Options): Source;
|
||||
/**
|
||||
* Set the scene's desired ambisonic order.
|
||||
* @param ambisonicOrder Desired ambisonic order.
|
||||
*/
|
||||
setAmbisonicOrder(ambisonicOrder: any): void;
|
||||
/**
|
||||
* Set the room's dimensions and wall materials.
|
||||
* @param dimensions Room dimensions (in meters).
|
||||
* @param materials Named acoustic materials per wall.
|
||||
*/
|
||||
setRoomProperties(dimensions: Utils.RoomDimensions, materials: Utils.RoomMaterials): void;
|
||||
/**
|
||||
* Set the listener's position (in meters), where origin is the center of
|
||||
* the room.
|
||||
*/
|
||||
setListenerPosition(x: number, y: number, z: number): any;
|
||||
/** Set the source's orientation using forward and up vectors. */
|
||||
setOrientation(forwardX: number, forwardY: number, forwardZ: number, upX: number, upY: number, upZ: number): void;
|
||||
/**
|
||||
* Set the listener's position and orientation using a Three.js Matrix4 object.
|
||||
* @param matrix
|
||||
* The Three.js Matrix4 object representing the listener's world transform.
|
||||
*/
|
||||
setListenerFromMatrix(matrix4: Float32Array): void;
|
||||
/**
|
||||
* Set the speed of sound.
|
||||
*/
|
||||
setSpeedOfSound(speedOfSound: number): void;
|
||||
}
|
||||
namespace Source {
|
||||
/** Options for constructing a new Source. */
|
||||
interface Options {
|
||||
/** The source's initial position (in meters), where origin is the center of
|
||||
* the room */
|
||||
position?: Float32Array;
|
||||
/** The source's initial forward vector */
|
||||
forward?: Float32Array;
|
||||
/** The source's initial up vector */
|
||||
up?: Float32Array;
|
||||
/** Min. distance (in meters) */
|
||||
minDistance?: number;
|
||||
/** Max. distance (in meters) */
|
||||
maxDistance?: number;
|
||||
/** Rolloff model to use */
|
||||
rolloff?: string;
|
||||
/** Input gain (linear) */
|
||||
gain?: number;
|
||||
/** Directivity alpha */
|
||||
alpha?: number;
|
||||
/** Directivity sharpness */
|
||||
sharpness?: number;
|
||||
/** Source width (in degrees). Where 0 degrees is a point source and 360 degrees
|
||||
* is an omnidirectional source */
|
||||
sourceWidth?: number;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Source model to spatialize an audio buffer.
|
||||
*/
|
||||
class Source {
|
||||
constructor(scene: ResonanceAudio, options?: Source.Options);
|
||||
/** Mono (1-channel) input */
|
||||
input: AudioNode;
|
||||
/**
|
||||
* Set source's position (in meters), where origin is the center of
|
||||
* the room.
|
||||
*/
|
||||
setPosition(x: number, y: number, z: number): void;
|
||||
/** Set source's rolloff. */
|
||||
setRolloff(rolloff: string): void;
|
||||
/** Set source's minimum distance (in meters). */
|
||||
setMinDistance(minDistance: number): void;
|
||||
/** Set source's maximum distance (in meters). */
|
||||
setMaxDistance(maxDistance: number): void;
|
||||
/** Set source's gain (linear). */
|
||||
setGain(gain: number): void;
|
||||
/** Set the source's orientation using forward and up vectors. */
|
||||
setOrientation(forwardX: number, forwardY: number, forwardZ: number, upX: number, upY: number, upZ: number): void;
|
||||
/** Set source's position and orientation using a
|
||||
* Three.js modelViewMatrix object */
|
||||
setFromMatrix(matrix4: Float32Array): void;
|
||||
/** Set the source width (in degrees). Where 0 degrees is a point source and 360
|
||||
* degrees is an omnidirectional source */
|
||||
setSourceWidth(sourceWidth: number): void;
|
||||
/**
|
||||
* 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 alpha
|
||||
* Determines directivity pattern (0 to 1).
|
||||
* @param sharpness
|
||||
* Determines the sharpness of the directivity pattern (1 to Inf).
|
||||
*/
|
||||
setDirectivityPattern(alpha: number, sharpness: number): void;
|
||||
}
|
||||
namespace Room {
|
||||
interface Options {
|
||||
/** The listener's initial position (in meters), where origin is the center of
|
||||
* the room */
|
||||
listenerPosition?: Float32Array;
|
||||
/** Room dimensions (in meters) */
|
||||
dimensions?: Utils.RoomDimensions;
|
||||
/** Named acoustic materials per wall */
|
||||
materials?: Utils.RoomMaterials;
|
||||
/** (in meters/second) */
|
||||
speedOfSound?: number;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Model that manages early and late reflections using acoustic
|
||||
* properties and listener position relative to a rectangular room.
|
||||
*/
|
||||
class Room {
|
||||
constructor(context: AudioContext, options?: Room.Options);
|
||||
/**
|
||||
* Set the room's dimensions and wall materials.
|
||||
* @param dimensions Room dimensions (in meters)
|
||||
* @param materials Named acoustic materials per wall
|
||||
*/
|
||||
setProperties(dimensions: Utils.RoomDimensions, materials: Utils.RoomMaterials): void;
|
||||
/**
|
||||
* Set the listener's position (in meters), where origin is the center of
|
||||
* the room.
|
||||
*/
|
||||
setListenerPosition(x: number, y: number, z: number): void;
|
||||
/**
|
||||
* Compute distance outside room of provided position (in meters).
|
||||
* @return
|
||||
* Distance outside room (in meters). Returns 0 if inside room.
|
||||
*/
|
||||
getDistanceOutsideRoom(x: number, y: number, z: number): number;
|
||||
}
|
||||
namespace Listener {
|
||||
interface Options {
|
||||
/** Desired ambisonic order */
|
||||
ambisonicOrder: number;
|
||||
/** Initial position (in meters), where origin is the center of
|
||||
* the room */
|
||||
position?: Float32Array;
|
||||
/** The listener's initial forward vector */
|
||||
forward?: Float32Array;
|
||||
/** The listener's initial up vector */
|
||||
up?: Float32Array;
|
||||
}
|
||||
}
|
||||
/** Listener model to spatialize sources in an environment */
|
||||
class Listener {
|
||||
/** Position (in meters) */
|
||||
position: Float32Array;
|
||||
/** Ambisonic (multichannel) input */
|
||||
input: AudioNode;
|
||||
/** Binaurally-rendered stereo (2-channel) output */
|
||||
output: AudioNode;
|
||||
/** Ambisonic (multichannel) output */
|
||||
ambisonicOutput: AudioNode;
|
||||
/**
|
||||
* Set the listener's orientation using forward and up vectors.
|
||||
*/
|
||||
setOrientation(forwardX: number, forwardY: number, forwardZ: number, upX: number, upY: number, upZ: number): void;
|
||||
/** Set listener's position and orientation using a
|
||||
* Three.js modelViewMatrix object */
|
||||
setFromMatrix(matrix4: Float32Array): void;
|
||||
}
|
||||
namespace Utils {
|
||||
/** Properties describing the geometry of a room. */
|
||||
interface RoomDimensions {
|
||||
width: number;
|
||||
height: number;
|
||||
depth: number;
|
||||
}
|
||||
/** Properties describing the wall materials */
|
||||
interface RoomMaterials {
|
||||
left: string;
|
||||
right: string;
|
||||
front: string;
|
||||
back: string;
|
||||
down: string;
|
||||
up: string;
|
||||
}
|
||||
}
|
||||
}
|
0
framework/resonator/vendor/resonance-es6/d.js
vendored
Normal file
0
framework/resonator/vendor/resonance-es6/d.js
vendored
Normal file
47
framework/resonator/vendor/resonance-es6/directivity.d.ts
vendored
Normal file
47
framework/resonator/vendor/resonance-es6/directivity.d.ts
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
export default Directivity;
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
declare class Directivity {
|
||||
constructor(context: any, options: any);
|
||||
_context: any;
|
||||
_lowpass: any;
|
||||
_cosTheta: number;
|
||||
input: any;
|
||||
output: any;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
computeAngle(forward: Float32Array, direction: Float32Array): void;
|
||||
/**
|
||||
* 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}.
|
||||
*/
|
||||
setPattern(alpha: number, sharpness: number): void;
|
||||
_alpha: number;
|
||||
_sharpness: number;
|
||||
}
|
117
framework/resonator/vendor/resonance-es6/directivity.js
vendored
Normal file
117
framework/resonator/vendor/resonance-es6/directivity.js
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
class Directivity {
|
||||
constructor(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.
|
||||
*/
|
||||
computeAngle(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}.
|
||||
*/
|
||||
setPattern(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]);
|
||||
}
|
||||
}
|
||||
export default Directivity;
|
56
framework/resonator/vendor/resonance-es6/early-reflections.d.ts
vendored
Normal file
56
framework/resonator/vendor/resonance-es6/early-reflections.d.ts
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
export default EarlyReflections;
|
||||
/**
|
||||
* @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 {Utils~RoomDimensions} 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}.
|
||||
*/
|
||||
declare class EarlyReflections {
|
||||
constructor(context: any, options: any);
|
||||
speedOfSound: any;
|
||||
input: any;
|
||||
output: any;
|
||||
_lowpass: any;
|
||||
_delays: {};
|
||||
_gains: {};
|
||||
_inverters: {};
|
||||
_merger: any;
|
||||
_listenerPosition: any;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
setListenerPosition(x: number, y: number, z: number): void;
|
||||
/**
|
||||
* Set the room's properties which determines the characteristics of
|
||||
* reflections.
|
||||
* @param {Utils~RoomDimensions} 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}.
|
||||
*/
|
||||
setRoomProperties(dimensions: any, coefficients: any): void;
|
||||
_coefficients: any;
|
||||
_halfDimensions: {};
|
||||
}
|
212
framework/resonator/vendor/resonance-es6/early-reflections.js
vendored
Normal file
212
framework/resonator/vendor/resonance-es6/early-reflections.js
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* @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 {Utils~RoomDimensions} 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}.
|
||||
*/
|
||||
class EarlyReflections {
|
||||
constructor(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
|
||||
*/
|
||||
setListenerPosition(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 {Utils~RoomDimensions} 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}.
|
||||
*/
|
||||
setRoomProperties(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]);
|
||||
}
|
||||
}
|
||||
export default EarlyReflections;
|
64
framework/resonator/vendor/resonance-es6/encoder.d.ts
vendored
Normal file
64
framework/resonator/vendor/resonance-es6/encoder.d.ts
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
export default Encoder;
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
declare class Encoder {
|
||||
constructor(context: any, options: any);
|
||||
_context: any;
|
||||
input: any;
|
||||
_channelGain: any[];
|
||||
_merger: any;
|
||||
output: any;
|
||||
_azimuth: any;
|
||||
_elevation: any;
|
||||
/**
|
||||
* Set the desired ambisonic order.
|
||||
* @param {Number} ambisonicOrder Desired ambisonic order.
|
||||
*/
|
||||
setAmbisonicOrder(ambisonicOrder: number): void;
|
||||
_ambisonicOrder: number;
|
||||
/**
|
||||
* 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}.
|
||||
*/
|
||||
setDirection(azimuth: number, elevation: number): void;
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
setSourceWidth(sourceWidth: number): void;
|
||||
_spreadIndex: number;
|
||||
}
|
||||
declare namespace Encoder {
|
||||
/**
|
||||
* Validate the provided ambisonic order.
|
||||
* @param {Number} ambisonicOrder Desired ambisonic order.
|
||||
* @return {Number} Validated/adjusted ambisonic order.
|
||||
* @private
|
||||
*/
|
||||
function validateAmbisonicOrder(ambisonicOrder: number): number;
|
||||
}
|
194
framework/resonator/vendor/resonance-es6/encoder.js
vendored
Normal file
194
framework/resonator/vendor/resonance-es6/encoder.js
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Tables from './tables.js';
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
class Encoder {
|
||||
constructor(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.
|
||||
*/
|
||||
setAmbisonicOrder(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}.
|
||||
*/
|
||||
setDirection(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).
|
||||
*/
|
||||
setSourceWidth(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 = 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;
|
||||
};
|
||||
export default Encoder;
|
42
framework/resonator/vendor/resonance-es6/late-reflections.d.ts
vendored
Normal file
42
framework/resonator/vendor/resonance-es6/late-reflections.d.ts
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
export default LateReflections;
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
declare class LateReflections {
|
||||
constructor(context: any, options: any);
|
||||
_bandwidthCoeff: number;
|
||||
_tailonsetSamples: number;
|
||||
_context: any;
|
||||
input: any;
|
||||
_predelay: any;
|
||||
_convolver: any;
|
||||
output: any;
|
||||
/**
|
||||
* 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}.
|
||||
*/
|
||||
setDurations(durations: any[]): void;
|
||||
}
|
187
framework/resonator/vendor/resonance-es6/late-reflections.js
vendored
Normal file
187
framework/resonator/vendor/resonance-es6/late-reflections.js
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
class LateReflections {
|
||||
constructor(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}.
|
||||
*/
|
||||
setDurations(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;
|
||||
}
|
||||
}
|
||||
export default LateReflections;
|
49
framework/resonator/vendor/resonance-es6/listener.d.ts
vendored
Normal file
49
framework/resonator/vendor/resonance-es6/listener.d.ts
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
export default Listener;
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
declare class Listener {
|
||||
constructor(context: any, options: any);
|
||||
position: Float32Array;
|
||||
_tempMatrix3: Float32Array;
|
||||
_ambisonicOrder: number;
|
||||
_context: any;
|
||||
_renderer: any;
|
||||
input: any;
|
||||
output: any;
|
||||
ambisonicOutput: any;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
setOrientation(forwardX: number, forwardY: number, forwardZ: number, upX: number, upY: number, upZ: number): void;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
setFromMatrix(matrix4: any): void;
|
||||
}
|
168
framework/resonator/vendor/resonance-es6/listener.js
vendored
Normal file
168
framework/resonator/vendor/resonance-es6/listener.js
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Omnitone from 'omnitone/build/omnitone.esm';
|
||||
import Encoder from './encoder.js';
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* @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}.
|
||||
*/
|
||||
class Listener {
|
||||
constructor(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.createFOARenderer(context, {});
|
||||
}
|
||||
else if (this._ambisonicOrder > 1) {
|
||||
this._renderer = 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(() => {
|
||||
// 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
|
||||
*/
|
||||
setOrientation(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.
|
||||
*/
|
||||
setFromMatrix(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];
|
||||
}
|
||||
}
|
||||
export default Listener;
|
2
framework/resonator/vendor/resonance-es6/main.d.ts
vendored
Normal file
2
framework/resonator/vendor/resonance-es6/main.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export default ResonanceAudio;
|
||||
import ResonanceAudio from "./resonance-audio";
|
23
framework/resonator/vendor/resonance-es6/main.js
vendored
Normal file
23
framework/resonator/vendor/resonance-es6/main.js
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
import ResonanceAudio from './resonance-audio';
|
||||
// Main module.
|
||||
export default ResonanceAudio;
|
130
framework/resonator/vendor/resonance-es6/resonance-audio.d.ts
vendored
Normal file
130
framework/resonator/vendor/resonance-es6/resonance-audio.d.ts
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
export default ResonanceAudio;
|
||||
/**
|
||||
* ~ResonanceAudioOptions
|
||||
*/
|
||||
export type ResonanceAudio = {
|
||||
/**
|
||||
* Desired ambisonic Order. Defaults to
|
||||
* {@link Utils.DEFAULT_AMBISONIC_ORDER DEFAULT_AMBISONIC_ORDER}.
|
||||
*/
|
||||
ambisonicOrder: number;
|
||||
/**
|
||||
* The listener's initial position (in meters), where origin is the center of
|
||||
* the room. Defaults to {@link Utils.DEFAULT_POSITION DEFAULT_POSITION}.
|
||||
*/
|
||||
listenerPosition: Float32Array;
|
||||
/**
|
||||
* The listener's initial forward vector.
|
||||
* Defaults to {@link Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
|
||||
*/
|
||||
listenerForward: Float32Array;
|
||||
/**
|
||||
* The listener's initial up vector.
|
||||
* Defaults to {@link Utils.DEFAULT_UP DEFAULT_UP}.
|
||||
*/
|
||||
listenerUp: Float32Array;
|
||||
/**
|
||||
* ~RoomDimensions} dimensions Room dimensions (in meters). Defaults to
|
||||
* {@link Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
|
||||
*/
|
||||
"": Utils;
|
||||
/**
|
||||
* (in meters/second). Defaults to
|
||||
* {@link Utils.DEFAULT_SPEED_OF_SOUND DEFAULT_SPEED_OF_SOUND}.
|
||||
*/
|
||||
speedOfSound: number;
|
||||
};
|
||||
/**
|
||||
* Options for constructing a new ResonanceAudio scene.
|
||||
* @typedef {Object} ResonanceAudio~ResonanceAudioOptions
|
||||
* @property {Number} ambisonicOrder
|
||||
* Desired ambisonic Order. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_AMBISONIC_ORDER DEFAULT_AMBISONIC_ORDER}.
|
||||
* @property {Float32Array} listenerPosition
|
||||
* The listener's initial position (in meters), where origin is the center of
|
||||
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
|
||||
* @property {Float32Array} listenerForward
|
||||
* The listener's initial forward vector.
|
||||
* Defaults to {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
|
||||
* @property {Float32Array} listenerUp
|
||||
* The listener's initial up vector.
|
||||
* Defaults to {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
|
||||
* @property {Utils~RoomDimensions} dimensions Room dimensions (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
|
||||
* @property {Utils~RoomMaterials} materials Named acoustic materials per wall.
|
||||
* Defaults to {@linkcode Utils.DEFAULT_ROOM_MATERIALS DEFAULT_ROOM_MATERIALS}.
|
||||
* @property {Number} speedOfSound
|
||||
* (in meters/second). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_SPEED_OF_SOUND DEFAULT_SPEED_OF_SOUND}.
|
||||
*/
|
||||
/**
|
||||
* @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 {ResonanceAudio~ResonanceAudioOptions} options
|
||||
* Options for constructing a new ResonanceAudio scene.
|
||||
*/
|
||||
declare class ResonanceAudio {
|
||||
constructor(context: any, options: any);
|
||||
_ambisonicOrder: number;
|
||||
_sources: any[];
|
||||
_room: Room;
|
||||
_listener: Listener;
|
||||
_context: any;
|
||||
output: any;
|
||||
ambisonicOutput: any;
|
||||
ambisonicInput: any;
|
||||
/**
|
||||
* Create a new source for the scene.
|
||||
* @param {Source~SourceOptions} options
|
||||
* Options for constructing a new Source.
|
||||
* @return {Source}
|
||||
*/
|
||||
createSource(options: any): Source;
|
||||
/**
|
||||
* Set the scene's desired ambisonic order.
|
||||
* @param {Number} ambisonicOrder Desired ambisonic order.
|
||||
*/
|
||||
setAmbisonicOrder(ambisonicOrder: number): void;
|
||||
/**
|
||||
* Set the room's dimensions and wall materials.
|
||||
* @param {Object} dimensions Room dimensions (in meters).
|
||||
* @param {Object} materials Named acoustic materials per wall.
|
||||
*/
|
||||
setRoomProperties(dimensions: any, materials: any): void;
|
||||
/**
|
||||
* Set the listener's position (in meters), where origin is the center of
|
||||
* the room.
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @param {Number} z
|
||||
*/
|
||||
setListenerPosition(x: number, y: number, z: number): void;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
setListenerOrientation(forwardX: number, forwardY: number, forwardZ: number, upX: number, upY: number, upZ: number): void;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
setListenerFromMatrix(matrix: any): void;
|
||||
/**
|
||||
* Set the speed of sound.
|
||||
* @param {Number} speedOfSound
|
||||
*/
|
||||
setSpeedOfSound(speedOfSound: number): void;
|
||||
}
|
||||
import Utils from "./utils.js";
|
||||
import Room from "./room.js";
|
||||
import Listener from "./listener.js";
|
||||
import Source from "./source.js";
|
213
framework/resonator/vendor/resonance-es6/resonance-audio.js
vendored
Normal file
213
framework/resonator/vendor/resonance-es6/resonance-audio.js
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Listener from './listener.js';
|
||||
import Source from './source.js';
|
||||
import Room from './room.js';
|
||||
import Encoder from './encoder.js';
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* Options for constructing a new ResonanceAudio scene.
|
||||
* @typedef {Object} ResonanceAudio~ResonanceAudioOptions
|
||||
* @property {Number} ambisonicOrder
|
||||
* Desired ambisonic Order. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_AMBISONIC_ORDER DEFAULT_AMBISONIC_ORDER}.
|
||||
* @property {Float32Array} listenerPosition
|
||||
* The listener's initial position (in meters), where origin is the center of
|
||||
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
|
||||
* @property {Float32Array} listenerForward
|
||||
* The listener's initial forward vector.
|
||||
* Defaults to {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
|
||||
* @property {Float32Array} listenerUp
|
||||
* The listener's initial up vector.
|
||||
* Defaults to {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
|
||||
* @property {Utils~RoomDimensions} dimensions Room dimensions (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
|
||||
* @property {Utils~RoomMaterials} materials Named acoustic materials per wall.
|
||||
* Defaults to {@linkcode Utils.DEFAULT_ROOM_MATERIALS DEFAULT_ROOM_MATERIALS}.
|
||||
* @property {Number} speedOfSound
|
||||
* (in meters/second). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_SPEED_OF_SOUND DEFAULT_SPEED_OF_SOUND}.
|
||||
*/
|
||||
/**
|
||||
* @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 {ResonanceAudio~ResonanceAudioOptions} options
|
||||
* Options for constructing a new ResonanceAudio scene.
|
||||
*/
|
||||
class ResonanceAudio {
|
||||
constructor(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 {Source~SourceOptions} options
|
||||
* Options for constructing a new Source.
|
||||
* @return {Source}
|
||||
*/
|
||||
createSource(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.
|
||||
*/
|
||||
setAmbisonicOrder(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.
|
||||
*/
|
||||
setRoomProperties(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
|
||||
*/
|
||||
setListenerPosition(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(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
|
||||
*/
|
||||
setListenerOrientation(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.
|
||||
*/
|
||||
setListenerFromMatrix(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
|
||||
*/
|
||||
setSpeedOfSound(speedOfSound) {
|
||||
this._room.speedOfSound = speedOfSound;
|
||||
}
|
||||
}
|
||||
export default ResonanceAudio;
|
55
framework/resonator/vendor/resonance-es6/room.d.ts
vendored
Normal file
55
framework/resonator/vendor/resonance-es6/room.d.ts
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
export default Room;
|
||||
/**
|
||||
* @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 {Utils~RoomDimensions} options.dimensions Room dimensions (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
|
||||
* @param {Utils~RoomMaterials} 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}.
|
||||
*/
|
||||
declare class Room {
|
||||
constructor(context: any, options: any);
|
||||
early: EarlyReflections;
|
||||
late: LateReflections;
|
||||
speedOfSound: any;
|
||||
output: any;
|
||||
_merger: any;
|
||||
/**
|
||||
* Set the room's dimensions and wall materials.
|
||||
* @param {Utils~RoomDimensions} dimensions Room dimensions (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
|
||||
* @param {Utils~RoomMaterials} materials Named acoustic materials per wall. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_MATERIALS DEFAULT_ROOM_MATERIALS}.
|
||||
*/
|
||||
setProperties(dimensions: any, materials: any): void;
|
||||
/**
|
||||
* Set the listener's position (in meters), where origin is the center of
|
||||
* the room.
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @param {Number} z
|
||||
*/
|
||||
setListenerPosition(x: number, y: number, z: number): void;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
getDistanceOutsideRoom(x: number, y: number, z: number): number;
|
||||
}
|
||||
import EarlyReflections from "./early-reflections.js";
|
||||
import LateReflections from "./late-reflections.js";
|
300
framework/resonator/vendor/resonance-es6/room.js
vendored
Normal file
300
framework/resonator/vendor/resonance-es6/room.js
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import LateReflections from './late-reflections.js';
|
||||
import EarlyReflections from './early-reflections.js';
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* 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 {Utils~RoomDimensions} dimensions
|
||||
* @return {Utils~RoomDimensions}
|
||||
*/
|
||||
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 {Utils~RoomDimensions} 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 {Utils~RoomDimensions} options.dimensions Room dimensions (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
|
||||
* @param {Utils~RoomMaterials} 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}.
|
||||
*/
|
||||
class Room {
|
||||
constructor(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 {Utils~RoomDimensions} dimensions Room dimensions (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_DIMENSIONS DEFAULT_ROOM_DIMENSIONS}.
|
||||
* @param {Utils~RoomMaterials} materials Named acoustic materials per wall. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_ROOM_MATERIALS DEFAULT_ROOM_MATERIALS}.
|
||||
*/
|
||||
setProperties(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
|
||||
*/
|
||||
setListenerPosition(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.
|
||||
*/
|
||||
getDistanceOutsideRoom(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);
|
||||
}
|
||||
}
|
||||
export default Room;
|
182
framework/resonator/vendor/resonance-es6/source.d.ts
vendored
Normal file
182
framework/resonator/vendor/resonance-es6/source.d.ts
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
export default Source;
|
||||
/**
|
||||
* ~SourceOptions
|
||||
*/
|
||||
export type Source = {
|
||||
/**
|
||||
* The source's initial position (in meters), where origin is the center of
|
||||
* the room. Defaults to {@link Utils.DEFAULT_POSITION DEFAULT_POSITION}.
|
||||
*/
|
||||
position: Float32Array;
|
||||
/**
|
||||
* The source's initial forward vector. Defaults to
|
||||
* {@link Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
|
||||
*/
|
||||
forward: Float32Array;
|
||||
/**
|
||||
* The source's initial up vector. Defaults to
|
||||
* {@link Utils.DEFAULT_UP DEFAULT_UP}.
|
||||
*/
|
||||
up: Float32Array;
|
||||
/**
|
||||
* Min. distance (in meters). Defaults to
|
||||
* {@link Utils.DEFAULT_MIN_DISTANCE DEFAULT_MIN_DISTANCE}.
|
||||
*/
|
||||
minDistance: number;
|
||||
/**
|
||||
* Max. distance (in meters). Defaults to
|
||||
* {@link Utils.DEFAULT_MAX_DISTANCE DEFAULT_MAX_DISTANCE}.
|
||||
*/
|
||||
maxDistance: number;
|
||||
/**
|
||||
* Rolloff model to use, chosen from options in
|
||||
* {@link Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}. Defaults to
|
||||
* {@link Utils.DEFAULT_ATTENUATION_ROLLOFF DEFAULT_ATTENUATION_ROLLOFF}.
|
||||
*/
|
||||
rolloff: string;
|
||||
/**
|
||||
* Input gain (linear). Defaults to
|
||||
* {@link Utils.DEFAULT_SOURCE_GAIN DEFAULT_SOURCE_GAIN}.
|
||||
*/
|
||||
gain: number;
|
||||
/**
|
||||
* Directivity alpha. Defaults to
|
||||
* {@link Utils.DEFAULT_DIRECTIVITY_ALPHA DEFAULT_DIRECTIVITY_ALPHA}.
|
||||
*/
|
||||
alpha: number;
|
||||
/**
|
||||
* Directivity sharpness. Defaults to
|
||||
* {@link Utils.DEFAULT_DIRECTIVITY_SHARPNESS * DEFAULT_DIRECTIVITY_SHARPNESS}.
|
||||
*/
|
||||
sharpness: number;
|
||||
/**
|
||||
* Source width (in degrees). Where 0 degrees is a point source and 360 degrees
|
||||
* is an omnidirectional source. Defaults to
|
||||
* {@link Utils.DEFAULT_SOURCE_WIDTH DEFAULT_SOURCE_WIDTH}.
|
||||
*/
|
||||
sourceWidth: number;
|
||||
};
|
||||
/**
|
||||
* Options for constructing a new Source.
|
||||
* @typedef {Object} Source~SourceOptions
|
||||
* @property {Float32Array} position
|
||||
* The source's initial position (in meters), where origin is the center of
|
||||
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
|
||||
* @property {Float32Array} forward
|
||||
* The source's initial forward vector. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
|
||||
* @property {Float32Array} up
|
||||
* The source's initial up vector. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
|
||||
* @property {Number} minDistance
|
||||
* Min. distance (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_MIN_DISTANCE DEFAULT_MIN_DISTANCE}.
|
||||
* @property {Number} maxDistance
|
||||
* Max. distance (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_MAX_DISTANCE DEFAULT_MAX_DISTANCE}.
|
||||
* @property {string} 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}.
|
||||
* @property {Number} gain Input gain (linear). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_SOURCE_GAIN DEFAULT_SOURCE_GAIN}.
|
||||
* @property {Number} alpha Directivity alpha. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_DIRECTIVITY_ALPHA DEFAULT_DIRECTIVITY_ALPHA}.
|
||||
* @property {Number} sharpness Directivity sharpness. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_DIRECTIVITY_SHARPNESS
|
||||
* DEFAULT_DIRECTIVITY_SHARPNESS}.
|
||||
* @property {Number} 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}.
|
||||
*/
|
||||
/**
|
||||
* @class Source
|
||||
* @description Source model to spatialize an audio buffer.
|
||||
* @param {ResonanceAudio} scene Associated {@link ResonanceAudio
|
||||
* ResonanceAudio} instance.
|
||||
* @param {Source~SourceOptions} options
|
||||
* Options for constructing a new Source.
|
||||
*/
|
||||
declare class Source {
|
||||
constructor(scene: any, options: any);
|
||||
_scene: any;
|
||||
_position: any;
|
||||
_forward: any;
|
||||
_up: any;
|
||||
_dx: Float32Array;
|
||||
_right: Float32Array;
|
||||
input: any;
|
||||
_directivity: Directivity;
|
||||
_toEarly: any;
|
||||
_toLate: any;
|
||||
_attenuation: Attenuation;
|
||||
_encoder: Encoder;
|
||||
/**
|
||||
* Set source's position (in meters), where origin is the center of
|
||||
* the room.
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @param {Number} z
|
||||
*/
|
||||
setPosition(x: number, y: number, z: number): void;
|
||||
_update(): void;
|
||||
/**
|
||||
* Set source's rolloff.
|
||||
* @param {string} rolloff
|
||||
* Rolloff model to use, chosen from options in
|
||||
* {@linkcode Utils.ATTENUATION_ROLLOFFS ATTENUATION_ROLLOFFS}.
|
||||
*/
|
||||
setRolloff(rolloff: string): void;
|
||||
/**
|
||||
* Set source's minimum distance (in meters).
|
||||
* @param {Number} minDistance
|
||||
*/
|
||||
setMinDistance(minDistance: number): void;
|
||||
/**
|
||||
* Set source's maximum distance (in meters).
|
||||
* @param {Number} maxDistance
|
||||
*/
|
||||
setMaxDistance(maxDistance: number): void;
|
||||
/**
|
||||
* Set source's gain (linear).
|
||||
* @param {Number} gain
|
||||
*/
|
||||
setGain(gain: number): void;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
setOrientation(forwardX: number, forwardY: number, forwardZ: number, upX: number, upY: number, upZ: number): void;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
setFromMatrix(matrix4: Float32Array): void;
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
setSourceWidth(sourceWidth: number): void;
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
setDirectivityPattern(alpha: number, sharpness: number): void;
|
||||
}
|
||||
import Directivity from "./directivity.js";
|
||||
import Attenuation from "./attenuation.js";
|
||||
import Encoder from "./encoder.js";
|
308
framework/resonator/vendor/resonance-es6/source.js
vendored
Normal file
308
framework/resonator/vendor/resonance-es6/source.js
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
// Internal dependencies.
|
||||
import Directivity from './directivity.js';
|
||||
import Attenuation from './attenuation.js';
|
||||
import Encoder from './encoder.js';
|
||||
import Utils from './utils.js';
|
||||
/**
|
||||
* Options for constructing a new Source.
|
||||
* @typedef {Object} Source~SourceOptions
|
||||
* @property {Float32Array} position
|
||||
* The source's initial position (in meters), where origin is the center of
|
||||
* the room. Defaults to {@linkcode Utils.DEFAULT_POSITION DEFAULT_POSITION}.
|
||||
* @property {Float32Array} forward
|
||||
* The source's initial forward vector. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_FORWARD DEFAULT_FORWARD}.
|
||||
* @property {Float32Array} up
|
||||
* The source's initial up vector. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_UP DEFAULT_UP}.
|
||||
* @property {Number} minDistance
|
||||
* Min. distance (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_MIN_DISTANCE DEFAULT_MIN_DISTANCE}.
|
||||
* @property {Number} maxDistance
|
||||
* Max. distance (in meters). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_MAX_DISTANCE DEFAULT_MAX_DISTANCE}.
|
||||
* @property {string} 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}.
|
||||
* @property {Number} gain Input gain (linear). Defaults to
|
||||
* {@linkcode Utils.DEFAULT_SOURCE_GAIN DEFAULT_SOURCE_GAIN}.
|
||||
* @property {Number} alpha Directivity alpha. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_DIRECTIVITY_ALPHA DEFAULT_DIRECTIVITY_ALPHA}.
|
||||
* @property {Number} sharpness Directivity sharpness. Defaults to
|
||||
* {@linkcode Utils.DEFAULT_DIRECTIVITY_SHARPNESS
|
||||
* DEFAULT_DIRECTIVITY_SHARPNESS}.
|
||||
* @property {Number} 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}.
|
||||
*/
|
||||
/**
|
||||
* @class Source
|
||||
* @description Source model to spatialize an audio buffer.
|
||||
* @param {ResonanceAudio} scene Associated {@link ResonanceAudio
|
||||
* ResonanceAudio} instance.
|
||||
* @param {Source~SourceOptions} options
|
||||
* Options for constructing a new Source.
|
||||
*/
|
||||
class Source {
|
||||
constructor(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
|
||||
*/
|
||||
setPosition(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.
|
||||
_update() {
|
||||
// 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}.
|
||||
*/
|
||||
setRolloff(rolloff) {
|
||||
this._attenuation.setRolloff(rolloff);
|
||||
}
|
||||
/**
|
||||
* Set source's minimum distance (in meters).
|
||||
* @param {Number} minDistance
|
||||
*/
|
||||
setMinDistance(minDistance) {
|
||||
this._attenuation.minDistance = minDistance;
|
||||
}
|
||||
/**
|
||||
* Set source's maximum distance (in meters).
|
||||
* @param {Number} maxDistance
|
||||
*/
|
||||
setMaxDistance(maxDistance) {
|
||||
this._attenuation.maxDistance = maxDistance;
|
||||
}
|
||||
/**
|
||||
* Set source's gain (linear).
|
||||
* @param {Number} gain
|
||||
*/
|
||||
setGain(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
|
||||
*/
|
||||
setOrientation(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.
|
||||
*/
|
||||
setFromMatrix(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).
|
||||
*/
|
||||
setSourceWidth(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).
|
||||
*/
|
||||
setDirectivityPattern(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;
|
||||
}
|
||||
export default Source;
|
38
framework/resonator/vendor/resonance-es6/tables.d.ts
vendored
Normal file
38
framework/resonator/vendor/resonance-es6/tables.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
declare namespace _default {
|
||||
export { SPHERICAL_HARMONICS };
|
||||
export { SPHERICAL_HARMONICS_AZIMUTH_RESOLUTION };
|
||||
export { SPHERICAL_HARMONICS_ELEVATION_RESOLUTION };
|
||||
export { SPHERICAL_HARMONICS_MAX_ORDER };
|
||||
export { MAX_RE_WEIGHTS };
|
||||
export { MAX_RE_WEIGHTS_RESOLUTION };
|
||||
}
|
||||
export default _default;
|
||||
/**
|
||||
* 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}
|
||||
*/
|
||||
declare const SPHERICAL_HARMONICS: Float32Array;
|
||||
/** @type {Number} */
|
||||
declare const SPHERICAL_HARMONICS_AZIMUTH_RESOLUTION: number;
|
||||
/** @type {Number} */
|
||||
declare const SPHERICAL_HARMONICS_ELEVATION_RESOLUTION: number;
|
||||
/**
|
||||
* The maximum allowed ambisonic order.
|
||||
* @type {Number}
|
||||
*/
|
||||
declare const SPHERICAL_HARMONICS_MAX_ORDER: number;
|
||||
/**
|
||||
* Pre-computed per-band weighting coefficients for producing energy-preserving
|
||||
* Max-Re sources.
|
||||
*/
|
||||
declare const MAX_RE_WEIGHTS: number[][];
|
||||
/** @type {Number} */
|
||||
declare const MAX_RE_WEIGHTS_RESOLUTION: number;
|
1144
framework/resonator/vendor/resonance-es6/tables.js
vendored
Normal file
1144
framework/resonator/vendor/resonance-es6/tables.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
98
framework/resonator/vendor/resonance-es6/utils.d.ts
vendored
Normal file
98
framework/resonator/vendor/resonance-es6/utils.d.ts
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
export default Utils;
|
||||
/**
|
||||
* @class Utils
|
||||
* @description A set of defaults, constants and utility functions.
|
||||
*/
|
||||
declare class Utils {
|
||||
/**
|
||||
* Properties describing the geometry of a room.
|
||||
* @typedef {Object} Utils~RoomDimensions
|
||||
* @property {Number} width (in meters).
|
||||
* @property {Number} height (in meters).
|
||||
* @property {Number} depth (in meters).
|
||||
*/
|
||||
/**
|
||||
* Properties describing the wall materials (from
|
||||
* {@linkcode Utils.ROOM_MATERIAL_COEFFICIENTS ROOM_MATERIAL_COEFFICIENTS})
|
||||
* of a room.
|
||||
* @typedef {Object} Utils~RoomMaterials
|
||||
* @property {String} left Left-wall material name.
|
||||
* @property {String} right Right-wall material name.
|
||||
* @property {String} front Front-wall material name.
|
||||
* @property {String} back Back-wall material name.
|
||||
* @property {String} up Up-wall material name.
|
||||
* @property {String} down Down-wall material name.
|
||||
*/
|
||||
/**
|
||||
* ResonanceAudio library logging function.
|
||||
* @type {Function}
|
||||
* @param {any} Message to be printed out.
|
||||
* @private
|
||||
*/
|
||||
private static log;
|
||||
}
|
||||
declare namespace Utils {
|
||||
const DEFAULT_SOURCE_GAIN: number;
|
||||
const LISTENER_MAX_OUTSIDE_ROOM_DISTANCE: number;
|
||||
const SOURCE_MAX_OUTSIDE_ROOM_DISTANCE: number;
|
||||
const DEFAULT_SOURCE_DISTANCE: number;
|
||||
const DEFAULT_POSITION: Float32Array;
|
||||
const DEFAULT_FORWARD: Float32Array;
|
||||
const DEFAULT_UP: Float32Array;
|
||||
const DEFAULT_RIGHT: Float32Array;
|
||||
const DEFAULT_SPEED_OF_SOUND: number;
|
||||
const ATTENUATION_ROLLOFFS: any[];
|
||||
const DEFAULT_ATTENUATION_ROLLOFF: string;
|
||||
const DEFAULT_MIN_DISTANCE: number;
|
||||
const DEFAULT_MAX_DISTANCE: number;
|
||||
const DEFAULT_DIRECTIVITY_ALPHA: number;
|
||||
const DEFAULT_DIRECTIVITY_SHARPNESS: number;
|
||||
const DEFAULT_AZIMUTH: number;
|
||||
const DEFAULT_ELEVATION: number;
|
||||
const DEFAULT_AMBISONIC_ORDER: number;
|
||||
const DEFAULT_SOURCE_WIDTH: number;
|
||||
const DEFAULT_REFLECTION_MAX_DURATION: number;
|
||||
const DEFAULT_REFLECTION_CUTOFF_FREQUENCY: number;
|
||||
const DEFAULT_REFLECTION_COEFFICIENTS: any;
|
||||
const DEFAULT_REFLECTION_MIN_DISTANCE: number;
|
||||
const DEFAULT_ROOM_DIMENSIONS: any;
|
||||
const DEFAULT_REFLECTION_MULTIPLIER: number;
|
||||
const DEFAULT_REVERB_BANDWIDTH: number;
|
||||
const DEFAULT_REVERB_DURATION_MULTIPLIER: number;
|
||||
const DEFAULT_REVERB_PREDELAY: number;
|
||||
const DEFAULT_REVERB_TAIL_ONSET: number;
|
||||
const DEFAULT_REVERB_GAIN: number;
|
||||
const DEFAULT_REVERB_MAX_DURATION: number;
|
||||
const DEFAULT_REVERB_FREQUENCY_BANDS: any[];
|
||||
const NUMBER_REVERB_FREQUENCY_BANDS: number;
|
||||
const DEFAULT_REVERB_DURATIONS: Float32Array;
|
||||
const ROOM_MATERIAL_COEFFICIENTS: any;
|
||||
const DEFAULT_ROOM_MATERIALS: any;
|
||||
const NUMBER_REFLECTION_AVERAGING_BANDS: number;
|
||||
const ROOM_STARTING_AVERAGING_BAND: number;
|
||||
const ROOM_MIN_VOLUME: number;
|
||||
const ROOM_AIR_ABSORPTION_COEFFICIENTS: Float32Array;
|
||||
const ROOM_EYRING_CORRECTION_COEFFICIENT: number;
|
||||
const TWO_PI: number;
|
||||
const TWENTY_FOUR_LOG10: number;
|
||||
const LOG1000: number;
|
||||
const LOG2_DIV2: number;
|
||||
const DEGREES_TO_RADIANS: number;
|
||||
const RADIANS_TO_DEGREES: number;
|
||||
const EPSILON_FLOAT: number;
|
||||
/**
|
||||
* Normalize a 3-d vector.
|
||||
* @param {Float32Array} v 3-element vector.
|
||||
* @return {Float32Array} 3-element vector.
|
||||
* @private
|
||||
*/
|
||||
function normalizeVector(v: Float32Array): Float32Array;
|
||||
/**
|
||||
* Cross-product between two 3-d vectors.
|
||||
* @param {Float32Array} a 3-element vector.
|
||||
* @param {Float32Array} b 3-element vector.
|
||||
* @return {Float32Array}
|
||||
* @private
|
||||
*/
|
||||
function crossProduct(a: Float32Array, b: Float32Array): Float32Array;
|
||||
}
|
379
framework/resonator/vendor/resonance-es6/utils.js
vendored
Normal file
379
framework/resonator/vendor/resonance-es6/utils.js
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
'use strict';
|
||||
/**
|
||||
* @class Utils
|
||||
* @description A set of defaults, constants and utility functions.
|
||||
*/
|
||||
class Utils {
|
||||
/**
|
||||
* Properties describing the geometry of a room.
|
||||
* @typedef {Object} Utils~RoomDimensions
|
||||
* @property {Number} width (in meters).
|
||||
* @property {Number} height (in meters).
|
||||
* @property {Number} depth (in meters).
|
||||
*/
|
||||
/**
|
||||
* Properties describing the wall materials (from
|
||||
* {@linkcode Utils.ROOM_MATERIAL_COEFFICIENTS ROOM_MATERIAL_COEFFICIENTS})
|
||||
* of a room.
|
||||
* @typedef {Object} Utils~RoomMaterials
|
||||
* @property {String} left Left-wall material name.
|
||||
* @property {String} right Right-wall material name.
|
||||
* @property {String} front Front-wall material name.
|
||||
* @property {String} back Back-wall material name.
|
||||
* @property {String} up Up-wall material name.
|
||||
* @property {String} down Down-wall material name.
|
||||
*/
|
||||
/**
|
||||
* ResonanceAudio library logging function.
|
||||
* @type {Function}
|
||||
* @param {any} Message to be printed out.
|
||||
* @private
|
||||
*/
|
||||
static log() {
|
||||
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',
|
||||
]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* Normalize a 3-d vector.
|
||||
* @param {Float32Array} v 3-element vector.
|
||||
* @return {Float32Array} 3-element vector.
|
||||
* @private
|
||||
*/
|
||||
Utils.normalizeVector = v => {
|
||||
let n = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
if (n > Utils.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 = (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],
|
||||
];
|
||||
};
|
||||
export default Utils;
|
2
framework/resonator/vendor/resonance-es6/version.d.ts
vendored
Normal file
2
framework/resonator/vendor/resonance-es6/version.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
declare var _default: "1.0.0";
|
||||
export default _default;
|
24
framework/resonator/vendor/resonance-es6/version.js
vendored
Normal file
24
framework/resonator/vendor/resonance-es6/version.js
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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 version.
|
||||
* @author Andrew Allen <bitllama@google.com>
|
||||
*/
|
||||
'use strict';
|
||||
/**
|
||||
* ResonanceAudio library version
|
||||
* @type {String}
|
||||
*/
|
||||
export default '1.0.0';
|
Reference in New Issue
Block a user