| Index: third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html
|
| diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html
|
| index 597206e05520bed0dd4932b25ad901f4c1df693c..7d6da79d30cf832ab52f2cbb26479cdb8ba1b32f 100644
|
| --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html
|
| +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions.html
|
| @@ -1,747 +1,802 @@
|
| -<!doctype html>
|
| +<!DOCTYPE html>
|
| <html>
|
| -<head>
|
| -<script src="../resources/testharness.js"></script>
|
| -<script src="../resources/testharnessreport.js"></script>
|
| -<script src="resources/audit-util.js"></script>
|
| -<script src="resources/audit.js"></script>
|
| -<script src="resources/biquad-testing.js"></script>
|
| -</head>
|
| -
|
| -<body>
|
| -<script>
|
| -let audit = Audit.createTaskRunner();
|
| -
|
| -let otherContext;
|
| -let node;
|
| -let node2;
|
| -let mode;
|
| -let panner;
|
| -let script;
|
| -let source;
|
| -
|
| -function shouldThrowAndBeUnchanged(should, node, attr, value) {
|
| - should(
|
| - () => node[attr] = value,
|
| - node.constructor.name + '.' + attr + ' = ' + value)
|
| - .throw();
|
| - should(node[attr], node.constructor.name + '.' + attr).notBeEqualTo(value);
|
| -}
|
| -
|
| -audit.define(
|
| - {label: 'initialize', description: 'Initialize contexts for testing'},
|
| - (task, should) => {
|
| -
|
| - should(() => {
|
| - context = new AudioContext();
|
| - }, 'context = new AudioContext()').notThrow();
|
| -
|
| - should(() => {
|
| - otherContext = new AudioContext();
|
| - }, 'otherContext = new AudioContext()').notThrow();
|
| -
|
| - task.done();
|
| - });
|
| -
|
| -audit.define('createBuffer', (task, should) => {
|
| - // Invalid number of channels: NotSupportedError
|
| - should(
|
| - () => context.createBuffer(99, 1, context.sampleRate),
|
| - 'context.createBuffer(99, 1, context.sampleRate)')
|
| - .throw('NotSupportedError');
|
| - should(
|
| - () => context.createBuffer(0, 1, context.sampleRate),
|
| - 'context.createBuffer(0, 1, context.sampleRate)')
|
| - .throw('NotSupportedError');
|
| - // Invalid sample rate: NotSupportedError
|
| - should(() => context.createBuffer(1, 1, 1), 'context.createBuffer(1, 1, 1)')
|
| - .throw('NotSupportedError');
|
| - should(
|
| - () => context.createBuffer(1, 1, 2999),
|
| - 'context.createBuffer(1, 1, 2999)')
|
| - .throw('NotSupportedError');
|
| - should(
|
| - () => context.createBuffer(1, 1, 384001),
|
| - 'context.createBuffer(1, 1, 384001)')
|
| - .throw('NotSupportedError');
|
| - should(
|
| - () => context.createBuffer(1, 1, 1e6), 'context.createBuffer(1, 1, 1e6)')
|
| - .throw('NotSupportedError');
|
| - // Check valid values from crbug.com/344375
|
| - should(
|
| - () => context.createBuffer(1, 1, 3000),
|
| - 'context.createBuffer(1, 1, 3000)')
|
| - .notThrow();
|
| - should(
|
| - () => context.createBuffer(1, 1, 192000),
|
| - 'context.createBuffer(1, 1, 192000)')
|
| - .notThrow();
|
| - should(
|
| - () => context.createBuffer(1, 1, 384000),
|
| - 'context.createBuffer(1, 1, 384000)')
|
| - .notThrow();
|
| - // Invalid number of frames: NotSupportedError
|
| - should(
|
| - () => context.createBuffer(1, 0, context.sampleRate),
|
| - 'context.createBuffer(1, 0, context.sampleRate)')
|
| - .throw('NotSupportedError');
|
| - // 2-arg createBuffer not allowed.
|
| - should(
|
| - () => context.createBuffer(new ArrayBuffer(100), true),
|
| - 'context.createBuffer(new ArrayBuffer(100), true)')
|
| - .throw('TypeError');
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('createMediaElementSource', (task, should) => {
|
| - // Invalid sources (unspecified error)
|
| - should(
|
| - () => context.createMediaElementSource(null),
|
| - 'context.createMediaElementSource(null)')
|
| - .throw();
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('createMediaStreamSource', (task, should) => {
|
| - // Invalid sources (unspecified error)
|
| - should(
|
| - () => context.createMediaStreamSource(null),
|
| - 'context.createMediaStreamSource(null)')
|
| - .throw();
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('createScriptProcessor', (task, should) => {
|
| - // Invalid buffer size: IndexSizeError
|
| - should(
|
| - () => context.createScriptProcessor(1, 1, 1),
|
| - 'context.createScriptProcessor(1, 1, 1)')
|
| - .throw('IndexSizeError');
|
| - // Invalid number of inputs and outputs: IndexSizeError
|
| - should(
|
| - () => context.createScriptProcessor(4096, 100, 1),
|
| - 'context.createScriptProcessor(4096, 100, 1)')
|
| - .throw('IndexSizeError');
|
| - should(
|
| - () => context.createScriptProcessor(4096, 1, 100),
|
| - 'context.createScriptProcessor(4096, 1, 100)')
|
| - .throw('IndexSizeError');
|
| - should(
|
| - () => context.createScriptProcessor(), 'context.createScriptProcessor()')
|
| - .notThrow();
|
| - should(
|
| - () => context.createScriptProcessor(0),
|
| - 'context.createScriptProcessor(0)')
|
| - .notThrow();
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('createChannelSplitter', (task, should) => {
|
| - // Invalid number of channels: IndexSizeError
|
| - should(
|
| - () => context.createChannelSplitter(0),
|
| - 'context.createChannelSplitter(0)')
|
| - .throw('IndexSizeError');
|
| - should(
|
| - () => context.createChannelSplitter(99),
|
| - 'context.createChannelSplitter(99)')
|
| - .throw('IndexSizeError');
|
| - should(() => context.createChannelMerger(0), 'context.createChannelMerger(0)')
|
| - .throw('IndexSizeError');
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('createChannelMerger', (task, should) => {
|
| - // Invalid number of channels: IndexSizeError
|
| - should(
|
| - () => context.createChannelMerger(99), 'context.createChannelMerger(99)')
|
| - .throw('IndexSizeError');
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('createPeriodicWave', (task, should) => {
|
| - // Invalid real/imag arrays: IndexSizeError
|
| - should(
|
| - () => context.createPeriodicWave(null, null),
|
| - 'context.createPeriodicWave(null, null)')
|
| - .throw('TypeError');
|
| - should(
|
| - () => context.createPeriodicWave(new Float32Array(10), null),
|
| - 'context.createPeriodicWave(new Float32Array(10), null)')
|
| - .throw('TypeError');
|
| - // Verify that we can use large arrays with no limit. Roughly.
|
| - should(
|
| - () => context.createPeriodicWave(
|
| - new Float32Array(4100), new Float32Array(4100)),
|
| - 'context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100))')
|
| - .notThrow();
|
| - should(
|
| - () => context.createPeriodicWave(
|
| - new Float32Array(8192), new Float32Array(8192)),
|
| - 'context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192))')
|
| - .notThrow();
|
| - should(
|
| - () => context.createPeriodicWave(
|
| - new Float32Array(10000), new Float32Array(10000)),
|
| - 'context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000))')
|
| - .notThrow();
|
| - // Real and imaginary arrays must have the same size: IndexSizeError
|
| - should(
|
| - () =>
|
| - context.createPeriodicWave(new Float32Array(10), new Float32Array(7)),
|
| - 'context.createPeriodicWave(new Float32Array(10), new Float32Array(7))')
|
| - .throw('IndexSizeError');
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('createAnalyser', (task, should) => {
|
| - // Analysers
|
| - node = context.createAnalyser();
|
| - // Invalid fftSize: IndexSizeError
|
| - shouldThrowAndBeUnchanged(should, node, 'fftSize', '42');
|
| - shouldThrowAndBeUnchanged(should, node, 'fftSize', '16');
|
| - should(() => node.fftSize = 32768, 'AnalyserNode.fftSize = 32768').notThrow();
|
| - shouldThrowAndBeUnchanged(should, node, 'fftSize', '65536');
|
| -
|
| - shouldThrowAndBeUnchanged(should, node, 'minDecibels', '-10');
|
| - shouldThrowAndBeUnchanged(should, node, 'maxDecibels', '-150');
|
| - shouldThrowAndBeUnchanged(should, node, 'minDecibels', '-30');
|
| - shouldThrowAndBeUnchanged(should, node, 'maxDecibels', '-100');
|
| -
|
| - shouldThrowAndBeUnchanged(should, node, 'smoothingTimeConstant', '-0.1');
|
| - shouldThrowAndBeUnchanged(should, node, 'smoothingTimeConstant', '1.5');
|
| -
|
| - should(
|
| - () => node.getFloatFrequencyData(null),
|
| - 'AnalyserNode.getFloatFrequencyData(null)')
|
| - .throw();
|
| - should(
|
| - () => node.getByteFrequencyData(null),
|
| - node.constructor.name + '.getByteFrequencyData(null)')
|
| - .throw();
|
| - should(
|
| - () => node.getFloatTimeDomainData(null),
|
| - node.constructor.name + '.getFloatTimeDomainData(null)')
|
| - .throw();
|
| - should(
|
| - () => node.getByteTimeDomainData(null),
|
| - node.constructor.name + '.getByteTimeDomainData(null)')
|
| - .throw();
|
| -
|
| - if (window.SharedArrayBuffer) {
|
| - should(
|
| - () => node.getFloatFrequencyData(new Float32Array(new SharedArrayBuffer(16))),
|
| - 'AnalyserNode.getFloatFrequencyData(SharedArrayBuffer view)')
|
| - .throw();
|
| - should(
|
| - () => node.getByteFrequencyData(new Uint8Array(new SharedArrayBuffer(16))),
|
| - node.constructor.name + '.getByteFrequencyData(SharedArrayBuffer view)')
|
| - .throw();
|
| - should(
|
| - () => node.getFloatTimeDomainData(new Float32Array(new SharedArrayBuffer(16))),
|
| - node.constructor.name + '.getFloatTimeDomainData(SharedArrayBuffer view)')
|
| - .throw();
|
| - should(
|
| - () => node.getByteTimeDomainData(new Uint8Array(new SharedArrayBuffer(16))),
|
| - node.constructor.name + '.getByteTimeDomainData(SharedArrayBuffer view)')
|
| - .throw();
|
| - }
|
| -
|
| - // AudioBuffers
|
| - node = context.createBuffer(1, 1, context.sampleRate);
|
| - // Invalid channel index: IndexSizeError
|
| - should(
|
| - () => node.getChannelData(2),
|
| - node.constructor.name + '.getChannelData(2)')
|
| - .throw();
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define(
|
| - {
|
| - label: 'Init test nodes',
|
| - description: 'Create test nodes for the following tests'
|
| - },
|
| - (task, should) => {
|
| - should(() => {
|
| - node = context.createGain();
|
| - }, 'node = context.createGain()').notThrow();
|
| - should(() => {
|
| - node2 = context.createGain();
|
| - }, 'node2 = context.createGain()').notThrow();
|
| -
|
| - task.done();
|
| - });
|
| -
|
| -audit.define(
|
| - {label: 'connections', description: 'AudioNode connections'},
|
| - (task, should) => {
|
| -
|
| - // AudioNode connections
|
| - // Invalid destination node (unspecified error)
|
| - should(() => node.connect(null, 0, 0), 'node.connect(null, 0, 0)')
|
| - .throw();
|
| - // Invalid input or output index: IndexSizeError
|
| - should(
|
| - () => node.connect(context.destination, 100, 0),
|
| - 'node.connect(context.destination, 100, 0)')
|
| - .throw('IndexSizeError');
|
| - should(
|
| - () => node.connect(context.destination, 0, 100),
|
| - 'node.connect(context.destination, 0, 100)')
|
| - .throw('IndexSizeError');
|
| - should(
|
| - () => node.connect(node2.gain, 100), 'node.connect(node2.gain, 100)')
|
| - .throw('IndexSizeError');
|
| - should(() => node.disconnect(99), 'node.disconnect(99)')
|
| - .throw('IndexSizeError');
|
| - // Can't connect to a different context (unspecified error)
|
| - should(
|
| - () => node.connect(otherContext.destination),
|
| - 'node.connect(otherContext.destination)')
|
| - .throw();
|
| -
|
| - task.done();
|
| - });
|
| -
|
| -audit.define(
|
| - {
|
| - label: 'channel-stuff',
|
| - description: 'channelCount, channelCountMode, channelInterpretation'
|
| - },
|
| - (task, should) => {
|
| -
|
| - // Invalid channel count: NotSupportedError
|
| - shouldThrowAndBeUnchanged(should, node, 'channelCount', '99');
|
| - // Invalid mode or interpretation (unspecified error)
|
| - currentMode = node.channelCountMode;
|
| - currentInterpretation = node.channelInterpretation;
|
| - should(
|
| - () => node.channelCountMode = 'fancy',
|
| - 'node.channelCountMode = "fancy"')
|
| - .notThrow();
|
| - should(node.channelCountMode, 'node.channelCountMode')
|
| - .beEqualTo(currentMode);
|
| - should(
|
| - () => node.channelInterpretation = mode,
|
| - 'node.channelInterpretation = mode')
|
| - .notThrow();
|
| - should(node.channelInterpretation, 'node.channelInterpretation')
|
| - .beEqualTo(currentInterpretation);
|
| - // Destination node channel count: should throw IndexSizeError on invalid
|
| - // channel count. shouldNotThrow() method cannot be used because the error
|
| - // message includes the number of channels, which can change depending on
|
| - // the actual attached hardware.
|
| - should(
|
| - () => context.destination.channelCount = 99,
|
| - 'context.destination.channelCount = 99')
|
| - .throw('IndexSizeError', { omitErrorMessage: true });
|
| -
|
| - task.done();
|
| - });
|
| -
|
| -audit.define('audioparam', (task, should) => {
|
| - // AudioParams
|
| - param = context.createGain().gain;
|
| - should(
|
| - () => param.setValueCurveAtTime(null, 0, 0),
|
| - 'param.setValueCurveAtTime(null, 0, 0)')
|
| - .throw();
|
| -
|
| - // exponentialRampToValue should throw only for "zero" target values.
|
| - should(
|
| - () => node.gain.exponentialRampToValueAtTime(-1, 0.1),
|
| - 'node.gain.exponentialRampToValueAtTime(-1, 0.1)')
|
| - .notThrow();
|
| - should(
|
| - () => node.gain.exponentialRampToValueAtTime(0, 0.1),
|
| - 'node.gain.exponentialRampToValueAtTime(0, 0.1)')
|
| - .throw();
|
| - // 1e-100 is 0 when converted to a single precision float.
|
| - should(
|
| - () => node.gain.exponentialRampToValueAtTime(1e-100, 0.1),
|
| - 'node.gain.exponentialRampToValueAtTime(1e-100, 0.1)')
|
| - .throw();
|
| - // See crbug.com/459391.
|
| - // Math.pow(2, -149) = 1.401298464324817e-45 is the double-float value of the
|
| - // least positive single float number. We do it this way to make sure no
|
| - // round-off or conversion
|
| - // errors happen when reading 1.401298464324817e-45.
|
| - should(
|
| - () => node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1),
|
| - 'node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1)')
|
| - .notThrow();
|
| - // Math.pow(2, -150) = 7.006492321624085d-46 is the largest double float value
|
| - // such that
|
| - // conversion to a float produces 0. Any larger value would produce a
|
| - // non-zero value when
|
| - // converted to a single float.
|
| - should(
|
| - () => node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1),
|
| - 'node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1)')
|
| - .throw();
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('biquad', (task, should) => {
|
| - // BiquadFilterNode
|
| - node = context.createBiquadFilter();
|
| - should(
|
| - () => node.getFrequencyResponse(
|
| - new Float32Array(1), new Float32Array(1), new Float32Array(1)),
|
| - 'node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1))')
|
| - .notThrow();
|
| - should(
|
| - () => node.getFrequencyResponse(
|
| - null, new Float32Array(1), new Float32Array(1)),
|
| - 'node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1))')
|
| - .throw();
|
| - should(
|
| - () => node.getFrequencyResponse(
|
| - new Float32Array(1), null, new Float32Array(1)),
|
| - 'node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1))')
|
| - .throw();
|
| - should(
|
| - () => node.getFrequencyResponse(
|
| - new Float32Array(1), new Float32Array(1), null),
|
| - 'node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null)')
|
| - .throw();
|
| -
|
| - if (window.SharedArrayBuffer) {
|
| - let shared_view = new Float32Array(new SharedArrayBuffer(4));
|
| - let nonshared_view = new Float32Array(1);
|
| -
|
| - should(
|
| - () => node.getFrequencyResponse(shared_view, nonshared_view, nonshared_view),
|
| - 'node.getFrequencyResponse(shared_view, nonshared_view, nonshared_view)')
|
| - .throw();
|
| - should(
|
| - () => node.getFrequencyResponse(nonshared_view, shared_view, nonshared_view),
|
| - 'node.getFrequencyResponse(nonshared_view, shared_view, nonshared_view)')
|
| - .throw();
|
| - should(
|
| - () => node.getFrequencyResponse(nonshared_view, nonshared_view, shared_view),
|
| - 'node.getFrequencyResponse(nonshared_view, nonshared_view, shared_view)')
|
| - .throw();
|
| - }
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('offline-audio-context', (task, should) => {
|
| - // OfflineAudioContext
|
| - // Max supported channels
|
| - should(
|
| - () => new OfflineAudioContext(32, 100, context.sampleRate),
|
| - 'new OfflineAudioContext(32, 100, context.sampleRate)')
|
| - .notThrow();
|
| - // Invalid number of channels
|
| - should(
|
| - () => new OfflineAudioContext(0, 100, context.sampleRate),
|
| - 'new OfflineAudioContext(0, 100, context.sampleRate)')
|
| - .throw('NotSupportedError');
|
| - should(
|
| - () => new OfflineAudioContext(99, 100, context.sampleRate),
|
| - 'new OfflineAudioContext(99, 100, context.sampleRate)')
|
| - .throw('NotSupportedError');
|
| - // Invalid sample rate.
|
| - should(
|
| - () => new OfflineAudioContext(1, 100, 1),
|
| - 'new OfflineAudioContext(1, 100, 1)')
|
| - .throw('NotSupportedError');
|
| - should(
|
| - () => new OfflineAudioContext(1, 100, 1e6),
|
| - 'new OfflineAudioContext(1, 100, 1e6)')
|
| - .throw('NotSupportedError');
|
| - // Invalid frame length (crbug.com/351277)
|
| - should(
|
| - () => new OfflineAudioContext(1, -88200000000000, 44100),
|
| - 'new OfflineAudioContext(1, -88200000000000, 44100)')
|
| - .throw('NotSupportedError');
|
| - should(
|
| - () => new OfflineAudioContext(1, 0, 44100),
|
| - 'new OfflineAudioContext(1, 0, 44100)')
|
| - .throw('NotSupportedError');
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('waveshaper', (task, should) => {
|
| - // WaveShaper types
|
| - node = context.createWaveShaper();
|
| - currentOversample = node.oversample;
|
| - should(() => node.oversample = '9x', 'node.oversample = "9x"').notThrow();
|
| - should(node.oversample, 'node.oversample').beEqualTo(currentOversample);
|
| - should(() => node.curve = {}, 'node.curve = {}').throw();
|
| - should(
|
| - () => node.curve = new Float32Array(1),
|
| - 'node.curve = new Float32Array(1)')
|
| - .throw();
|
| - should(node.curve, 'node.curve').beEqualTo(null);
|
| - should(
|
| - () => node.curve = new Float32Array(2),
|
| - 'node.curve = new Float32Array(2)')
|
| - .notThrow();
|
| - should(() => node.curve = null, 'node.curve = null').notThrow();
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define(
|
| - {label: 'audio-buffer-source', description: 'AudioBufferSource start/stop'},
|
| - (task, should) => {
|
| - // Start/stop for AudioBufferSourceNodes
|
| - buffer = context.createBuffer(1, 1, context.sampleRate);
|
| - should(
|
| - () => source = context.createBufferSource(),
|
| - 'source = context.createBufferSource()')
|
| - .notThrow();
|
| - should(() => { source.buffer = buffer}, 'source.buffer = buffer').notThrow();
|
| - should(
|
| - () => source.buffer = context.createBuffer(1, 10, context.sampleRate),
|
| - 'source.buffer = context.createBuffer(1, 10, context.sampleRate)')
|
| - .throw();
|
| - should(() => {source.start(-1)}, 'source.start(-1)').throw();
|
| - should(() => {source.start(Infinity)}, 'source.start(Infinity)').throw();
|
| - should(() => {source.start(-Infinity)}, 'source.start(-Infinity)').throw();
|
| - should(() => {source.start(NaN)}, 'source.start(NaN)').throw();
|
| - should(() => {source.start(1, Infinity)}, 'source.start(1, Infinity)')
|
| - .throw();
|
| - should(() => {source.start(1, -Infinity)}, 'source.start(1, -Infinity)')
|
| - .throw();
|
| - should(() => {source.start(1, NaN)}, 'source.start(1, NaN)').throw();
|
| - should(() => {source.start(1, -1)}, 'source.start(1, -1)').throw();
|
| - should(
|
| - () => {source.start(1, -Number.MIN_VALUE)},
|
| - 'source.start(1, -Number.MIN_VALUE)')
|
| - .throw();
|
| - should(() => {source.start(1, 1, Infinity)}, 'source.start(1, 1, Infinity)')
|
| - .throw();
|
| - should(
|
| - () => {source.start(1, 1, -Infinity)}, 'source.start(1, 1, -Infinity)')
|
| - .throw();
|
| - should(() => {source.start(1, 1, NaN)}, 'source.start(1, 1, NaN)').throw();
|
| - should(() => {source.start(1, 1, -1)}, 'source.start(1, 1, -1)').throw();
|
| - should(
|
| - () => {source.start(1, 1, -Number.MIN_VALUE)},
|
| - 'source.start(1, 1, -Number.MIN_VALUE)')
|
| - .throw();
|
| - should(() => source.start(), 'source.start()').notThrow();
|
| - should(
|
| - () => source.stop(-Number.MIN_VALUE),
|
| - 'source.stop(-Number.MIN_VALUE)')
|
| - .throw();
|
| - should(() => source.stop(Infinity), 'source.stop(Infinity)').throw();
|
| - should(() => source.stop(-Infinity), 'source.stop(-Infinity)').throw();
|
| - should(() => source.stop(NaN), 'source.stop(NaN)').throw();
|
| - should(() => source.stop(), 'source.stop()').notThrow();
|
| -
|
| - // Verify that start(0, 0) doesn't signal.
|
| - let source2;
|
| - should(
|
| - () => { source2 = context.createBufferSource()},
|
| - 'source2 = context.createBufferSource()')
|
| - .notThrow();
|
| - should(() => source2.buffer = buffer, 'source2.buffer = buffer').notThrow();
|
| - should(() => source2.start(0, 0), 'source2.start(0, 0)').notThrow();
|
| -
|
| - // Verify that start(0, -0.0) doesn't signal.
|
| - let source3;
|
| - should(
|
| - () => source3 = context.createBufferSource(),
|
| - 'source3 = context.createBufferSource()')
|
| - .notThrow();
|
| - should(() => source3.buffer = buffer, 'source3.buffer = buffer').notThrow();
|
| - should(
|
| - () => source3.start(0, -1 / Infinity), 'source3.start(0, -1/Infinity)')
|
| - .notThrow();
|
| -
|
| - // It's not clear from the spec, but I think it's valid to call start().
|
| - // The spec is silent on what happens if we call stop() afterwards, so
|
| - // don't call it.
|
| - let source4;
|
| - should(
|
| - () => source4 = context.createBufferSource(),
|
| - 'source4 = context.createBufferSource()')
|
| - .notThrow();
|
| - should(() => source4.start(), 'source4.start()').notThrow();
|
| -
|
| - buffer = context.createBuffer(1, 1, context.sampleRate);
|
| - let source5;
|
| - should(
|
| - () => source5 = context.createBufferSource(),
|
| - 'source5 = context.createBufferSource()')
|
| - .notThrow();
|
| - should(() => source5.buffer = buffer, 'source5.buffer = buffer').notThrow();
|
| - should(() => source5.stop(), 'source5.stop()').throw();
|
| -
|
| - buffer = context.createBuffer(1, 1, context.sampleRate);
|
| - let source6;
|
| - should(
|
| - () => source6 = context.createBufferSource(),
|
| - 'source6 = context.createBufferSource()')
|
| - .notThrow();
|
| - should(() => source6.buffer = buffer, 'source6.buffer = buffer').notThrow();
|
| - should(() => source6.start(), 'source6.start()').notThrow();
|
| - should(() => source6.start(), 'source6.start()').throw();
|
| -
|
| - buffer = context.createBuffer(1, 1, context.sampleRate);
|
| - let source7;
|
| - should(
|
| - () => source7 = context.createBufferSource(),
|
| - 'source7 = context.createBufferSource()')
|
| - .notThrow();
|
| - should(() => source7.buffer = buffer, 'source7.buffer = buffer').notThrow();
|
| - should(() => source7.start(), 'source7.start()').notThrow();
|
| - should(() => source7.stop(), 'source7.stop()').notThrow();
|
| -
|
| - task.done();
|
| - });
|
| -
|
| -audit.define(
|
| - {label: 'oscillator', description: 'start/stop'}, (task, should) => {
|
| -
|
| - let source8;
|
| - // Start/stop for OscillatorNodes
|
| - should(
|
| - () => source8 = context.createOscillator(),
|
| - 'source8 = context.createOscillator()')
|
| - .notThrow();
|
| - should(
|
| - () => source8.start(-Number.MIN_VALUE),
|
| - 'source8.start(-Number.MIN_VALUE)')
|
| - .throw();
|
| - should(() => source8.start(Infinity), 'source8.start(Infinity)').throw();
|
| - should(() => source8.start(-Infinity), 'source8.start(-Infinity)').throw();
|
| - should(() => source8.start(NaN), 'source8.start(NaN)').throw();
|
| - should(() => source8.start(), 'source8.start()').notThrow();
|
| - should(
|
| - () => source8.stop(-Number.MIN_VALUE),
|
| - 'source8.stop(-Number.MIN_VALUE)')
|
| - .throw();
|
| - should(() => source8.stop(Infinity), 'source8.stop(Infinity)').throw();
|
| - should(() => source8.stop(-Infinity), 'source8.stop(-Infinity)').throw();
|
| - should(() => source8.stop(NaN), 'source8.stop(NaN)').throw();
|
| - should(() => source8.stop(), 'source8.stop()').notThrow();
|
| -
|
| - should(
|
| - () => osc = context.createOscillator(),
|
| - 'osc = context.createOscillator()')
|
| - .notThrow();
|
| - should(() => osc.stop(), 'osc.stop()').throw();
|
| - should(
|
| - () => osc1 = context.createOscillator(),
|
| - 'osc1 = context.createOscillator()')
|
| - .notThrow();
|
| - should(() => osc1.start(), 'osc1.start()').notThrow();
|
| - should(() => osc1.stop(), 'osc1.stop()').notThrow();
|
| -
|
| - should(() => osc.setPeriodicWave(null), 'osc.setPeriodicWave(null)')
|
| - .throw();
|
| -
|
| -
|
| - task.done();
|
| - });
|
| -
|
| -audit.define('convolver', (task, should) => {
|
| - // Convolver buffer rate must match context rate. Create on offline context so
|
| - // we
|
| - // specify the context rate exactly, in case the test is run on platforms with
|
| - // different
|
| - // HW sample rates.
|
| - should(
|
| - () => oc = new OfflineAudioContext(1, 44100, 44100),
|
| - 'oc = new OfflineAudioContext(1, 44100, 44100)')
|
| - .notThrow();
|
| - should(() => conv = oc.createConvolver(), 'conv = oc.createConvolver()')
|
| - .notThrow();
|
| - should(() => conv.buffer = {}, 'conv.buffer = {}').throw();
|
| - should(
|
| - () => conv.buffer = oc.createBuffer(1, 100, 22050),
|
| - 'conv.buffer = oc.createBuffer(1, 100, 22050)')
|
| - .throw();
|
| - // conv.buffer should be unchanged (null) because the above failed.
|
| - should(conv.buffer, 'conv.buffer').beEqualTo(null);
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('panner', (task, should) => {
|
| - // PannerNode channel count and mode
|
| - panner = context.createPanner();
|
| - // Channel count can only be set to 1 or 2.
|
| - should(() => panner.channelCount = 1, 'panner.channelCount = 1').notThrow();
|
| - should(() => panner.channelCount = 2, 'panner.channelCount = 2').notThrow();
|
| - shouldThrowAndBeUnchanged(should, panner, 'channelCount', 0);
|
| - shouldThrowAndBeUnchanged(should, panner, 'channelCount', 3);
|
| - // It is illegal to set the mode to 'max'
|
| - shouldThrowAndBeUnchanged(should, panner, 'channelCountMode', 'max');
|
| - should(
|
| - () => panner.channelCountMode = 'explicit',
|
| - 'panner.channelCountMode = "explicit"')
|
| - .notThrow();
|
| - should(
|
| - () => panner.channelCountMode = 'clamped-max',
|
| - 'panner.channelCountMode = "clamped-max"')
|
| - .notThrow();
|
| - should(
|
| - () => panner.channelCountMode = 'junk',
|
| - 'panner.channelCountMode = "junk"')
|
| - .notThrow();
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define('script-processor', (task, should) => {
|
| - // Test channel count and mode for a ScriptProcessor.
|
| - should(
|
| - () => script = context.createScriptProcessor(256, 3),
|
| - 'script = context.createScriptProcessor(256, 3)')
|
| - .notThrow();
|
| - // Make sure the channelCount and mode are set correctly.
|
| - should(script.channelCount, 'script.channelCount').beEqualTo(3);
|
| - should(script.channelCountMode, 'script.channelCountMode')
|
| - .beEqualTo('explicit');
|
| - // Cannot change the channelCount or mode to anything else
|
| - should(() => script.channelCount = 3, 'script.channelCount = 3').notThrow();
|
| - shouldThrowAndBeUnchanged(should, script, 'channelCount', 1);
|
| -
|
| - shouldThrowAndBeUnchanged(should, script, 'channelCount', 7);
|
| - should(
|
| - () => script.channelCountMode = 'explicit',
|
| - 'script.channelCountMode = "explicit"')
|
| - .notThrow();
|
| - shouldThrowAndBeUnchanged(should, script, 'channelCountMode', 'max');
|
| - shouldThrowAndBeUnchanged(should, script, 'channelCountMode', 'clamped-max');
|
| - should(
|
| - () => script.channelCountMode = 'junk',
|
| - 'script.channelCountMode = "junk"')
|
| - .notThrow();
|
| -
|
| - task.done();
|
| -});
|
| -
|
| -audit.define(
|
| - {label: 'misc', description: 'Miscellaneous tests'}, (task, should) => {
|
| -
|
| - // noteOn and noteOff don't exist anymore
|
| - should(osc.noteOn, 'osc.noteOn').beEqualTo(undefined);
|
| - should(osc.noteOff, 'osc.noteOff').beEqualTo(undefined);
|
| - should(source.noteOn, 'source.noteOn').beEqualTo(undefined);
|
| - should(source.noteOff, 'source.noteOff').beEqualTo(undefined);
|
| -
|
| - task.done();
|
| - });
|
| -
|
| -audit.run();
|
| -</script>
|
| -</body>
|
| + <head>
|
| + <title>
|
| + dom-exceptions.html
|
| + </title>
|
| + <script src="../resources/testharness.js"></script>
|
| + <script src="../resources/testharnessreport.js"></script>
|
| + <script src="resources/audit-util.js"></script>
|
| + <script src="resources/audit.js"></script>
|
| + <script src="resources/biquad-testing.js"></script>
|
| + </head>
|
| + <body>
|
| + <script id="layout-test-code">
|
| + let audit = Audit.createTaskRunner();
|
| +
|
| + let otherContext;
|
| + let node;
|
| + let node2;
|
| + let mode;
|
| + let panner;
|
| + let script;
|
| + let source;
|
| +
|
| + function shouldThrowAndBeUnchanged(should, node, attr, value) {
|
| + should(
|
| + () => node[attr] = value,
|
| + node.constructor.name + '.' + attr + ' = ' + value)
|
| + .throw();
|
| + should(node[attr], node.constructor.name + '.' + attr)
|
| + .notBeEqualTo(value);
|
| + }
|
| +
|
| + audit.define(
|
| + {label: 'initialize', description: 'Initialize contexts for testing'},
|
| + (task, should) => {
|
| +
|
| + should(() => {
|
| + context = new AudioContext();
|
| + }, 'context = new AudioContext()').notThrow();
|
| +
|
| + should(() => {
|
| + otherContext = new AudioContext();
|
| + }, 'otherContext = new AudioContext()').notThrow();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createBuffer', (task, should) => {
|
| + // Invalid number of channels: NotSupportedError
|
| + should(
|
| + () => context.createBuffer(99, 1, context.sampleRate),
|
| + 'context.createBuffer(99, 1, context.sampleRate)')
|
| + .throw('NotSupportedError');
|
| + should(
|
| + () => context.createBuffer(0, 1, context.sampleRate),
|
| + 'context.createBuffer(0, 1, context.sampleRate)')
|
| + .throw('NotSupportedError');
|
| + // Invalid sample rate: NotSupportedError
|
| + should(
|
| + () => context.createBuffer(1, 1, 1),
|
| + 'context.createBuffer(1, 1, 1)')
|
| + .throw('NotSupportedError');
|
| + should(
|
| + () => context.createBuffer(1, 1, 2999),
|
| + 'context.createBuffer(1, 1, 2999)')
|
| + .throw('NotSupportedError');
|
| + should(
|
| + () => context.createBuffer(1, 1, 384001),
|
| + 'context.createBuffer(1, 1, 384001)')
|
| + .throw('NotSupportedError');
|
| + should(
|
| + () => context.createBuffer(1, 1, 1e6),
|
| + 'context.createBuffer(1, 1, 1e6)')
|
| + .throw('NotSupportedError');
|
| + // Check valid values from crbug.com/344375
|
| + should(
|
| + () => context.createBuffer(1, 1, 3000),
|
| + 'context.createBuffer(1, 1, 3000)')
|
| + .notThrow();
|
| + should(
|
| + () => context.createBuffer(1, 1, 192000),
|
| + 'context.createBuffer(1, 1, 192000)')
|
| + .notThrow();
|
| + should(
|
| + () => context.createBuffer(1, 1, 384000),
|
| + 'context.createBuffer(1, 1, 384000)')
|
| + .notThrow();
|
| + // Invalid number of frames: NotSupportedError
|
| + should(
|
| + () => context.createBuffer(1, 0, context.sampleRate),
|
| + 'context.createBuffer(1, 0, context.sampleRate)')
|
| + .throw('NotSupportedError');
|
| + // 2-arg createBuffer not allowed.
|
| + should(
|
| + () => context.createBuffer(new ArrayBuffer(100), true),
|
| + 'context.createBuffer(new ArrayBuffer(100), true)')
|
| + .throw('TypeError');
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createMediaElementSource', (task, should) => {
|
| + // Invalid sources (unspecified error)
|
| + should(
|
| + () => context.createMediaElementSource(null),
|
| + 'context.createMediaElementSource(null)')
|
| + .throw();
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createMediaStreamSource', (task, should) => {
|
| + // Invalid sources (unspecified error)
|
| + should(
|
| + () => context.createMediaStreamSource(null),
|
| + 'context.createMediaStreamSource(null)')
|
| + .throw();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createScriptProcessor', (task, should) => {
|
| + // Invalid buffer size: IndexSizeError
|
| + should(
|
| + () => context.createScriptProcessor(1, 1, 1),
|
| + 'context.createScriptProcessor(1, 1, 1)')
|
| + .throw('IndexSizeError');
|
| + // Invalid number of inputs and outputs: IndexSizeError
|
| + should(
|
| + () => context.createScriptProcessor(4096, 100, 1),
|
| + 'context.createScriptProcessor(4096, 100, 1)')
|
| + .throw('IndexSizeError');
|
| + should(
|
| + () => context.createScriptProcessor(4096, 1, 100),
|
| + 'context.createScriptProcessor(4096, 1, 100)')
|
| + .throw('IndexSizeError');
|
| + should(
|
| + () => context.createScriptProcessor(),
|
| + 'context.createScriptProcessor()')
|
| + .notThrow();
|
| + should(
|
| + () => context.createScriptProcessor(0),
|
| + 'context.createScriptProcessor(0)')
|
| + .notThrow();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createChannelSplitter', (task, should) => {
|
| + // Invalid number of channels: IndexSizeError
|
| + should(
|
| + () => context.createChannelSplitter(0),
|
| + 'context.createChannelSplitter(0)')
|
| + .throw('IndexSizeError');
|
| + should(
|
| + () => context.createChannelSplitter(99),
|
| + 'context.createChannelSplitter(99)')
|
| + .throw('IndexSizeError');
|
| + should(
|
| + () => context.createChannelMerger(0),
|
| + 'context.createChannelMerger(0)')
|
| + .throw('IndexSizeError');
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createChannelMerger', (task, should) => {
|
| + // Invalid number of channels: IndexSizeError
|
| + should(
|
| + () => context.createChannelMerger(99),
|
| + 'context.createChannelMerger(99)')
|
| + .throw('IndexSizeError');
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createPeriodicWave', (task, should) => {
|
| + // Invalid real/imag arrays: IndexSizeError
|
| + should(
|
| + () => context.createPeriodicWave(null, null),
|
| + 'context.createPeriodicWave(null, null)')
|
| + .throw('TypeError');
|
| + should(
|
| + () => context.createPeriodicWave(new Float32Array(10), null),
|
| + 'context.createPeriodicWave(new Float32Array(10), null)')
|
| + .throw('TypeError');
|
| + // Verify that we can use large arrays with no limit. Roughly.
|
| + should(
|
| + () => context.createPeriodicWave(
|
| + new Float32Array(4100), new Float32Array(4100)),
|
| + 'context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100))')
|
| + .notThrow();
|
| + should(
|
| + () => context.createPeriodicWave(
|
| + new Float32Array(8192), new Float32Array(8192)),
|
| + 'context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192))')
|
| + .notThrow();
|
| + should(
|
| + () => context.createPeriodicWave(
|
| + new Float32Array(10000), new Float32Array(10000)),
|
| + 'context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000))')
|
| + .notThrow();
|
| + // Real and imaginary arrays must have the same size: IndexSizeError
|
| + should(
|
| + () => context.createPeriodicWave(
|
| + new Float32Array(10), new Float32Array(7)),
|
| + 'context.createPeriodicWave(new Float32Array(10), new Float32Array(7))')
|
| + .throw('IndexSizeError');
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('createAnalyser', (task, should) => {
|
| + // Analysers
|
| + node = context.createAnalyser();
|
| + // Invalid fftSize: IndexSizeError
|
| + shouldThrowAndBeUnchanged(should, node, 'fftSize', '42');
|
| + shouldThrowAndBeUnchanged(should, node, 'fftSize', '16');
|
| + should(() => node.fftSize = 32768, 'AnalyserNode.fftSize = 32768')
|
| + .notThrow();
|
| + shouldThrowAndBeUnchanged(should, node, 'fftSize', '65536');
|
| +
|
| + shouldThrowAndBeUnchanged(should, node, 'minDecibels', '-10');
|
| + shouldThrowAndBeUnchanged(should, node, 'maxDecibels', '-150');
|
| + shouldThrowAndBeUnchanged(should, node, 'minDecibels', '-30');
|
| + shouldThrowAndBeUnchanged(should, node, 'maxDecibels', '-100');
|
| +
|
| + shouldThrowAndBeUnchanged(
|
| + should, node, 'smoothingTimeConstant', '-0.1');
|
| + shouldThrowAndBeUnchanged(should, node, 'smoothingTimeConstant', '1.5');
|
| +
|
| + should(
|
| + () => node.getFloatFrequencyData(null),
|
| + 'AnalyserNode.getFloatFrequencyData(null)')
|
| + .throw();
|
| + should(
|
| + () => node.getByteFrequencyData(null),
|
| + node.constructor.name + '.getByteFrequencyData(null)')
|
| + .throw();
|
| + should(
|
| + () => node.getFloatTimeDomainData(null),
|
| + node.constructor.name + '.getFloatTimeDomainData(null)')
|
| + .throw();
|
| + should(
|
| + () => node.getByteTimeDomainData(null),
|
| + node.constructor.name + '.getByteTimeDomainData(null)')
|
| + .throw();
|
| +
|
| + if (window.SharedArrayBuffer) {
|
| + should(
|
| + () => node.getFloatFrequencyData(
|
| + new Float32Array(new SharedArrayBuffer(16))),
|
| + 'AnalyserNode.getFloatFrequencyData(SharedArrayBuffer view)')
|
| + .throw();
|
| + should(
|
| + () => node.getByteFrequencyData(
|
| + new Uint8Array(new SharedArrayBuffer(16))),
|
| + node.constructor.name +
|
| + '.getByteFrequencyData(SharedArrayBuffer view)')
|
| + .throw();
|
| + should(
|
| + () => node.getFloatTimeDomainData(
|
| + new Float32Array(new SharedArrayBuffer(16))),
|
| + node.constructor.name +
|
| + '.getFloatTimeDomainData(SharedArrayBuffer view)')
|
| + .throw();
|
| + should(
|
| + () => node.getByteTimeDomainData(
|
| + new Uint8Array(new SharedArrayBuffer(16))),
|
| + node.constructor.name +
|
| + '.getByteTimeDomainData(SharedArrayBuffer view)')
|
| + .throw();
|
| + }
|
| +
|
| + // AudioBuffers
|
| + node = context.createBuffer(1, 1, context.sampleRate);
|
| + // Invalid channel index: IndexSizeError
|
| + should(
|
| + () => node.getChannelData(2),
|
| + node.constructor.name + '.getChannelData(2)')
|
| + .throw();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define(
|
| + {
|
| + label: 'Init test nodes',
|
| + description: 'Create test nodes for the following tests'
|
| + },
|
| + (task, should) => {
|
| + should(() => {
|
| + node = context.createGain();
|
| + }, 'node = context.createGain()').notThrow();
|
| + should(() => {
|
| + node2 = context.createGain();
|
| + }, 'node2 = context.createGain()').notThrow();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define(
|
| + {label: 'connections', description: 'AudioNode connections'},
|
| + (task, should) => {
|
| +
|
| + // AudioNode connections
|
| + // Invalid destination node (unspecified error)
|
| + should(() => node.connect(null, 0, 0), 'node.connect(null, 0, 0)')
|
| + .throw();
|
| + // Invalid input or output index: IndexSizeError
|
| + should(
|
| + () => node.connect(context.destination, 100, 0),
|
| + 'node.connect(context.destination, 100, 0)')
|
| + .throw('IndexSizeError');
|
| + should(
|
| + () => node.connect(context.destination, 0, 100),
|
| + 'node.connect(context.destination, 0, 100)')
|
| + .throw('IndexSizeError');
|
| + should(
|
| + () => node.connect(node2.gain, 100),
|
| + 'node.connect(node2.gain, 100)')
|
| + .throw('IndexSizeError');
|
| + should(() => node.disconnect(99), 'node.disconnect(99)')
|
| + .throw('IndexSizeError');
|
| + // Can't connect to a different context (unspecified error)
|
| + should(
|
| + () => node.connect(otherContext.destination),
|
| + 'node.connect(otherContext.destination)')
|
| + .throw();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define(
|
| + {
|
| + label: 'channel-stuff',
|
| + description: 'channelCount, channelCountMode, channelInterpretation'
|
| + },
|
| + (task, should) => {
|
| +
|
| + // Invalid channel count: NotSupportedError
|
| + shouldThrowAndBeUnchanged(should, node, 'channelCount', '99');
|
| + // Invalid mode or interpretation (unspecified error)
|
| + currentMode = node.channelCountMode;
|
| + currentInterpretation = node.channelInterpretation;
|
| + should(
|
| + () => node.channelCountMode = 'fancy',
|
| + 'node.channelCountMode = "fancy"')
|
| + .notThrow();
|
| + should(node.channelCountMode, 'node.channelCountMode')
|
| + .beEqualTo(currentMode);
|
| + should(
|
| + () => node.channelInterpretation = mode,
|
| + 'node.channelInterpretation = mode')
|
| + .notThrow();
|
| + should(node.channelInterpretation, 'node.channelInterpretation')
|
| + .beEqualTo(currentInterpretation);
|
| + // Destination node channel count: should throw IndexSizeError on
|
| + // invalid channel count. shouldNotThrow() method cannot be used
|
| + // because the error message includes the number of channels, which
|
| + // can change depending on the actual attached hardware.
|
| + should(
|
| + () => context.destination.channelCount = 99,
|
| + 'context.destination.channelCount = 99')
|
| + .throw('IndexSizeError', {omitErrorMessage: true});
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('audioparam', (task, should) => {
|
| + // AudioParams
|
| + param = context.createGain().gain;
|
| + should(
|
| + () => param.setValueCurveAtTime(null, 0, 0),
|
| + 'param.setValueCurveAtTime(null, 0, 0)')
|
| + .throw();
|
| +
|
| + // exponentialRampToValue should throw only for "zero" target values.
|
| + should(
|
| + () => node.gain.exponentialRampToValueAtTime(-1, 0.1),
|
| + 'node.gain.exponentialRampToValueAtTime(-1, 0.1)')
|
| + .notThrow();
|
| + should(
|
| + () => node.gain.exponentialRampToValueAtTime(0, 0.1),
|
| + 'node.gain.exponentialRampToValueAtTime(0, 0.1)')
|
| + .throw();
|
| + // 1e-100 is 0 when converted to a single precision float.
|
| + should(
|
| + () => node.gain.exponentialRampToValueAtTime(1e-100, 0.1),
|
| + 'node.gain.exponentialRampToValueAtTime(1e-100, 0.1)')
|
| + .throw();
|
| + // See crbug.com/459391.
|
| + // Math.pow(2, -149) = 1.401298464324817e-45 is the double-float value
|
| + // of the least positive single float number. We do it this way to make
|
| + // sure no round-off or conversion errors happen when reading
|
| + // 1.401298464324817e-45.
|
| + should(
|
| + () =>
|
| + node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1),
|
| + 'node.gain.exponentialRampToValueAtTime(Math.pow(2, -149), 0.1)')
|
| + .notThrow();
|
| + // Math.pow(2, -150) = 7.006492321624085d-46 is the largest double float
|
| + // value such that conversion to a float produces 0. Any larger value
|
| + // would produce a non-zero value when converted to a single float.
|
| + should(
|
| + () =>
|
| + node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1),
|
| + 'node.gain.exponentialRampToValueAtTime(Math.pow(2, -150), 0.1)')
|
| + .throw();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('biquad', (task, should) => {
|
| + // BiquadFilterNode
|
| + node = context.createBiquadFilter();
|
| + should(
|
| + () => node.getFrequencyResponse(
|
| + new Float32Array(1), new Float32Array(1), new Float32Array(1)),
|
| + 'node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), new Float32Array(1))')
|
| + .notThrow();
|
| + should(
|
| + () => node.getFrequencyResponse(
|
| + null, new Float32Array(1), new Float32Array(1)),
|
| + 'node.getFrequencyResponse(null, new Float32Array(1), new Float32Array(1))')
|
| + .throw();
|
| + should(
|
| + () => node.getFrequencyResponse(
|
| + new Float32Array(1), null, new Float32Array(1)),
|
| + 'node.getFrequencyResponse(new Float32Array(1), null, new Float32Array(1))')
|
| + .throw();
|
| + should(
|
| + () => node.getFrequencyResponse(
|
| + new Float32Array(1), new Float32Array(1), null),
|
| + 'node.getFrequencyResponse(new Float32Array(1), new Float32Array(1), null)')
|
| + .throw();
|
| +
|
| + if (window.SharedArrayBuffer) {
|
| + let shared_view = new Float32Array(new SharedArrayBuffer(4));
|
| + let nonshared_view = new Float32Array(1);
|
| +
|
| + should(
|
| + () => node.getFrequencyResponse(
|
| + shared_view, nonshared_view, nonshared_view),
|
| + 'node.getFrequencyResponse(shared_view, nonshared_view, nonshared_view)')
|
| + .throw();
|
| + should(
|
| + () => node.getFrequencyResponse(
|
| + nonshared_view, shared_view, nonshared_view),
|
| + 'node.getFrequencyResponse(nonshared_view, shared_view, nonshared_view)')
|
| + .throw();
|
| + should(
|
| + () => node.getFrequencyResponse(
|
| + nonshared_view, nonshared_view, shared_view),
|
| + 'node.getFrequencyResponse(nonshared_view, nonshared_view, shared_view)')
|
| + .throw();
|
| + }
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('offline-audio-context', (task, should) => {
|
| + // OfflineAudioContext
|
| + // Max supported channels
|
| + should(
|
| + () => new OfflineAudioContext(32, 100, context.sampleRate),
|
| + 'new OfflineAudioContext(32, 100, context.sampleRate)')
|
| + .notThrow();
|
| + // Invalid number of channels
|
| + should(
|
| + () => new OfflineAudioContext(0, 100, context.sampleRate),
|
| + 'new OfflineAudioContext(0, 100, context.sampleRate)')
|
| + .throw('NotSupportedError');
|
| + should(
|
| + () => new OfflineAudioContext(99, 100, context.sampleRate),
|
| + 'new OfflineAudioContext(99, 100, context.sampleRate)')
|
| + .throw('NotSupportedError');
|
| + // Invalid sample rate.
|
| + should(
|
| + () => new OfflineAudioContext(1, 100, 1),
|
| + 'new OfflineAudioContext(1, 100, 1)')
|
| + .throw('NotSupportedError');
|
| + should(
|
| + () => new OfflineAudioContext(1, 100, 1e6),
|
| + 'new OfflineAudioContext(1, 100, 1e6)')
|
| + .throw('NotSupportedError');
|
| + // Invalid frame length (crbug.com/351277)
|
| + should(
|
| + () => new OfflineAudioContext(1, -88200000000000, 44100),
|
| + 'new OfflineAudioContext(1, -88200000000000, 44100)')
|
| + .throw('NotSupportedError');
|
| + should(
|
| + () => new OfflineAudioContext(1, 0, 44100),
|
| + 'new OfflineAudioContext(1, 0, 44100)')
|
| + .throw('NotSupportedError');
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('waveshaper', (task, should) => {
|
| + // WaveShaper types
|
| + node = context.createWaveShaper();
|
| + currentOversample = node.oversample;
|
| + should(() => node.oversample = '9x', 'node.oversample = "9x"')
|
| + .notThrow();
|
| + should(node.oversample, 'node.oversample').beEqualTo(currentOversample);
|
| + should(() => node.curve = {}, 'node.curve = {}').throw();
|
| + should(
|
| + () => node.curve = new Float32Array(1),
|
| + 'node.curve = new Float32Array(1)')
|
| + .throw();
|
| + should(node.curve, 'node.curve').beEqualTo(null);
|
| + should(
|
| + () => node.curve = new Float32Array(2),
|
| + 'node.curve = new Float32Array(2)')
|
| + .notThrow();
|
| + should(() => node.curve = null, 'node.curve = null').notThrow();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define(
|
| + {
|
| + label: 'audio-buffer-source',
|
| + description: 'AudioBufferSource start/stop'
|
| + },
|
| + (task, should) => {
|
| + // Start/stop for AudioBufferSourceNodes
|
| + buffer = context.createBuffer(1, 1, context.sampleRate);
|
| + should(
|
| + () => source = context.createBufferSource(),
|
| + 'source = context.createBufferSource()')
|
| + .notThrow();
|
| + should(() => {source.buffer = buffer}, 'source.buffer = buffer')
|
| + .notThrow();
|
| + should(
|
| + () => source.buffer =
|
| + context.createBuffer(1, 10, context.sampleRate),
|
| + 'source.buffer = context.createBuffer(1, 10, context.sampleRate)')
|
| + .throw();
|
| + should(() => {source.start(-1)}, 'source.start(-1)').throw();
|
| + should(() => {source.start(Infinity)}, 'source.start(Infinity)')
|
| + .throw();
|
| + should(() => {source.start(-Infinity)}, 'source.start(-Infinity)')
|
| + .throw();
|
| + should(() => {source.start(NaN)}, 'source.start(NaN)').throw();
|
| + should(
|
| + () => {source.start(1, Infinity)}, 'source.start(1, Infinity)')
|
| + .throw();
|
| + should(
|
| + () => {source.start(1, -Infinity)},
|
| + 'source.start(1, -Infinity)')
|
| + .throw();
|
| + should(() => {source.start(1, NaN)}, 'source.start(1, NaN)')
|
| + .throw();
|
| + should(() => {source.start(1, -1)}, 'source.start(1, -1)').throw();
|
| + should(
|
| + () => {source.start(1, -Number.MIN_VALUE)},
|
| + 'source.start(1, -Number.MIN_VALUE)')
|
| + .throw();
|
| + should(
|
| + () => {source.start(1, 1, Infinity)},
|
| + 'source.start(1, 1, Infinity)')
|
| + .throw();
|
| + should(
|
| + () => {source.start(1, 1, -Infinity)},
|
| + 'source.start(1, 1, -Infinity)')
|
| + .throw();
|
| + should(() => {source.start(1, 1, NaN)}, 'source.start(1, 1, NaN)')
|
| + .throw();
|
| + should(() => {source.start(1, 1, -1)}, 'source.start(1, 1, -1)')
|
| + .throw();
|
| + should(
|
| + () => {source.start(1, 1, -Number.MIN_VALUE)},
|
| + 'source.start(1, 1, -Number.MIN_VALUE)')
|
| + .throw();
|
| + should(() => source.start(), 'source.start()').notThrow();
|
| + should(
|
| + () => source.stop(-Number.MIN_VALUE),
|
| + 'source.stop(-Number.MIN_VALUE)')
|
| + .throw();
|
| + should(() => source.stop(Infinity), 'source.stop(Infinity)')
|
| + .throw();
|
| + should(() => source.stop(-Infinity), 'source.stop(-Infinity)')
|
| + .throw();
|
| + should(() => source.stop(NaN), 'source.stop(NaN)').throw();
|
| + should(() => source.stop(), 'source.stop()').notThrow();
|
| +
|
| + // Verify that start(0, 0) doesn't signal.
|
| + let source2;
|
| + should(
|
| + () => {source2 = context.createBufferSource()},
|
| + 'source2 = context.createBufferSource()')
|
| + .notThrow();
|
| + should(() => source2.buffer = buffer, 'source2.buffer = buffer')
|
| + .notThrow();
|
| + should(() => source2.start(0, 0), 'source2.start(0, 0)').notThrow();
|
| +
|
| + // Verify that start(0, -0.0) doesn't signal.
|
| + let source3;
|
| + should(
|
| + () => source3 = context.createBufferSource(),
|
| + 'source3 = context.createBufferSource()')
|
| + .notThrow();
|
| + should(() => source3.buffer = buffer, 'source3.buffer = buffer')
|
| + .notThrow();
|
| + should(
|
| + () => source3.start(0, -1 / Infinity),
|
| + 'source3.start(0, -1/Infinity)')
|
| + .notThrow();
|
| +
|
| + // It's not clear from the spec, but I think it's valid to call
|
| + // start(). The spec is silent on what happens if we call stop()
|
| + // afterwards, so don't call it.
|
| + let source4;
|
| + should(
|
| + () => source4 = context.createBufferSource(),
|
| + 'source4 = context.createBufferSource()')
|
| + .notThrow();
|
| + should(() => source4.start(), 'source4.start()').notThrow();
|
| +
|
| + buffer = context.createBuffer(1, 1, context.sampleRate);
|
| + let source5;
|
| + should(
|
| + () => source5 = context.createBufferSource(),
|
| + 'source5 = context.createBufferSource()')
|
| + .notThrow();
|
| + should(() => source5.buffer = buffer, 'source5.buffer = buffer')
|
| + .notThrow();
|
| + should(() => source5.stop(), 'source5.stop()').throw();
|
| +
|
| + buffer = context.createBuffer(1, 1, context.sampleRate);
|
| + let source6;
|
| + should(
|
| + () => source6 = context.createBufferSource(),
|
| + 'source6 = context.createBufferSource()')
|
| + .notThrow();
|
| + should(() => source6.buffer = buffer, 'source6.buffer = buffer')
|
| + .notThrow();
|
| + should(() => source6.start(), 'source6.start()').notThrow();
|
| + should(() => source6.start(), 'source6.start()').throw();
|
| +
|
| + buffer = context.createBuffer(1, 1, context.sampleRate);
|
| + let source7;
|
| + should(
|
| + () => source7 = context.createBufferSource(),
|
| + 'source7 = context.createBufferSource()')
|
| + .notThrow();
|
| + should(() => source7.buffer = buffer, 'source7.buffer = buffer')
|
| + .notThrow();
|
| + should(() => source7.start(), 'source7.start()').notThrow();
|
| + should(() => source7.stop(), 'source7.stop()').notThrow();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define(
|
| + {label: 'oscillator', description: 'start/stop'}, (task, should) => {
|
| +
|
| + let source8;
|
| + // Start/stop for OscillatorNodes
|
| + should(
|
| + () => source8 = context.createOscillator(),
|
| + 'source8 = context.createOscillator()')
|
| + .notThrow();
|
| + should(
|
| + () => source8.start(-Number.MIN_VALUE),
|
| + 'source8.start(-Number.MIN_VALUE)')
|
| + .throw();
|
| + should(() => source8.start(Infinity), 'source8.start(Infinity)')
|
| + .throw();
|
| + should(() => source8.start(-Infinity), 'source8.start(-Infinity)')
|
| + .throw();
|
| + should(() => source8.start(NaN), 'source8.start(NaN)').throw();
|
| + should(() => source8.start(), 'source8.start()').notThrow();
|
| + should(
|
| + () => source8.stop(-Number.MIN_VALUE),
|
| + 'source8.stop(-Number.MIN_VALUE)')
|
| + .throw();
|
| + should(() => source8.stop(Infinity), 'source8.stop(Infinity)')
|
| + .throw();
|
| + should(() => source8.stop(-Infinity), 'source8.stop(-Infinity)')
|
| + .throw();
|
| + should(() => source8.stop(NaN), 'source8.stop(NaN)').throw();
|
| + should(() => source8.stop(), 'source8.stop()').notThrow();
|
| +
|
| + should(
|
| + () => osc = context.createOscillator(),
|
| + 'osc = context.createOscillator()')
|
| + .notThrow();
|
| + should(() => osc.stop(), 'osc.stop()').throw();
|
| + should(
|
| + () => osc1 = context.createOscillator(),
|
| + 'osc1 = context.createOscillator()')
|
| + .notThrow();
|
| + should(() => osc1.start(), 'osc1.start()').notThrow();
|
| + should(() => osc1.stop(), 'osc1.stop()').notThrow();
|
| +
|
| + should(() => osc.setPeriodicWave(null), 'osc.setPeriodicWave(null)')
|
| + .throw();
|
| +
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('convolver', (task, should) => {
|
| + // Convolver buffer rate must match context rate. Create on offline
|
| + // context so we specify the context rate exactly, in case the test is
|
| + // run on platforms with different HW sample rates.
|
| + should(
|
| + () => oc = new OfflineAudioContext(1, 44100, 44100),
|
| + 'oc = new OfflineAudioContext(1, 44100, 44100)')
|
| + .notThrow();
|
| + should(() => conv = oc.createConvolver(), 'conv = oc.createConvolver()')
|
| + .notThrow();
|
| + should(() => conv.buffer = {}, 'conv.buffer = {}').throw();
|
| + should(
|
| + () => conv.buffer = oc.createBuffer(1, 100, 22050),
|
| + 'conv.buffer = oc.createBuffer(1, 100, 22050)')
|
| + .throw();
|
| + // conv.buffer should be unchanged (null) because the above failed.
|
| + should(conv.buffer, 'conv.buffer').beEqualTo(null);
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('panner', (task, should) => {
|
| + // PannerNode channel count and mode
|
| + panner = context.createPanner();
|
| + // Channel count can only be set to 1 or 2.
|
| + should(() => panner.channelCount = 1, 'panner.channelCount = 1')
|
| + .notThrow();
|
| + should(() => panner.channelCount = 2, 'panner.channelCount = 2')
|
| + .notThrow();
|
| + shouldThrowAndBeUnchanged(should, panner, 'channelCount', 0);
|
| + shouldThrowAndBeUnchanged(should, panner, 'channelCount', 3);
|
| + // It is illegal to set the mode to 'max'
|
| + shouldThrowAndBeUnchanged(should, panner, 'channelCountMode', 'max');
|
| + should(
|
| + () => panner.channelCountMode = 'explicit',
|
| + 'panner.channelCountMode = "explicit"')
|
| + .notThrow();
|
| + should(
|
| + () => panner.channelCountMode = 'clamped-max',
|
| + 'panner.channelCountMode = "clamped-max"')
|
| + .notThrow();
|
| + should(
|
| + () => panner.channelCountMode = 'junk',
|
| + 'panner.channelCountMode = "junk"')
|
| + .notThrow();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define('script-processor', (task, should) => {
|
| + // Test channel count and mode for a ScriptProcessor.
|
| + should(
|
| + () => script = context.createScriptProcessor(256, 3),
|
| + 'script = context.createScriptProcessor(256, 3)')
|
| + .notThrow();
|
| + // Make sure the channelCount and mode are set correctly.
|
| + should(script.channelCount, 'script.channelCount').beEqualTo(3);
|
| + should(script.channelCountMode, 'script.channelCountMode')
|
| + .beEqualTo('explicit');
|
| + // Cannot change the channelCount or mode to anything else
|
| + should(() => script.channelCount = 3, 'script.channelCount = 3')
|
| + .notThrow();
|
| + shouldThrowAndBeUnchanged(should, script, 'channelCount', 1);
|
| +
|
| + shouldThrowAndBeUnchanged(should, script, 'channelCount', 7);
|
| + should(
|
| + () => script.channelCountMode = 'explicit',
|
| + 'script.channelCountMode = "explicit"')
|
| + .notThrow();
|
| + shouldThrowAndBeUnchanged(should, script, 'channelCountMode', 'max');
|
| + shouldThrowAndBeUnchanged(
|
| + should, script, 'channelCountMode', 'clamped-max');
|
| + should(
|
| + () => script.channelCountMode = 'junk',
|
| + 'script.channelCountMode = "junk"')
|
| + .notThrow();
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.define(
|
| + {label: 'misc', description: 'Miscellaneous tests'},
|
| + (task, should) => {
|
| +
|
| + // noteOn and noteOff don't exist anymore
|
| + should(osc.noteOn, 'osc.noteOn').beEqualTo(undefined);
|
| + should(osc.noteOff, 'osc.noteOff').beEqualTo(undefined);
|
| + should(source.noteOn, 'source.noteOn').beEqualTo(undefined);
|
| + should(source.noteOff, 'source.noteOff').beEqualTo(undefined);
|
| +
|
| + task.done();
|
| + });
|
| +
|
| + audit.run();
|
| + </script>
|
| + </body>
|
| </html>
|
|
|