Bug 1324352 - Implement BaseAudioContext, r=padenot
☠☠ backed out by 9a3a17725724 ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 20 Dec 2016 20:20:41 +0100
changeset 326521 50a74758ee7d3079f021694c61f20eba60b0eae2
parent 326520 b352c7f6bc15bcfe4e8f933045878aa5f1238c55
child 326522 d70b97db8d9e50e3b698f4fd76a5bf995b9ddb4a
push id84984
push useramarchesini@mozilla.com
push dateTue, 20 Dec 2016 19:21:06 +0000
treeherdermozilla-inbound@f350bbf9e636 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1324352
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1324352 - Implement BaseAudioContext, r=padenot
dom/bindings/Bindings.conf
dom/media/MediaStreamGraph.cpp
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/MediaBufferDecoder.cpp
dom/media/webaudio/test/test_OfflineAudioContext.html
dom/media/webaudio/test/test_audioContextSuspendResumeClose.html
dom/webidl/AnalyserNode.webidl
dom/webidl/AudioBuffer.webidl
dom/webidl/AudioBufferSourceNode.webidl
dom/webidl/AudioContext.webidl
dom/webidl/AudioNode.webidl
dom/webidl/BaseAudioContext.webidl
dom/webidl/BiquadFilterNode.webidl
dom/webidl/ChannelMergerNode.webidl
dom/webidl/ChannelSplitterNode.webidl
dom/webidl/ConstantSourceNode.webidl
dom/webidl/ConvolverNode.webidl
dom/webidl/DelayNode.webidl
dom/webidl/DynamicsCompressorNode.webidl
dom/webidl/GainNode.webidl
dom/webidl/IIRFilterNode.webidl
dom/webidl/OfflineAudioContext.webidl
dom/webidl/OscillatorNode.webidl
dom/webidl/PannerNode.webidl
dom/webidl/PeriodicWave.webidl
dom/webidl/StereoPannerNode.webidl
dom/webidl/WaveShaperNode.webidl
dom/webidl/moz.build
testing/web-platform/tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html
testing/web-platform/tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html
testing/web-platform/tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html
testing/web-platform/tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -98,16 +98,20 @@ DOMInterfaces = {
         'channelInterpretation': 'channelInterpretationValue',
     },
 },
 
 'BarProp': {
     'headerFile': 'mozilla/dom/BarProps.h',
 },
 
+'BaseAudioContext': {
+    'nativeType': 'mozilla::dom::AudioContext',
+},
+
 'Blob': {
     'headerFile': 'mozilla/dom/File.h',
 },
 
 'BatteryManager': {
     'nativeType': 'mozilla::dom::battery::BatteryManager',
     'headerFile': 'BatteryManager.h'
 },
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -19,17 +19,17 @@
 #include "TrackUnionStream.h"
 #include "ImageContainer.h"
 #include "AudioCaptureStream.h"
 #include "AudioChannelService.h"
 #include "AudioNodeStream.h"
 #include "AudioNodeExternalInputStream.h"
 #include "MediaStreamListener.h"
 #include "MediaStreamVideoSink.h"
-#include "mozilla/dom/AudioContextBinding.h"
+#include "mozilla/dom/BaseAudioContextBinding.h"
 #include "mozilla/media/MediaUtils.h"
 #include <algorithm>
 #include "GeckoProfiler.h"
 #include "VideoFrameContainer.h"
 #include "mozilla/Unused.h"
 #include "mozilla/media/MediaUtils.h"
 #ifdef MOZ_WEBRTC
 #include "AudioOutputObserver.h"
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -10,30 +10,32 @@
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/OwningNonNull.h"
 
 #include "mozilla/dom/AnalyserNode.h"
 #include "mozilla/dom/AnalyserNodeBinding.h"
 #include "mozilla/dom/AudioBufferSourceNodeBinding.h"
 #include "mozilla/dom/AudioContextBinding.h"
+#include "mozilla/dom/BaseAudioContextBinding.h"
 #include "mozilla/dom/BiquadFilterNodeBinding.h"
 #include "mozilla/dom/ChannelMergerNodeBinding.h"
 #include "mozilla/dom/ChannelSplitterNodeBinding.h"
 #include "mozilla/dom/ConvolverNodeBinding.h"
 #include "mozilla/dom/DelayNodeBinding.h"
 #include "mozilla/dom/DynamicsCompressorNodeBinding.h"
 #include "mozilla/dom/GainNodeBinding.h"
 #include "mozilla/dom/IIRFilterNodeBinding.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/MediaElementAudioSourceNodeBinding.h"
 #include "mozilla/dom/MediaStreamAudioSourceNodeBinding.h"
 #include "mozilla/dom/OfflineAudioContextBinding.h"
 #include "mozilla/dom/OscillatorNodeBinding.h"
 #include "mozilla/dom/PannerNodeBinding.h"
+#include "mozilla/dom/PeriodicWaveBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/StereoPannerNodeBinding.h"
 #include "mozilla/dom/WaveShaperNodeBinding.h"
 
 #include "AudioBuffer.h"
 #include "AudioBufferSourceNode.h"
 #include "AudioChannelService.h"
 #include "AudioDestinationNode.h"
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -2,16 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaBufferDecoder.h"
 #include "BufferDecoder.h"
 #include "mozilla/dom/AudioContextBinding.h"
+#include "mozilla/dom/BaseAudioContextBinding.h"
 #include "mozilla/dom/DOMException.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include <speex/speex_resampler.h>
 #include "nsXPCOMCIDInternal.h"
 #include "nsComponentManagerUtils.h"
 #include "MediaDecoderReader.h"
 #include "BufferMediaResource.h"
 #include "DecoderTraits.h"
--- a/dom/media/webaudio/test/test_OfflineAudioContext.html
+++ b/dom/media/webaudio/test/test_OfflineAudioContext.html
@@ -38,20 +38,16 @@ addLoadEvent(function() {
   var buf = ctx.createBuffer(2, 100, ctx.sampleRate);
   for (var i = 0; i < 2; ++i) {
     for (var j = 0; j < 100; ++j) {
       buf.getChannelData(i)[j] = Math.sin(2 * Math.PI * 200 * j / ctx.sampleRate);
     }
   }
 
   expectException(function() {
-    ctx.createMediaStreamDestination();
-  }, DOMException.NOT_SUPPORTED_ERR);
-
-  expectException(function() {
     new OfflineAudioContext(2, 100, 0);
   }, DOMException.NOT_SUPPORTED_ERR);
   expectException(function() {
     new OfflineAudioContext(2, 100, -1);
   }, DOMException.NOT_SUPPORTED_ERR);
   expectException(function() {
     new OfflineAudioContext(0, 100, 44100);
   }, DOMException.NOT_SUPPORTED_ERR);
--- a/dom/media/webaudio/test/test_audioContextSuspendResumeClose.html
+++ b/dom/media/webaudio/test/test_audioContextSuspendResumeClose.html
@@ -321,19 +321,17 @@ function testAudioContext() {
 
   ac.onstatechange = initialSuspendToRunning;
 }
 
 function testOfflineAudioContext() {
   var o = new OfflineAudioContext(1, 44100, 44100);
   is(o.state, "suspended", "OfflineAudioContext should start in suspended state.");
 
-  expectRejectedPromise(o, "suspend", "NotSupportedError");
   expectRejectedPromise(o, "resume", "NotSupportedError");
-  expectRejectedPromise(o, "close", "NotSupportedError");
 
   var previousState = o.state,
       finishedRendering = false;
   function beforeStartRendering() {
     ok(previousState == "suspended" && o.state == "running", "onstatechanged" +
         "handler is called on state changed, and the new state is running");
     previousState = o.state;
     o.onstatechange = onRenderingFinished;
--- a/dom/webidl/AnalyserNode.webidl
+++ b/dom/webidl/AnalyserNode.webidl
@@ -13,17 +13,17 @@
 dictionary AnalyserOptions : AudioNodeOptions {
              unsigned long fftSize = 2048;
              float         maxDecibels = -30;
              float         minDecibels = -100;
              float         smoothingTimeConstant = 0.8;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional AnalyserOptions options)]
+ Constructor(BaseAudioContext context, optional AnalyserOptions options)]
 interface AnalyserNode : AudioNode {
 
     // Real-time frequency-domain data
     void getFloatFrequencyData(Float32Array array);
     void getByteFrequencyData(Uint8Array array);
 
     // Real-time waveform data
     void getFloatTimeDomainData(Float32Array array);
--- a/dom/webidl/AudioBuffer.webidl
+++ b/dom/webidl/AudioBuffer.webidl
@@ -12,17 +12,17 @@
 
 dictionary AudioBufferOptions {
              unsigned long numberOfChannels = 1;
     required unsigned long length;
              float         sampleRate;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, AudioBufferOptions options)]
+ Constructor(BaseAudioContext context, AudioBufferOptions options)]
 interface AudioBuffer {
 
     readonly attribute float sampleRate;
     readonly attribute unsigned long length;
 
     // in seconds 
     readonly attribute double duration;
 
--- a/dom/webidl/AudioBufferSourceNode.webidl
+++ b/dom/webidl/AudioBufferSourceNode.webidl
@@ -15,17 +15,17 @@ dictionary AudioBufferSourceOptions {
              float        detune = 0;
              boolean      loop = false;
              double       loopEnd = 0;
              double       loopStart = 0;
              float        playbackRate = 1;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional AudioBufferSourceOptions options)]
+ Constructor(BaseAudioContext context, optional AudioBufferSourceOptions options)]
 interface AudioBufferSourceNode : AudioNode {
 
     attribute AudioBuffer? buffer;
 
     readonly attribute AudioParam playbackRate;
     readonly attribute AudioParam detune;
 
     attribute boolean loop;
--- a/dom/webidl/AudioContext.webidl
+++ b/dom/webidl/AudioContext.webidl
@@ -5,106 +5,39 @@
  *
  * The origin of this IDL file is
  * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-callback DecodeSuccessCallback = void (AudioBuffer decodedData);
-callback DecodeErrorCallback = void (DOMException error);
-
-enum AudioContextState {
-    "suspended",
-    "running",
-    "closed"
-};
-
-dictionary PeriodicWaveConstraints {
-  boolean disableNormalization = false;
-};
-
 [Constructor,
  Constructor(AudioChannel audioChannelType),
  Pref="dom.webaudio.enabled"]
-interface AudioContext : EventTarget {
+interface AudioContext : BaseAudioContext {
 
-    readonly attribute AudioDestinationNode destination;
-    readonly attribute float sampleRate;
-    readonly attribute double currentTime;
-    readonly attribute AudioListener listener;
-    readonly attribute AudioContextState state;
+    // Bug 1324545: readonly        attribute double outputLatency;
+    // Bug 1324545: AudioTimestamp                  getOutputTimestamp ();
+
     [Throws]
     Promise<void> suspend();
     [Throws]
-    Promise<void> resume();
-    [Throws]
     Promise<void> close();
-    attribute EventHandler onstatechange;
 
-    [NewObject, Throws]
-    AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long length, float sampleRate);
+    [NewObject, Throws, UnsafeInPrerendering]
+    MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
 
-    [Throws]
-    Promise<AudioBuffer> decodeAudioData(ArrayBuffer audioData,
-                                         optional DecodeSuccessCallback successCallback,
-                                         optional DecodeErrorCallback errorCallback);
+    [NewObject, Throws, UnsafeInPrerendering]
+    MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
 
-    // AudioNode creation
-    [NewObject, Throws]
-    AudioBufferSourceNode createBufferSource();
-
-    [NewObject, Throws]
-    ConstantSourceNode createConstantSource();
+    // Bug 1324548: MediaStreamTrackAudioSourceNode createMediaStreamTrackSource (AudioMediaStreamTrack mediaStreamTrack);
 
     [NewObject, Throws]
     MediaStreamAudioDestinationNode createMediaStreamDestination();
-
-    [NewObject, Throws]
-    ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
-                                              optional unsigned long numberOfInputChannels = 2,
-                                              optional unsigned long numberOfOutputChannels = 2);
-
-    [NewObject, Throws]
-    StereoPannerNode createStereoPanner();
-    [NewObject, Throws]
-    AnalyserNode createAnalyser();
-    [NewObject, Throws, UnsafeInPrerendering]
-    MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
-    [NewObject, Throws, UnsafeInPrerendering]
-    MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
-    [NewObject, Throws]
-    GainNode createGain();
-    [NewObject, Throws]
-    DelayNode createDelay(optional double maxDelayTime = 1);
-    [NewObject, Throws]
-    BiquadFilterNode createBiquadFilter();
-    [NewObject, Throws]
-    IIRFilterNode createIIRFilter(sequence<double> feedforward, sequence<double> feedback);
-    [NewObject, Throws]
-    WaveShaperNode createWaveShaper();
-    [NewObject, Throws]
-    PannerNode createPanner();
-    [NewObject, Throws]
-    ConvolverNode createConvolver();
-
-    [NewObject, Throws]
-    ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
-    [NewObject, Throws]
-    ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
-
-    [NewObject, Throws]
-    DynamicsCompressorNode createDynamicsCompressor();
-
-    [NewObject, Throws]
-    OscillatorNode createOscillator();
-    [NewObject, Throws]
-    PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints);
-
 };
 
 // Mozilla extensions
 partial interface AudioContext {
   // Read AudioChannel.webidl for more information about this attribute.
   [Pref="media.useAudioChannelAPI"]
   readonly attribute AudioChannel mozAudioChannelType;
 
--- a/dom/webidl/AudioNode.webidl
+++ b/dom/webidl/AudioNode.webidl
@@ -44,17 +44,17 @@ interface AudioNode : EventTarget {
     void disconnect(AudioNode destination, unsigned long output);
     [Throws]
     void disconnect(AudioNode destination, unsigned long output, unsigned long input);
     [Throws]
     void disconnect(AudioParam destination);
     [Throws]
     void disconnect(AudioParam destination, unsigned long output);
 
-    readonly attribute AudioContext context;
+    readonly attribute BaseAudioContext context;
     readonly attribute unsigned long numberOfInputs;
     readonly attribute unsigned long numberOfOutputs;
 
     // Channel up-mixing and down-mixing rules for all inputs.
     [SetterThrows]
     attribute unsigned long channelCount;
     [SetterThrows]
     attribute ChannelCountMode channelCountMode;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/BaseAudioContext.webidl
@@ -0,0 +1,100 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * https://webaudio.github.io/web-audio-api/#idl-def-BaseAudioContext
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+callback DecodeSuccessCallback = void (AudioBuffer decodedData);
+callback DecodeErrorCallback = void (DOMException error);
+
+enum AudioContextState {
+    "suspended",
+    "running",
+    "closed"
+};
+
+interface BaseAudioContext : EventTarget {
+    readonly        attribute AudioDestinationNode destination;
+    readonly        attribute float                sampleRate;
+    readonly        attribute double               currentTime;
+    readonly        attribute AudioListener        listener;
+    readonly        attribute AudioContextState    state;
+    // Bug 1324552: readonly        attribute double               baseLatency;
+
+    [Throws]
+    Promise<void> resume();
+
+                    attribute EventHandler         onstatechange;
+
+    [NewObject, Throws]
+    AudioBuffer            createBuffer (unsigned long numberOfChannels,
+                                         unsigned long length,
+                                         float sampleRate);
+
+    [Throws]
+    Promise<AudioBuffer> decodeAudioData(ArrayBuffer audioData,
+                                         optional DecodeSuccessCallback successCallback,
+                                         optional DecodeErrorCallback errorCallback);
+
+    // AudioNode creation
+    [NewObject, Throws]
+    AudioBufferSourceNode createBufferSource();
+
+    [NewObject, Throws]
+    ConstantSourceNode createConstantSource();
+
+    [NewObject, Throws]
+    ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
+                                              optional unsigned long numberOfInputChannels = 2,
+                                              optional unsigned long numberOfOutputChannels = 2);
+
+    [NewObject, Throws]
+    AnalyserNode createAnalyser();
+
+    [NewObject, Throws]
+    GainNode createGain();
+
+    [NewObject, Throws]
+    DelayNode createDelay(optional double maxDelayTime = 1);
+
+    [NewObject, Throws]
+    BiquadFilterNode createBiquadFilter();
+
+    [NewObject, Throws]
+    IIRFilterNode createIIRFilter(sequence<double> feedforward, sequence<double> feedback);
+
+    [NewObject, Throws]
+    WaveShaperNode createWaveShaper();
+
+    [NewObject, Throws]
+    PannerNode createPanner();
+
+    [NewObject, Throws]
+    StereoPannerNode createStereoPanner();
+
+    [NewObject, Throws]
+    ConvolverNode createConvolver();
+
+    [NewObject, Throws]
+    ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
+
+    [NewObject, Throws]
+    ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
+
+    [NewObject, Throws]
+    DynamicsCompressorNode createDynamicsCompressor();
+
+    [NewObject, Throws]
+    OscillatorNode createOscillator();
+
+    [NewObject, Throws]
+    PeriodicWave createPeriodicWave(Float32Array real,
+                                    Float32Array imag,
+                                    optional PeriodicWaveConstraints constraints);
+};
--- a/dom/webidl/BiquadFilterNode.webidl
+++ b/dom/webidl/BiquadFilterNode.webidl
@@ -25,17 +25,17 @@ dictionary BiquadFilterOptions : AudioNo
              BiquadFilterType type = "lowpass";
              float            Q = 1;
              float            detune = 0;
              float            frequency = 350;
              float            gain = 0;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional BiquadFilterOptions options)]
+ Constructor(BaseAudioContext context, optional BiquadFilterOptions options)]
 interface BiquadFilterNode : AudioNode {
 
     attribute BiquadFilterType type;
     readonly attribute AudioParam frequency; // in Hertz
     readonly attribute AudioParam detune; // in Cents
     readonly attribute AudioParam Q; // Quality factor
     readonly attribute AudioParam gain; // in Decibels
 
--- a/dom/webidl/ChannelMergerNode.webidl
+++ b/dom/webidl/ChannelMergerNode.webidl
@@ -10,11 +10,11 @@
  * liability, trademark and document use rules apply.
  */
 
 dictionary ChannelMergerOptions : AudioNodeOptions {
              unsigned long numberOfInputs = 6;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional ChannelMergerOptions options)]
+ Constructor(BaseAudioContext context, optional ChannelMergerOptions options)]
 interface ChannelMergerNode : AudioNode {
 };
--- a/dom/webidl/ChannelSplitterNode.webidl
+++ b/dom/webidl/ChannelSplitterNode.webidl
@@ -10,13 +10,13 @@
  * liability, trademark and document use rules apply.
  */
 
 dictionary ChannelSplitterOptions : AudioNodeOptions {
              unsigned long numberOfOutputs = 6;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional ChannelSplitterOptions options)]
+ Constructor(BaseAudioContext context, optional ChannelSplitterOptions options)]
 interface ChannelSplitterNode : AudioNode {
 
 };
 
--- a/dom/webidl/ConstantSourceNode.webidl
+++ b/dom/webidl/ConstantSourceNode.webidl
@@ -10,17 +10,17 @@
  * liability, trademark and document use rules apply.
  */
 
 dictionary ConstantSourceOptions {
     float offset = 1;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional ConstantSourceOptions options)]
+ Constructor(BaseAudioContext context, optional ConstantSourceOptions options)]
 interface ConstantSourceNode : AudioNode {
     readonly        attribute AudioParam   offset;
                     attribute EventHandler onended;
     [Throws, UnsafeInPrerendering]
     void start (optional double when = 0);
     [Throws, UnsafeInPrerendering]
     void stop (optional double when = 0);
 };
--- a/dom/webidl/ConvolverNode.webidl
+++ b/dom/webidl/ConvolverNode.webidl
@@ -11,17 +11,17 @@
  */
 
 dictionary ConvolverOptions : AudioNodeOptions {
              AudioBuffer? buffer;
              boolean      disableNormalization = false;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional ConvolverOptions options)]
+ Constructor(BaseAudioContext context, optional ConvolverOptions options)]
 interface ConvolverNode : AudioNode {
 
       [SetterThrows]
       attribute AudioBuffer? buffer;
       attribute boolean normalize;
 
 };
 
--- a/dom/webidl/DelayNode.webidl
+++ b/dom/webidl/DelayNode.webidl
@@ -11,17 +11,17 @@
  */
 
 dictionary DelayOptions : AudioNodeOptions {
              double maxDelayTime = 1;
              double delayTime = 0;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional DelayOptions options)]
+ Constructor(BaseAudioContext context, optional DelayOptions options)]
 interface DelayNode : AudioNode {
 
     readonly attribute AudioParam delayTime;
 
 };
 
 // Mozilla extension
 DelayNode implements AudioNodePassThrough;
--- a/dom/webidl/DynamicsCompressorNode.webidl
+++ b/dom/webidl/DynamicsCompressorNode.webidl
@@ -14,17 +14,17 @@ dictionary DynamicsCompressorOptions : A
              float attack = 0.003;
              float knee = 30;
              float ratio = 12;
              float release = 0.25;
              float threshold = -24;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional DynamicsCompressorOptions options)]
+ Constructor(BaseAudioContext context, optional DynamicsCompressorOptions options)]
 interface DynamicsCompressorNode : AudioNode {
 
     readonly attribute AudioParam threshold; // in Decibels
     readonly attribute AudioParam knee; // in Decibels
     readonly attribute AudioParam ratio; // unit-less
     readonly attribute float reduction; // in Decibels
     readonly attribute AudioParam attack; // in Seconds
     readonly attribute AudioParam release; // in Seconds
--- a/dom/webidl/GainNode.webidl
+++ b/dom/webidl/GainNode.webidl
@@ -10,17 +10,17 @@
  * liability, trademark and document use rules apply.
  */
 
 dictionary GainOptions : AudioNodeOptions {
              float gain = 1.0;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional GainOptions options)]
+ Constructor(BaseAudioContext context, optional GainOptions options)]
 interface GainNode : AudioNode {
 
     readonly attribute AudioParam gain;
 
 };
 
 // Mozilla extension
 GainNode implements AudioNodePassThrough;
--- a/dom/webidl/IIRFilterNode.webidl
+++ b/dom/webidl/IIRFilterNode.webidl
@@ -10,15 +10,15 @@
  */
 
 dictionary IIRFilterOptions : AudioNodeOptions {
     required sequence<double> feedforward;
     required sequence<double> feedback;
 };
 
 [Pref="dom.webaudio.enabled",
-Constructor(AudioContext context, IIRFilterOptions options)]
+Constructor(BaseAudioContext context, IIRFilterOptions options)]
 interface IIRFilterNode : AudioNode {
     void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse);
 };
 
 // Mozilla extension
 IIRFilterNode implements AudioNodePassThrough;
--- a/dom/webidl/OfflineAudioContext.webidl
+++ b/dom/webidl/OfflineAudioContext.webidl
@@ -7,17 +7,18 @@
  * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate),
 Pref="dom.webaudio.enabled"]
-interface OfflineAudioContext : AudioContext {
+interface OfflineAudioContext : BaseAudioContext {
 
     [Throws]
     Promise<AudioBuffer> startRendering();
 
-    attribute EventHandler oncomplete;
-    readonly attribute unsigned long length;
+    // TODO: Promise<void>        suspend (double suspendTime);
 
+    readonly        attribute unsigned long length;
+                    attribute EventHandler  oncomplete;
 };
--- a/dom/webidl/OscillatorNode.webidl
+++ b/dom/webidl/OscillatorNode.webidl
@@ -21,17 +21,17 @@ enum OscillatorType {
 dictionary OscillatorOptions : AudioNodeOptions {
              OscillatorType type = "sine";
              float          frequency = 440;
              float          detune = 0;
              PeriodicWave   periodicWave;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional OscillatorOptions options)]
+ Constructor(BaseAudioContext context, optional OscillatorOptions options)]
 interface OscillatorNode : AudioNode {
 
     [SetterThrows]
     attribute OscillatorType type;
 
     readonly attribute AudioParam frequency; // in Hertz
     readonly attribute AudioParam detune; // in Cents
 
--- a/dom/webidl/PannerNode.webidl
+++ b/dom/webidl/PannerNode.webidl
@@ -34,17 +34,17 @@ dictionary PannerOptions : AudioNodeOpti
              double            maxDistance = 10000;
              double            rolloffFactor = 1;
              double            coneInnerAngle = 360;
              double            coneOuterAngle = 360;
              double            coneOuterGain = 0;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional PannerOptions options)]
+ Constructor(BaseAudioContext context, optional PannerOptions options)]
 interface PannerNode : AudioNode {
 
     // Default for stereo is equalpower
     attribute PanningModelType panningModel;
 
     // Uses a 3D cartesian coordinate system
     void setPosition(double x, double y, double z);
     void setOrientation(double x, double y, double z);
--- a/dom/webidl/PeriodicWave.webidl
+++ b/dom/webidl/PeriodicWave.webidl
@@ -5,20 +5,24 @@
  *
  * The origin of this IDL file is
  * https://webaudio.github.io/web-audio-api/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
+dictionary PeriodicWaveConstraints {
+  boolean disableNormalization = false;
+};
+
 dictionary PeriodicWaveOptions : PeriodicWaveConstraints {
              sequence<float> real;
              sequence<float> imag;
 };
 
 [Pref="dom.webaudio.enabled",
  // XXXbz The second arg is not optional in the spec, but that looks
  // like a spec bug to me.  See
  // <https://github.com/WebAudio/web-audio-api/issues/1116>.
- Constructor(AudioContext context, optional PeriodicWaveOptions options)]
+ Constructor(BaseAudioContext context, optional PeriodicWaveOptions options)]
 interface PeriodicWave {
 };
--- a/dom/webidl/StereoPannerNode.webidl
+++ b/dom/webidl/StereoPannerNode.webidl
@@ -10,16 +10,16 @@
  * liability, trademark and document use rules apply.
  */
 
 dictionary StereoPannerOptions : AudioNodeOptions {
              float pan = 0;
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional StereoPannerOptions options)]
+ Constructor(BaseAudioContext context, optional StereoPannerOptions options)]
 interface StereoPannerNode : AudioNode {
   readonly attribute AudioParam pan;
 };
 
 // Mozilla extension
 StereoPannerNode implements AudioNodePassThrough;
 
--- a/dom/webidl/WaveShaperNode.webidl
+++ b/dom/webidl/WaveShaperNode.webidl
@@ -17,17 +17,17 @@ enum OverSampleType {
 };
 
 dictionary WaveShaperOptions : AudioNodeOptions {
              sequence<float> curve;
              OverSampleType  oversample = "none";
 };
 
 [Pref="dom.webaudio.enabled",
- Constructor(AudioContext context, optional WaveShaperOptions options)]
+ Constructor(BaseAudioContext context, optional WaveShaperOptions options)]
 interface WaveShaperNode : AudioNode {
 
       [Cached, Pure, SetterThrows]
       attribute Float32Array? curve;
       attribute OverSampleType oversample;
 
 };
 
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -42,16 +42,17 @@ WEBIDL_FILES = [
     'AudioParam.webidl',
     'AudioProcessingEvent.webidl',
     'AudioStreamTrack.webidl',
     'AudioTrack.webidl',
     'AudioTrackList.webidl',
     'AudioWorkletGlobalScope.webidl',
     'AutocompleteInfo.webidl',
     'BarProp.webidl',
+    'BaseAudioContext.webidl',
     'BaseKeyframeTypes.webidl',
     'BatteryManager.webidl',
     'BeforeAfterKeyboardEvent.webidl',
     'BeforeUnloadEvent.webidl',
     'BiquadFilterNode.webidl',
     'Blob.webidl',
     'BoxObject.webidl',
     'BroadcastChannel.webidl',
--- a/testing/web-platform/tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html class="a">
 <head>
 <title>AudioBuffer IDL Test</title>
 <script src="/resources/testharness.js"></script><script src="/resources/testharnessreport.js"></script><script src="/resources/idlharness.js"></script><script src="/resources/WebIDLParser.js"></script><script src="/webaudio/js/lodash.js"></script><script src="/webaudio/js/vendor-prefixes.js"></script><script src="/webaudio/js/helpers.js"></script><style type="text/css">
     #event-target-idl,
-    #audio-context-idl
+    #base-audio-context-idl
     { visibility:hidden; height: 0px;}
   </style>
 </head>
 <body class="a">
 
    <pre id="event-target-idl">interface EventTarget {
   void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
   void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
@@ -20,92 +20,80 @@
 callback interface EventListener {
   void handleEvent(Event event);
 };
 */
 // Callback interfaces are not supported yet, but that's ok
 interface EventListener {};
 </pre>
 
-   <pre id="audio-context-idl">callback DecodeSuccessCallback = void (AudioBuffer decodedData);
-callback DecodeErrorCallback = void (DOMException error);
-
-[Constructor]
-interface AudioContext : EventTarget {
-
-    readonly attribute AudioDestinationNode destination;
-    readonly attribute float sampleRate;
-    readonly attribute double currentTime;
-    readonly attribute AudioListener listener;
-
-    AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long length, float sampleRate);
-
-    void decodeAudioData(ArrayBuffer audioData,
-                         DecodeSuccessCallback successCallback,
-                         optional DecodeErrorCallback errorCallback);
-
-
-    // AudioNode creation
-    AudioBufferSourceNode createBufferSource();
-
-    MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
+   <pre id="base-audio-context-idl">callback DecodeErrorCallback = void (DOMException error);
+callback DecodeSuccessCallback = void (AudioBuffer decodedData);
 
-    MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
-    MediaStreamAudioDestinationNode createMediaStreamDestination();
-
-    ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
-                                              optional unsigned long numberOfInputChannels = 2,
-                                              optional unsigned long numberOfOutputChannels = 2);
-
-    AnalyserNode createAnalyser();
-    GainNode createGain();
-    DelayNode createDelay(optional double maxDelayTime = 1.0);
-    BiquadFilterNode createBiquadFilter();
-    WaveShaperNode createWaveShaper();
-    PannerNode createPanner();
-    ConvolverNode createConvolver();
-
-    ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
-    ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
-
-    DynamicsCompressorNode createDynamicsCompressor();
-
-    OscillatorNode createOscillator();
-    PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag);
-
+interface BaseAudioContext : EventTarget {
+    readonly        attribute AudioDestinationNode destination;
+    readonly        attribute float                sampleRate;
+    readonly        attribute double               currentTime;
+    readonly        attribute AudioListener        listener;
+    readonly        attribute AudioContextState    state;
+    readonly        attribute double               baseLatency;
+    Promise<void>          resume ();
+                    attribute EventHandler         onstatechange;
+    AudioBuffer            createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate);
+    Promise<AudioBuffer>   decodeAudioData (ArrayBuffer audioData, optional DecodeSuccessCallback successCallback, optional DecodeErrorCallback errorCallback);
+    AudioBufferSourceNode  createBufferSource ();
+    ConstantSourceNode     createConstantSource ();
+    ScriptProcessorNode    createScriptProcessor (optional unsigned long bufferSize = 0
+              , optional unsigned long numberOfInputChannels = 2
+              , optional unsigned long numberOfOutputChannels = 2
+              );
+    AnalyserNode           createAnalyser ();
+    GainNode               createGain ();
+    DelayNode              createDelay (optional double maxDelayTime);
+    BiquadFilterNode       createBiquadFilter ();
+    IIRFilterNode          createIIRFilter (sequence<double> feedforward, sequence<double> feedback);
+    WaveShaperNode         createWaveShaper ();
+    PannerNode             createPanner ();
+    StereoPannerNode       createStereoPanner ();
+    ConvolverNode          createConvolver ();
+    ChannelSplitterNode    createChannelSplitter (optional unsigned long numberOfOutputs = 6
+              );
+    ChannelMergerNode      createChannelMerger (optional unsigned long numberOfInputs = 6
+              );
+    DynamicsCompressorNode createDynamicsCompressor ();
+    OscillatorNode         createOscillator ();
+    PeriodicWave           createPeriodicWave (Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints);
 };</pre>
 
    <pre id="audio-buffer-idl">dictionary AudioBufferOptions {
              unsigned long numberOfChannels = 1;
     required unsigned long length;
              float         sampleRate;
 };
 
-[Constructor(AudioContext context, AudioBufferOptions options)]
+[Constructor(BaseAudioContext context, AudioBufferOptions options)]
 interface AudioBuffer {
-
-    readonly attribute float sampleRate;
-    readonly attribute long length;
-
-    // in seconds
-    readonly attribute double duration;
-
-    readonly attribute long numberOfChannels;
-
-    Float32Array getChannelData(unsigned long channel);
-
+    readonly        attribute float         sampleRate;
+    readonly        attribute unsigned long length;
+    readonly        attribute double        duration;
+    readonly        attribute unsigned long numberOfChannels;
+    Float32Array getChannelData (unsigned long channel);
+    void         copyFromChannel (Float32Array destination, unsigned long channelNumber, optional unsigned long startInChannel = 0
+              );
+    void         copyToChannel (Float32Array source, unsigned long channelNumber, optional unsigned long startInChannel = 0
+              );
 };</pre>
 
   <div id="log"></div>
 
   <script>
 (function() {
   var idl_array = new IdlArray();
   idl_array.add_untested_idls(document.getElementById("event-target-idl").textContent);
-  idl_array.add_untested_idls(document.getElementById("audio-context-idl").textContent);
+  idl_array.add_untested_idls(document.getElementById("base-audio-context-idl").textContent);
   idl_array.add_idls(document.getElementById("audio-buffer-idl").textContent);
 
   // For these tests the value of the arguments is unimportant.
   audio_buffer = (new AudioContext).createBuffer(numberOfChannels = 1, length = 256, sampleRate = 44100);
 
   idl_array.add_objects({AudioBuffer: ["audio_buffer"]});
   idl_array.test();
 })();
--- a/testing/web-platform/tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html class="a">
 <head>
 <title>AudioDestinationNode IDL Test</title>
 <script src="/resources/testharness.js"></script><script src="/resources/testharnessreport.js"></script><script src="/resources/idlharness.js"></script><script src="/resources/WebIDLParser.js"></script><script src="/webaudio/js/lodash.js"></script><script src="/webaudio/js/vendor-prefixes.js"></script><script src="/webaudio/js/helpers.js"></script><style type="text/css">
     #event-target-idl,
-    #audio-context-idl,
+    #base-audio-context-idl,
     #audio-node-idl
     { visibility:hidden; height: 0px;}
   </style>
 </head>
 <body class="a">
 
    <pre id="event-target-idl">interface EventTarget {
   void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false);
@@ -21,62 +21,53 @@
 callback interface EventListener {
   void handleEvent(Event event);
 };
 */
 // Callback interfaces are not supported yet, but that's ok
 interface EventListener {};
 </pre>
 
-   <pre id="audio-context-idl">callback DecodeSuccessCallback = void (AudioBuffer decodedData);
-callback DecodeErrorCallback = void (DOMException error);
-
-[Constructor]
-interface AudioContext : EventTarget {
-
-    readonly attribute AudioDestinationNode destination;
-    readonly attribute float sampleRate;
-    readonly attribute double currentTime;
-    readonly attribute AudioListener listener;
+   <pre id="base-audio-context-idl">callback DecodeErrorCallback = void (DOMException error);
 
-    AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long length, float sampleRate);
-
-    void decodeAudioData(ArrayBuffer audioData,
-                         DecodeSuccessCallback successCallback,
-                         optional DecodeErrorCallback errorCallback);
-
-
-    // AudioNode creation
-    AudioBufferSourceNode createBufferSource();
-
-    MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
+callback DecodeSuccessCallback = void (AudioBuffer decodedData);
 
-    MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
-    MediaStreamAudioDestinationNode createMediaStreamDestination();
-
-    ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
-                                              optional unsigned long numberOfInputChannels = 2,
-                                              optional unsigned long numberOfOutputChannels = 2);
-
-    AnalyserNode createAnalyser();
-    GainNode createGain();
-    DelayNode createDelay(optional double maxDelayTime = 1.0);
-    BiquadFilterNode createBiquadFilter();
-    WaveShaperNode createWaveShaper();
-    PannerNode createPanner();
-    ConvolverNode createConvolver();
-
-    ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
-    ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
-
-    DynamicsCompressorNode createDynamicsCompressor();
-
-    OscillatorNode createOscillator();
-    PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag);
-
+interface BaseAudioContext : EventTarget {
+    readonly        attribute AudioDestinationNode destination;
+    readonly        attribute float                sampleRate;
+    readonly        attribute double               currentTime;
+    readonly        attribute AudioListener        listener;
+    readonly        attribute AudioContextState    state;
+    readonly        attribute double               baseLatency;
+    Promise<void>          resume ();
+                    attribute EventHandler         onstatechange;
+    AudioBuffer            createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate);
+    Promise<AudioBuffer>   decodeAudioData (ArrayBuffer audioData, optional DecodeSuccessCallback successCallback, optional DecodeErrorCallback errorCallback);
+    AudioBufferSourceNode  createBufferSource ();
+    ConstantSourceNode     createConstantSource ();
+    ScriptProcessorNode    createScriptProcessor (optional unsigned long bufferSize = 0
+              , optional unsigned long numberOfInputChannels = 2
+              , optional unsigned long numberOfOutputChannels = 2
+              );
+    AnalyserNode           createAnalyser ();
+    GainNode               createGain ();
+    DelayNode              createDelay (optional double maxDelayTime);
+    BiquadFilterNode       createBiquadFilter ();
+    IIRFilterNode          createIIRFilter (sequence<double> feedforward, sequence<double> feedback);
+    WaveShaperNode         createWaveShaper ();
+    PannerNode             createPanner ();
+    StereoPannerNode       createStereoPanner ();
+    ConvolverNode          createConvolver ();
+    ChannelSplitterNode    createChannelSplitter (optional unsigned long numberOfOutputs = 6
+              );
+    ChannelMergerNode      createChannelMerger (optional unsigned long numberOfInputs = 6
+              );
+    DynamicsCompressorNode createDynamicsCompressor ();
+    OscillatorNode         createOscillator ();
+    PeriodicWave           createPeriodicWave (Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints);
 };</pre>
 
    <pre id="audio-node-idl">enum ChannelCountMode {
     "max",
     "clamped-max",
     "explicit"
 };
 
@@ -86,17 +77,17 @@ enum ChannelInterpretation {
 };
 
 interface AudioNode : EventTarget {
 
     void connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0);
     void connect(AudioParam destination, optional unsigned long output = 0);
     void disconnect(optional unsigned long output = 0);
 
-    readonly attribute AudioContext context;
+    readonly attribute BaseAudioContext context;
     readonly attribute unsigned long numberOfInputs;
     readonly attribute unsigned long numberOfOutputs;
 
     // Channel up-mixing and down-mixing rules for all inputs.
     attribute unsigned long channelCount;
     attribute ChannelCountMode channelCountMode;
     attribute ChannelInterpretation channelInterpretation;
 
@@ -109,17 +100,17 @@ interface AudioNode : EventTarget {
 };</pre>
 
   <div id="log"></div>
 
   <script>
 (function() {
   var idl_array = new IdlArray();
   idl_array.add_untested_idls(document.getElementById("event-target-idl").textContent);
-  idl_array.add_untested_idls(document.getElementById("audio-context-idl").textContent);
+  idl_array.add_untested_idls(document.getElementById("base-audio-context-idl").textContent);
   idl_array.add_untested_idls(document.getElementById("audio-node-idl").textContent);
   idl_array.add_idls(document.getElementById("audio-destination-node-idl").textContent);
 
   audio_destination_node = (new AudioContext).destination;
 
   idl_array.add_objects({AudioDestinationNode: ["audio_destination_node"]});
   idl_array.test();
 })();
--- a/testing/web-platform/tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-delaynode-interface/idl-test.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html class="a">
 <head>
 <title>DelayNode IDL Test</title>
 <script src="/resources/testharness.js"></script><script src="/resources/testharnessreport.js"></script><script src="/resources/idlharness.js"></script><script src="/resources/WebIDLParser.js"></script><script src="/webaudio/js/lodash.js"></script><script src="/webaudio/js/vendor-prefixes.js"></script><script src="/webaudio/js/helpers.js"></script><style type="text/css">
     #event-target-idl,
-    #audio-context-idl,
+    #base-audio-context-idl,
     #audio-node-idl,
     #audio-param-idl
     { visibility:hidden; height: 0px;}
   </style>
 </head>
 <body class="a">
 
    <pre id="event-target-idl">interface EventTarget {
@@ -22,62 +22,53 @@
 callback interface EventListener {
   void handleEvent(Event event);
 };
 */
 // Callback interfaces are not supported yet, but that's ok
 interface EventListener {};
 </pre>
 
-   <pre id="audio-context-idl">callback DecodeSuccessCallback = void (AudioBuffer decodedData);
-callback DecodeErrorCallback = void (DOMException error);
-
-[Constructor]
-interface AudioContext : EventTarget {
-
-    readonly attribute AudioDestinationNode destination;
-    readonly attribute float sampleRate;
-    readonly attribute double currentTime;
-    readonly attribute AudioListener listener;
+   <pre id="base-audio-context-idl">callback DecodeSuccessCallback = void (AudioBuffer decodedData);
 
-    AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long length, float sampleRate);
-
-    void decodeAudioData(ArrayBuffer audioData,
-                         DecodeSuccessCallback successCallback,
-                         optional DecodeErrorCallback errorCallback);
-
-
-    // AudioNode creation
-    AudioBufferSourceNode createBufferSource();
-
-    MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
+callback DecodeSuccessCallback = void (AudioBuffer decodedData);
 
-    MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
-    MediaStreamAudioDestinationNode createMediaStreamDestination();
-
-    ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
-                                              optional unsigned long numberOfInputChannels = 2,
-                                              optional unsigned long numberOfOutputChannels = 2);
-
-    AnalyserNode createAnalyser();
-    GainNode createGain();
-    DelayNode createDelay(optional double maxDelayTime = 1.0);
-    BiquadFilterNode createBiquadFilter();
-    WaveShaperNode createWaveShaper();
-    PannerNode createPanner();
-    ConvolverNode createConvolver();
-
-    ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
-    ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
-
-    DynamicsCompressorNode createDynamicsCompressor();
-
-    OscillatorNode createOscillator();
-    PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag);
-
+interface BaseAudioContext : EventTarget {
+    readonly        attribute AudioDestinationNode destination;
+    readonly        attribute float                sampleRate;
+    readonly        attribute double               currentTime;
+    readonly        attribute AudioListener        listener;
+    readonly        attribute AudioContextState    state;
+    readonly        attribute double               baseLatency;
+    Promise<void>          resume ();
+                    attribute EventHandler         onstatechange;
+    AudioBuffer            createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate);
+    Promise<AudioBuffer>   decodeAudioData (ArrayBuffer audioData, optional DecodeSuccessCallback successCallback, optional DecodeErrorCallback errorCallback);
+    AudioBufferSourceNode  createBufferSource ();
+    ConstantSourceNode     createConstantSource ();
+    ScriptProcessorNode    createScriptProcessor (optional unsigned long bufferSize = 0
+              , optional unsigned long numberOfInputChannels = 2
+              , optional unsigned long numberOfOutputChannels = 2
+              );
+    AnalyserNode           createAnalyser ();
+    GainNode               createGain ();
+    DelayNode              createDelay (optional double maxDelayTime);
+    BiquadFilterNode       createBiquadFilter ();
+    IIRFilterNode          createIIRFilter (sequence<double> feedforward, sequence<double> feedback);
+    WaveShaperNode         createWaveShaper ();
+    PannerNode             createPanner ();
+    StereoPannerNode       createStereoPanner ();
+    ConvolverNode          createConvolver ();
+    ChannelSplitterNode    createChannelSplitter (optional unsigned long numberOfOutputs = 6
+              );
+    ChannelMergerNode      createChannelMerger (optional unsigned long numberOfInputs = 6
+              );
+    DynamicsCompressorNode createDynamicsCompressor ();
+    OscillatorNode         createOscillator ();
+    PeriodicWave           createPeriodicWave (Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints);
 };</pre>
 
    <pre id="audio-node-idl">enum ChannelCountMode {
     "max",
     "clamped-max",
     "explicit"
 };
 
@@ -87,17 +78,17 @@ enum ChannelInterpretation {
 };
 
 interface AudioNode : EventTarget {
 
     void connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0);
     void connect(AudioParam destination, optional unsigned long output = 0);
     void disconnect(optional unsigned long output = 0);
 
-    readonly attribute AudioContext context;
+    readonly attribute BaseAudioContext context;
     readonly attribute unsigned long numberOfInputs;
     readonly attribute unsigned long numberOfOutputs;
 
     // Channel up-mixing and down-mixing rules for all inputs.
     attribute unsigned long channelCount;
     attribute ChannelCountMode channelCountMode;
     attribute ChannelInterpretation channelInterpretation;
 
@@ -125,30 +116,30 @@ interface AudioNode : EventTarget {
 
 };</pre>
 
 <pre id="delay-node-idl">dictionary DelayOptions : AudioNodeOptions {
              double maxDelayTime = 1;
              double delayTime = 0;
 };
 
-[Constructor(AudioContext context, optional DelayOptions options)]
+[Constructor(BaseAudioContext context, optional DelayOptions options)]
 interface DelayNode : AudioNode {
 
     readonly attribute AudioParam delayTime;
 
 };</pre>
 
   <div id="log"></div>
 
   <script>
 (function() {
   var idl_array = new IdlArray();
   idl_array.add_untested_idls(document.getElementById("event-target-idl").textContent);
-  idl_array.add_untested_idls(document.getElementById("audio-context-idl").textContent);
+  idl_array.add_untested_idls(document.getElementById("base-audio-context-idl").textContent);
   idl_array.add_untested_idls(document.getElementById("audio-node-idl").textContent);
   idl_array.add_untested_idls(document.getElementById("audio-param-idl").textContent);
   idl_array.add_idls(document.getElementById("delay-node-idl").textContent);
 
   delay_node = (new AudioContext).createDelay();
 
   idl_array.add_objects({DelayNode: ["delay_node"]});
   idl_array.test();
--- a/testing/web-platform/tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html
+++ b/testing/web-platform/tests/webaudio/the-audio-api/the-gainnode-interface/idl-test.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
 <html class="a">
 <head>
 <title>GainNode IDL Test</title>
 <script src="/resources/testharness.js"></script><script src="/resources/testharnessreport.js"></script><script src="/resources/idlharness.js"></script><script src="/resources/WebIDLParser.js"></script><script src="/webaudio/js/lodash.js"></script><script src="/webaudio/js/vendor-prefixes.js"></script><script src="/webaudio/js/helpers.js"></script><style type="text/css">
     #event-target-idl,
-    #audio-context-idl,
+    #base-audio-context-idl,
     #audio-node-idl,
     #audio-param-idl
     { visibility:hidden; height: 0px;}
   </style>
 </head>
 <body class="a">
 
    <pre id="event-target-idl">interface EventTarget {
@@ -22,62 +22,52 @@
 callback interface EventListener {
   void handleEvent(Event event);
 };
 */
 // Callback interfaces are not supported yet, but that's ok
 interface EventListener {};
 </pre>
 
-   <pre id="audio-context-idl">callback DecodeSuccessCallback = void (AudioBuffer decodedData);
-callback DecodeErrorCallback = void (DOMException error);
-
-[Constructor]
-interface AudioContext : EventTarget {
-
-    readonly attribute AudioDestinationNode destination;
-    readonly attribute float sampleRate;
-    readonly attribute double currentTime;
-    readonly attribute AudioListener listener;
-
-    AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long length, float sampleRate);
-
-    void decodeAudioData(ArrayBuffer audioData,
-                         DecodeSuccessCallback successCallback,
-                         optional DecodeErrorCallback errorCallback);
-
-
-    // AudioNode creation
-    AudioBufferSourceNode createBufferSource();
-
-    MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
+   <pre id="base-audio-context-idl">callback DecodeSuccessCallback = void (AudioBuffer decodedData);
+callback DecodeSuccessCallback = void (AudioBuffer decodedData);
 
-    MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
-    MediaStreamAudioDestinationNode createMediaStreamDestination();
-
-    ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
-                                              optional unsigned long numberOfInputChannels = 2,
-                                              optional unsigned long numberOfOutputChannels = 2);
-
-    AnalyserNode createAnalyser();
-    GainNode createGain();
-    DelayNode createDelay(optional double maxDelayTime = 1.0);
-    BiquadFilterNode createBiquadFilter();
-    WaveShaperNode createWaveShaper();
-    PannerNode createPanner();
-    ConvolverNode createConvolver();
-
-    ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs = 6);
-    ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs = 6);
-
-    DynamicsCompressorNode createDynamicsCompressor();
-
-    OscillatorNode createOscillator();
-    PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag);
-
+interface BaseAudioContext : EventTarget {
+    readonly        attribute AudioDestinationNode destination;
+    readonly        attribute float                sampleRate;
+    readonly        attribute double               currentTime;
+    readonly        attribute AudioListener        listener;
+    readonly        attribute AudioContextState    state;
+    readonly        attribute double               baseLatency;
+    Promise<void>          resume ();
+                    attribute EventHandler         onstatechange;
+    AudioBuffer            createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate);
+    Promise<AudioBuffer>   decodeAudioData (ArrayBuffer audioData, optional DecodeSuccessCallback successCallback, optional DecodeErrorCallback errorCallback);
+    AudioBufferSourceNode  createBufferSource ();
+    ConstantSourceNode     createConstantSource ();
+    ScriptProcessorNode    createScriptProcessor (optional unsigned long bufferSize = 0
+              , optional unsigned long numberOfInputChannels = 2
+              , optional unsigned long numberOfOutputChannels = 2
+              );
+    AnalyserNode           createAnalyser ();
+    GainNode               createGain ();
+    DelayNode              createDelay (optional double maxDelayTime);
+    BiquadFilterNode       createBiquadFilter ();
+    IIRFilterNode          createIIRFilter (sequence<double> feedforward, sequence<double> feedback);
+    WaveShaperNode         createWaveShaper ();
+    PannerNode             createPanner ();
+    StereoPannerNode       createStereoPanner ();
+    ConvolverNode          createConvolver ();
+    ChannelSplitterNode    createChannelSplitter (optional unsigned long numberOfOutputs = 6
+              );
+    ChannelMergerNode      createChannelMerger (optional unsigned long numberOfInputs = 6
+              );
+    DynamicsCompressorNode createDynamicsCompressor ();
+    OscillatorNode         createOscillator ();
+    PeriodicWave           createPeriodicWave (Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints);
 };</pre>
 
    <pre id="audio-node-idl">enum ChannelCountMode {
     "max",
     "clamped-max",
     "explicit"
 };
 
@@ -87,17 +77,17 @@ enum ChannelInterpretation {
 };
 
 interface AudioNode : EventTarget {
 
     void connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0);
     void connect(AudioParam destination, optional unsigned long output = 0);
     void disconnect(optional unsigned long output = 0);
 
-    readonly attribute AudioContext context;
+    readonly attribute BaseAudioContext context;
     readonly attribute unsigned long numberOfInputs;
     readonly attribute unsigned long numberOfOutputs;
 
     // Channel up-mixing and down-mixing rules for all inputs.
     attribute unsigned long channelCount;
     attribute ChannelCountMode channelCountMode;
     attribute ChannelInterpretation channelInterpretation;
 
@@ -124,30 +114,30 @@ interface AudioNode : EventTarget {
     void cancelScheduledValues(double startTime);
 
 };</pre>
 
 <pre id="gain-node-idl">dictionary GainOptions : AudioNodeOptions {
              float gain = 1.0;
 };
 
-[Constructor(AudioContext context, optional GainOptions options)]
+[Constructor(BaseAudioContext context, optional GainOptions options)]
 interface GainNode : AudioNode {
 
     readonly attribute AudioParam gain;
 
 };</pre>
 
   <div id="log"></div>
 
   <script>
 (function() {
   var idl_array = new IdlArray();
   idl_array.add_untested_idls(document.getElementById("event-target-idl").textContent);
-  idl_array.add_untested_idls(document.getElementById("audio-context-idl").textContent);
+  idl_array.add_untested_idls(document.getElementById("base-audio-context-idl").textContent);
   idl_array.add_untested_idls(document.getElementById("audio-node-idl").textContent);
   idl_array.add_untested_idls(document.getElementById("audio-param-idl").textContent);
   idl_array.add_idls(document.getElementById("gain-node-idl").textContent);
 
   gain_node = (new AudioContext).createGain();
 
   idl_array.add_objects({GainNode: ["gain_node"]});
   idl_array.test();