/*
 * 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.
 */

[
    Conditional=WEB_AUDIO,
    ActiveDOMObject,
    CustomConstructor,
    ConstructorParameters=0,
    JSCustomMarkFunction,
    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 (in 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;
    
    AudioBuffer createBuffer(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate)
        raises(DOMException);
    AudioBuffer createBuffer(in ArrayBuffer? buffer, in boolean mixToMono)
        raises(DOMException);

    // Asynchronous audio file data decoding.
    void decodeAudioData(in ArrayBuffer audioData, in [Callback] AudioBufferCallback successCallback, in [Optional, Callback] AudioBufferCallback errorCallback)
        raises(DOMException);

    // Sources
    AudioBufferSourceNode createBufferSource();

#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
    MediaElementAudioSourceNode createMediaElementSource(in HTMLMediaElement mediaElement)
        raises(DOMException);
#endif

#if defined(ENABLE_MEDIA_STREAM) && ENABLE_MEDIA_STREAM
    MediaStreamAudioSourceNode createMediaStreamSource(in MediaStream mediaStream)
        raises(DOMException);
    MediaStreamAudioDestinationNode createMediaStreamDestination();
#endif

    // Processing nodes
    GainNode createGain();
    DelayNode createDelay(in [Optional] double maxDelayTime) raises(DOMException);
    BiquadFilterNode createBiquadFilter();
    WaveShaperNode createWaveShaper();
    PannerNode createPanner();
    ConvolverNode createConvolver();
    DynamicsCompressorNode createDynamicsCompressor();
    AnalyserNode createAnalyser();
    ScriptProcessorNode createScriptProcessor(in unsigned long bufferSize, in [Optional] unsigned long numberOfInputChannels, in [Optional] unsigned long numberOfOutputChannels)
        raises(DOMException);
    OscillatorNode createOscillator();
    WaveTable createWaveTable(in Float32Array real, in Float32Array imag)
        raises(DOMException);

    // Channel splitting and merging
    ChannelSplitterNode createChannelSplitter(in [Optional] unsigned long numberOfOutputs)
        raises(DOMException);
    ChannelMergerNode createChannelMerger(in [Optional] unsigned long numberOfInputs)
        raises(DOMException);

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

#if defined(ENABLE_LEGACY_WEB_AUDIO) && ENABLE_LEGACY_WEB_AUDIO
    [V8MeasureAs=LegacyWebAudio, ImplementedAs=createGain] GainNode createGainNode();
    [V8MeasureAs=LegacyWebAudio, ImplementedAs=createDelay] DelayNode createDelayNode(in [Optional] double maxDelayTime) 
        raises(DOMException);

    [V8MeasureAs=LegacyWebAudio, ImplementedAs=createScriptProcessor] ScriptProcessorNode createJavaScriptNode(in unsigned long bufferSize, in [Optional] unsigned long numberOfInputChannels, in [Optional] unsigned long numberOfOutputChannels)
        raises(DOMException);
#endif

};
