/*
 * 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,
    CustomConstructor,
    EventTarget
] interface AudioContext {
    // 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(unsigned long bufferSize, optional unsigned long numberOfInputChannels, optional unsigned long numberOfOutputChannels);
    OscillatorNode createOscillator();
    [RaisesException] WaveTable createWaveTable(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 EventListener 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);

};
