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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/resources/oscillator-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 // Notes about generated waveforms: 1 // Notes about generated waveforms:
2 // 2 //
3 // QUESTION: Why does the wave shape not look like the exact shape (sharp edges) ? 3 // QUESTION: Why does the wave shape not look like the exact shape (sharp
4 // ANSWER: Because a shape with sharp edges has infinitely high frequency conten t. 4 // edges)? ANSWER: Because a shape with sharp edges has infinitely high
5 // Since a digital audio signal must be band-limited based on the nyquist freque ncy (half the sample-rate) 5 // frequency content. Since a digital audio signal must be band-limited based on
6 // in order to avoid aliasing, this creates more rounded edges and "ringing" in the 6 // the nyquist frequency (half the sample-rate) in order to avoid aliasing, this
7 // appearance of the waveform. See Nyquist-Shannon sampling theorem: 7 // creates more rounded edges and "ringing" in the appearance of the waveform.
8 // See Nyquist-Shannon sampling theorem:
8 // http://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem 9 // http://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem
9 // 10 //
10 // QUESTION: Why does the very end of the generated signal appear to get slightl y weaker? 11 // QUESTION: Why does the very end of the generated signal appear to get
11 // ANSWER: This is an artifact of the algorithm to avoid aliasing. 12 // slightly weaker? ANSWER: This is an artifact of the algorithm to avoid
13 // aliasing.
12 // 14 //
13 // QUESTION: Since the tests compare the actual result with an expected referenc e file, how are the 15 // QUESTION: Since the tests compare the actual result with an expected
14 // reference files created? 16 // reference file, how are the reference files created? ANSWER: Run the test in
15 // ANSWER: Run the test in a browser. When the test completes, a 17 // a browser. When the test completes, a generated reference file with the name
16 // generated reference file with the name "<file>-actual.wav" is 18 // "<file>-actual.wav" is automatically downloaded. Use this as the new
17 // automatically downloaded. Use this as the new reference, after 19 // reference, after carefully inspecting to see if this is correct.
18 // carefully inspecting to see if this is correct.
19 // 20 //
20 21
21 OscillatorTestingUtils = (function () { 22 OscillatorTestingUtils = (function() {
22 23
23 var sampleRate = 44100.0; 24 let sampleRate = 44100.0;
24 var nyquist = 0.5 * sampleRate; 25 let nyquist = 0.5 * sampleRate;
25 var lengthInSeconds = 4; 26 let lengthInSeconds = 4;
26 var lowFrequency = 10; 27 let lowFrequency = 10;
27 var highFrequency = nyquist + 2000; // go slightly higher than nyquist to make s ure we generate silence there 28 let highFrequency = nyquist + 2000; // go slightly higher than nyquist to
28 var context = 0; 29 // make sure we generate silence there
30 let context = 0;
29 31
30 // Scaling factor for converting the 16-bit WAV data to float (and vice-versa). 32 // Scaling factor for converting the 16-bit WAV data to float (and
31 var waveScaleFactor = 32768; 33 // vice-versa).
34 let waveScaleFactor = 32768;
32 35
33 // Thresholds for verifying the test passes. The thresholds are experimentally determined. The 36 // Thresholds for verifying the test passes. The thresholds are
34 // default values here will cause the test to fail, which is useful for determin ing new thresholds, 37 // experimentally determined. The default values here will cause the test to
35 // if needed. 38 // fail, which is useful for determining new thresholds, if needed.
36 39
37 // SNR must be greater than this to pass the test. 40 // SNR must be greater than this to pass the test.
38 // Q: Why is the SNR threshold not infinity? 41 // Q: Why is the SNR threshold not infinity?
39 // A: The reference result is a 16-bit WAV file, so it won't compare exactly wit h the 42 // A: The reference result is a 16-bit WAV file, so it won't compare exactly
40 // floating point result. 43 // with the
41 var thresholdSNR = 10000; 44 // floating point result.
45 let thresholdSNR = 10000;
42 46
43 // Max diff must be less than this to pass the test. 47 // Max diff must be less than this to pass the test.
44 var thresholdDiff = 0; 48 let thresholdDiff = 0;
45 49
46 // Mostly for debugging 50 // Mostly for debugging
47 51
48 // An AudioBuffer for the reference (expected) result. 52 // An AudioBuffer for the reference (expected) result.
49 var reference = 0; 53 let reference = 0;
50 54
51 // Signal power of the reference 55 // Signal power of the reference
52 var signalPower = 0; 56 let signalPower = 0;
53 57
54 // Noise power of the difference between the reference and actual result. 58 // Noise power of the difference between the reference and actual result.
55 var noisePower = 0; 59 let noisePower = 0;
56 60
57 function generateExponentialOscillatorSweep(context, oscillatorType) { 61 function generateExponentialOscillatorSweep(context, oscillatorType) {
58 var osc = context.createOscillator(); 62 let osc = context.createOscillator();
59 if (oscillatorType == "custom") { 63 if (oscillatorType == 'custom') {
60 // Create a simple waveform with three Fourier coefficients. 64 // Create a simple waveform with three Fourier coefficients.
61 // Note the first values are expected to be zero (DC for coeffA and Nyqu ist for coeffB). 65 // Note the first values are expected to be zero (DC for coeffA and
62 var coeffA = new Float32Array([0, 1, 0.5]); 66 // Nyquist for coeffB).
63 var coeffB = new Float32Array([0, 0, 0]); 67 let coeffA = new Float32Array([0, 1, 0.5]);
64 var wave = context.createPeriodicWave(coeffA, coeffB); 68 let coeffB = new Float32Array([0, 0, 0]);
65 osc.setPeriodicWave(wave); 69 let wave = context.createPeriodicWave(coeffA, coeffB);
70 osc.setPeriodicWave(wave);
66 } else { 71 } else {
67 osc.type = oscillatorType; 72 osc.type = oscillatorType;
68 } 73 }
69 74
70 // Scale by 1/2 to better visualize the waveform and to avoid clipping past full scale. 75 // Scale by 1/2 to better visualize the waveform and to avoid clipping past
71 var gainNode = context.createGain(); 76 // full scale.
77 let gainNode = context.createGain();
72 gainNode.gain.value = 0.5; 78 gainNode.gain.value = 0.5;
73 osc.connect(gainNode); 79 osc.connect(gainNode);
74 gainNode.connect(context.destination); 80 gainNode.connect(context.destination);
75 81
76 osc.start(0); 82 osc.start(0);
77 83
78 osc.frequency.setValueAtTime(10, 0); 84 osc.frequency.setValueAtTime(10, 0);
79 osc.frequency.exponentialRampToValueAtTime(highFrequency, lengthInSeconds); 85 osc.frequency.exponentialRampToValueAtTime(highFrequency, lengthInSeconds);
80 } 86 }
81 87
82 function calculateSNR(sPower, nPower) 88 function calculateSNR(sPower, nPower) {
83 {
84 return 10 * Math.log10(sPower / nPower); 89 return 10 * Math.log10(sPower / nPower);
85 } 90 }
86 91
87 function loadReferenceAndRunTest(context, oscType, task, should) { 92 function loadReferenceAndRunTest(context, oscType, task, should) {
88 Audit 93 Audit
89 .loadFileFromUrl( 94 .loadFileFromUrl(
90 '../Oscillator/oscillator-' + oscType + '-expected.wav') 95 '../Oscillator/oscillator-' + oscType + '-expected.wav')
91 .then(response => { 96 .then(response => {
92 return context.decodeAudioData(response); 97 return context.decodeAudioData(response);
93 }) 98 })
94 .then(audioBuffer => { 99 .then(audioBuffer => {
95 reference = audioBuffer.getChannelData(0); 100 reference = audioBuffer.getChannelData(0);
96 generateExponentialOscillatorSweep(context, oscType); 101 generateExponentialOscillatorSweep(context, oscType);
97 return context.startRendering(); 102 return context.startRendering();
98 }) 103 })
99 .then(resultBuffer => { 104 .then(resultBuffer => {
100 checkResult(resultBuffer, should, oscType); 105 checkResult(resultBuffer, should, oscType);
101 }) 106 })
102 .then(() => task.done()); 107 .then(() => task.done());
103 } 108 }
104 109
105 function checkResult (renderedBuffer, should, oscType) { 110 function checkResult(renderedBuffer, should, oscType) {
106 let renderedData = renderedBuffer.getChannelData(0); 111 let renderedData = renderedBuffer.getChannelData(0);
107 // Compute signal to noise ratio between the result and the reference. Also keep track 112 // Compute signal to noise ratio between the result and the reference. Also
108 // of the max difference (and position). 113 // keep track of the max difference (and position).
109 114
110 var maxError = -1; 115 let maxError = -1;
111 var errorPosition = -1; 116 let errorPosition = -1;
112 var diffCount = 0; 117 let diffCount = 0;
113 118
114 for (var k = 0; k < renderedData.length; ++k) { 119 for (let k = 0; k < renderedData.length; ++k) {
115 var diff = renderedData[k] - reference[k]; 120 let diff = renderedData[k] - reference[k];
116 noisePower += diff * diff; 121 noisePower += diff * diff;
117 signalPower += reference[k] * reference[k]; 122 signalPower += reference[k] * reference[k];
118 if (Math.abs(diff) > maxError) { 123 if (Math.abs(diff) > maxError) {
119 maxError = Math.abs(diff); 124 maxError = Math.abs(diff);
120 errorPosition = k; 125 errorPosition = k;
121 } 126 }
122 } 127 }
123 128
124 var snr = calculateSNR(signalPower, noisePower); 129 let snr = calculateSNR(signalPower, noisePower);
125 should(snr, "SNR") 130 should(snr, 'SNR').beGreaterThanOrEqualTo(thresholdSNR);
126 .beGreaterThanOrEqualTo(thresholdSNR); 131 should(maxError, 'Maximum difference').beLessThanOrEqualTo(thresholdDiff);
127 should(maxError, "Maximum difference")
128 .beLessThanOrEqualTo(thresholdDiff);
129 132
130 var filename = "oscillator-" + oscType + "-actual.wav"; 133 let filename = 'oscillator-' + oscType + '-actual.wav';
131 if (downloadAudioBuffer(renderedBuffer, filename, true)) 134 if (downloadAudioBuffer(renderedBuffer, filename, true))
132 should(true, "Saved reference file").message(filename, ""); 135 should(true, 'Saved reference file').message(filename, '');
133 } 136 }
134 137
135 function setThresholds(thresholds) { 138 function setThresholds(thresholds) {
136 thresholdSNR = thresholds.snr; 139 thresholdSNR = thresholds.snr;
137 thresholdDiff = thresholds.maxDiff; 140 thresholdDiff = thresholds.maxDiff;
138 thresholdDiffCount = thresholds.diffCount; 141 thresholdDiffCount = thresholds.diffCount;
139 } 142 }
140 143
141 function runTest(context, oscType, description, task, should) { 144 function runTest(context, oscType, description, task, should) {
142 loadReferenceAndRunTest(context, oscType, task, should); 145 loadReferenceAndRunTest(context, oscType, task, should);
143 } 146 }
144 147
145 return { 148 return {
146 sampleRate: sampleRate, 149 sampleRate: sampleRate,
147 lengthInSeconds: lengthInSeconds, 150 lengthInSeconds: lengthInSeconds,
148 thresholdSNR: thresholdSNR, 151 thresholdSNR: thresholdSNR,
149 thresholdDiff: thresholdDiff, 152 thresholdDiff: thresholdDiff,
150 waveScaleFactor: waveScaleFactor, 153 waveScaleFactor: waveScaleFactor,
151 setThresholds: setThresholds, 154 setThresholds: setThresholds,
152 runTest: runTest, 155 runTest: runTest,
153 }; 156 };
154 157
155 }()); 158 }());
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698