| Index: third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js
|
| diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js b/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js
|
| index baff5d48c5cb2ddf056bafd5e8b54ed143b67e79..c5defc3349a9fe93cb5304d4cfc02bf1ad886b58 100644
|
| --- a/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js
|
| +++ b/third_party/WebKit/LayoutTests/webaudio/resources/distance-model-testing.js
|
| @@ -19,174 +19,173 @@ var bufferSource;
|
| var panner;
|
| var position;
|
| var time;
|
| -
|
| +
|
| // For the record, these distance formulas were taken from the OpenAL
|
| // spec
|
| // (http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.pdf),
|
| // not the code. The Web Audio spec follows the OpenAL formulas.
|
|
|
| function linearDistance(panner, x, y, z) {
|
| - var distance = Math.sqrt(x * x + y * y + z * z);
|
| - distance = Math.min(distance, panner.maxDistance);
|
| - var rolloff = panner.rolloffFactor;
|
| - var gain = (1 - rolloff * (distance - panner.refDistance) / (panner.maxDistance - panner.refDistance));
|
| -
|
| - return gain;
|
| + let distance = Math.sqrt(x * x + y * y + z * z);
|
| + distance = Math.min(distance, panner.maxDistance);
|
| + let rolloff = panner.rolloffFactor;
|
| + let gain =
|
| + (1 -
|
| + rolloff * (distance - panner.refDistance) /
|
| + (panner.maxDistance - panner.refDistance));
|
| +
|
| + return gain;
|
| }
|
|
|
| function inverseDistance(panner, x, y, z) {
|
| - var distance = Math.sqrt(x * x + y * y + z * z);
|
| - distance = Math.min(distance, panner.maxDistance);
|
| - var rolloff = panner.rolloffFactor;
|
| - var gain = panner.refDistance / (panner.refDistance + rolloff * (distance - panner.refDistance));
|
| + let distance = Math.sqrt(x * x + y * y + z * z);
|
| + distance = Math.min(distance, panner.maxDistance);
|
| + let rolloff = panner.rolloffFactor;
|
| + let gain = panner.refDistance /
|
| + (panner.refDistance + rolloff * (distance - panner.refDistance));
|
|
|
| - return gain;
|
| + return gain;
|
| }
|
|
|
| function exponentialDistance(panner, x, y, z) {
|
| - var distance = Math.sqrt(x * x + y * y + z * z);
|
| - distance = Math.min(distance, panner.maxDistance);
|
| - var rolloff = panner.rolloffFactor;
|
| - var gain = Math.pow(distance / panner.refDistance, -rolloff);
|
| + let distance = Math.sqrt(x * x + y * y + z * z);
|
| + distance = Math.min(distance, panner.maxDistance);
|
| + let rolloff = panner.rolloffFactor;
|
| + let gain = Math.pow(distance / panner.refDistance, -rolloff);
|
|
|
| - return gain;
|
| + return gain;
|
| }
|
|
|
| // Map the distance model to the function that implements the model
|
| -var distanceModelFunction = {"linear": linearDistance,
|
| - "inverse": inverseDistance,
|
| - "exponential": exponentialDistance};
|
| +var distanceModelFunction = {
|
| + 'linear': linearDistance,
|
| + 'inverse': inverseDistance,
|
| + 'exponential': exponentialDistance
|
| +};
|
|
|
| function createGraph(context, distanceModel, nodeCount) {
|
| - bufferSource = new Array(nodeCount);
|
| - panner = new Array(nodeCount);
|
| - position = new Array(nodeCount);
|
| - time = new Array(nodesToCreate);
|
| -
|
| - impulse = createImpulseBuffer(context, pulseLengthFrames);
|
| -
|
| - // Create all the sources and panners.
|
| - //
|
| - // We MUST use the EQUALPOWER panning model so that we can easily
|
| - // figure out the gain introduced by the panner.
|
| - //
|
| - // We want to stay in the middle of the panning range, which means
|
| - // we want to stay on the z-axis. If we don't, then the effect of
|
| - // panning model will be much more complicated. We're not testing
|
| - // the panner, but the distance model, so we want the panner effect
|
| - // to be simple.
|
| - //
|
| - // The panners are placed at a uniform intervals between the panner
|
| - // reference distance and the panner max distance. The source is
|
| - // also started at regular intervals.
|
| - for (var k = 0; k < nodeCount; ++k) {
|
| - bufferSource[k] = context.createBufferSource();
|
| - bufferSource[k].buffer = impulse;
|
| -
|
| - panner[k] = context.createPanner();
|
| - panner[k].panningModel = "equalpower";
|
| - panner[k].distanceModel = distanceModel;
|
| -
|
| - var distanceStep = (panner[k].maxDistance - panner[k].refDistance) / nodeCount;
|
| - position[k] = distanceStep * k + panner[k].refDistance;
|
| - panner[k].setPosition(0, 0, position[k]);
|
| -
|
| - bufferSource[k].connect(panner[k]);
|
| - panner[k].connect(context.destination);
|
| -
|
| - time[k] = k * timeStep;
|
| - bufferSource[k].start(time[k]);
|
| - }
|
| + bufferSource = new Array(nodeCount);
|
| + panner = new Array(nodeCount);
|
| + position = new Array(nodeCount);
|
| + time = new Array(nodesToCreate);
|
| +
|
| + impulse = createImpulseBuffer(context, pulseLengthFrames);
|
| +
|
| + // Create all the sources and panners.
|
| + //
|
| + // We MUST use the EQUALPOWER panning model so that we can easily
|
| + // figure out the gain introduced by the panner.
|
| + //
|
| + // We want to stay in the middle of the panning range, which means
|
| + // we want to stay on the z-axis. If we don't, then the effect of
|
| + // panning model will be much more complicated. We're not testing
|
| + // the panner, but the distance model, so we want the panner effect
|
| + // to be simple.
|
| + //
|
| + // The panners are placed at a uniform intervals between the panner
|
| + // reference distance and the panner max distance. The source is
|
| + // also started at regular intervals.
|
| + for (let k = 0; k < nodeCount; ++k) {
|
| + bufferSource[k] = context.createBufferSource();
|
| + bufferSource[k].buffer = impulse;
|
| +
|
| + panner[k] = context.createPanner();
|
| + panner[k].panningModel = 'equalpower';
|
| + panner[k].distanceModel = distanceModel;
|
| +
|
| + let distanceStep =
|
| + (panner[k].maxDistance - panner[k].refDistance) / nodeCount;
|
| + position[k] = distanceStep * k + panner[k].refDistance;
|
| + panner[k].setPosition(0, 0, position[k]);
|
| +
|
| + bufferSource[k].connect(panner[k]);
|
| + panner[k].connect(context.destination);
|
| +
|
| + time[k] = k * timeStep;
|
| + bufferSource[k].start(time[k]);
|
| + }
|
| }
|
|
|
| // distanceModel should be the distance model string like
|
| // "linear", "inverse", or "exponential".
|
| function createTestAndRun(context, distanceModel, should) {
|
| - // To test the distance models, we create a number of panners at
|
| - // uniformly spaced intervals on the z-axis. Each of these are
|
| - // started at equally spaced time intervals. After rendering the
|
| - // signals, we examine where each impulse is located and the
|
| - // attenuation of the impulse. The attenuation is compared
|
| - // against our expected attenuation.
|
| + // To test the distance models, we create a number of panners at
|
| + // uniformly spaced intervals on the z-axis. Each of these are
|
| + // started at equally spaced time intervals. After rendering the
|
| + // signals, we examine where each impulse is located and the
|
| + // attenuation of the impulse. The attenuation is compared
|
| + // against our expected attenuation.
|
|
|
| - createGraph(context, distanceModel, nodesToCreate);
|
| + createGraph(context, distanceModel, nodesToCreate);
|
|
|
| - return context.startRendering()
|
| - .then(buffer => checkDistanceResult(buffer, distanceModel, should));
|
| + return context.startRendering().then(
|
| + buffer => checkDistanceResult(buffer, distanceModel, should));
|
| }
|
|
|
| // The gain caused by the EQUALPOWER panning model, if we stay on the
|
| // z axis, with the default orientations.
|
| function equalPowerGain() {
|
| - return Math.SQRT1_2;
|
| + return Math.SQRT1_2;
|
| }
|
|
|
| function checkDistanceResult(renderedBuffer, model, should) {
|
| - renderedData = renderedBuffer.getChannelData(0);
|
| -
|
| - // The max allowed error between the actual gain and the expected
|
| - // value. This is determined experimentally. Set to 0 to see
|
| - // what the actual errors are.
|
| - var maxAllowedError = 3.3e-6;
|
| -
|
| - var success = true;
|
| -
|
| - // Number of impulses we found in the rendered result.
|
| - var impulseCount = 0;
|
| -
|
| - // Maximum relative error in the gain of the impulses.
|
| - var maxError = 0;
|
| -
|
| - // Array of locations of the impulses that were not at the
|
| - // expected location. (Contains the actual and expected frame
|
| - // of the impulse.)
|
| - var impulsePositionErrors = new Array();
|
| -
|
| - // Step through the rendered data to find all the non-zero points
|
| - // so we can find where our distance-attenuated impulses are.
|
| - // These are tested against the expected attenuations at that
|
| - // distance.
|
| - for (var k = 0; k < renderedData.length; ++k) {
|
| - if (renderedData[k] != 0) {
|
| - // Convert from string to index.
|
| - var distanceFunction = distanceModelFunction[model];
|
| - var expected =
|
| - distanceFunction(panner[impulseCount], 0, 0,
|
| - position[impulseCount]);
|
| -
|
| - // Adjust for the center-panning of the EQUALPOWER panning
|
| - // model that we're using.
|
| - expected *= equalPowerGain();
|
| -
|
| - var error =
|
| - Math.abs(renderedData[k] - expected) / Math.abs(expected);
|
| -
|
| - maxError = Math.max(maxError, Math.abs(error));
|
| -
|
| - // Keep track of any impulses that aren't where we expect them
|
| - // to be.
|
| - var expectedOffset = timeToSampleFrame(time[impulseCount],
|
| - sampleRate);
|
| - if (k != expectedOffset) {
|
| - impulsePositionErrors.push({
|
| - actual: k,
|
| - expected: expectedOffset
|
| - });
|
| - }
|
| - ++impulseCount;
|
| - }
|
| - }
|
| - should(impulseCount, "Number of impulses")
|
| - .beEqualTo(nodesToCreate);
|
| -
|
| - should(maxError, "Max error in distance gains")
|
| - .beLessThanOrEqualTo(maxAllowedError);
|
| -
|
| - // Display any timing errors that we found.
|
| - if (impulsePositionErrors.length > 0) {
|
| - let actual = impulsePositionErrors.map(x => x.actual);
|
| - let expected = impulsePositionErrors.map(x => x.expected);
|
| - should(actual, "Actual impulse positions found")
|
| - .beEqualToArray(expected);
|
| + renderedData = renderedBuffer.getChannelData(0);
|
| +
|
| + // The max allowed error between the actual gain and the expected
|
| + // value. This is determined experimentally. Set to 0 to see
|
| + // what the actual errors are.
|
| + let maxAllowedError = 3.3e-6;
|
| +
|
| + let success = true;
|
| +
|
| + // Number of impulses we found in the rendered result.
|
| + let impulseCount = 0;
|
| +
|
| + // Maximum relative error in the gain of the impulses.
|
| + let maxError = 0;
|
| +
|
| + // Array of locations of the impulses that were not at the
|
| + // expected location. (Contains the actual and expected frame
|
| + // of the impulse.)
|
| + let impulsePositionErrors = new Array();
|
| +
|
| + // Step through the rendered data to find all the non-zero points
|
| + // so we can find where our distance-attenuated impulses are.
|
| + // These are tested against the expected attenuations at that
|
| + // distance.
|
| + for (let k = 0; k < renderedData.length; ++k) {
|
| + if (renderedData[k] != 0) {
|
| + // Convert from string to index.
|
| + let distanceFunction = distanceModelFunction[model];
|
| + let expected =
|
| + distanceFunction(panner[impulseCount], 0, 0, position[impulseCount]);
|
| +
|
| + // Adjust for the center-panning of the EQUALPOWER panning
|
| + // model that we're using.
|
| + expected *= equalPowerGain();
|
| +
|
| + let error = Math.abs(renderedData[k] - expected) / Math.abs(expected);
|
| +
|
| + maxError = Math.max(maxError, Math.abs(error));
|
| +
|
| + // Keep track of any impulses that aren't where we expect them
|
| + // to be.
|
| + let expectedOffset = timeToSampleFrame(time[impulseCount], sampleRate);
|
| + if (k != expectedOffset) {
|
| + impulsePositionErrors.push({actual: k, expected: expectedOffset});
|
| + }
|
| + ++impulseCount;
|
| }
|
| + }
|
| + should(impulseCount, 'Number of impulses').beEqualTo(nodesToCreate);
|
| +
|
| + should(maxError, 'Max error in distance gains')
|
| + .beLessThanOrEqualTo(maxAllowedError);
|
| +
|
| + // Display any timing errors that we found.
|
| + if (impulsePositionErrors.length > 0) {
|
| + let actual = impulsePositionErrors.map(x => x.actual);
|
| + let expected = impulsePositionErrors.map(x => x.expected);
|
| + should(actual, 'Actual impulse positions found').beEqualToArray(expected);
|
| + }
|
| }
|
|
|