1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
<!DOCTYPE html>
<title>Test normalization of convolution buffers</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
// Constants from
// https://www.w3.org/TR/2015/WD-webaudio-20151208/#widl-ConvolverNode-normalize
const GainCalibration = 0.00125;
const GainCalibrationSampleRate = 44100;
const sampleRate = GainCalibrationSampleRate;
const LENGTH = 12800;
// tolerate 16-bit math.
const EPSILON = 1.0 / Math.pow(2, 15);
function test_normalization_via_response_concat(delayIndex)
{
var context = new OfflineAudioContext(1, LENGTH, sampleRate);
var impulse = context.createBuffer(1, 1, sampleRate);
impulse.getChannelData(0)[0] = 1.0;
var source = context.createBufferSource();
source.buffer = impulse;
source.start(0);
// Construct a set of adjacent responses in such a way that, when each is
// convolved with the impulse, they can be merged to produce a constant.
// The 5/4 ratio provides a range of lengths with different offsets within
// blocks.
var i = 0;
for (var responseEnd = 1;
i < LENGTH;
responseEnd = Math.floor((5 * responseEnd) / 4) + 1) {
var responseBuffer = context.createBuffer(1, responseEnd, sampleRate);
var response = responseBuffer.getChannelData(0);
var responseStart = i;
// The values in the response should be normalized, and so the output
// should not be dependent on the value. Pick a changing value to test
// this.
var value = responseStart + 1;
for (; i < responseEnd; ++i) {
response[i] = value;
}
var convolver = context.createConvolver();
convolver.normalize = true;
convolver.buffer = responseBuffer;
convolver.connect(context.destination);
// Undo the normalization calibration by scaling the impulse so as to
// expect unit pulse output from the convolver.
var gain = context.createGain();
gain.gain.value =
Math.sqrt((responseEnd - responseStart) / responseEnd) / GainCalibration;
gain.connect(convolver);
source.connect(gain);
}
return context.startRendering().
then((buffer) => {
var output = buffer.getChannelData(0);
var max = output[0];
var maxIndex = 0;
var min = max;
var minIndex = 0;
for (var i = 1; i < buffer.length; ++i) {
if (output[i] > max) {
max = output[i];
maxIndex = i;
} else if (output[i] < min) {
min = output[i];
minIndex = i;
}
}
assert_approx_equals(output[maxIndex], 1.0, EPSILON,
"max output at " + maxIndex);
assert_approx_equals(output[minIndex], 1.0, EPSILON,
"min output at " + minIndex);
});
}
promise_test(test_normalization_via_response_concat,
"via response concatenation");
</script>
|