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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/LayoutTests/webaudio/osc-negative-freq.html
diff --git a/third_party/WebKit/LayoutTests/webaudio/osc-negative-freq.html b/third_party/WebKit/LayoutTests/webaudio/osc-negative-freq.html
new file mode 100644
index 0000000000000000000000000000000000000000..031da35e81ffcdb7c72e77f252e880b8a2ea77f6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/osc-negative-freq.html
@@ -0,0 +1,198 @@
+<!doctype html>
+<html>
+ <head>
+ <script src="../resources/js-test.js"></script>
+ <script src="resources/compatibility.js"></script>
+ <script src="resources/audio-testing.js"></script>
+ <title>Test OscillatorNode with Negative Frequency</title>
+ </head>
+
+ <body>
+ <script>
+ description("Test OscillatorNode with Negative Frequency.");
+ window.jsTestIsAsync = true;
+
+ // Some arbitrary sample rate for the offline context.
+ var sampleRate = 48000;
+ var renderDuration = 1;
+ var renderFrames = renderDuration * sampleRate;
+
+ var audit = Audit.createTaskRunner();
+
+ audit.defineTask("sine", function (done) {
+ runTest({
+ message: "Sum of positive and negative frequency sine oscillators",
+ type: "sine",
+ threshold: 4.1724e-7
+ }).then(done);
+ });
+
+ audit.defineTask("square", function (done) {
+ runTest({
+ message: "Sum of positive and negative frequency square oscillators",
+ type: "square",
+ threshold: 4.3959e-6
+ }).then(done);
+ });
+
+ audit.defineTask("sawtooth", function (done) {
+ runTest({
+ message: "Sum of positive and negative frequency sawtooth oscillators",
+ type: "sawtooth",
+ threshold: 4.3735e-6
+ }).then(done);
+ });
+
+ audit.defineTask("triangle", function (done) {
+ runTest({
+ message: "Sum of positive and negative frequency triangle oscillators",
+ type: "triangle",
+ threshold: 3.5763e-7
+ }).then(done);
+ });
+
+ audit.defineTask("auto-sawtooth", function (done) {
+ runTest({
+ message: "Sum of positive and negative frequency-ramped sawtooth oscillators",
+ type: "sawtooth",
+ automation: {
+ type: "linearRampToValueAtTime",
+ startTime: 0,
+ endTime: renderDuration / 2,
+ startFrequency: 440,
+ endFrequency: sampleRate / 4
+ },
+ threshold: 4.1202e-6
+ }).then(done);
+ });
+
+ audit.defineTask("periodic-wave", function (done) {
+ // Test negative frequencies for a custom oscillator. Two channels are
+ // needed for the context; one for the expected result, and one for the
+ // actual, as explained below.
+ var context = new OfflineAudioContext(2, renderFrames, sampleRate);
+
+ var oscPositive = context.createOscillator();
+ var oscNegative = context.createOscillator();
+
+ // The Fourier coefficients for our custom oscillator. The actual values
+ // not important. The waveform for our custom oscillator is
+ //
+ // x(t) = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
+ // + sum(imag[k]*sin(2*%pi*f*k/Fs), k, 0)
+ //
+ // With a negative frequency we have
+ //
+ // x(t) = sum(real[k]*cos(2*%pi*(-f)*k/Fs), k, 1)
+ // + sum(imag[k]*sin(2*%pi*(-f)*k/Fs), k, 0)
+ //
+ // = sum(real[k]*cos(2*%pi*f*k/Fs), k, 1)
+ // + sum((-imag[k])*sin(2*%pi*f*k/Fs), k, 0)
+ //
+ // That is, when the frequency is inverted, it behaves as if the
+ // coefficients of the imaginary part are inverted.
+ //
+ // Thus, the test is to create two custom oscillators. The second
+ // osillator uses the same PeriodicWave as the first except the
+ // imaginary coefficients are inverted. This second oscillator also
+ // gets a negative frequency. The combination of the two results in an
+ // oscillator that is the same as the first with gain of 2.
+ var real = [0, 1, 1];
+ var imag = [0, 1, 1];
+
+ var wavePositive = context.createPeriodicWave(
+ Float32Array.from(real),
+ Float32Array.from(imag));
+ var waveNegative = context.createPeriodicWave(
+ Float32Array.from(real),
+ Float32Array.from(imag.map(x => -x)));
+
+ oscPositive.setPeriodicWave(wavePositive);
+ oscNegative.setPeriodicWave(waveNegative);
+
+ oscPositive.frequency.value = 440;
+ oscNegative.frequency.value = -oscPositive.frequency.value;
+
+ var merger = context.createChannelMerger(2);
+ var gain = context.createGain();
+
+ // As explained above, the expected result should be positive frequency
+ // oscillator but with a gain of 2.
+ gain.gain.value = 2;
+ oscPositive.connect(gain);
+ gain.connect(merger, 0, 0);
+
+ // Sum the positive and negative frequency oscillators by using the same
+ // input to the merger.
+ oscPositive.connect(merger, 0, 1);
+ oscNegative.connect(merger, 0, 1);
+
+ merger.connect(context.destination);
+
+ oscPositive.start();
+ oscNegative.start();
+
+ context.startRendering().then(function (buffer) {
+ var expected = buffer.getChannelData(0);
+ var actual = buffer.getChannelData(1);
+
+ Should("Sum of positive and negative frequency custom oscillators",
+ actual, {
+ verbose: true,
+ precision: 6
+ })
+ .beCloseToArray(expected, 4.7684e-7);
+ }).then(done);
+ });
+
+
+ // All done!
+ audit.defineTask("finish", function (done) {
+ finishJSTest();
+ done();
+ });
+
+ audit.runTasks();
+
+ function runTest(options) {
+ // To test if negative frequencies work, create two oscillators. One
+ // has a positive frequency and the other has a negative frequency.
+ // Sum the oscillator outputs; the output should be zero because all of
+ // the builtin oscillator types are odd functions of frequency.
+ var context = new OfflineAudioContext(1, renderFrames, sampleRate);
+
+ var oscPositive = context.createOscillator();
+ var oscNegative = context.createOscillator();
+
+ oscPositive.type = options.type;
+ oscNegative.type = oscPositive.type;
+
+ if (options.automation) {
+ var {type, startTime, endTime, startFrequency, endFrequency} = options.automation;
+ oscPositive.frequency.setValueAtTime(startFrequency, startTime);
+ oscPositive.frequency[type](endFrequency, endTime)
+
+ oscNegative.frequency.setValueAtTime(-startFrequency, startTime);
+ oscNegative.frequency[type](-endFrequency, endTime)
+ } else {
+ oscPositive.frequency.value = 440;
+ oscNegative.frequency.value = -oscPositive.frequency.value;
+ }
+
+ oscPositive.connect(context.destination);
+ oscNegative.connect(context.destination);
+
+ oscPositive.start();
+ oscNegative.start();
+
+ return context.startRendering().then(function (buffer) {
+ var result = buffer.getChannelData(0);
+
+ var zero = new Float32Array(result.length);
+ zero.fill(0);
+ Should(options.message, result).beCloseToArray(zero, options.threshold || 0);
+ });
+ }
+ </script>
+ </body>
+</html>

Powered by Google App Engine
This is Rietveld 408576698