140 lines
3.6 KiB
HTML
140 lines
3.6 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Test PannerNode produces output even when the even when the distance is from the listener is zero</title>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script type="text/javascript" src="webaudio.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
</head>
|
|
<body>
|
|
<pre id="test">
|
|
<script class="testbody" type="text/javascript">
|
|
|
|
const BUF_SIZE = 1024;
|
|
const sampleRate = 44100;
|
|
var types = [
|
|
"equalpower",
|
|
"HRTF"
|
|
]
|
|
|
|
async function testMono(panningModel) {
|
|
var ac = new OfflineAudioContext(2, BUF_SIZE, sampleRate);
|
|
|
|
// A sine to be used to fill the buffers
|
|
function sine(t) {
|
|
return Math.sin(440 * 2 * Math.PI * t / ac.sampleRate);
|
|
}
|
|
|
|
var monoBuffer = ac.createBuffer(1, BUF_SIZE, ac.sampleRate);
|
|
for (var i = 0; i < BUF_SIZE; ++i) {
|
|
monoBuffer.getChannelData(0)[i] = sine(i);
|
|
}
|
|
|
|
var monoSource = ac.createBufferSource();
|
|
monoSource.buffer = monoBuffer;
|
|
monoSource.start(0);
|
|
|
|
var panner = new PannerNode(ac, {
|
|
panningModel,
|
|
distanceModel: "linear",
|
|
});
|
|
monoSource.connect(panner);
|
|
|
|
var panner2 = new PannerNode(ac, {
|
|
panningModel,
|
|
distanceModel: "inverse",
|
|
});
|
|
panner.connect(panner2);
|
|
|
|
var panner3 = new PannerNode(ac, {
|
|
panningModel,
|
|
distanceModel: "exponential"
|
|
});
|
|
panner2.connect(panner3);
|
|
|
|
panner3.connect(ac.destination);
|
|
|
|
const buffer = await ac.startRendering();
|
|
|
|
if (panningModel == "equalpower") {
|
|
// Use the input buffer to compare the output. According to the spec,
|
|
// mono input at zero distance will apply gain = cos(0.5 * Math.PI / 2)
|
|
// https://webaudio.github.io/web-audio-api/#Spatialzation-equal-power-panning
|
|
const gain = Math.cos(0.5 * Math.PI / 2);
|
|
for (var i = 0; i < BUF_SIZE; ++i) {
|
|
monoBuffer.getChannelData(0)[i] = gain * monoBuffer.getChannelData(0)[i];
|
|
}
|
|
compareChannels(buffer.getChannelData(0), monoBuffer.getChannelData(0));
|
|
} else {
|
|
ok(!isChannelSilent(buffer.getChannelData(0)),
|
|
"mono panning: expect non-zero left channel");
|
|
}
|
|
// Check symmetry
|
|
compareChannels(buffer.getChannelData(0), buffer.getChannelData(1));
|
|
}
|
|
|
|
async function testStereo(panningModel) {
|
|
var ac = new OfflineAudioContext(2, BUF_SIZE, sampleRate);
|
|
|
|
// A sine to be used to fill the buffers
|
|
function sine(t) {
|
|
return Math.sin(440 * 2 * Math.PI * t / ac.sampleRate);
|
|
}
|
|
|
|
var stereoBuffer = ac.createBuffer(2, BUF_SIZE, ac.sampleRate);
|
|
for (var i = 0; i < BUF_SIZE; ++i) {
|
|
stereoBuffer.getChannelData(0)[i] = sine(i);
|
|
stereoBuffer.getChannelData(1)[i] = sine(i);
|
|
}
|
|
|
|
var stereoSource = ac.createBufferSource();
|
|
stereoSource.buffer = stereoBuffer;
|
|
stereoSource.start(0);
|
|
|
|
var panner = new PannerNode(ac, {
|
|
panningModel,
|
|
distanceModel: "linear",
|
|
});
|
|
stereoSource.connect(panner);
|
|
|
|
var panner2 = new PannerNode(ac, {
|
|
panningModel,
|
|
distanceModel: "inverse",
|
|
});
|
|
panner.connect(panner2);
|
|
|
|
var panner3 = new PannerNode(ac, {
|
|
panningModel,
|
|
distanceModel: "exponential",
|
|
});
|
|
panner2.connect(panner3);
|
|
|
|
panner3.connect(ac.destination);
|
|
|
|
const buffer = await ac.startRendering();
|
|
if (panningModel == "equalpower") {
|
|
compareBuffers(buffer, stereoBuffer);
|
|
} else {
|
|
ok(!isChannelSilent(buffer.getChannelData(0)),
|
|
"stereo panning: expect non-zero left channel");
|
|
// Check symmetry
|
|
compareChannels(buffer.getChannelData(0), buffer.getChannelData(1));
|
|
}
|
|
}
|
|
|
|
async function test(type) {
|
|
await promiseHRTFReady(sampleRate);
|
|
await testMono(type)
|
|
await testStereo(type);
|
|
}
|
|
|
|
add_task(async function() {
|
|
for (const panningModel of types) {
|
|
await test(panningModel);
|
|
}
|
|
});
|
|
|
|
</script>
|
|
</pre>
|
|
</body>
|
|
</html>
|