AudioNode.cpp 16 KB

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