Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(374)

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/resources/waveshaper-testing.js

Issue 2895963003: Apply layout-test-tidy to LayoutTests/webaudio (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 var context; 1 var context;
2 var lengthInSeconds = 2; 2 var lengthInSeconds = 2;
3 3
4 // Skip this many frames before comparing against reference to allow 4 // Skip this many frames before comparing against reference to allow
5 // a steady-state to be reached in the up-sampling filters. 5 // a steady-state to be reached in the up-sampling filters.
6 var filterStabilizeSkipFrames = 2048; 6 var filterStabilizeSkipFrames = 2048;
7 7
8 var numberOfCurveFrames = 65536; 8 var numberOfCurveFrames = 65536;
9 var waveShapingCurve; 9 var waveShapingCurve;
10 10
11 var waveshaper; 11 var waveshaper;
12 12
13 // FIXME: test at more frequencies. 13 // FIXME: test at more frequencies.
14 // When using the up-sampling filters (2x, 4x) any significant aliasing componen ts 14 // When using the up-sampling filters (2x, 4x) any significant aliasing
15 // should be at very high frequencies near Nyquist. These tests could be improv ed 15 // components should be at very high frequencies near Nyquist. These tests
16 // to allow for a higher acceptable amount of aliasing near Nyquist, but then 16 // could be improved to allow for a higher acceptable amount of aliasing near
17 // become more stringent for lower frequencies. 17 // Nyquist, but then become more stringent for lower frequencies.
18 18
19 // These test parameters are set in runWaveShaperOversamplingTest(). 19 // These test parameters are set in runWaveShaperOversamplingTest().
20 var sampleRate; 20 var sampleRate;
21 var nyquist; 21 var nyquist;
22 var oversample; 22 var oversample;
23 var fundamentalFrequency; 23 var fundamentalFrequency;
24 var acceptableAliasingThresholdDecibels; 24 var acceptableAliasingThresholdDecibels;
25 25
26 var kScale = 0.25; 26 var kScale = 0.25;
27 27
28 // Chebyshev Polynomials. 28 // Chebyshev Polynomials.
29 // Given an input sinusoid, returns an output sinusoid of the given frequency mu ltiple. 29 // Given an input sinusoid, returns an output sinusoid of the given frequency
30 function T0(x) { return 1; } 30 // multiple.
31 function T1(x) { return x; } 31 function T0(x) {
32 function T2(x) { return 2*x*x - 1; } 32 return 1;
33 function T3(x) { return 4*x*x*x - 3*x; } 33 }
34 function T4(x) { return 8*x*x*x*x - 8*x*x + 1; } 34 function T1(x) {
35 return x;
36 }
37 function T2(x) {
38 return 2 * x * x - 1;
39 }
40 function T3(x) {
41 return 4 * x * x * x - 3 * x;
42 }
43 function T4(x) {
44 return 8 * x * x * x * x - 8 * x * x + 1;
45 }
35 46
36 function generateWaveShapingCurve() { 47 function generateWaveShapingCurve() {
37 var n = 65536; 48 let n = 65536;
38 var n2 = n / 2; 49 let n2 = n / 2;
39 var curve = new Float32Array(n); 50 let curve = new Float32Array(n);
40 51
41 // The shaping curve uses Chebyshev Polynomial such that an input sinusoid 52 // The shaping curve uses Chebyshev Polynomial such that an input sinusoid
42 // at frequency f will generate an output of four sinusoids of frequencies: 53 // at frequency f will generate an output of four sinusoids of frequencies:
43 // f, 2*f, 3*f, 4*f 54 // f, 2*f, 3*f, 4*f
44 // each of which is scaled. 55 // each of which is scaled.
45 for (var i = 0; i < n; ++i) { 56 for (let i = 0; i < n; ++i) {
46 var x = (i - n2) / n2; 57 let x = (i - n2) / n2;
47 var y = kScale * (T1(x) + T2(x) + T3(x) + T4(x)); 58 let y = kScale * (T1(x) + T2(x) + T3(x) + T4(x));
48 curve[i] = y; 59 curve[i] = y;
49 } 60 }
50 61
51 return curve; 62 return curve;
52 } 63 }
53 64
54 function checkShapedCurve(buffer, should) { 65 function checkShapedCurve(buffer, should) {
55 var outputData = buffer.getChannelData(0); 66 let outputData = buffer.getChannelData(0);
56 var n = buffer.length; 67 let n = buffer.length;
57 68
58 // The WaveShaperNode will have a processing latency if oversampling is used , 69 // The WaveShaperNode will have a processing latency if oversampling is used,
59 // so we should account for it. 70 // so we should account for it.
60 71
61 // FIXME: .latency should be exposed as an attribute of the node 72 // FIXME: .latency should be exposed as an attribute of the node
62 // var waveShaperLatencyFrames = waveshaper.latency * sampleRate; 73 // var waveShaperLatencyFrames = waveshaper.latency * sampleRate;
63 // But for now we'll use the hard-coded values corresponding to the actual l atencies: 74 // But for now we'll use the hard-coded values corresponding to the actual
64 var waveShaperLatencyFrames = 0; 75 // latencies:
65 if (oversample == "2x") 76 let waveShaperLatencyFrames = 0;
66 waveShaperLatencyFrames = 128; 77 if (oversample == '2x')
67 else if (oversample == "4x") 78 waveShaperLatencyFrames = 128;
68 waveShaperLatencyFrames = 192; 79 else if (oversample == '4x')
80 waveShaperLatencyFrames = 192;
69 81
70 var worstDeltaInDecibels = -1000; 82 let worstDeltaInDecibels = -1000;
71 83
72 for (var i = waveShaperLatencyFrames; i < n; ++i) { 84 for (let i = waveShaperLatencyFrames; i < n; ++i) {
73 var actual = outputData[i]; 85 let actual = outputData[i];
74 86
75 // Account for the expected processing latency. 87 // Account for the expected processing latency.
76 var j = i - waveShaperLatencyFrames; 88 let j = i - waveShaperLatencyFrames;
77 89
78 // Compute reference sinusoids. 90 // Compute reference sinusoids.
79 var phaseInc = 2 * Math.PI * fundamentalFrequency / sampleRate; 91 let phaseInc = 2 * Math.PI * fundamentalFrequency / sampleRate;
80 92
81 // Generate an idealized reference based on the four generated frequenci es truncated 93 // Generate an idealized reference based on the four generated frequencies
82 // to the Nyquist rate. Ideally, we'd like the waveshaper's oversamplin g to perfectly 94 // truncated to the Nyquist rate. Ideally, we'd like the waveshaper's
83 // remove all frequencies above Nyquist to avoid aliasing. In reality t he oversampling filters are not 95 // oversampling to perfectly remove all frequencies above Nyquist to avoid
84 // quite perfect, so there will be a (hopefully small) amount of aliasin g. We should 96 // aliasing. In reality the oversampling filters are not quite perfect, so
85 // be close to the ideal. 97 // there will be a (hopefully small) amount of aliasing. We should be close
86 var reference = 0; 98 // to the ideal.
99 let reference = 0;
87 100
88 // Sum in fundamental frequency. 101 // Sum in fundamental frequency.
89 if (fundamentalFrequency < nyquist) 102 if (fundamentalFrequency < nyquist)
90 reference += Math.sin(phaseInc * j); 103 reference += Math.sin(phaseInc * j);
91 104
92 // Note that the phase of each of the expected generated harmonics is di fferent. 105 // Note that the phase of each of the expected generated harmonics is
93 if (fundamentalFrequency * 2 < nyquist) 106 // different.
94 reference += -Math.cos(phaseInc * j * 2); 107 if (fundamentalFrequency * 2 < nyquist)
95 if (fundamentalFrequency * 3 < nyquist) 108 reference += -Math.cos(phaseInc * j * 2);
96 reference += -Math.sin(phaseInc * j * 3); 109 if (fundamentalFrequency * 3 < nyquist)
97 if (fundamentalFrequency * 4 < nyquist) 110 reference += -Math.sin(phaseInc * j * 3);
98 reference += Math.cos(phaseInc * j * 4); 111 if (fundamentalFrequency * 4 < nyquist)
112 reference += Math.cos(phaseInc * j * 4);
99 113
100 // Scale the reference the same as the waveshaping curve itself. 114 // Scale the reference the same as the waveshaping curve itself.
101 reference *= kScale; 115 reference *= kScale;
102 116
103 var delta = Math.abs(actual - reference); 117 let delta = Math.abs(actual - reference);
104 var deltaInDecibels = delta > 0 ? 20 * Math.log(delta)/Math.log(10) : -2 00; 118 let deltaInDecibels =
119 delta > 0 ? 20 * Math.log(delta) / Math.log(10) : -200;
105 120
106 if (j >= filterStabilizeSkipFrames) { 121 if (j >= filterStabilizeSkipFrames) {
107 if (deltaInDecibels > worstDeltaInDecibels) { 122 if (deltaInDecibels > worstDeltaInDecibels) {
108 worstDeltaInDecibels = deltaInDecibels; 123 worstDeltaInDecibels = deltaInDecibels;
109 } 124 }
110 }
111 } 125 }
126 }
112 127
113 // console.log("worstDeltaInDecibels: " + worstDeltaInDecibels); 128 // console.log("worstDeltaInDecibels: " + worstDeltaInDecibels);
114 129
115 should(worstDeltaInDecibels, oversample + 130 should(
116 " WaveshaperNode oversampling error (in dBFS)") 131 worstDeltaInDecibels,
117 .beLessThan(acceptableAliasingThresholdDecibels); 132 oversample + ' WaveshaperNode oversampling error (in dBFS)')
133 .beLessThan(acceptableAliasingThresholdDecibels);
118 } 134 }
119 135
120 function createImpulseBuffer(context, sampleFrameLength) { 136 function createImpulseBuffer(context, sampleFrameLength) {
121 var audioBuffer = context.createBuffer(1, sampleFrameLength, context.sampleR ate); 137 let audioBuffer =
122 var n = audioBuffer.length; 138 context.createBuffer(1, sampleFrameLength, context.sampleRate);
123 var dataL = audioBuffer.getChannelData(0); 139 let n = audioBuffer.length;
140 let dataL = audioBuffer.getChannelData(0);
124 141
125 for (var k = 0; k < n; ++k) 142 for (let k = 0; k < n; ++k)
126 dataL[k] = 0; 143 dataL[k] = 0;
127 144
128 dataL[0] = 1; 145 dataL[0] = 1;
129 146
130 return audioBuffer; 147 return audioBuffer;
131 } 148 }
132 149
133 function runWaveShaperOversamplingTest(testParams) { 150 function runWaveShaperOversamplingTest(testParams) {
134 sampleRate = testParams.sampleRate; 151 sampleRate = testParams.sampleRate;
135 nyquist = 0.5 * sampleRate; 152 nyquist = 0.5 * sampleRate;
136 oversample = testParams.oversample; 153 oversample = testParams.oversample;
137 fundamentalFrequency = testParams.fundamentalFrequency; 154 fundamentalFrequency = testParams.fundamentalFrequency;
138 acceptableAliasingThresholdDecibels = testParams.acceptableAliasingThreshold Decibels; 155 acceptableAliasingThresholdDecibels =
156 testParams.acceptableAliasingThresholdDecibels;
139 157
140 let audit = Audit.createTaskRunner(); 158 let audit = Audit.createTaskRunner();
141 159
142 audit.define({ 160 audit.define(
143 label: "test", 161 {label: 'test', description: testParams.description},
144 description: testParams.description 162 function(task, should) {
145 }, function (task, should) {
146 163
147 // Create offline audio context. 164 // Create offline audio context.
148 var numberOfRenderFrames = sampleRate * lengthInSeconds; 165 let numberOfRenderFrames = sampleRate * lengthInSeconds;
149 context = new OfflineAudioContext(1, numberOfRenderFrames, 166 context = new OfflineAudioContext(1, numberOfRenderFrames, sampleRate);
150 sampleRate);
151 167
152 // source -> waveshaper -> destination 168 // source -> waveshaper -> destination
153 var source = context.createBufferSource(); 169 let source = context.createBufferSource();
154 source.buffer = createToneBuffer(context, fundamentalFrequency, 170 source.buffer =
155 lengthInSeconds, 1); 171 createToneBuffer(context, fundamentalFrequency, lengthInSeconds, 1);
156 172
157 // Apply a non-linear distortion curve. 173 // Apply a non-linear distortion curve.
158 waveshaper = context.createWaveShaper(); 174 waveshaper = context.createWaveShaper();
159 waveshaper.curve = generateWaveShapingCurve(); 175 waveshaper.curve = generateWaveShapingCurve();
160 waveshaper.oversample = oversample; 176 waveshaper.oversample = oversample;
161 177
162 source.connect(waveshaper); 178 source.connect(waveshaper);
163 waveshaper.connect(context.destination); 179 waveshaper.connect(context.destination);
164 180
165 source.start(0); 181 source.start(0);
166 182
167 context.startRendering() 183 context.startRendering()
168 .then(buffer => checkShapedCurve(buffer, should)) 184 .then(buffer => checkShapedCurve(buffer, should))
169 .then(() => task.done()); 185 .then(() => task.done());
170 }); 186 });
171 187
172 audit.run(); 188 audit.run();
173 } 189 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698