| <!DOCTYPE html> |
| <html> |
| <head> |
| <title> |
| Test Negative AudioParam.exponentialRampToValueAtTime |
| </title> |
| <script src="../../imported/w3c/web-platform-tests/resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="../resources/audit-util.js"></script> |
| <script src="../resources/audit.js"></script> |
| </head> |
| <body> |
| <script id="layout-test-code"> |
| let sampleRate = 48000; |
| |
| let audit = Audit.createTaskRunner(); |
| |
| audit.define('both negative values', (task, should) => { |
| let renderDuration = 0.125; |
| |
| // Create context with two channels. Channel 0 contains the |
| // positive-valued exponential and channel 1 contains the |
| // negative-valued exponential. We'll compare the two channels to |
| // verify that they're the same, as they should be. |
| let context = |
| new OfflineAudioContext(2, renderDuration * sampleRate, sampleRate); |
| let source = context.createBufferSource(); |
| source.buffer = createConstantBuffer(context, 1, 1); |
| source.loop = true; |
| |
| // Gain node gp is for the positive-valued exponential ramp, and gn is |
| // for the negative-valued exponential ramp. |
| let gp = context.createGain(); |
| let gn = context.createGain(); |
| let merger = context.createChannelMerger(2); |
| |
| source.connect(gp).connect(merger, 0, 0); |
| source.connect(gn).connect(merger, 0, 1); |
| merger.connect(context.destination); |
| |
| gp.gain.setValueAtTime(1, 0); |
| gp.gain.exponentialRampToValueAtTime(2, renderDuration); |
| |
| gn.gain.setValueAtTime(-1, 0); |
| gn.gain.exponentialRampToValueAtTime(-2, renderDuration); |
| |
| source.start(); |
| |
| context.startRendering() |
| .then(function(resultBuffer) { |
| // Verify that channels have the same values, except for the sign. |
| let expected = resultBuffer.getChannelData(0); |
| let actual = resultBuffer.getChannelData(1); |
| let inverted = expected.map(sample => -sample); |
| |
| should(actual, 'Negative exponential ramp from -1 to -2') |
| .beEqualToArray(inverted); |
| }) |
| .then(() => task.done()); |
| }); |
| |
| audit.define('negative-end', (task, should) => { |
| // Positive start value and negative end value should just do nothing. |
| let renderDuration = 0.125; |
| let context = |
| new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); |
| let source = context.createBufferSource(); |
| source.buffer = createConstantBuffer(context, 1, 1); |
| source.loop = true; |
| |
| // Gain node gp is for the positive-valued exponential ramp, and gn is |
| // for the negative-valued exponential ramp. |
| let g = context.createGain(); |
| |
| g.gain.setValueAtTime(2, 0); |
| g.gain.exponentialRampToValueAtTime(-1, renderDuration); |
| |
| source.connect(g).connect(context.destination); |
| |
| source.start(); |
| |
| context.startRendering() |
| .then(function(resultBuffer) { |
| let actual = resultBuffer.getChannelData(0); |
| |
| should(actual, 'Exponential ramp from 2 to -1') |
| .beConstantValueOf(2); |
| }) |
| .then(() => task.done()); |
| }); |
| |
| audit.define('positive-end', (task, should) => { |
| // Positive start value and negative end value should just do nothing. |
| let renderDuration = 0.125; |
| let context = |
| new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); |
| let source = context.createBufferSource(); |
| source.buffer = createConstantBuffer(context, 1, 1); |
| source.loop = true; |
| |
| let g = context.createGain(); |
| |
| g.gain.setValueAtTime(-1, 0); |
| g.gain.exponentialRampToValueAtTime(1, renderDuration); |
| |
| source.connect(g).connect(context.destination); |
| source.start(); |
| |
| context.startRendering() |
| .then(function(resultBuffer) { |
| let actual = resultBuffer.getChannelData(0); |
| |
| should(actual, 'Exponential ramp from -1 to 1') |
| .beConstantValueOf(-1); |
| }) |
| .then(() => task.done()); |
| }); |
| |
| audit.define('propagate', (task, should) => { |
| // Test propagation of ramp if the exponential ramp start and end values |
| // have opposite sign. |
| let renderDuration = 0.125; |
| let linearRampEnd = renderDuration / 4; |
| let exponentialRampEnd = renderDuration / 2; |
| |
| let context = |
| new OfflineAudioContext(1, renderDuration * sampleRate, sampleRate); |
| let source = context.createBufferSource(); |
| source.buffer = createConstantBuffer(context, 1, 1); |
| source.loop = true; |
| |
| let g = context.createGain(); |
| |
| g.gain.setValueAtTime(2, 0); |
| g.gain.linearRampToValueAtTime(-1, linearRampEnd); |
| g.gain.exponentialRampToValueAtTime(1, exponentialRampEnd); |
| |
| source.connect(g).connect(context.destination); |
| source.start(); |
| |
| context.startRendering() |
| .then(function(resultBuffer) { |
| let actual = resultBuffer.getChannelData(0); |
| |
| // Since the start value of the exponential ramp is -1 and the end |
| // value is 1, the ramp should just propagate -1 to the end of |
| // the exponential ramp, and then propagate the exponential ramp |
| // value "forever" afterwards. |
| const linearEndFrame = Math.ceil(linearRampEnd * sampleRate); |
| const expoEndFrame = Math.ceil(exponentialRampEnd * sampleRate); |
| should( |
| actual.slice(linearEndFrame, expoEndFrame), |
| 'Exponential ramp from -1 to 1 after the end of the linear ramp') |
| .beConstantValueOf(-1); |
| should( |
| actual.slice(expoEndFrame), |
| 'Exponential ramp after end of ramp') |
| .beConstantValueOf(1); |
| }) |
| .then(() => task.done()); |
| }); |
| |
| audit.run(); |
| </script> |
| </body> |
| </html> |