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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
<!doctype html>
<html>
<head>
<title>WaveShaperNode interface - Curve tests | WebAudio</title>
<script type="text/javascript" src="/resources/testharness.js"></script>
<script type="text/javascript" src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="log">
</div>
<script type="text/javascript">
var sampleRate=44100.0;
var tolerance=0.01;
/*
Testing that -1, 0 and +1 map correctly to curve (with 1:1 correlation)
=======================================================================
From the specification:
The input signal is nominally within the range -1 -> +1.
Each input sample within this range will index into the shaping curve with a signal level of zero corresponding
to the center value of the curve array.
*/
(function() {
var threeElementCurve=[2.0, -3.0, 4.0];
var inputData=[-1.0, 0, 1.0];
var expectedData=[2.0, -3.0, 4.0];
executeTest(threeElementCurve, inputData, expectedData, "Testing that -1, 0 and +1 map correctly to curve (with 1:1 correlation)");
})();
/*
Testing interpolation (where inputs don't correlate directly to curve elements)
===============================================================================
From the specification:
The implementation must perform linear interpolation between adjacent points in the curve.
*/
(function() {
var threeElementCurve=[2.0, -3.0, 4.0];
var inputData=[-0.5, +0.5, +0.75];
var expectedData=[-0.5, +0.5, +2.25];
executeTest(threeElementCurve, inputData, expectedData, "Testing interpolation (where inputs don't correlate directly to curve elements)");
})();
/*
Testing out-of-range inputs (should be mapped to the first/last elements of the curve)
======================================================================================
From the specification:
Any sample value less than -1 will correspond to the first value in the curve array.
Any sample value greater than +1 will correspond to the last value in the curve array.
*/
(function() {
var threeElementCurve=[2.0, -3.0, 4.0];
var inputData=[-1.5, +1.5];
var expectedData=[2.0, 4.0];
executeTest(threeElementCurve, inputData, expectedData, "Testing out-of-range inputs (should be mapped to the first/last elements of the curve)");
})();
/*
Testing a 2-element curve (does not have a middle element)
==========================================================
From the specification:
Each input sample within this range will index into the shaping curve with a signal level of zero corresponding
to the center value of the curve array.
The implementation must perform linear interpolation between adjacent points in the curve.
*/
(function() {
var twoElementCurve=[2.0, -2.0];
var inputData=[-1.0, 0, 1.0];
var expectedData=[2.0, 0.0, -2.0];
executeTest(twoElementCurve, inputData, expectedData, "Testing a 2-element curve (does not have a middle element)");
})();
/*
Testing a 4-element curve (does not have a middle element)
==========================================================
From the specification:
Each input sample within this range will index into the shaping curve with a signal level of zero corresponding
to the center value of the curve array.
The implementation must perform linear interpolation between adjacent points in the curve.
*/
(function() {
var fourElementCurve=[1.0, 2.0, 4.0, 7.0];
var inputData=[-1.0, 0, 1.0];
var expectedData=[1.0, 3.0, 7.0];
executeTest(fourElementCurve, inputData, expectedData, "Testing a 4-element curve (does not have a middle element)");
})();
/*
Testing a huge curve
====================
From the specification:
Each input sample within this range will index into the shaping curve with a signal level of zero corresponding
to the center value of the curve array.
*/
(function() {
var bigCurve=[];
for(var i=0;i<=60000;i++) { bigCurve.push(i/3.5435); }
var inputData=[-1.0, 0, 1.0];
var expectedData=[bigCurve[0], bigCurve[30000], bigCurve[60000]];
executeTest(bigCurve, inputData, expectedData, "Testing a huge curve");
})();
/*
Testing single-element curve (boundary condition)
=================================================
From the specification:
Each input sample within this range will index into the shaping curve with a signal level of zero corresponding
to the center value of the curve array.
Any sample value less than -1 will correspond to the first value in the curve array.
Any sample value greater than +1 will correspond to the last value in the curve array.
The implementation must perform linear interpolation between adjacent points in the curve.
*/
/*
Testing null curve (should return input values)
===============================================
From the specification:
Initially the curve attribute is null, which means that the WaveShaperNode will pass its input to its output
without modification.
*/
(function() {
var inputData=[-1.0, 0, 1.0, 2.0];
var expectedData=[-1.0, 0.0, 1.0, 2.0];
executeTest(null, inputData, expectedData, "Testing null curve (should return input values)");
})();
/**
* Function that does the actual testing (using an asynchronous test).
* @param {?Array.<number>} curveData - Array containing values for the WaveShaper curve.
* @param {!Array.<number>} inputData - Array containing values for the input stream.
* @param {!Array.<number>} expectedData - Array containing expected results for each of the corresponding inputs.
* @param {!string} testName - Name of the test case.
*/
function executeTest(curveData, inputData, expectedData, testName) {
var stTest=async_test("WaveShaperNode - "+testName);
stTest.step(function() {
// Create offline audio context.
var ac=new OfflineAudioContext(1, inputData.length, sampleRate);
// Create the WaveShaper and its curve.
var waveShaper=ac.createWaveShaper();
if(curveData!=null) {
var curve=new Float32Array(curveData.length);
for(var i=0;i<curveData.length;i++) { curve[i]=curveData[i]; }
waveShaper.curve=curve;
}
waveShaper.connect(ac.destination);
// Create buffer containing the input values.
var inputBuffer=ac.createBuffer(1, Math.max(inputData.length, 2), sampleRate);
var d=inputBuffer.getChannelData(0);
for(var i=0;i<inputData.length;i++) { d[i]=inputData[i]; }
// Play the input buffer through the WaveShaper.
var src=ac.createBufferSource();
src.buffer=inputBuffer;
src.connect(waveShaper);
src.start();
// Test the outputs match the expected values.
ac.oncomplete=stTest.step_func_done(function(ev) {
var d=ev.renderedBuffer.getChannelData(0);
for(var i=0;i<expectedData.length;i++) {
var curveText="null";
if(curve!=null) {
if(curveData.length<20) {
curveText=curveData.join(",");
} else {
curveText="TooBigToDisplay ("+(curveData.length-1)+" elements)";
}
}
var comment="Input="+inputData[i]+", Curve=["+curveText+"] >>> ";
assert_approx_equals(d[i], expectedData[i], tolerance, comment);
}
});
ac.startRendering();
});
}
</script>
</body>
</html>
|