/*
 * 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,
    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, [Callback] AudioBufferCallback successCallback, [Optional, Callback] AudioBufferCallback errorCallback);

    // Sources
    AudioBufferSourceNode createBufferSource();

#if defined(ENABLE_VIDEO) && ENABLE_VIDEO
    [RaisesException] MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement);
#endif

#if defined(ENABLE_MEDIA_STREAM) && ENABLE_MEDIA_STREAM
    [RaisesException] MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream);
    MediaStreamAudioDestinationNode createMediaStreamDestination();
#endif

    // 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();

#if defined(ENABLE_LEGACY_WEB_AUDIO) && ENABLE_LEGACY_WEB_AUDIO
    [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);
#endif

};
