content/media/webaudio/AudioNode.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:7f64f4d4cbef
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef AudioNode_h_
8 #define AudioNode_h_
9
10 #include "mozilla/DOMEventTargetHelper.h"
11 #include "mozilla/dom/AudioNodeBinding.h"
12 #include "nsCycleCollectionParticipant.h"
13 #include "nsAutoPtr.h"
14 #include "nsTArray.h"
15 #include "AudioContext.h"
16 #include "MediaStreamGraph.h"
17 #include "WebAudioUtils.h"
18 #include "mozilla/MemoryReporting.h"
19
20 namespace mozilla {
21
22 namespace dom {
23
24 class AudioContext;
25 class AudioBufferSourceNode;
26 class AudioParam;
27 class AudioParamTimeline;
28 struct ThreeDPoint;
29
30 template<class T>
31 class SelfReference {
32 public:
33 SelfReference() : mHeld(false) {}
34 ~SelfReference()
35 {
36 NS_ASSERTION(!mHeld, "Forgot to drop the self reference?");
37 }
38
39 void Take(T* t)
40 {
41 if (!mHeld) {
42 mHeld = true;
43 t->AddRef();
44 }
45 }
46 void Drop(T* t)
47 {
48 if (mHeld) {
49 mHeld = false;
50 t->Release();
51 }
52 }
53
54 operator bool() const { return mHeld; }
55
56 private:
57 bool mHeld;
58 };
59
60 /**
61 * The DOM object representing a Web Audio AudioNode.
62 *
63 * Each AudioNode has a MediaStream representing the actual
64 * real-time processing and output of this AudioNode.
65 *
66 * We track the incoming and outgoing connections to other AudioNodes.
67 * Outgoing connections have strong ownership. Also, AudioNodes that will
68 * produce sound on their output even when they have silent or no input ask
69 * the AudioContext to keep playing or tail-time references to keep them alive
70 * until the context is finished.
71 *
72 * Explicit disconnections will only remove references from output nodes after
73 * the graph is notified and the main thread receives a reply. Similarly,
74 * nodes with playing or tail-time references release these references only
75 * after receiving notification from their engine on the graph thread that
76 * playing has stopped. Engines notifying the main thread that they have
77 * finished do so strictly *after* producing and returning their last block.
78 * In this way, an engine that receives non-null input knows that the input
79 * comes from nodes that are still alive and will keep their output nodes
80 * alive for at least as long as it takes to process messages from the graph
81 * thread. i.e. the engine receiving non-null input knows that its node is
82 * still alive, and will still be alive when it receives a message from the
83 * engine.
84 */
85 class AudioNode : public DOMEventTargetHelper
86 {
87 protected:
88 // You can only use refcounting to delete this object
89 virtual ~AudioNode();
90
91 public:
92 AudioNode(AudioContext* aContext,
93 uint32_t aChannelCount,
94 ChannelCountMode aChannelCountMode,
95 ChannelInterpretation aChannelInterpretation);
96
97 // This should be idempotent (safe to call multiple times).
98 virtual void DestroyMediaStream();
99
100 NS_DECL_ISUPPORTS_INHERITED
101 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioNode,
102 DOMEventTargetHelper)
103
104 virtual AudioBufferSourceNode* AsAudioBufferSourceNode() {
105 return nullptr;
106 }
107
108 virtual const DelayNode* AsDelayNode() const {
109 return nullptr;
110 }
111
112 AudioContext* GetParentObject() const
113 {
114 return mContext;
115 }
116
117 AudioContext* Context() const
118 {
119 return mContext;
120 }
121
122 virtual void Connect(AudioNode& aDestination, uint32_t aOutput,
123 uint32_t aInput, ErrorResult& aRv);
124
125 virtual void Connect(AudioParam& aDestination, uint32_t aOutput,
126 ErrorResult& aRv);
127
128 virtual void Disconnect(uint32_t aOutput, ErrorResult& aRv);
129
130 // The following two virtual methods must be implemented by each node type
131 // to provide their number of input and output ports. These numbers are
132 // constant for the lifetime of the node. Both default to 1.
133 virtual uint16_t NumberOfInputs() const { return 1; }
134 virtual uint16_t NumberOfOutputs() const { return 1; }
135
136 uint32_t ChannelCount() const { return mChannelCount; }
137 virtual void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv)
138 {
139 if (aChannelCount == 0 ||
140 aChannelCount > WebAudioUtils::MaxChannelCount) {
141 aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
142 return;
143 }
144 mChannelCount = aChannelCount;
145 SendChannelMixingParametersToStream();
146 }
147 ChannelCountMode ChannelCountModeValue() const
148 {
149 return mChannelCountMode;
150 }
151 virtual void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv)
152 {
153 mChannelCountMode = aMode;
154 SendChannelMixingParametersToStream();
155 }
156 ChannelInterpretation ChannelInterpretationValue() const
157 {
158 return mChannelInterpretation;
159 }
160 void SetChannelInterpretationValue(ChannelInterpretation aMode)
161 {
162 mChannelInterpretation = aMode;
163 SendChannelMixingParametersToStream();
164 }
165
166 struct InputNode {
167 ~InputNode()
168 {
169 if (mStreamPort) {
170 mStreamPort->Destroy();
171 }
172 }
173
174 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
175 {
176 size_t amount = 0;
177 if (mStreamPort) {
178 amount += mStreamPort->SizeOfIncludingThis(aMallocSizeOf);
179 }
180
181 return amount;
182 }
183
184 // Weak reference.
185 AudioNode* mInputNode;
186 nsRefPtr<MediaInputPort> mStreamPort;
187 // The index of the input port this node feeds into.
188 // This is not used for connections to AudioParams.
189 uint32_t mInputPort;
190 // The index of the output port this node comes out of.
191 uint32_t mOutputPort;
192 };
193
194 MediaStream* Stream() { return mStream; }
195
196 const nsTArray<InputNode>& InputNodes() const
197 {
198 return mInputNodes;
199 }
200 const nsTArray<nsRefPtr<AudioNode> >& OutputNodes() const
201 {
202 return mOutputNodes;
203 }
204 const nsTArray<nsRefPtr<AudioParam> >& OutputParams() const
205 {
206 return mOutputParams;
207 }
208
209 void RemoveOutputParam(AudioParam* aParam);
210
211 // MarkActive() asks the context to keep the AudioNode alive until the
212 // context is finished. This takes care of "playing" references and
213 // "tail-time" references.
214 void MarkActive() { Context()->RegisterActiveNode(this); }
215 // Active nodes call MarkInactive() when they have finished producing sound
216 // for the foreseeable future.
217 // Do not call MarkInactive from a node destructor. If the destructor is
218 // called, then the node is already inactive.
219 // MarkInactive() may delete |this|.
220 void MarkInactive() { Context()->UnregisterActiveNode(this); }
221
222 virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
223 virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
224
225 virtual const char* NodeType() const = 0;
226
227 private:
228 friend class AudioBufferSourceNode;
229 // This could possibly delete 'this'.
230 void DisconnectFromGraph();
231
232 protected:
233 static void Callback(AudioNode* aNode) { /* not implemented */ }
234
235 // Helpers for sending different value types to streams
236 void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
237 void SendInt32ParameterToStream(uint32_t aIndex, int32_t aValue);
238 void SendThreeDPointParameterToStream(uint32_t aIndex, const ThreeDPoint& aValue);
239 void SendChannelMixingParametersToStream();
240 static void SendTimelineParameterToStream(AudioNode* aNode, uint32_t aIndex,
241 const AudioParamTimeline& aValue);
242
243 private:
244 nsRefPtr<AudioContext> mContext;
245
246 protected:
247 // Must be set in the constructor. Must not be null.
248 // If MaxNumberOfInputs() is > 0, then mStream must be a ProcessedMediaStream.
249 nsRefPtr<MediaStream> mStream;
250
251 private:
252 // For every InputNode, there is a corresponding entry in mOutputNodes of the
253 // InputNode's mInputNode.
254 nsTArray<InputNode> mInputNodes;
255 // For every mOutputNode entry, there is a corresponding entry in mInputNodes
256 // of the mOutputNode entry. We won't necessarily be able to identify the
257 // exact matching entry, since mOutputNodes doesn't include the port
258 // identifiers and the same node could be connected on multiple ports.
259 nsTArray<nsRefPtr<AudioNode> > mOutputNodes;
260 // For every mOutputParams entry, there is a corresponding entry in
261 // AudioParam::mInputNodes of the mOutputParams entry. We won't necessarily be
262 // able to identify the exact matching entry, since mOutputParams doesn't
263 // include the port identifiers and the same node could be connected on
264 // multiple ports.
265 nsTArray<nsRefPtr<AudioParam> > mOutputParams;
266 uint32_t mChannelCount;
267 ChannelCountMode mChannelCountMode;
268 ChannelInterpretation mChannelInterpretation;
269 };
270
271 }
272 }
273
274 #endif

mercurial