JS Test Harness: Remove more link tags
[WebKit-https.git] / LayoutTests / webaudio / waveshaper.html
1 <!DOCTYPE html>
2
3 <html>
4 <head>
5 <script src="../fast/js/resources/js-test-pre.js"></script>
6 <script type="text/javascript" src="resources/audio-testing.js"></script>
7 <script type="text/javascript" src="resources/buffer-loader.js"></script>
8 </head>
9
10 <body>
11
12 <div id="description"></div>
13 <div id="console"></div>
14
15 <script>
16 description("Tests that WaveShaperNode applies proper non-linear distortion.");
17
18 var sampleRate = 44100;
19 var lengthInSeconds = 4;
20 var numberOfRenderFrames = sampleRate * lengthInSeconds;
21 var numberOfCurveFrames = 65536;
22 var inputBuffer;
23 var waveShapingCurve;
24
25 var context;
26
27 function generateInputBuffer() {
28     // Create mono input buffer.
29     var buffer = context.createBuffer(1, numberOfRenderFrames, context.sampleRate);
30     var data = buffer.getChannelData(0);
31     
32     // Generate an input vector with values from -1 -> +1 over a duration of lengthInSeconds.
33     // This exercises the full nominal input range and will touch every point of the shaping curve.
34     for (var i = 0; i < numberOfRenderFrames; ++i) {
35         var x = i / numberOfRenderFrames; // 0 -> 1
36         x = 2 * x - 1; // -1 -> +1
37         data[i] = x;
38     }
39
40     return buffer;
41 }
42
43 // Generates a symmetric curve: Math.atan(5 * x) / (0.5 * Math.PI)
44 // (with x == 0 corresponding to the center of the array)
45 // This curve is arbitrary, but would be useful in the real-world.
46 // To some extent, the actual curve we choose is not important in this test,
47 // since the input vector walks through all possible curve values.
48 function generateWaveShapingCurve() {
49     var curve = new Float32Array(numberOfCurveFrames);
50     
51     var n = numberOfCurveFrames;
52     var n2 = n / 2;
53     
54     for (var i = 0; i < n; ++i) {
55         var x = (i - n2) / n2;
56         var y = Math.atan(5 * x) / (0.5 * Math.PI);
57     }
58
59     return curve;
60 }
61
62 function checkShapedCurve(event) {
63     var buffer = event.renderedBuffer;
64
65     var inputData = inputBuffer.getChannelData(0);
66     var outputData = buffer.getChannelData(0);
67
68     var success = true;
69     
70     // Go through every sample and make sure it has been shaped exactly according to the shaping curve we gave it.
71     for (var i = 0; i < buffer.length; ++i) {
72         var input = inputData[i];
73         
74         // Calculate an index based on input -1 -> +1 with 0 being at the center of the curve data.
75         var index = Math.floor(numberOfCurveFrames * 0.5 * (input + 1));
76
77         // Clip index to the input range of the curve.
78         // This takes care of input outside of nominal range -1 -> +1
79         index = index < 0 ? 0 : index;
80         index = index > numberOfCurveFrames - 1 ? numberOfCurveFrames - 1 : index;
81
82         var expectedOutput = waveShapingCurve[index];
83         
84         var output = outputData[i];
85         
86         if (output != expectedOutput) {
87             success = false;
88             break;
89         }
90     }
91
92     if (success) {
93         testPassed("WaveShaperNode properly applied non-linear distortion.");
94     } else {
95         testFailed("WaveShaperNode did not properly apply non-linear distortion.");
96     }
97
98     finishJSTest();
99 }
100
101 function runTest() {
102     if (window.layoutTestController) {
103         layoutTestController.dumpAsText();
104         layoutTestController.waitUntilDone();
105     }
106     
107     window.jsTestIsAsync = true;
108         
109     // Create offline audio context.
110     context = new webkitAudioContext(1, numberOfRenderFrames, sampleRate);
111     
112     // source -> waveshaper -> destination
113     var source = context.createBufferSource();
114     var waveshaper = context.createWaveShaper();
115     source.connect(waveshaper);
116     waveshaper.connect(context.destination);
117
118     // Create an input test vector.
119     inputBuffer = generateInputBuffer();
120     source.buffer = inputBuffer;
121     
122     // We'll apply non-linear distortion according to this shaping curve.
123     waveShapingCurve = generateWaveShapingCurve();
124     waveshaper.curve = waveShapingCurve;
125     
126     source.noteOn(0);
127     
128     context.oncomplete = checkShapedCurve;
129     context.startRendering();
130 }
131
132 runTest();
133 successfullyParsed = true;
134
135 </script>
136
137 <script src="../fast/js/resources/js-test-post.js"></script>
138 </body>
139 </html>