/*
 * Copyright (C) 2010, Google Inc. All rights reserved.
 * Copyright (C) 2011 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

[
    NoInterfaceObject,
    Conditional=WEB_AUDIO,
    ActiveDOMObject,
    Constructor,
    Constructor(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate),
    ConstructorCallWith=Document,
    ConstructorRaisesException
] interface AudioContext : EventTarget {
    // All rendered audio ultimately connects to destination, which represents the audio hardware.
    readonly attribute AudioDestinationNode destination;

    // All scheduled times are relative to this time in seconds.
    readonly attribute float currentTime;

    // All AudioNodes in the context run at this sample-rate (sample-frames per second).
    readonly attribute float sampleRate;

    // All panning is relative to this listener.
    readonly attribute AudioListener listener;

    // Number of AudioBufferSourceNodes that are currently playing.
    readonly attribute unsigned long activeSourceCount;

    [RaisesException] AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate);
    [RaisesException] AudioBuffer createBuffer(ArrayBuffer? buffer, boolean mixToMono);

    // Asynchronous audio file data decoding.
    [RaisesException] void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback successCallback, optional AudioBufferCallback errorCallback);

    // Sources
    AudioBufferSourceNode createBufferSource();

    [RaisesException] MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);

    [RaisesException] MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
    MediaStreamAudioDestinationNode createMediaStreamDestination();

    // Processing nodes
    GainNode createGain();
    [RaisesException] DelayNode createDelay(optional double maxDelayTime);
    BiquadFilterNode createBiquadFilter();
    WaveShaperNode createWaveShaper();
    PannerNode createPanner();
    ConvolverNode createConvolver();
    DynamicsCompressorNode createDynamicsCompressor();
    AnalyserNode createAnalyser();
    [RaisesException] ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize, optional unsigned long numberOfInputChannels, optional unsigned long numberOfOutputChannels);
    OscillatorNode createOscillator();
    [RaisesException] PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag);

    // Channel splitting and merging
    [RaisesException] ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs);
    [RaisesException] ChannelMergerNode createChannelMerger(optional unsigned long numberOfInputs);

    // Offline rendering
    // void prepareOfflineBufferRendering(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate);
    attribute EventHandler oncomplete;
    void startRendering();

    [MeasureAs=LegacyWebAudio, ImplementedAs=createGain] GainNode createGainNode();
    [MeasureAs=LegacyWebAudio, ImplementedAs=createDelay, RaisesException] DelayNode createDelayNode(optional double maxDelayTime);

    [MeasureAs=LegacyWebAudio, ImplementedAs=createScriptProcessor, RaisesException] ScriptProcessorNode createJavaScriptNode(unsigned long bufferSize, optional unsigned long numberOfInputChannels, optional unsigned long numberOfOutputChannels);

};
