1 /* 2 * Copyright (C) 2010, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #ifndef AudioNodeInput_h 26 #define AudioNodeInput_h 27 28 #include "AudioBus.h" 29 #include "AudioNode.h" 30 #include <wtf/HashSet.h> 31 #include <wtf/Vector.h> 32 33 namespace WebCore { 34 35 class AudioNode; 36 class AudioNodeOutput; 37 38 // An AudioNodeInput represents an input to an AudioNode and can be connected from one or more AudioNodeOutputs. 39 // In the case of multiple connections, the input will act as a unity-gain summing junction, mixing all the outputs. 40 // The number of channels of the input's bus is the maximum of the number of channels of all its connections. 41 42 class AudioNodeInput { 43 public: 44 AudioNodeInput(AudioNode*); 45 46 // Can be called from any thread. node()47 AudioNode* node() const { return m_node; } context()48 AudioContext* context() { return m_node->context(); } 49 50 // Must be called with the context's graph lock. 51 void connect(AudioNodeOutput*); 52 void disconnect(AudioNodeOutput*); 53 54 // disable() will take the output out of the active connections list and set aside in a disabled list. 55 // enable() will put the output back into the active connections list. 56 // Must be called with the context's graph lock. 57 void enable(AudioNodeOutput*); 58 void disable(AudioNodeOutput*); 59 60 // pull() processes all of the AudioNodes connected to us. 61 // In the case of multiple connections it sums the result into an internal summing bus. 62 // In the single connection case, it allows in-place processing where possible using inPlaceBus. 63 // It returns the bus which it rendered into, returning inPlaceBus if in-place processing was performed. 64 // Called from context's audio thread. 65 AudioBus* pull(AudioBus* inPlaceBus, size_t framesToProcess); 66 67 // bus() contains the rendered audio after pull() has been called for each time quantum. 68 // Called from context's audio thread. 69 AudioBus* bus(); 70 71 // This copies m_outputs to m_renderingOutputs. Please see comments for these lists below. 72 // This must be called when we own the context's graph lock in the audio thread at the very start or end of the render quantum. 73 void updateRenderingState(); 74 75 // Rendering code accesses its version of the current connections here. numberOfRenderingConnections()76 unsigned numberOfRenderingConnections() const { return m_renderingOutputs.size(); } renderingOutput(unsigned i)77 AudioNodeOutput* renderingOutput(unsigned i) { return m_renderingOutputs[i]; } renderingOutput(unsigned i)78 const AudioNodeOutput* renderingOutput(unsigned i) const { return m_renderingOutputs[i]; } isConnected()79 bool isConnected() const { return numberOfRenderingConnections() > 0; } 80 81 // The number of channels of the connection with the largest number of channels. 82 unsigned numberOfChannels() const; 83 84 private: 85 AudioNode* m_node; 86 87 // m_outputs contains the AudioNodeOutputs representing current connections which are not disabled. 88 // The rendering code should never use this directly, but instead uses m_renderingOutputs. 89 HashSet<AudioNodeOutput*> m_outputs; 90 91 // numberOfConnections() should never be called from the audio rendering thread. 92 // Instead numberOfRenderingConnections() and renderingOutput() should be used. numberOfConnections()93 unsigned numberOfConnections() const { return m_outputs.size(); } 94 95 // This must be called whenever we modify m_outputs. 96 void changedOutputs(); 97 98 // m_renderingOutputs is a copy of m_outputs which will never be modified during the graph rendering on the audio thread. 99 // This is the list which is used by the rendering code. 100 // Whenever m_outputs is modified, the context is told so it can later update m_renderingOutputs from m_outputs at a safe time. 101 // Most of the time, m_renderingOutputs is identical to m_outputs. 102 Vector<AudioNodeOutput*> m_renderingOutputs; 103 104 // m_renderingStateNeedUpdating keeps track if m_outputs is modified. 105 bool m_renderingStateNeedUpdating; 106 107 // The number of channels of the rendering connection with the largest number of channels. 108 unsigned numberOfRenderingChannels(); 109 110 // m_disabledOutputs contains the AudioNodeOutputs which are disabled (will not be processed) by the audio graph rendering. 111 // But, from JavaScript's perspective, these outputs are still connected to us. 112 // Generally, these represent disabled connections from "notes" which have finished playing but are not yet garbage collected. 113 HashSet<AudioNodeOutput*> m_disabledOutputs; 114 115 // Called from context's audio thread. 116 AudioBus* internalSummingBus(); 117 void sumAllConnections(AudioBus* summingBus, size_t framesToProcess); 118 119 OwnPtr<AudioBus> m_monoSummingBus; 120 OwnPtr<AudioBus> m_stereoSummingBus; 121 }; 122 123 } // namespace WebCore 124 125 #endif // AudioNodeInput_h 126