1bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen/* 2e14391e94c850b8bd03680c23b38978db68687a8John Reck * Copyright (C) 2010, Google Inc. All rights reserved. 3bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * 4bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * Redistribution and use in source and binary forms, with or without 5bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * modification, are permitted provided that the following conditions 6bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * are met: 7bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * 1. Redistributions of source code must retain the above copyright 8e14391e94c850b8bd03680c23b38978db68687a8John Reck * notice, this list of conditions and the following disclaimer. 9bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * 2. Redistributions in binary form must reproduce the above copyright 10e14391e94c850b8bd03680c23b38978db68687a8John Reck * notice, this list of conditions and the following disclaimer in the 11e14391e94c850b8bd03680c23b38978db68687a8John Reck * documentation and/or other materials provided with the distribution. 12bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * 13e14391e94c850b8bd03680c23b38978db68687a8John Reck * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16e14391e94c850b8bd03680c23b38978db68687a8John Reck * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19e14391e94c850b8bd03680c23b38978db68687a8John Reck * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20e14391e94c850b8bd03680c23b38978db68687a8John Reck * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21e14391e94c850b8bd03680c23b38978db68687a8John Reck * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22e14391e94c850b8bd03680c23b38978db68687a8John Reck * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen */ 24bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 25bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#ifndef AudioNode_h 26bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#define AudioNode_h 27bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 28bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <wtf/OwnPtr.h> 29bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <wtf/PassOwnPtr.h> 30bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <wtf/RefPtr.h> 31bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <wtf/Vector.h> 32bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 33bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#define DEBUG_AUDIONODE_REFERENCES 0 34bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 35bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsennamespace WebCore { 36bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 37bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenclass AudioContext; 38bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenclass AudioNodeInput; 39bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenclass AudioNodeOutput; 40bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 41bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen// An AudioNode is the basic building block for handling audio within an AudioContext. 42bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen// It may be an audio source, an intermediate processing module, or an audio destination. 43bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen// Each AudioNode can have inputs and/or outputs. An AudioSourceNode has no inputs and a single output. 44bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen// An AudioDestinationNode has one input and no outputs and represents the final destination to the audio hardware. 45bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen// Most processing nodes such as filters will have one input and one output, although multiple inputs and outputs are possible. 46bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 47bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenclass AudioNode { 48bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenpublic: 49bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen enum { ProcessingSizeInFrames = 128 }; 50bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 51bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen AudioNode(AudioContext*, double sampleRate); 52bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen virtual ~AudioNode(); 53bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 54bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen AudioContext* context() { return m_context.get(); } 55bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 56bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen enum NodeType { 57bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeUnknown, 58bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeDestination, 59bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeAudioBufferSource, 60bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeJavaScript, 61bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeLowPass2Filter, 62bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeHighPass2Filter, 63bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypePanner, 64bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeConvolver, 65bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeDelay, 66bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeGain, 67bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeChannelSplitter, 68bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeChannelMerger, 69bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeAnalyser, 70bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeTypeEnd 71bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen }; 72bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 73bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeType type() const { return m_type; } 74bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void setType(NodeType); 75bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 76bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // We handle our own ref-counting because of the threading issues and subtle nature of 77bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // how AudioNodes can continue processing (playing one-shot sound) after there are no more 78bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // JavaScript references to the object. 79bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen enum RefType { RefTypeNormal, RefTypeConnection, RefTypeDisabled }; 80bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 81bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Can be called from main thread or context's audio thread. 82bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void ref(RefType refType = RefTypeNormal); 83bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void deref(RefType refType = RefTypeNormal); 84bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 85bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Can be called from main thread or context's audio thread. It must be called while the context's graph lock is held. 86bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void finishDeref(RefType refType); 87bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 88bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // The AudioNodeInput(s) (if any) will already have their input data available when process() is called. 89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Subclasses will take this input data and put the results in the AudioBus(s) of its AudioNodeOutput(s) (if any). 90bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called from context's audio thread. 91bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen virtual void process(size_t framesToProcess) = 0; 92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 93bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Resets DSP processing state (clears delay lines, filter memory, etc.) 94bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called from context's audio thread. 95bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen virtual void reset() = 0; 96bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 97bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // No significant resources should be allocated until initialize() is called. 98bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Processing may not occur until a node is initialized. 99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch virtual void initialize(); 100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch virtual void uninitialize(); 101bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 102bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen bool isInitialized() const { return m_isInitialized; } 103bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void lazyInitialize(); 104bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 105bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen unsigned numberOfInputs() const { return m_inputs.size(); } 106bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen unsigned numberOfOutputs() const { return m_outputs.size(); } 107bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 108bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen AudioNodeInput* input(unsigned); 109bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen AudioNodeOutput* output(unsigned); 110bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 111bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // connect() / disconnect() return true on success. 112bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called from main thread by corresponding JavaScript methods. 113bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen bool connect(AudioNode* destination, unsigned outputIndex = 0, unsigned inputIndex = 0); 114bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen bool disconnect(unsigned outputIndex = 0); 115bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 116bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen double sampleRate() const { return m_sampleRate; } 117bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 118bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // processIfNecessary() is called by our output(s) when the rendering graph needs this AudioNode to process. 119bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // This method ensures that the AudioNode will only process once per rendering time quantum even if it's called repeatedly. 120bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // This handles the case of "fanout" where an output is connected to multiple AudioNode inputs. 121bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called from context's audio thread. 122bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void processIfNecessary(size_t framesToProcess); 123bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 124bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called when a new connection has been made to one of our inputs or the connection number of channels has changed. 125bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // This potentially gives us enough information to perform a lazy initialization or, if necessary, a re-initialization. 126bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called from main thread. 127bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen virtual void checkNumberOfChannelsForInput(AudioNodeInput*) { } 128bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 129bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if DEBUG_AUDIONODE_REFERENCES 130bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen static void printNodeCounts(); 131bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif 132bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 133e14391e94c850b8bd03680c23b38978db68687a8John Reck bool isMarkedForDeletion() const { return m_isMarkedForDeletion; } 134e14391e94c850b8bd03680c23b38978db68687a8John Reck 135bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenprotected: 136bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Inputs and outputs must be created before the AudioNode is initialized. 137bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void addInput(PassOwnPtr<AudioNodeInput>); 138bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen void addOutput(PassOwnPtr<AudioNodeOutput>); 139bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 140bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called by processIfNecessary() to cause all parts of the rendering graph connected to us to process. 141bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Each rendering quantum, the audio data for each of the AudioNode's inputs will be available after this method is called. 142bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Called from context's audio thread. 143bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen virtual void pullInputs(size_t framesToProcess); 144bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 145bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenprivate: 146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch volatile bool m_isInitialized; 147bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NodeType m_type; 148bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen RefPtr<AudioContext> m_context; 149bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen double m_sampleRate; 150bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Vector<OwnPtr<AudioNodeInput> > m_inputs; 151bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Vector<OwnPtr<AudioNodeOutput> > m_outputs; 152bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 153bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen double m_lastProcessingTime; 154bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 155bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Ref-counting 156bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen volatile int m_normalRefCount; 157bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen volatile int m_connectionRefCount; 158bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen volatile int m_disabledRefCount; 159bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 160bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen bool m_isMarkedForDeletion; 161bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen bool m_isDisabled; 162bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 163bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if DEBUG_AUDIONODE_REFERENCES 164bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen static bool s_isNodeCountInitialized; 165bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen static int s_nodeCount[NodeTypeEnd]; 166bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif 167bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}; 168bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 169bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} // namespace WebCore 170bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 171bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#endif // AudioNode_h 172