| <!doctype html> |
| |
| <!-- |
| Tests that GainNode is properly scaling the gain. |
| We'll render 11 notes, starting at a gain of 1.0, decreasing in gain by 0.1. |
| The 11th note will be of gain 0.0, so it should be silent (at the end in the rendered output). |
| |
| Based on a test from the WebKit test suite |
| (https://github.com/WebKit/webkit/blob/master/LayoutTests/webaudio/gain.html) |
| --> |
| |
| <html class="a"> |
| <head> |
| <title>GainNode interface</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/webaudio/js/lodash.js"></script> |
| <script src="/webaudio/js/vendor-prefixes.js"></script> |
| <script src="/webaudio/js/helpers.js"></script> |
| <script src="/webaudio/js/buffer-loader.js"></script> |
| </head> |
| <body class="a"> |
| <div id="log"></div> |
| <script> |
| var gainNodeTest = async_test("GainNode"); |
| |
| var sampleRate = 44100.0; |
| var bufferDurationSeconds = 0.125; |
| var numberOfNotes = 11; |
| var noteSpacing = bufferDurationSeconds + 0.020; // leave 20ms of silence between each "note" |
| var lengthInSeconds = numberOfNotes * noteSpacing; |
| |
| var context = 0; |
| var expectedBuffer = 0; |
| var actualBuffer = 0; |
| var sinWaveBuffer = 0; |
| |
| function createSinWaveBuffer(lengthInSeconds, frequency) { |
| var audioBuffer = context.createBuffer(2, lengthInSeconds * sampleRate, sampleRate); |
| |
| var n = audioBuffer.length; |
| var channelL = audioBuffer.getChannelData(0); |
| var channelR = audioBuffer.getChannelData(1); |
| |
| for (var i = 0; i < n; ++i) { |
| channelL[i] = Math.sin(frequency * 2.0*Math.PI * i / sampleRate); |
| channelR[i] = channelL[i]; |
| } |
| |
| return audioBuffer; |
| } |
| |
| function playNote(time, gain) { |
| var source = context.createBufferSource(); |
| source.buffer = sinWaveBuffer; |
| |
| var gainNode = context.createGain(); |
| gainNode.gain.value = gain; |
| |
| source.connect(gainNode); |
| gainNode.connect(context.destination); |
| |
| source.start(time); |
| } |
| |
| function loadExpectedBuffer(event) { |
| actualBuffer = event.renderedBuffer; |
| |
| bufferLoader = new BufferLoader( |
| context, |
| ['/webaudio/the-audio-api/the-gainnode-interface/gain-expected.wav'], |
| bufferLoadCompleted |
| ); |
| bufferLoader.load(); |
| }; |
| |
| function bufferLoadCompleted(buffer) { |
| compareExpectedWithActualBuffer(buffer); |
| }; |
| |
| setup( function() { |
| // Create offline audio context. |
| context = new OfflineAudioContext(2, sampleRate * lengthInSeconds, sampleRate); |
| |
| // Create a buffer for a short "note". |
| sinWaveBuffer = createSinWaveBuffer(bufferDurationSeconds, 880.0); |
| |
| // Render 11 notes, starting at a gain of 1.0, decreasing in gain by 0.1. |
| // The last note will be of gain 0.0, so shouldn't be perceptible in the rendered output. |
| for (var i = 0; i < numberOfNotes; ++i) { |
| var time = i * noteSpacing; |
| var gain = 1.0 - i / (numberOfNotes - 1); |
| playNote(time, gain); |
| } |
| |
| context.oncomplete = loadExpectedBuffer; |
| context.startRendering(); |
| }, {timeout: 10000}); |
| |
| function compareExpectedWithActualBuffer(expected) { |
| var expectedBuffer = expected[0]; |
| |
| gainNodeTest.step(function() { |
| assert_array_approx_equals(expectedBuffer.getChannelData(0), |
| actualBuffer.getChannelData(0), |
| 1e-4, |
| "comparing expected and rendered buffers (channel 0)"); |
| }); |
| |
| gainNodeTest.step(function() { |
| assert_array_approx_equals(expectedBuffer.getChannelData(1), |
| actualBuffer.getChannelData(1), |
| 1e-4, |
| "comparing expected and rendered buffers (channel 1)"); |
| }); |
| |
| gainNodeTest.done(); |
| }; |
| </script> |
| </body> |
| </html> |