| <!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> |