514ec7a3ea47e202180b496fb8f0e2619830b213
[WebKit-https.git] / Source / WebCore / Modules / webaudio / AudioNode.cpp
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 #include "config.h"
26
27 #if ENABLE(WEB_AUDIO)
28
29 #include "AudioNode.h"
30
31 #include "AudioContext.h"
32 #include "AudioNodeInput.h"
33 #include "AudioNodeOutput.h"
34 #include "AudioParam.h"
35 #include "ExceptionCode.h"
36 #include <wtf/Atomics.h>
37 #include <wtf/MainThread.h>
38
39 #if DEBUG_AUDIONODE_REFERENCES
40 #include <stdio.h>
41 #endif
42
43 namespace WebCore {
44
45 AudioNode::AudioNode(AudioContext* context, float sampleRate)
46     : m_isInitialized(false)
47     , m_nodeType(NodeTypeUnknown)
48     , m_context(context)
49     , m_sampleRate(sampleRate)
50     , m_lastProcessingTime(-1)
51     , m_lastNonSilentTime(-1)
52     , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class)
53     , m_connectionRefCount(0)
54     , m_isMarkedForDeletion(false)
55     , m_isDisabled(false)
56     , m_channelCount(2)
57     , m_channelCountMode(Max)
58     , m_channelInterpretation(AudioBus::Speakers)
59 {
60 #if DEBUG_AUDIONODE_REFERENCES
61     if (!s_isNodeCountInitialized) {
62         s_isNodeCountInitialized = true;
63         atexit(AudioNode::printNodeCounts);
64     }
65 #endif
66 }
67
68 AudioNode::~AudioNode()
69 {
70 #if DEBUG_AUDIONODE_REFERENCES
71     --s_nodeCount[nodeType()];
72     fprintf(stderr, "%p: %d: AudioNode::~AudioNode() %d %d\n", this, nodeType(), m_normalRefCount.load(), m_connectionRefCount);
73 #endif
74 }
75
76 void AudioNode::initialize()
77 {
78     m_isInitialized = true;
79 }
80
81 void AudioNode::uninitialize()
82 {
83     m_isInitialized = false;
84 }
85
86 void AudioNode::setNodeType(NodeType type)
87 {
88     m_nodeType = type;
89
90 #if DEBUG_AUDIONODE_REFERENCES
91     ++s_nodeCount[type];
92 #endif
93 }
94
95 void AudioNode::lazyInitialize()
96 {
97     if (!isInitialized())
98         initialize();
99 }
100
101 void AudioNode::addInput(std::unique_ptr<AudioNodeInput> input)
102 {
103     m_inputs.append(std::move(input));
104 }
105
106 void AudioNode::addOutput(std::unique_ptr<AudioNodeOutput> output)
107 {
108     m_outputs.append(std::move(output));
109 }
110
111 AudioNodeInput* AudioNode::input(unsigned i)
112 {
113     if (i < m_inputs.size())
114         return m_inputs[i].get();
115     return nullptr;
116 }
117
118 AudioNodeOutput* AudioNode::output(unsigned i)
119 {
120     if (i < m_outputs.size())
121         return m_outputs[i].get();
122     return nullptr;
123 }
124
125 void AudioNode::connect(AudioNode* destination, unsigned outputIndex, unsigned inputIndex, ExceptionCode& ec)
126 {
127     ASSERT(isMainThread()); 
128     AudioContext::AutoLocker locker(*context());
129
130     if (!destination) {
131         ec = SYNTAX_ERR;
132         return;
133     }
134
135     // Sanity check input and output indices.
136     if (outputIndex >= numberOfOutputs()) {
137         ec = INDEX_SIZE_ERR;
138         return;
139     }
140
141     if (destination && inputIndex >= destination->numberOfInputs()) {
142         ec = INDEX_SIZE_ERR;
143         return;
144     }
145
146     if (context() != destination->context()) {
147         ec = SYNTAX_ERR;
148         return;
149     }
150
151     AudioNodeInput* input = destination->input(inputIndex);
152     AudioNodeOutput* output = this->output(outputIndex);
153     input->connect(output);
154
155     // Let context know that a connection has been made.
156     context()->incrementConnectionCount();
157 }
158
159 void AudioNode::connect(AudioParam* param, unsigned outputIndex, ExceptionCode& ec)
160 {
161     ASSERT(isMainThread());
162     AudioContext::AutoLocker locker(*context());
163
164     if (!param) {
165         ec = SYNTAX_ERR;
166         return;
167     }
168
169     if (outputIndex >= numberOfOutputs()) {
170         ec = INDEX_SIZE_ERR;
171         return;
172     }
173
174     if (context() != param->context()) {
175         ec = SYNTAX_ERR;
176         return;
177     }
178
179     AudioNodeOutput* output = this->output(outputIndex);
180     param->connect(output);
181 }
182
183 void AudioNode::disconnect(unsigned outputIndex, ExceptionCode& ec)
184 {
185     ASSERT(isMainThread());
186     AudioContext::AutoLocker locker(*context());
187
188     // Sanity check input and output indices.
189     if (outputIndex >= numberOfOutputs()) {
190         ec = INDEX_SIZE_ERR;
191         return;
192     }
193
194     AudioNodeOutput* output = this->output(outputIndex);
195     output->disconnectAll();
196 }
197
198 unsigned long AudioNode::channelCount()
199 {
200     return m_channelCount;
201 }
202
203 void AudioNode::setChannelCount(unsigned long channelCount, ExceptionCode& ec)
204 {
205     ASSERT(isMainThread());
206     AudioContext::AutoLocker locker(*context());
207
208     if (channelCount > 0 && channelCount <= AudioContext::maxNumberOfChannels()) {
209         if (m_channelCount != channelCount) {
210             m_channelCount = channelCount;
211             if (m_channelCountMode != Max)
212                 updateChannelsForInputs();
213         }
214     } else
215         ec = INVALID_STATE_ERR;
216 }
217
218 String AudioNode::channelCountMode()
219 {
220     switch (m_channelCountMode) {
221     case Max:
222         return "max";
223     case ClampedMax:
224         return "clamped-max";
225     case Explicit:
226         return "explicit";
227     }
228     ASSERT_NOT_REACHED();
229     return "";
230 }
231
232 void AudioNode::setChannelCountMode(const String& mode, ExceptionCode& ec)
233 {
234     ASSERT(isMainThread());
235     AudioContext::AutoLocker locker(*context());
236
237     ChannelCountMode oldMode = m_channelCountMode;
238
239     if (mode == "max")
240         m_channelCountMode = Max;
241     else if (mode == "clamped-max")
242         m_channelCountMode = ClampedMax;
243     else if (mode == "explicit")
244         m_channelCountMode = Explicit;
245     else
246         ec = INVALID_STATE_ERR;
247
248     if (m_channelCountMode != oldMode)
249         updateChannelsForInputs();
250 }
251
252 String AudioNode::channelInterpretation()
253 {
254     switch (m_channelInterpretation) {
255     case AudioBus::Speakers:
256         return "speakers";
257     case AudioBus::Discrete:
258         return "discrete";
259     }
260     ASSERT_NOT_REACHED();
261     return "";
262 }
263
264 void AudioNode::setChannelInterpretation(const String& interpretation, ExceptionCode& ec)
265 {
266     ASSERT(isMainThread());
267     AudioContext::AutoLocker locker(*context());
268
269     if (interpretation == "speakers")
270         m_channelInterpretation = AudioBus::Speakers;
271     else if (interpretation == "discrete")
272         m_channelInterpretation = AudioBus::Discrete;
273     else
274         ec = INVALID_STATE_ERR;
275 }
276
277 void AudioNode::updateChannelsForInputs()
278 {
279     for (unsigned i = 0; i < m_inputs.size(); ++i)
280         input(i)->changedOutputs();
281 }
282
283 EventTargetInterface AudioNode::eventTargetInterface() const
284 {
285     return AudioNodeEventTargetInterfaceType;
286 }
287
288 ScriptExecutionContext* AudioNode::scriptExecutionContext() const
289 {
290     return const_cast<AudioNode*>(this)->context()->scriptExecutionContext();
291 }
292
293 void AudioNode::processIfNecessary(size_t framesToProcess)
294 {
295     ASSERT(context()->isAudioThread());
296
297     if (!isInitialized())
298         return;
299
300     // Ensure that we only process once per rendering quantum.
301     // This handles the "fanout" problem where an output is connected to multiple inputs.
302     // The first time we're called during this time slice we process, but after that we don't want to re-process,
303     // instead our output(s) will already have the results cached in their bus;
304     double currentTime = context()->currentTime();
305     if (m_lastProcessingTime != currentTime) {
306         m_lastProcessingTime = currentTime; // important to first update this time because of feedback loops in the rendering graph
307
308         pullInputs(framesToProcess);
309
310         bool silentInputs = inputsAreSilent();
311         if (!silentInputs)
312             m_lastNonSilentTime = (context()->currentSampleFrame() + framesToProcess) / static_cast<double>(m_sampleRate);
313
314         if (silentInputs && propagatesSilence())
315             silenceOutputs();
316         else {
317             process(framesToProcess);
318             unsilenceOutputs();
319         }
320     }
321 }
322
323 void AudioNode::checkNumberOfChannelsForInput(AudioNodeInput* input)
324 {
325     ASSERT(context()->isAudioThread() && context()->isGraphOwner());
326
327     for (const std::unique_ptr<AudioNodeInput>& savedInput : m_inputs) {
328         if (input == savedInput.get()) {
329             input->updateInternalBus();
330             return;
331         }
332     }
333
334     ASSERT_NOT_REACHED();
335 }
336
337 bool AudioNode::propagatesSilence() const
338 {
339     return m_lastNonSilentTime + latencyTime() + tailTime() < context()->currentTime();
340 }
341
342 void AudioNode::pullInputs(size_t framesToProcess)
343 {
344     ASSERT(context()->isAudioThread());
345     
346     // Process all of the AudioNodes connected to our inputs.
347     for (unsigned i = 0; i < m_inputs.size(); ++i)
348         input(i)->pull(0, framesToProcess);
349 }
350
351 bool AudioNode::inputsAreSilent()
352 {
353     for (unsigned i = 0; i < m_inputs.size(); ++i) {
354         if (!input(i)->bus()->isSilent())
355             return false;
356     }
357     return true;
358 }
359
360 void AudioNode::silenceOutputs()
361 {
362     for (unsigned i = 0; i < m_outputs.size(); ++i)
363         output(i)->bus()->zero();
364 }
365
366 void AudioNode::unsilenceOutputs()
367 {
368     for (unsigned i = 0; i < m_outputs.size(); ++i)
369         output(i)->bus()->clearSilentFlag();
370 }
371
372 void AudioNode::enableOutputsIfNecessary()
373 {
374     if (m_isDisabled && m_connectionRefCount > 0) {
375         ASSERT(isMainThread());
376         AudioContext::AutoLocker locker(*context());
377
378         m_isDisabled = false;
379         for (unsigned i = 0; i < m_outputs.size(); ++i)
380             output(i)->enable();
381     }
382 }
383
384 void AudioNode::disableOutputsIfNecessary()
385 {
386     // Disable outputs if appropriate. We do this if the number of connections is 0 or 1. The case
387     // of 0 is from finishDeref() where there are no connections left. The case of 1 is from
388     // AudioNodeInput::disable() where we want to disable outputs when there's only one connection
389     // left because we're ready to go away, but can't quite yet.
390     if (m_connectionRefCount <= 1 && !m_isDisabled) {
391         // Still may have JavaScript references, but no more "active" connection references, so put all of our outputs in a "dormant" disabled state.
392         // Garbage collection may take a very long time after this time, so the "dormant" disabled nodes should not bog down the rendering...
393
394         // As far as JavaScript is concerned, our outputs must still appear to be connected.
395         // But internally our outputs should be disabled from the inputs they're connected to.
396         // disable() can recursively deref connections (and call disable()) down a whole chain of connected nodes.
397
398         // FIXME: we special case the convolver and delay since they have a significant tail-time and shouldn't be disconnected simply
399         // because they no longer have any input connections. This needs to be handled more generally where AudioNodes have
400         // a tailTime attribute. Then the AudioNode only needs to remain "active" for tailTime seconds after there are no
401         // longer any active connections.
402         if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) {
403             m_isDisabled = true;
404             for (unsigned i = 0; i < m_outputs.size(); ++i)
405                 output(i)->disable();
406         }
407     }
408 }
409
410 void AudioNode::ref(RefType refType)
411 {
412     switch (refType) {
413     case RefTypeNormal:
414         ++m_normalRefCount;
415         break;
416     case RefTypeConnection:
417         ++m_connectionRefCount;
418         break;
419     default:
420         ASSERT_NOT_REACHED();
421     }
422
423 #if DEBUG_AUDIONODE_REFERENCES
424     fprintf(stderr, "%p: %d: AudioNode::ref(%d) %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount);
425 #endif
426
427     // See the disabling code in finishDeref() below. This handles the case where a node
428     // is being re-connected after being used at least once and disconnected.
429     // In this case, we need to re-enable.
430     if (refType == RefTypeConnection)
431         enableOutputsIfNecessary();
432 }
433
434 void AudioNode::deref(RefType refType)
435 {
436     // The actually work for deref happens completely within the audio context's graph lock.
437     // In the case of the audio thread, we must use a tryLock to avoid glitches.
438     bool hasLock = false;
439     bool mustReleaseLock = false;
440     
441     if (context()->isAudioThread()) {
442         // Real-time audio thread must not contend lock (to avoid glitches).
443         hasLock = context()->tryLock(mustReleaseLock);
444     } else {
445         context()->lock(mustReleaseLock);
446         hasLock = true;
447     }
448     
449     if (hasLock) {
450         // This is where the real deref work happens.
451         finishDeref(refType);
452
453         if (mustReleaseLock)
454             context()->unlock();
455     } else {
456         // We were unable to get the lock, so put this in a list to finish up later.
457         ASSERT(context()->isAudioThread());
458         ASSERT(refType == RefTypeConnection);
459         context()->addDeferredFinishDeref(this);
460     }
461
462     // Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here.
463     // We can't call in AudioContext::~AudioContext() since it will never be called as long as any AudioNode is alive
464     // because AudioNodes keep a reference to the context.
465     if (context()->isAudioThreadFinished())
466         context()->deleteMarkedNodes();
467 }
468
469 void AudioNode::finishDeref(RefType refType)
470 {
471     ASSERT(context()->isGraphOwner());
472     
473     switch (refType) {
474     case RefTypeNormal:
475         ASSERT(m_normalRefCount > 0);
476         --m_normalRefCount;
477         break;
478     case RefTypeConnection:
479         ASSERT(m_connectionRefCount > 0);
480         --m_connectionRefCount;
481         break;
482     default:
483         ASSERT_NOT_REACHED();
484     }
485     
486 #if DEBUG_AUDIONODE_REFERENCES
487     fprintf(stderr, "%p: %d: AudioNode::deref(%d) %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount);
488 #endif
489
490     if (!m_connectionRefCount) {
491         if (!m_normalRefCount) {
492             if (!m_isMarkedForDeletion) {
493                 // All references are gone - we need to go away.
494                 for (unsigned i = 0; i < m_outputs.size(); ++i)
495                     output(i)->disconnectAll(); // This will deref() nodes we're connected to.
496
497                 // Mark for deletion at end of each render quantum or when context shuts down.
498                 context()->markForDeletion(this);
499                 m_isMarkedForDeletion = true;
500             }
501         } else if (refType == RefTypeConnection)
502             disableOutputsIfNecessary();
503     }
504 }
505
506 #if DEBUG_AUDIONODE_REFERENCES
507
508 bool AudioNode::s_isNodeCountInitialized = false;
509 int AudioNode::s_nodeCount[NodeTypeEnd];
510
511 void AudioNode::printNodeCounts()
512 {
513     fprintf(stderr, "\n\n");
514     fprintf(stderr, "===========================\n");
515     fprintf(stderr, "AudioNode: reference counts\n");
516     fprintf(stderr, "===========================\n");
517
518     for (unsigned i = 0; i < NodeTypeEnd; ++i)
519         fprintf(stderr, "%d: %d\n", i, s_nodeCount[i]);
520
521     fprintf(stderr, "===========================\n\n\n");
522 }
523
524 #endif // DEBUG_AUDIONODE_REFERENCES
525
526 } // namespace WebCore
527
528 #endif // ENABLE(WEB_AUDIO)