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

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

Issue 2059823002: Use correct value for Oscillator.frequency.minValue (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update results for Windows. Created 4 years, 6 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
(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/audio-testing.js"></script>
7 <title>Test OscillatorNode with Negative Frequency</title>
8 </head>
9
10 <body>
11 <script>
12 description("Test OscillatorNode with Negative Frequency.");
13 window.jsTestIsAsync = true;
14
15 // Some arbitrary sample rate for the offline context.
16 var sampleRate = 48000;
17 var renderDuration = 1;
18 var renderFrames = renderDuration * sampleRate;
19
20 var audit = Audit.createTaskRunner();
21
22 audit.defineTask("sine", function (done) {
23 runTest({
24 message: "Sum of positive and negative frequency sine oscillators",
25 type: "sine",
26 threshold: 4.1724e-7
27 }).then(done);
28 });
29
30 audit.defineTask("square", function (done) {
31 runTest({
32 message: "Sum of positive and negative frequency square oscillators",
33 type: "square",
34 threshold: 4.3959e-6
35 }).then(done);
36 });
37
38 audit.defineTask("sawtooth", function (done) {
39 runTest({
40 message: "Sum of positive and negative frequency sawtooth oscillators" ,
41 type: "sawtooth",
42 threshold: 4.3735e-6
43 }).then(done);
44 });
45
46 audit.defineTask("triangle", function (done) {
47 runTest({
48 message: "Sum of positive and negative frequency triangle oscillators" ,
49 type: "triangle",
50 threshold: 3.5763e-7
51 }).then(done);
52 });
53
54 audit.defineTask("auto-sawtooth", function (done) {
55 runTest({
56 message: "Sum of positive and negative frequency-ramped sawtooth oscil lators",
57 type: "sawtooth",
58 automation: {
59 type: "linearRampToValueAtTime",
60 startTime: 0,
61 endTime: renderDuration / 2,
62 startFrequency: 440,
63 endFrequency: sampleRate / 4
64 },
65 threshold: 4.1202e-6
66 }).then(done);
67 });
68
69 audit.defineTask("periodic-wave", function (done) {
70 // Test negative frequencies for a custom oscillator. Two channels are
71 // needed for the context; one for the expected result, and one for the
72 // actual, as explained below.
73 var context = new OfflineAudioContext(2, renderFrames, sampleRate);
74
75 var oscPositive = context.createOscillator();
76 var oscNegative = context.createOscillator();
77
78 // The Fourier coefficients for our custom oscillator. The actual value s
79 // not important. The waveform for our custom oscillator is
80 //
81 // x(t) = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
82 // + sum(imag[k]*sin(2*%pi*f*k/Fs), k, 0)
83 //
84 // With a negative frequency we have
85 //
86 // x(t) = sum(real[k]*cos(2*%pi*(-f)*k/Fs), k, 1)
87 // + sum(imag[k]*sin(2*%pi*(-f)*k/Fs), k, 0)
88 //
89 // = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
90 // + sum((-imag[k])*sin(2*%pi*f*k/Fs), k, 0)
91 //
92 // That is, when the frequency is inverted, it behaves as if the
93 // coefficients of the imaginary part are inverted.
94 //
95 // Thus, the test is to create two custom oscillators. The second
96 // osillator uses the same PeriodicWave as the first except the
97 // imaginary coefficients are inverted. This second oscillator also
98 // gets a negative frequency. The combination of the two results in an
99 // oscillator that is the same as the first with gain of 2.
100 var real = [0, 1, 1];
101 var imag = [0, 1, 1];
102
103 var wavePositive = context.createPeriodicWave(
104 Float32Array.from(real),
105 Float32Array.from(imag));
106 var waveNegative = context.createPeriodicWave(
107 Float32Array.from(real),
108 Float32Array.from(imag.map(x => -x)));
109
110 oscPositive.setPeriodicWave(wavePositive);
111 oscNegative.setPeriodicWave(waveNegative);
112
113 oscPositive.frequency.value = 440;
114 oscNegative.frequency.value = -oscPositive.frequency.value;
115
116 var merger = context.createChannelMerger(2);
117 var gain = context.createGain();
118
119 // As explained above, the expected result should be positive frequency
120 // oscillator but with a gain of 2.
121 gain.gain.value = 2;
122 oscPositive.connect(gain);
123 gain.connect(merger, 0, 0);
124
125 // Sum the positive and negative frequency oscillators by using the same
126 // input to the merger.
127 oscPositive.connect(merger, 0, 1);
128 oscNegative.connect(merger, 0, 1);
129
130 merger.connect(context.destination);
131
132 oscPositive.start();
133 oscNegative.start();
134
135 context.startRendering().then(function (buffer) {
136 var expected = buffer.getChannelData(0);
137 var actual = buffer.getChannelData(1);
138
139 Should("Sum of positive and negative frequency custom oscillators",
140 actual, {
141 verbose: true,
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).beCloseToArray(zero, options.threshold || 0);
194 });
195 }
196 </script>
197 </body>
198 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698