/**
 * High-fidelity audio programming in the browser.
 */
library dart.dom.web_audio;

import 'dart:async';
import 'dart:collection';
import 'dart:_internal';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
import 'dart:typed_data';
import 'dart:_blink' as _blink;
import 'dart:js' as js;
// DO NOT EDIT
// Auto-generated dart:audio library.




// FIXME: Can we make this private?
final web_audioBlinkMap = {
  'AnalyserNode': () => AnalyserNode,
  'AudioBuffer': () => AudioBuffer,
  'AudioBufferSourceNode': () => AudioBufferSourceNode,
  'AudioContext': () => AudioContext,
  'AudioDestinationNode': () => AudioDestinationNode,
  'AudioListener': () => AudioListener,
  'AudioNode': () => AudioNode,
  'AudioParam': () => AudioParam,
  'AudioProcessingEvent': () => AudioProcessingEvent,
  'AudioSourceNode': () => AudioSourceNode,
  'BiquadFilterNode': () => BiquadFilterNode,
  'ChannelMergerNode': () => ChannelMergerNode,
  'ChannelSplitterNode': () => ChannelSplitterNode,
  'ConvolverNode': () => ConvolverNode,
  'DelayNode': () => DelayNode,
  'DynamicsCompressorNode': () => DynamicsCompressorNode,
  'GainNode': () => GainNode,
  'MediaElementAudioSourceNode': () => MediaElementAudioSourceNode,
  'MediaStreamAudioDestinationNode': () => MediaStreamAudioDestinationNode,
  'MediaStreamAudioSourceNode': () => MediaStreamAudioSourceNode,
  'OfflineAudioCompletionEvent': () => OfflineAudioCompletionEvent,
  'OfflineAudioContext': () => OfflineAudioContext,
  'OscillatorNode': () => OscillatorNode,
  'PannerNode': () => PannerNode,
  'PeriodicWave': () => PeriodicWave,
  'ScriptProcessorNode': () => ScriptProcessorNode,
  'WaveShaperNode': () => WaveShaperNode,

};

// FIXME: Can we make this private?
final web_audioBlinkFunctionMap = {
  'AnalyserNode': () => AnalyserNode.internalCreateAnalyserNode,
  'AudioBuffer': () => AudioBuffer.internalCreateAudioBuffer,
  'AudioBufferSourceNode': () => AudioBufferSourceNode.internalCreateAudioBufferSourceNode,
  'AudioContext': () => AudioContext.internalCreateAudioContext,
  'AudioDestinationNode': () => AudioDestinationNode.internalCreateAudioDestinationNode,
  'AudioListener': () => AudioListener.internalCreateAudioListener,
  'AudioNode': () => AudioNode.internalCreateAudioNode,
  'AudioParam': () => AudioParam.internalCreateAudioParam,
  'AudioProcessingEvent': () => AudioProcessingEvent.internalCreateAudioProcessingEvent,
  'AudioSourceNode': () => AudioSourceNode.internalCreateAudioSourceNode,
  'BiquadFilterNode': () => BiquadFilterNode.internalCreateBiquadFilterNode,
  'ChannelMergerNode': () => ChannelMergerNode.internalCreateChannelMergerNode,
  'ChannelSplitterNode': () => ChannelSplitterNode.internalCreateChannelSplitterNode,
  'ConvolverNode': () => ConvolverNode.internalCreateConvolverNode,
  'DelayNode': () => DelayNode.internalCreateDelayNode,
  'DynamicsCompressorNode': () => DynamicsCompressorNode.internalCreateDynamicsCompressorNode,
  'GainNode': () => GainNode.internalCreateGainNode,
  'MediaElementAudioSourceNode': () => MediaElementAudioSourceNode.internalCreateMediaElementAudioSourceNode,
  'MediaStreamAudioDestinationNode': () => MediaStreamAudioDestinationNode.internalCreateMediaStreamAudioDestinationNode,
  'MediaStreamAudioSourceNode': () => MediaStreamAudioSourceNode.internalCreateMediaStreamAudioSourceNode,
  'OfflineAudioCompletionEvent': () => OfflineAudioCompletionEvent.internalCreateOfflineAudioCompletionEvent,
  'OfflineAudioContext': () => OfflineAudioContext.internalCreateOfflineAudioContext,
  'OscillatorNode': () => OscillatorNode.internalCreateOscillatorNode,
  'PannerNode': () => PannerNode.internalCreatePannerNode,
  'PeriodicWave': () => PeriodicWave.internalCreatePeriodicWave,
  'ScriptProcessorNode': () => ScriptProcessorNode.internalCreateScriptProcessorNode,
  'WaveShaperNode': () => WaveShaperNode.internalCreateWaveShaperNode,

};
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AnalyserNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AnalyserNode
@Experimental()
class AnalyserNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory AnalyserNode._() { throw new UnsupportedError("Not supported"); }


  static AnalyserNode internalCreateAnalyserNode() {
    return new AnalyserNode._internalWrap();
  }

  factory AnalyserNode._internalWrap() {
    return new AnalyserNode.internal_();
  }

  AnalyserNode.internal_() : super.internal_();


  @DomName('AnalyserNode.fftSize')
  @DocsEditable()
  int get fftSize => _blink.BlinkAnalyserNode.instance.fftSize_Getter_(unwrap_jso(this));
  
  @DomName('AnalyserNode.fftSize')
  @DocsEditable()
  set fftSize(int value) => _blink.BlinkAnalyserNode.instance.fftSize_Setter_(unwrap_jso(this), value);
  
  @DomName('AnalyserNode.frequencyBinCount')
  @DocsEditable()
  int get frequencyBinCount => _blink.BlinkAnalyserNode.instance.frequencyBinCount_Getter_(unwrap_jso(this));
  
  @DomName('AnalyserNode.maxDecibels')
  @DocsEditable()
  num get maxDecibels => _blink.BlinkAnalyserNode.instance.maxDecibels_Getter_(unwrap_jso(this));
  
  @DomName('AnalyserNode.maxDecibels')
  @DocsEditable()
  set maxDecibels(num value) => _blink.BlinkAnalyserNode.instance.maxDecibels_Setter_(unwrap_jso(this), value);
  
  @DomName('AnalyserNode.minDecibels')
  @DocsEditable()
  num get minDecibels => _blink.BlinkAnalyserNode.instance.minDecibels_Getter_(unwrap_jso(this));
  
  @DomName('AnalyserNode.minDecibels')
  @DocsEditable()
  set minDecibels(num value) => _blink.BlinkAnalyserNode.instance.minDecibels_Setter_(unwrap_jso(this), value);
  
  @DomName('AnalyserNode.smoothingTimeConstant')
  @DocsEditable()
  num get smoothingTimeConstant => _blink.BlinkAnalyserNode.instance.smoothingTimeConstant_Getter_(unwrap_jso(this));
  
  @DomName('AnalyserNode.smoothingTimeConstant')
  @DocsEditable()
  set smoothingTimeConstant(num value) => _blink.BlinkAnalyserNode.instance.smoothingTimeConstant_Setter_(unwrap_jso(this), value);
  
  @DomName('AnalyserNode.getByteFrequencyData')
  @DocsEditable()
  void getByteFrequencyData(Uint8List array) => _blink.BlinkAnalyserNode.instance.getByteFrequencyData_Callback_1_(unwrap_jso(this), array);
  
  @DomName('AnalyserNode.getByteTimeDomainData')
  @DocsEditable()
  void getByteTimeDomainData(Uint8List array) => _blink.BlinkAnalyserNode.instance.getByteTimeDomainData_Callback_1_(unwrap_jso(this), array);
  
  @DomName('AnalyserNode.getFloatFrequencyData')
  @DocsEditable()
  void getFloatFrequencyData(Float32List array) => _blink.BlinkAnalyserNode.instance.getFloatFrequencyData_Callback_1_(unwrap_jso(this), array);
  
  @DomName('AnalyserNode.getFloatTimeDomainData')
  @DocsEditable()
  @Experimental() // untriaged
  void getFloatTimeDomainData(Float32List array) => _blink.BlinkAnalyserNode.instance.getFloatTimeDomainData_Callback_1_(unwrap_jso(this), array);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AudioBuffer')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioBuffer-section
@Experimental()
class AudioBuffer extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory AudioBuffer._() { throw new UnsupportedError("Not supported"); }

  static AudioBuffer internalCreateAudioBuffer() {
    return new AudioBuffer._internalWrap();
  }

  js.JsObject blink_jsObject;

  factory AudioBuffer._internalWrap() {
    return new AudioBuffer.internal_();
  }

  AudioBuffer.internal_() { }

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AudioBuffer.duration')
  @DocsEditable()
  num get duration => _blink.BlinkAudioBuffer.instance.duration_Getter_(unwrap_jso(this));
  
  @DomName('AudioBuffer.length')
  @DocsEditable()
  int get length => _blink.BlinkAudioBuffer.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('AudioBuffer.numberOfChannels')
  @DocsEditable()
  int get numberOfChannels => _blink.BlinkAudioBuffer.instance.numberOfChannels_Getter_(unwrap_jso(this));
  
  @DomName('AudioBuffer.sampleRate')
  @DocsEditable()
  num get sampleRate => _blink.BlinkAudioBuffer.instance.sampleRate_Getter_(unwrap_jso(this));
  
  @DomName('AudioBuffer.getChannelData')
  @DocsEditable()
  Float32List getChannelData(int channelIndex) => _blink.BlinkAudioBuffer.instance.getChannelData_Callback_1_(unwrap_jso(this), channelIndex);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('AudioBufferCallback')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioBuffer-section
@Experimental()
typedef void AudioBufferCallback(AudioBuffer audioBuffer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AudioBufferSourceNode')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@Experimental()
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioBufferSourceNode-section
class AudioBufferSourceNode extends AudioSourceNode {
  // To suppress missing implicit constructor warnings.
  factory AudioBufferSourceNode._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [AudioBufferSourceNode].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('AudioBufferSourceNode.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');


  static AudioBufferSourceNode internalCreateAudioBufferSourceNode() {
    return new AudioBufferSourceNode._internalWrap();
  }

  factory AudioBufferSourceNode._internalWrap() {
    return new AudioBufferSourceNode.internal_();
  }

  AudioBufferSourceNode.internal_() : super.internal_();


  @DomName('AudioBufferSourceNode.buffer')
  @DocsEditable()
  AudioBuffer get buffer => wrap_jso(_blink.BlinkAudioBufferSourceNode.instance.buffer_Getter_(unwrap_jso(this)));
  
  @DomName('AudioBufferSourceNode.buffer')
  @DocsEditable()
  set buffer(AudioBuffer value) => _blink.BlinkAudioBufferSourceNode.instance.buffer_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('AudioBufferSourceNode.loop')
  @DocsEditable()
  bool get loop => _blink.BlinkAudioBufferSourceNode.instance.loop_Getter_(unwrap_jso(this));
  
  @DomName('AudioBufferSourceNode.loop')
  @DocsEditable()
  set loop(bool value) => _blink.BlinkAudioBufferSourceNode.instance.loop_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioBufferSourceNode.loopEnd')
  @DocsEditable()
  num get loopEnd => _blink.BlinkAudioBufferSourceNode.instance.loopEnd_Getter_(unwrap_jso(this));
  
  @DomName('AudioBufferSourceNode.loopEnd')
  @DocsEditable()
  set loopEnd(num value) => _blink.BlinkAudioBufferSourceNode.instance.loopEnd_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioBufferSourceNode.loopStart')
  @DocsEditable()
  num get loopStart => _blink.BlinkAudioBufferSourceNode.instance.loopStart_Getter_(unwrap_jso(this));
  
  @DomName('AudioBufferSourceNode.loopStart')
  @DocsEditable()
  set loopStart(num value) => _blink.BlinkAudioBufferSourceNode.instance.loopStart_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioBufferSourceNode.playbackRate')
  @DocsEditable()
  AudioParam get playbackRate => wrap_jso(_blink.BlinkAudioBufferSourceNode.instance.playbackRate_Getter_(unwrap_jso(this)));
  
  void start([num when, num grainOffset, num grainDuration]) {
    if (grainDuration != null) {
      _blink.BlinkAudioBufferSourceNode.instance.start_Callback_3_(unwrap_jso(this), when, grainOffset, grainDuration);
      return;
    }
    if (grainOffset != null) {
      _blink.BlinkAudioBufferSourceNode.instance.start_Callback_2_(unwrap_jso(this), when, grainOffset);
      return;
    }
    if (when != null) {
      _blink.BlinkAudioBufferSourceNode.instance.start_Callback_1_(unwrap_jso(this), when);
      return;
    }
    _blink.BlinkAudioBufferSourceNode.instance.start_Callback_0_(unwrap_jso(this));
    return;
  }

  void stop([num when]) {
    if (when != null) {
      _blink.BlinkAudioBufferSourceNode.instance.stop_Callback_1_(unwrap_jso(this), when);
      return;
    }
    _blink.BlinkAudioBufferSourceNode.instance.stop_Callback_0_(unwrap_jso(this));
    return;
  }

  /// Stream of `ended` events handled by this [AudioBufferSourceNode].
  @DomName('AudioBufferSourceNode.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => endedEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('AudioContext')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@Experimental()
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioContext-section
class AudioContext extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AudioContext._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `complete` events to event
   * handlers that are not necessarily instances of [AudioContext].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('AudioContext.completeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');

  @DomName('AudioContext.AudioContext')
  @DocsEditable()
  factory AudioContext() {
    return wrap_jso(_blink.BlinkAudioContext.instance.constructorCallback_0_());
  }


  static AudioContext internalCreateAudioContext() {
    return new AudioContext._internalWrap();
  }

  factory AudioContext._internalWrap() {
    return new AudioContext.internal_();
  }

  AudioContext.internal_() : super.internal_();


  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('AudioContext.currentTime')
  @DocsEditable()
  num get currentTime => _blink.BlinkAudioContext.instance.currentTime_Getter_(unwrap_jso(this));
  
  @DomName('AudioContext.destination')
  @DocsEditable()
  AudioDestinationNode get destination => wrap_jso(_blink.BlinkAudioContext.instance.destination_Getter_(unwrap_jso(this)));
  
  @DomName('AudioContext.listener')
  @DocsEditable()
  AudioListener get listener => wrap_jso(_blink.BlinkAudioContext.instance.listener_Getter_(unwrap_jso(this)));
  
  @DomName('AudioContext.sampleRate')
  @DocsEditable()
  num get sampleRate => _blink.BlinkAudioContext.instance.sampleRate_Getter_(unwrap_jso(this));
  
  @DomName('AudioContext.createAnalyser')
  @DocsEditable()
  AnalyserNode createAnalyser() => wrap_jso(_blink.BlinkAudioContext.instance.createAnalyser_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.createBiquadFilter')
  @DocsEditable()
  BiquadFilterNode createBiquadFilter() => wrap_jso(_blink.BlinkAudioContext.instance.createBiquadFilter_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.createBuffer')
  @DocsEditable()
  AudioBuffer createBuffer(int numberOfChannels, int numberOfFrames, num sampleRate) => wrap_jso(_blink.BlinkAudioContext.instance.createBuffer_Callback_3_(unwrap_jso(this), numberOfChannels, numberOfFrames, sampleRate));
  
  @DomName('AudioContext.createBufferSource')
  @DocsEditable()
  AudioBufferSourceNode createBufferSource() => wrap_jso(_blink.BlinkAudioContext.instance.createBufferSource_Callback_0_(unwrap_jso(this)));
  
  ChannelMergerNode createChannelMerger([int numberOfInputs]) {
    if (numberOfInputs != null) {
      return wrap_jso(_blink.BlinkAudioContext.instance.createChannelMerger_Callback_1_(unwrap_jso(this), numberOfInputs));
    }
    return wrap_jso(_blink.BlinkAudioContext.instance.createChannelMerger_Callback_0_(unwrap_jso(this)));
  }

  ChannelSplitterNode createChannelSplitter([int numberOfOutputs]) {
    if (numberOfOutputs != null) {
      return wrap_jso(_blink.BlinkAudioContext.instance.createChannelSplitter_Callback_1_(unwrap_jso(this), numberOfOutputs));
    }
    return wrap_jso(_blink.BlinkAudioContext.instance.createChannelSplitter_Callback_0_(unwrap_jso(this)));
  }

  @DomName('AudioContext.createConvolver')
  @DocsEditable()
  ConvolverNode createConvolver() => wrap_jso(_blink.BlinkAudioContext.instance.createConvolver_Callback_0_(unwrap_jso(this)));
  
  DelayNode createDelay([num maxDelayTime]) {
    if (maxDelayTime != null) {
      return wrap_jso(_blink.BlinkAudioContext.instance.createDelay_Callback_1_(unwrap_jso(this), maxDelayTime));
    }
    return wrap_jso(_blink.BlinkAudioContext.instance.createDelay_Callback_0_(unwrap_jso(this)));
  }

  @DomName('AudioContext.createDynamicsCompressor')
  @DocsEditable()
  DynamicsCompressorNode createDynamicsCompressor() => wrap_jso(_blink.BlinkAudioContext.instance.createDynamicsCompressor_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.createGain')
  @DocsEditable()
  GainNode createGain() => wrap_jso(_blink.BlinkAudioContext.instance.createGain_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.createMediaElementSource')
  @DocsEditable()
  MediaElementAudioSourceNode createMediaElementSource(MediaElement mediaElement) => wrap_jso(_blink.BlinkAudioContext.instance.createMediaElementSource_Callback_1_(unwrap_jso(this), unwrap_jso(mediaElement)));
  
  @DomName('AudioContext.createMediaStreamDestination')
  @DocsEditable()
  MediaStreamAudioDestinationNode createMediaStreamDestination() => wrap_jso(_blink.BlinkAudioContext.instance.createMediaStreamDestination_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.createMediaStreamSource')
  @DocsEditable()
  MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream) => wrap_jso(_blink.BlinkAudioContext.instance.createMediaStreamSource_Callback_1_(unwrap_jso(this), unwrap_jso(mediaStream)));
  
  @DomName('AudioContext.createOscillator')
  @DocsEditable()
  OscillatorNode createOscillator() => wrap_jso(_blink.BlinkAudioContext.instance.createOscillator_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.createPanner')
  @DocsEditable()
  PannerNode createPanner() => wrap_jso(_blink.BlinkAudioContext.instance.createPanner_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.createPeriodicWave')
  @DocsEditable()
  @Experimental() // untriaged
  PeriodicWave createPeriodicWave(Float32List real, Float32List imag) => wrap_jso(_blink.BlinkAudioContext.instance.createPeriodicWave_Callback_2_(unwrap_jso(this), real, imag));
  
  ScriptProcessorNode createScriptProcessor([int bufferSize, int numberOfInputChannels, int numberOfOutputChannels]) {
    if (numberOfOutputChannels != null) {
      return wrap_jso(_blink.BlinkAudioContext.instance.createScriptProcessor_Callback_3_(unwrap_jso(this), bufferSize, numberOfInputChannels, numberOfOutputChannels));
    }
    if (numberOfInputChannels != null) {
      return wrap_jso(_blink.BlinkAudioContext.instance.createScriptProcessor_Callback_2_(unwrap_jso(this), bufferSize, numberOfInputChannels));
    }
    if (bufferSize != null) {
      return wrap_jso(_blink.BlinkAudioContext.instance.createScriptProcessor_Callback_1_(unwrap_jso(this), bufferSize));
    }
    return wrap_jso(_blink.BlinkAudioContext.instance.createScriptProcessor_Callback_0_(unwrap_jso(this)));
  }

  @DomName('AudioContext.createWaveShaper')
  @DocsEditable()
  WaveShaperNode createWaveShaper() => wrap_jso(_blink.BlinkAudioContext.instance.createWaveShaper_Callback_0_(unwrap_jso(this)));
  
  @DomName('AudioContext.decodeAudioData')
  @DocsEditable()
  void _decodeAudioData(ByteBuffer audioData, AudioBufferCallback successCallback, [AudioBufferCallback errorCallback]) => _blink.BlinkAudioContext.instance.decodeAudioData_Callback_3_(unwrap_jso(this), audioData, unwrap_jso((audioBuffer) => successCallback(wrap_jso(audioBuffer))), unwrap_jso((audioBuffer) => errorCallback(wrap_jso(audioBuffer))));
  
  @DomName('AudioContext.startRendering')
  @DocsEditable()
  void startRendering() => _blink.BlinkAudioContext.instance.startRendering_Callback_0_(unwrap_jso(this));
  
  /// Stream of `complete` events handled by this [AudioContext].
  @DomName('AudioContext.oncomplete')
  @DocsEditable()
  Stream<Event> get onComplete => completeEvent.forTarget(this);

  @DomName('AudioContext.decodeAudioData')
  Future<AudioBuffer> decodeAudioData(ByteBuffer audioData) {
    var completer = new Completer<AudioBuffer>();
    _decodeAudioData(audioData,
        (value) { completer.complete(value); },
        (error) {
          if (error == null) {
            completer.completeError('');
          } else {
            completer.completeError(error);
          }
        });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AudioDestinationNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioDestinationNode-section
@Experimental()
class AudioDestinationNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory AudioDestinationNode._() { throw new UnsupportedError("Not supported"); }


  static AudioDestinationNode internalCreateAudioDestinationNode() {
    return new AudioDestinationNode._internalWrap();
  }

  factory AudioDestinationNode._internalWrap() {
    return new AudioDestinationNode.internal_();
  }

  AudioDestinationNode.internal_() : super.internal_();


  @DomName('AudioDestinationNode.maxChannelCount')
  @DocsEditable()
  int get maxChannelCount => _blink.BlinkAudioDestinationNode.instance.maxChannelCount_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AudioListener')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioListener-section
@Experimental()
class AudioListener extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory AudioListener._() { throw new UnsupportedError("Not supported"); }

  static AudioListener internalCreateAudioListener() {
    return new AudioListener._internalWrap();
  }

  js.JsObject blink_jsObject;

  factory AudioListener._internalWrap() {
    return new AudioListener.internal_();
  }

  AudioListener.internal_() { }

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AudioListener.dopplerFactor')
  @DocsEditable()
  num get dopplerFactor => _blink.BlinkAudioListener.instance.dopplerFactor_Getter_(unwrap_jso(this));
  
  @DomName('AudioListener.dopplerFactor')
  @DocsEditable()
  set dopplerFactor(num value) => _blink.BlinkAudioListener.instance.dopplerFactor_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioListener.speedOfSound')
  @DocsEditable()
  num get speedOfSound => _blink.BlinkAudioListener.instance.speedOfSound_Getter_(unwrap_jso(this));
  
  @DomName('AudioListener.speedOfSound')
  @DocsEditable()
  set speedOfSound(num value) => _blink.BlinkAudioListener.instance.speedOfSound_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioListener.setOrientation')
  @DocsEditable()
  void setOrientation(num x, num y, num z, num xUp, num yUp, num zUp) => _blink.BlinkAudioListener.instance.setOrientation_Callback_6_(unwrap_jso(this), x, y, z, xUp, yUp, zUp);
  
  @DomName('AudioListener.setPosition')
  @DocsEditable()
  void setPosition(num x, num y, num z) => _blink.BlinkAudioListener.instance.setPosition_Callback_3_(unwrap_jso(this), x, y, z);
  
  @DomName('AudioListener.setVelocity')
  @DocsEditable()
  void setVelocity(num x, num y, num z) => _blink.BlinkAudioListener.instance.setVelocity_Callback_3_(unwrap_jso(this), x, y, z);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('AudioNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioNode-section
@Experimental()
class AudioNode extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AudioNode._() { throw new UnsupportedError("Not supported"); }


  static AudioNode internalCreateAudioNode() {
    return new AudioNode._internalWrap();
  }

  factory AudioNode._internalWrap() {
    return new AudioNode.internal_();
  }

  AudioNode.internal_() : super.internal_();


  @DomName('AudioNode.channelCount')
  @DocsEditable()
  int get channelCount => _blink.BlinkAudioNode.instance.channelCount_Getter_(unwrap_jso(this));
  
  @DomName('AudioNode.channelCount')
  @DocsEditable()
  set channelCount(int value) => _blink.BlinkAudioNode.instance.channelCount_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioNode.channelCountMode')
  @DocsEditable()
  String get channelCountMode => _blink.BlinkAudioNode.instance.channelCountMode_Getter_(unwrap_jso(this));
  
  @DomName('AudioNode.channelCountMode')
  @DocsEditable()
  set channelCountMode(String value) => _blink.BlinkAudioNode.instance.channelCountMode_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioNode.channelInterpretation')
  @DocsEditable()
  String get channelInterpretation => _blink.BlinkAudioNode.instance.channelInterpretation_Getter_(unwrap_jso(this));
  
  @DomName('AudioNode.channelInterpretation')
  @DocsEditable()
  set channelInterpretation(String value) => _blink.BlinkAudioNode.instance.channelInterpretation_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioNode.context')
  @DocsEditable()
  AudioContext get context => wrap_jso(_blink.BlinkAudioNode.instance.context_Getter_(unwrap_jso(this)));
  
  @DomName('AudioNode.numberOfInputs')
  @DocsEditable()
  int get numberOfInputs => _blink.BlinkAudioNode.instance.numberOfInputs_Getter_(unwrap_jso(this));
  
  @DomName('AudioNode.numberOfOutputs')
  @DocsEditable()
  int get numberOfOutputs => _blink.BlinkAudioNode.instance.numberOfOutputs_Getter_(unwrap_jso(this));
  
  void _connect(destination, int output, [int input]) {
    if ((input is int || input == null) && (output is int || output == null) && (destination is AudioNode || destination == null)) {
      _blink.BlinkAudioNode.instance.connect_Callback_3_(unwrap_jso(this), unwrap_jso(destination), output, input);
      return;
    }
    if ((output is int || output == null) && (destination is AudioParam || destination == null) && input == null) {
      _blink.BlinkAudioNode.instance.connect_Callback_2_(unwrap_jso(this), unwrap_jso(destination), output);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('AudioNode.disconnect')
  @DocsEditable()
  void disconnect(int output) => _blink.BlinkAudioNode.instance.disconnect_Callback_1_(unwrap_jso(this), output);
  
  @DomName('AudioNode.connect')
  void connectNode(AudioNode destination, [int output = 0, int input = 0]) =>
      _connect(destination, output, input);

  @DomName('AudioNode.connect')
  void connectParam(AudioParam destination, [int output = 0]) =>
      _connect(destination, output);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AudioParam')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioParam
@Experimental()
class AudioParam extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory AudioParam._() { throw new UnsupportedError("Not supported"); }

  static AudioParam internalCreateAudioParam() {
    return new AudioParam._internalWrap();
  }

  js.JsObject blink_jsObject;

  factory AudioParam._internalWrap() {
    return new AudioParam.internal_();
  }

  AudioParam.internal_() { }

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AudioParam.defaultValue')
  @DocsEditable()
  num get defaultValue => _blink.BlinkAudioParam.instance.defaultValue_Getter_(unwrap_jso(this));
  
  @DomName('AudioParam.value')
  @DocsEditable()
  num get value => _blink.BlinkAudioParam.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('AudioParam.value')
  @DocsEditable()
  set value(num value) => _blink.BlinkAudioParam.instance.value_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioParam.cancelScheduledValues')
  @DocsEditable()
  void cancelScheduledValues(num startTime) => _blink.BlinkAudioParam.instance.cancelScheduledValues_Callback_1_(unwrap_jso(this), startTime);
  
  @DomName('AudioParam.exponentialRampToValueAtTime')
  @DocsEditable()
  void exponentialRampToValueAtTime(num value, num time) => _blink.BlinkAudioParam.instance.exponentialRampToValueAtTime_Callback_2_(unwrap_jso(this), value, time);
  
  @DomName('AudioParam.linearRampToValueAtTime')
  @DocsEditable()
  void linearRampToValueAtTime(num value, num time) => _blink.BlinkAudioParam.instance.linearRampToValueAtTime_Callback_2_(unwrap_jso(this), value, time);
  
  @DomName('AudioParam.setTargetAtTime')
  @DocsEditable()
  void setTargetAtTime(num target, num time, num timeConstant) => _blink.BlinkAudioParam.instance.setTargetAtTime_Callback_3_(unwrap_jso(this), target, time, timeConstant);
  
  @DomName('AudioParam.setValueAtTime')
  @DocsEditable()
  void setValueAtTime(num value, num time) => _blink.BlinkAudioParam.instance.setValueAtTime_Callback_2_(unwrap_jso(this), value, time);
  
  @DomName('AudioParam.setValueCurveAtTime')
  @DocsEditable()
  void setValueCurveAtTime(Float32List values, num time, num duration) => _blink.BlinkAudioParam.instance.setValueCurveAtTime_Callback_3_(unwrap_jso(this), values, time, duration);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AudioProcessingEvent')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioProcessingEvent-section
@Experimental()
class AudioProcessingEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AudioProcessingEvent._() { throw new UnsupportedError("Not supported"); }


  static AudioProcessingEvent internalCreateAudioProcessingEvent() {
    return new AudioProcessingEvent._internalWrap();
  }

  factory AudioProcessingEvent._internalWrap() {
    return new AudioProcessingEvent.internal_();
  }

  AudioProcessingEvent.internal_() : super.internal_();


  @DomName('AudioProcessingEvent.inputBuffer')
  @DocsEditable()
  AudioBuffer get inputBuffer => wrap_jso(_blink.BlinkAudioProcessingEvent.instance.inputBuffer_Getter_(unwrap_jso(this)));
  
  @DomName('AudioProcessingEvent.outputBuffer')
  @DocsEditable()
  AudioBuffer get outputBuffer => wrap_jso(_blink.BlinkAudioProcessingEvent.instance.outputBuffer_Getter_(unwrap_jso(this)));
  
  @DomName('AudioProcessingEvent.playbackTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackTime => _blink.BlinkAudioProcessingEvent.instance.playbackTime_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('AudioSourceNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
@Experimental()
class AudioSourceNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory AudioSourceNode._() { throw new UnsupportedError("Not supported"); }


  static AudioSourceNode internalCreateAudioSourceNode() {
    return new AudioSourceNode._internalWrap();
  }

  factory AudioSourceNode._internalWrap() {
    return new AudioSourceNode.internal_();
  }

  AudioSourceNode.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('BiquadFilterNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
@Experimental()
class BiquadFilterNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory BiquadFilterNode._() { throw new UnsupportedError("Not supported"); }


  static BiquadFilterNode internalCreateBiquadFilterNode() {
    return new BiquadFilterNode._internalWrap();
  }

  factory BiquadFilterNode._internalWrap() {
    return new BiquadFilterNode.internal_();
  }

  BiquadFilterNode.internal_() : super.internal_();


  @DomName('BiquadFilterNode.Q')
  @DocsEditable()
  AudioParam get Q => wrap_jso(_blink.BlinkBiquadFilterNode.instance.Q_Getter_(unwrap_jso(this)));
  
  @DomName('BiquadFilterNode.detune')
  @DocsEditable()
  AudioParam get detune => wrap_jso(_blink.BlinkBiquadFilterNode.instance.detune_Getter_(unwrap_jso(this)));
  
  @DomName('BiquadFilterNode.frequency')
  @DocsEditable()
  AudioParam get frequency => wrap_jso(_blink.BlinkBiquadFilterNode.instance.frequency_Getter_(unwrap_jso(this)));
  
  @DomName('BiquadFilterNode.gain')
  @DocsEditable()
  AudioParam get gain => wrap_jso(_blink.BlinkBiquadFilterNode.instance.gain_Getter_(unwrap_jso(this)));
  
  @DomName('BiquadFilterNode.type')
  @DocsEditable()
  String get type => _blink.BlinkBiquadFilterNode.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('BiquadFilterNode.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkBiquadFilterNode.instance.type_Setter_(unwrap_jso(this), value);
  
  @DomName('BiquadFilterNode.getFrequencyResponse')
  @DocsEditable()
  void getFrequencyResponse(Float32List frequencyHz, Float32List magResponse, Float32List phaseResponse) => _blink.BlinkBiquadFilterNode.instance.getFrequencyResponse_Callback_3_(unwrap_jso(this), frequencyHz, magResponse, phaseResponse);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ChannelMergerNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#ChannelMergerNode-section
@Experimental()
class ChannelMergerNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory ChannelMergerNode._() { throw new UnsupportedError("Not supported"); }


  static ChannelMergerNode internalCreateChannelMergerNode() {
    return new ChannelMergerNode._internalWrap();
  }

  factory ChannelMergerNode._internalWrap() {
    return new ChannelMergerNode.internal_();
  }

  ChannelMergerNode.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ChannelSplitterNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#ChannelSplitterNode-section
@Experimental()
class ChannelSplitterNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory ChannelSplitterNode._() { throw new UnsupportedError("Not supported"); }


  static ChannelSplitterNode internalCreateChannelSplitterNode() {
    return new ChannelSplitterNode._internalWrap();
  }

  factory ChannelSplitterNode._internalWrap() {
    return new ChannelSplitterNode.internal_();
  }

  ChannelSplitterNode.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ConvolverNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#ConvolverNode
@Experimental()
class ConvolverNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory ConvolverNode._() { throw new UnsupportedError("Not supported"); }


  static ConvolverNode internalCreateConvolverNode() {
    return new ConvolverNode._internalWrap();
  }

  factory ConvolverNode._internalWrap() {
    return new ConvolverNode.internal_();
  }

  ConvolverNode.internal_() : super.internal_();


  @DomName('ConvolverNode.buffer')
  @DocsEditable()
  AudioBuffer get buffer => wrap_jso(_blink.BlinkConvolverNode.instance.buffer_Getter_(unwrap_jso(this)));
  
  @DomName('ConvolverNode.buffer')
  @DocsEditable()
  set buffer(AudioBuffer value) => _blink.BlinkConvolverNode.instance.buffer_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('ConvolverNode.normalize')
  @DocsEditable()
  bool get normalize => _blink.BlinkConvolverNode.instance.normalize_Getter_(unwrap_jso(this));
  
  @DomName('ConvolverNode.normalize')
  @DocsEditable()
  set normalize(bool value) => _blink.BlinkConvolverNode.instance.normalize_Setter_(unwrap_jso(this), value);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DelayNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#DelayNode
@Experimental()
class DelayNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory DelayNode._() { throw new UnsupportedError("Not supported"); }


  static DelayNode internalCreateDelayNode() {
    return new DelayNode._internalWrap();
  }

  factory DelayNode._internalWrap() {
    return new DelayNode.internal_();
  }

  DelayNode.internal_() : super.internal_();


  @DomName('DelayNode.delayTime')
  @DocsEditable()
  AudioParam get delayTime => wrap_jso(_blink.BlinkDelayNode.instance.delayTime_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DynamicsCompressorNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#DynamicsCompressorNode
@Experimental()
class DynamicsCompressorNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory DynamicsCompressorNode._() { throw new UnsupportedError("Not supported"); }


  static DynamicsCompressorNode internalCreateDynamicsCompressorNode() {
    return new DynamicsCompressorNode._internalWrap();
  }

  factory DynamicsCompressorNode._internalWrap() {
    return new DynamicsCompressorNode.internal_();
  }

  DynamicsCompressorNode.internal_() : super.internal_();


  @DomName('DynamicsCompressorNode.attack')
  @DocsEditable()
  AudioParam get attack => wrap_jso(_blink.BlinkDynamicsCompressorNode.instance.attack_Getter_(unwrap_jso(this)));
  
  @DomName('DynamicsCompressorNode.knee')
  @DocsEditable()
  AudioParam get knee => wrap_jso(_blink.BlinkDynamicsCompressorNode.instance.knee_Getter_(unwrap_jso(this)));
  
  @DomName('DynamicsCompressorNode.ratio')
  @DocsEditable()
  AudioParam get ratio => wrap_jso(_blink.BlinkDynamicsCompressorNode.instance.ratio_Getter_(unwrap_jso(this)));
  
  @DomName('DynamicsCompressorNode.reduction')
  @DocsEditable()
  AudioParam get reduction => wrap_jso(_blink.BlinkDynamicsCompressorNode.instance.reduction_Getter_(unwrap_jso(this)));
  
  @DomName('DynamicsCompressorNode.release')
  @DocsEditable()
  AudioParam get release => wrap_jso(_blink.BlinkDynamicsCompressorNode.instance.release_Getter_(unwrap_jso(this)));
  
  @DomName('DynamicsCompressorNode.threshold')
  @DocsEditable()
  AudioParam get threshold => wrap_jso(_blink.BlinkDynamicsCompressorNode.instance.threshold_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('GainNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#GainNode
@Experimental()
class GainNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory GainNode._() { throw new UnsupportedError("Not supported"); }


  static GainNode internalCreateGainNode() {
    return new GainNode._internalWrap();
  }

  factory GainNode._internalWrap() {
    return new GainNode.internal_();
  }

  GainNode.internal_() : super.internal_();


  @DomName('GainNode.gain')
  @DocsEditable()
  AudioParam get gain => wrap_jso(_blink.BlinkGainNode.instance.gain_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaElementAudioSourceNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#MediaElementAudioSourceNode
@Experimental()
class MediaElementAudioSourceNode extends AudioSourceNode {
  // To suppress missing implicit constructor warnings.
  factory MediaElementAudioSourceNode._() { throw new UnsupportedError("Not supported"); }


  static MediaElementAudioSourceNode internalCreateMediaElementAudioSourceNode() {
    return new MediaElementAudioSourceNode._internalWrap();
  }

  factory MediaElementAudioSourceNode._internalWrap() {
    return new MediaElementAudioSourceNode.internal_();
  }

  MediaElementAudioSourceNode.internal_() : super.internal_();


  @DomName('MediaElementAudioSourceNode.mediaElement')
  @DocsEditable()
  @Experimental() // non-standard
  MediaElement get mediaElement => wrap_jso(_blink.BlinkMediaElementAudioSourceNode.instance.mediaElement_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaStreamAudioDestinationNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#MediaStreamAudioDestinationNode
@Experimental()
class MediaStreamAudioDestinationNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamAudioDestinationNode._() { throw new UnsupportedError("Not supported"); }


  static MediaStreamAudioDestinationNode internalCreateMediaStreamAudioDestinationNode() {
    return new MediaStreamAudioDestinationNode._internalWrap();
  }

  factory MediaStreamAudioDestinationNode._internalWrap() {
    return new MediaStreamAudioDestinationNode.internal_();
  }

  MediaStreamAudioDestinationNode.internal_() : super.internal_();


  @DomName('MediaStreamAudioDestinationNode.stream')
  @DocsEditable()
  MediaStream get stream => wrap_jso(_blink.BlinkMediaStreamAudioDestinationNode.instance.stream_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaStreamAudioSourceNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#MediaStreamAudioSourceNode
@Experimental()
class MediaStreamAudioSourceNode extends AudioSourceNode {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamAudioSourceNode._() { throw new UnsupportedError("Not supported"); }


  static MediaStreamAudioSourceNode internalCreateMediaStreamAudioSourceNode() {
    return new MediaStreamAudioSourceNode._internalWrap();
  }

  factory MediaStreamAudioSourceNode._internalWrap() {
    return new MediaStreamAudioSourceNode.internal_();
  }

  MediaStreamAudioSourceNode.internal_() : super.internal_();


  @DomName('MediaStreamAudioSourceNode.mediaStream')
  @DocsEditable()
  MediaStream get mediaStream => wrap_jso(_blink.BlinkMediaStreamAudioSourceNode.instance.mediaStream_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('OfflineAudioCompletionEvent')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#OfflineAudioCompletionEvent-section
@Experimental()
class OfflineAudioCompletionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory OfflineAudioCompletionEvent._() { throw new UnsupportedError("Not supported"); }


  static OfflineAudioCompletionEvent internalCreateOfflineAudioCompletionEvent() {
    return new OfflineAudioCompletionEvent._internalWrap();
  }

  factory OfflineAudioCompletionEvent._internalWrap() {
    return new OfflineAudioCompletionEvent.internal_();
  }

  OfflineAudioCompletionEvent.internal_() : super.internal_();


  @DomName('OfflineAudioCompletionEvent.renderedBuffer')
  @DocsEditable()
  AudioBuffer get renderedBuffer => wrap_jso(_blink.BlinkOfflineAudioCompletionEvent.instance.renderedBuffer_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('OfflineAudioContext')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#OfflineAudioContext-section
@Experimental()
class OfflineAudioContext extends AudioContext {
  // To suppress missing implicit constructor warnings.
  factory OfflineAudioContext._() { throw new UnsupportedError("Not supported"); }

  @DomName('OfflineAudioContext.OfflineAudioContext')
  @DocsEditable()
  factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) {
    return wrap_jso(_blink.BlinkOfflineAudioContext.instance.constructorCallback_3_(numberOfChannels, numberOfFrames, sampleRate));
  }


  static OfflineAudioContext internalCreateOfflineAudioContext() {
    return new OfflineAudioContext._internalWrap();
  }

  factory OfflineAudioContext._internalWrap() {
    return new OfflineAudioContext.internal_();
  }

  OfflineAudioContext.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('OscillatorNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#dfn-OscillatorNode
@Experimental()
class OscillatorNode extends AudioSourceNode {
  // To suppress missing implicit constructor warnings.
  factory OscillatorNode._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [OscillatorNode].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('OscillatorNode.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');


  static OscillatorNode internalCreateOscillatorNode() {
    return new OscillatorNode._internalWrap();
  }

  factory OscillatorNode._internalWrap() {
    return new OscillatorNode.internal_();
  }

  OscillatorNode.internal_() : super.internal_();


  @DomName('OscillatorNode.detune')
  @DocsEditable()
  AudioParam get detune => wrap_jso(_blink.BlinkOscillatorNode.instance.detune_Getter_(unwrap_jso(this)));
  
  @DomName('OscillatorNode.frequency')
  @DocsEditable()
  AudioParam get frequency => wrap_jso(_blink.BlinkOscillatorNode.instance.frequency_Getter_(unwrap_jso(this)));
  
  @DomName('OscillatorNode.type')
  @DocsEditable()
  String get type => _blink.BlinkOscillatorNode.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('OscillatorNode.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkOscillatorNode.instance.type_Setter_(unwrap_jso(this), value);
  
  @DomName('OscillatorNode.noteOff')
  @DocsEditable()
  void noteOff(num when) => _blink.BlinkOscillatorNode.instance.noteOff_Callback_1_(unwrap_jso(this), when);
  
  @DomName('OscillatorNode.noteOn')
  @DocsEditable()
  void noteOn(num when) => _blink.BlinkOscillatorNode.instance.noteOn_Callback_1_(unwrap_jso(this), when);
  
  @DomName('OscillatorNode.setPeriodicWave')
  @DocsEditable()
  @Experimental() // untriaged
  void setPeriodicWave(PeriodicWave periodicWave) => _blink.BlinkOscillatorNode.instance.setPeriodicWave_Callback_1_(unwrap_jso(this), unwrap_jso(periodicWave));
  
  void start([num when]) {
    if (when != null) {
      _blink.BlinkOscillatorNode.instance.start_Callback_1_(unwrap_jso(this), when);
      return;
    }
    _blink.BlinkOscillatorNode.instance.start_Callback_0_(unwrap_jso(this));
    return;
  }

  void stop([num when]) {
    if (when != null) {
      _blink.BlinkOscillatorNode.instance.stop_Callback_1_(unwrap_jso(this), when);
      return;
    }
    _blink.BlinkOscillatorNode.instance.stop_Callback_0_(unwrap_jso(this));
    return;
  }

  /// Stream of `ended` events handled by this [OscillatorNode].
  @DomName('OscillatorNode.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => endedEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PannerNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#PannerNode
@Experimental()
class PannerNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory PannerNode._() { throw new UnsupportedError("Not supported"); }


  static PannerNode internalCreatePannerNode() {
    return new PannerNode._internalWrap();
  }

  factory PannerNode._internalWrap() {
    return new PannerNode.internal_();
  }

  PannerNode.internal_() : super.internal_();


  @DomName('PannerNode.coneInnerAngle')
  @DocsEditable()
  num get coneInnerAngle => _blink.BlinkPannerNode.instance.coneInnerAngle_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.coneInnerAngle')
  @DocsEditable()
  set coneInnerAngle(num value) => _blink.BlinkPannerNode.instance.coneInnerAngle_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.coneOuterAngle')
  @DocsEditable()
  num get coneOuterAngle => _blink.BlinkPannerNode.instance.coneOuterAngle_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.coneOuterAngle')
  @DocsEditable()
  set coneOuterAngle(num value) => _blink.BlinkPannerNode.instance.coneOuterAngle_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.coneOuterGain')
  @DocsEditable()
  num get coneOuterGain => _blink.BlinkPannerNode.instance.coneOuterGain_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.coneOuterGain')
  @DocsEditable()
  set coneOuterGain(num value) => _blink.BlinkPannerNode.instance.coneOuterGain_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.distanceModel')
  @DocsEditable()
  String get distanceModel => _blink.BlinkPannerNode.instance.distanceModel_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.distanceModel')
  @DocsEditable()
  set distanceModel(String value) => _blink.BlinkPannerNode.instance.distanceModel_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.maxDistance')
  @DocsEditable()
  num get maxDistance => _blink.BlinkPannerNode.instance.maxDistance_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.maxDistance')
  @DocsEditable()
  set maxDistance(num value) => _blink.BlinkPannerNode.instance.maxDistance_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.panningModel')
  @DocsEditable()
  String get panningModel => _blink.BlinkPannerNode.instance.panningModel_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.panningModel')
  @DocsEditable()
  set panningModel(String value) => _blink.BlinkPannerNode.instance.panningModel_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.refDistance')
  @DocsEditable()
  num get refDistance => _blink.BlinkPannerNode.instance.refDistance_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.refDistance')
  @DocsEditable()
  set refDistance(num value) => _blink.BlinkPannerNode.instance.refDistance_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.rolloffFactor')
  @DocsEditable()
  num get rolloffFactor => _blink.BlinkPannerNode.instance.rolloffFactor_Getter_(unwrap_jso(this));
  
  @DomName('PannerNode.rolloffFactor')
  @DocsEditable()
  set rolloffFactor(num value) => _blink.BlinkPannerNode.instance.rolloffFactor_Setter_(unwrap_jso(this), value);
  
  @DomName('PannerNode.setOrientation')
  @DocsEditable()
  void setOrientation(num x, num y, num z) => _blink.BlinkPannerNode.instance.setOrientation_Callback_3_(unwrap_jso(this), x, y, z);
  
  @DomName('PannerNode.setPosition')
  @DocsEditable()
  void setPosition(num x, num y, num z) => _blink.BlinkPannerNode.instance.setPosition_Callback_3_(unwrap_jso(this), x, y, z);
  
  @DomName('PannerNode.setVelocity')
  @DocsEditable()
  void setVelocity(num x, num y, num z) => _blink.BlinkPannerNode.instance.setVelocity_Callback_3_(unwrap_jso(this), x, y, z);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PeriodicWave')
@Experimental() // untriaged
class PeriodicWave extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory PeriodicWave._() { throw new UnsupportedError("Not supported"); }

  static PeriodicWave internalCreatePeriodicWave() {
    return new PeriodicWave._internalWrap();
  }

  js.JsObject blink_jsObject;

  factory PeriodicWave._internalWrap() {
    return new PeriodicWave.internal_();
  }

  PeriodicWave.internal_() { }

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ScriptProcessorNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#ScriptProcessorNode
@Experimental()
class ScriptProcessorNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory ScriptProcessorNode._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `audioprocess` events to event
   * handlers that are not necessarily instances of [ScriptProcessorNode].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ScriptProcessorNode.audioprocessEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<AudioProcessingEvent> audioProcessEvent = const EventStreamProvider<AudioProcessingEvent>('audioprocess');


  static ScriptProcessorNode internalCreateScriptProcessorNode() {
    return new ScriptProcessorNode._internalWrap();
  }

  factory ScriptProcessorNode._internalWrap() {
    return new ScriptProcessorNode.internal_();
  }

  ScriptProcessorNode.internal_() : super.internal_();


  @DomName('ScriptProcessorNode.bufferSize')
  @DocsEditable()
  int get bufferSize => _blink.BlinkScriptProcessorNode.instance.bufferSize_Getter_(unwrap_jso(this));
  
  @DomName('ScriptProcessorNode.setEventListener')
  @DocsEditable()
  @Experimental() // untriaged
  void setEventListener(EventListener eventListener) => _blink.BlinkScriptProcessorNode.instance.setEventListener_Callback_1_(unwrap_jso(this), unwrap_jso((event) => eventListener(wrap_jso(event))));
  
  /// Stream of `audioprocess` events handled by this [ScriptProcessorNode].
/**
   * Get a Stream that fires events when AudioProcessingEvents occur.
   * This particular stream is special in that it only allows one listener to a
   * given stream. Converting the returned Stream [asBroadcast] will likely ruin
   * the soft-real-time properties which which these events are fired and can
   * be processed.
   */
  @DomName('ScriptProcessorNode.onaudioprocess')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<AudioProcessingEvent> get onAudioProcess => audioProcessEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WaveShaperNode')
// https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#dfn-WaveShaperNode
@Experimental()
class WaveShaperNode extends AudioNode {
  // To suppress missing implicit constructor warnings.
  factory WaveShaperNode._() { throw new UnsupportedError("Not supported"); }


  static WaveShaperNode internalCreateWaveShaperNode() {
    return new WaveShaperNode._internalWrap();
  }

  factory WaveShaperNode._internalWrap() {
    return new WaveShaperNode.internal_();
  }

  WaveShaperNode.internal_() : super.internal_();


  @DomName('WaveShaperNode.curve')
  @DocsEditable()
  Float32List get curve => _blink.BlinkWaveShaperNode.instance.curve_Getter_(unwrap_jso(this));
  
  @DomName('WaveShaperNode.curve')
  @DocsEditable()
  set curve(Float32List value) => _blink.BlinkWaveShaperNode.instance.curve_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('WaveShaperNode.oversample')
  @DocsEditable()
  String get oversample => _blink.BlinkWaveShaperNode.instance.oversample_Getter_(unwrap_jso(this));
  
  @DomName('WaveShaperNode.oversample')
  @DocsEditable()
  set oversample(String value) => _blink.BlinkWaveShaperNode.instance.oversample_Setter_(unwrap_jso(this), value);
  
}
