mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
178 lines
6.9 KiB
HTML
178 lines
6.9 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<title>Test k-rate AudioParams of PannerNode</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/webaudio/resources/audit-util.js"></script>
|
|
<script src="/webaudio/resources/audit.js"></script>
|
|
<script src="automation-rate-testing.js"></script>
|
|
</head>
|
|
|
|
<body>
|
|
<script>
|
|
let audit = Audit.createTaskRunner();
|
|
|
|
// Define a test where we verify that a k-rate audio param produces
|
|
// different results from an a-rate audio param for each of the audio
|
|
// params of a biquad.
|
|
//
|
|
// Each entry gives the name of the AudioParam, an initial value to be
|
|
// used with setValueAtTime, and a final value to be used with
|
|
// linearRampToValueAtTime. (See |doTest| for details as well.)
|
|
|
|
[{name: 'positionX', initial: 0, final: 1000},
|
|
{name: 'positionY', initial: 0, final: 1000},
|
|
{name: 'orientationX', initial: 1, final: 10},
|
|
{name: 'orientationY', initial: 1, final: 10},
|
|
{name: 'orientationZ', initial: 1, final: 10},
|
|
].forEach(paramProperty => {
|
|
audit.define('Panner k-rate ' + paramProperty.name, (task, should) => {
|
|
// Arbitrary sample rate and duration.
|
|
let sampleRate = 8000;
|
|
let testDuration = 5 * 128 / sampleRate;
|
|
let context = new OfflineAudioContext({
|
|
numberOfChannels: 3,
|
|
sampleRate: sampleRate,
|
|
length: testDuration * sampleRate
|
|
});
|
|
|
|
doTest(context, should, {
|
|
sourceNodeName: 'ConstantSourceNode',
|
|
verifyPieceWiseConstant: true,
|
|
nodeName: 'PannerNode',
|
|
// Make the source directional so orientation matters, and set some
|
|
// defaults for the position and orientation so that we're not on an
|
|
// axis where the azimuth and elevation might be constant when
|
|
// moving one of the AudioParams.
|
|
nodeOptions: {
|
|
distanceModel: 'inverse',
|
|
coneOuterAngle: 360,
|
|
coneInnerAngle: 0,
|
|
positionX: 1,
|
|
positionY: 1,
|
|
positionZ: 1,
|
|
orientationX: 0,
|
|
orientationY: 1,
|
|
orientationZ: 1
|
|
},
|
|
prefix: `k-rate ${paramProperty.name}`,
|
|
// Just set the frequency to k-rate
|
|
rateSettings: [
|
|
{name: paramProperty.name, value: 'k-rate'},
|
|
],
|
|
// Automate just the given AudioParam
|
|
automations: [{
|
|
name: paramProperty.name,
|
|
methods: [
|
|
{name: 'setValueAtTime', options: [paramProperty.initial, 0]}, {
|
|
name: 'linearRampToValueAtTime',
|
|
options: [paramProperty.final, testDuration]
|
|
}
|
|
]
|
|
}]
|
|
}).then(() => task.done());
|
|
});
|
|
});
|
|
|
|
// Test k-rate automation of the listener. The intial and final
|
|
// automation values are pretty arbitrary, except that they should be such
|
|
// that the panner and listener produces non-constant output.
|
|
[{name: 'positionX', initial: [1, 0], final: [1000, 1]},
|
|
{name: 'positionY', initial: [1, 0], final: [1000, 1]},
|
|
{name: 'positionZ', initial: [1, 0], final: [1000, 1]},
|
|
{name: 'forwardX', initial: [-1, 0], final: [1, 1]},
|
|
{name: 'forwardY', initial: [-1, 0], final: [1, 1]},
|
|
{name: 'forwardZ', initial: [-1, 0], final: [1, 1]},
|
|
{name: 'upX', initial: [-1, 0], final: [1000, 1]},
|
|
{name: 'upY', initial: [-1, 0], final: [1000, 1]},
|
|
{name: 'upZ', initial: [-1, 0], final: [1000, 1]},
|
|
].forEach(paramProperty => {
|
|
audit.define(
|
|
'Listener k-rate ' + paramProperty.name, (task, should) => {
|
|
// Arbitrary sample rate and duration.
|
|
let sampleRate = 8000;
|
|
let testDuration = 5 * 128 / sampleRate;
|
|
let context = new OfflineAudioContext({
|
|
numberOfChannels: 1,
|
|
sampleRate: sampleRate,
|
|
length: testDuration * sampleRate
|
|
});
|
|
|
|
doListenerTest(context, should, {
|
|
param: paramProperty.name,
|
|
initial: paramProperty.initial,
|
|
final: paramProperty.final
|
|
}).then(() => task.done());
|
|
});
|
|
});
|
|
|
|
audit.run();
|
|
|
|
function doListenerTest(context, should, options) {
|
|
let src = new ConstantSourceNode(context);
|
|
let panner = new PannerNode(context, {
|
|
distanceModel: 'inverse',
|
|
coneOuterAngle: 360,
|
|
coneInnerAngle: 10,
|
|
positionX: 10,
|
|
positionY: 10,
|
|
positionZ: 10,
|
|
orientationX: 1,
|
|
orientationY: 1,
|
|
orientationZ: 1
|
|
});
|
|
|
|
src.connect(panner).connect(context.destination);
|
|
|
|
src.start();
|
|
|
|
let listener = context.listener;
|
|
|
|
// Set listener properties to "random" values so that motion on one of
|
|
// the attributes actually changes things relative to the panner
|
|
// location. And the up and forward directions should have a simple
|
|
// relationship between them.
|
|
listener.positionX.value = -1;
|
|
listener.positionY.value = 1;
|
|
listener.positionZ.value = -1;
|
|
listener.forwardX.value = -1;
|
|
listener.forwardY.value = 1;
|
|
listener.forwardZ.value = -1;
|
|
// Make the up vector not parallel or perpendicular to the forward and
|
|
// position vectors so that automations of the up vector produce
|
|
// noticeable differences.
|
|
listener.upX.value = 1;
|
|
listener.upY.value = 1;
|
|
listener.upZ.value = 2;
|
|
|
|
let audioParam = listener[options.param];
|
|
audioParam.automationRate = 'k-rate';
|
|
|
|
let prefix = `Listener ${options.param}`;
|
|
should(audioParam.automationRate, prefix + '.automationRate')
|
|
.beEqualTo('k-rate');
|
|
should(() => {
|
|
audioParam.setValueAtTime(...options.initial);
|
|
}, prefix + `.setValueAtTime(${options.initial})`).notThrow();
|
|
should(() => {
|
|
audioParam.linearRampToValueAtTime(...options.final);
|
|
}, prefix + `.linearRampToValueAtTime(${options.final})`).notThrow();
|
|
|
|
return context.startRendering().then(renderedBuffer => {
|
|
let prefix = `Listener k-rate ${options.param}: `;
|
|
let output = renderedBuffer.getChannelData(0);
|
|
// Sanity check that the output isn't constant.
|
|
should(output, prefix + `Output`).notBeConstantValueOf(output[0]);
|
|
|
|
// Verify that the output is constant over each render quantum
|
|
for (let k = 0; k < output.length; k += 128) {
|
|
should(
|
|
output.slice(k, k + 128), prefix + `Output [${k}, ${k + 127}]`)
|
|
.beConstantValueOf(output[k]);
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|