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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/osc-negative-freq.html

Issue 2581463002: Refactor WebAudio test directory (Closed)
Patch Set: Use correct path for wav result files Created 4 years 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
(Empty)
1 <!doctype html>
2 <html>
3 <head>
4 <script src="../resources/js-test.js"></script>
5 <script src="resources/compatibility.js"></script>
6 <script src="resources/audit-util.js"></script>
7 <script src="resources/audio-testing.js"></script>
8 <title>Test OscillatorNode with Negative Frequency</title>
9 </head>
10
11 <body>
12 <script>
13 description("Test OscillatorNode with Negative Frequency.");
14 window.jsTestIsAsync = true;
15
16 // Some arbitrary sample rate for the offline context.
17 var sampleRate = 48000;
18 var renderDuration = 1;
19 var renderFrames = renderDuration * sampleRate;
20
21 var audit = Audit.createTaskRunner();
22
23 audit.defineTask("sine", function (done) {
24 runTest({
25 message: "Sum of positive and negative frequency sine oscillators",
26 type: "sine",
27 threshold: 4.7684e-7
28 }).then(done);
29 });
30
31 audit.defineTask("square", function (done) {
32 runTest({
33 message: "Sum of positive and negative frequency square oscillators",
34 type: "square",
35 threshold: 4.4108e-6
36 }).then(done);
37 });
38
39 audit.defineTask("sawtooth", function (done) {
40 runTest({
41 message: "Sum of positive and negative frequency sawtooth oscillators" ,
42 type: "sawtooth",
43 threshold: 4.3735e-6
44 }).then(done);
45 });
46
47 audit.defineTask("triangle", function (done) {
48 runTest({
49 message: "Sum of positive and negative frequency triangle oscillators" ,
50 type: "triangle",
51 threshold: 3.5763e-7
52 }).then(done);
53 });
54
55 audit.defineTask("auto-sawtooth", function (done) {
56 runTest({
57 message: "Sum of positive and negative frequency-ramped sawtooth oscil lators",
58 type: "sawtooth",
59 automation: {
60 type: "linearRampToValueAtTime",
61 startTime: 0,
62 endTime: renderDuration / 2,
63 startFrequency: 440,
64 endFrequency: sampleRate / 4
65 },
66 threshold: 4.1202e-6
67 }).then(done);
68 });
69
70 audit.defineTask("periodic-wave", function (done) {
71 // Test negative frequencies for a custom oscillator. Two channels are
72 // needed for the context; one for the expected result, and one for the
73 // actual, as explained below.
74 var context = new OfflineAudioContext(2, renderFrames, sampleRate);
75
76 var oscPositive = context.createOscillator();
77 var oscNegative = context.createOscillator();
78
79 // The Fourier coefficients for our custom oscillator. The actual value s
80 // not important. The waveform for our custom oscillator is
81 //
82 // x(t) = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
83 // + sum(imag[k]*sin(2*%pi*f*k/Fs), k, 0)
84 //
85 // With a negative frequency we have
86 //
87 // x(t) = sum(real[k]*cos(2*%pi*(-f)*k/Fs), k, 1)
88 // + sum(imag[k]*sin(2*%pi*(-f)*k/Fs), k, 0)
89 //
90 // = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
91 // + sum((-imag[k])*sin(2*%pi*f*k/Fs), k, 0)
92 //
93 // That is, when the frequency is inverted, it behaves as if the
94 // coefficients of the imaginary part are inverted.
95 //
96 // Thus, the test is to create two custom oscillators. The second
97 // osillator uses the same PeriodicWave as the first except the
98 // imaginary coefficients are inverted. This second oscillator also
99 // gets a negative frequency. The combination of the two results in an
100 // oscillator that is the same as the first with gain of 2.
101 var real = [0, 1, 1];
102 var imag = [0, 1, 1];
103
104 var wavePositive = context.createPeriodicWave(
105 Float32Array.from(real),
106 Float32Array.from(imag));
107 var waveNegative = context.createPeriodicWave(
108 Float32Array.from(real),
109 Float32Array.from(imag.map(x => -x)));
110
111 oscPositive.setPeriodicWave(wavePositive);
112 oscNegative.setPeriodicWave(waveNegative);
113
114 oscPositive.frequency.value = 440;
115 oscNegative.frequency.value = -oscPositive.frequency.value;
116
117 var merger = context.createChannelMerger(2);
118 var gain = context.createGain();
119
120 // As explained above, the expected result should be positive frequency
121 // oscillator but with a gain of 2.
122 gain.gain.value = 2;
123 oscPositive.connect(gain);
124 gain.connect(merger, 0, 0);
125
126 // Sum the positive and negative frequency oscillators by using the same
127 // input to the merger.
128 oscPositive.connect(merger, 0, 1);
129 oscNegative.connect(merger, 0, 1);
130
131 merger.connect(context.destination);
132
133 oscPositive.start();
134 oscNegative.start();
135
136 context.startRendering().then(function (buffer) {
137 var expected = buffer.getChannelData(0);
138 var actual = buffer.getChannelData(1);
139
140 Should("Sum of positive and negative frequency custom oscillators",
141 actual, {
142 precision: 6
143 })
144 .beCloseToArray(expected, 4.7684e-7);
145 }).then(done);
146 });
147
148
149 // All done!
150 audit.defineTask("finish", function (done) {
151 finishJSTest();
152 done();
153 });
154
155 audit.runTasks();
156
157 function runTest(options) {
158 // To test if negative frequencies work, create two oscillators. One
159 // has a positive frequency and the other has a negative frequency.
160 // Sum the oscillator outputs; the output should be zero because all of
161 // the builtin oscillator types are odd functions of frequency.
162 var context = new OfflineAudioContext(1, renderFrames, sampleRate);
163
164 var oscPositive = context.createOscillator();
165 var oscNegative = context.createOscillator();
166
167 oscPositive.type = options.type;
168 oscNegative.type = oscPositive.type;
169
170 if (options.automation) {
171 var {type, startTime, endTime, startFrequency, endFrequency} = options .automation;
172 oscPositive.frequency.setValueAtTime(startFrequency, startTime);
173 oscPositive.frequency[type](endFrequency, endTime)
174
175 oscNegative.frequency.setValueAtTime(-startFrequency, startTime);
176 oscNegative.frequency[type](-endFrequency, endTime)
177 } else {
178 oscPositive.frequency.value = 440;
179 oscNegative.frequency.value = -oscPositive.frequency.value;
180 }
181
182 oscPositive.connect(context.destination);
183 oscNegative.connect(context.destination);
184
185 oscPositive.start();
186 oscNegative.start();
187
188 return context.startRendering().then(function (buffer) {
189 var result = buffer.getChannelData(0);
190
191 var zero = new Float32Array(result.length);
192 zero.fill(0);
193 Should(options.message, result, {
194 verbose: true
195 }).beCloseToArray(zero, options.threshold || 0);
196 });
197 }
198 </script>
199 </body>
200 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698