| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010, Google Inc. All rights reserved. | 2 * Copyright (C) 2010, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 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 AN
Y | 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y |
| 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 O
N | 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N |
| 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 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 | 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. | 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 23 */ | 23 */ |
| 24 | 24 |
| 25 #include "modules/webaudio/AudioNode.h" | 25 #include "modules/webaudio/AudioNode.h" |
| 26 #include "bindings/core/v8/ExceptionState.h" | 26 #include "bindings/core/v8/ExceptionState.h" |
| 27 #include "core/dom/ExceptionCode.h" | 27 #include "core/dom/ExceptionCode.h" |
| 28 #include "core/inspector/InstanceCounters.h" | 28 #include "core/inspector/InstanceCounters.h" |
| 29 #include "modules/webaudio/AbstractAudioContext.h" | |
| 30 #include "modules/webaudio/AudioNodeInput.h" | 29 #include "modules/webaudio/AudioNodeInput.h" |
| 31 #include "modules/webaudio/AudioNodeOutput.h" | 30 #include "modules/webaudio/AudioNodeOutput.h" |
| 32 #include "modules/webaudio/AudioParam.h" | 31 #include "modules/webaudio/AudioParam.h" |
| 32 #include "modules/webaudio/BaseAudioContext.h" |
| 33 #include "wtf/Atomics.h" | 33 #include "wtf/Atomics.h" |
| 34 | 34 |
| 35 #if DEBUG_AUDIONODE_REFERENCES | 35 #if DEBUG_AUDIONODE_REFERENCES |
| 36 #include <stdio.h> | 36 #include <stdio.h> |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 namespace blink { | 39 namespace blink { |
| 40 | 40 |
| 41 AudioHandler::AudioHandler(NodeType nodeType, AudioNode& node, float sampleRate) | 41 AudioHandler::AudioHandler(NodeType nodeType, AudioNode& node, float sampleRate) |
| 42 : m_isInitialized(false) | 42 : m_isInitialized(false) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 output->dispose(); | 103 output->dispose(); |
| 104 m_node = nullptr; | 104 m_node = nullptr; |
| 105 } | 105 } |
| 106 | 106 |
| 107 AudioNode* AudioHandler::node() const | 107 AudioNode* AudioHandler::node() const |
| 108 { | 108 { |
| 109 ASSERT(isMainThread()); | 109 ASSERT(isMainThread()); |
| 110 return m_node; | 110 return m_node; |
| 111 } | 111 } |
| 112 | 112 |
| 113 AbstractAudioContext* AudioHandler::context() const | 113 BaseAudioContext* AudioHandler::context() const |
| 114 { | 114 { |
| 115 return m_context; | 115 return m_context; |
| 116 } | 116 } |
| 117 | 117 |
| 118 String AudioHandler::nodeTypeName() const | 118 String AudioHandler::nodeTypeName() const |
| 119 { | 119 { |
| 120 switch (m_nodeType) { | 120 switch (m_nodeType) { |
| 121 case NodeTypeDestination: | 121 case NodeTypeDestination: |
| 122 return "AudioDestinationNode"; | 122 return "AudioDestinationNode"; |
| 123 case NodeTypeOscillator: | 123 case NodeTypeOscillator: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 } | 201 } |
| 202 | 202 |
| 203 unsigned long AudioHandler::channelCount() | 203 unsigned long AudioHandler::channelCount() |
| 204 { | 204 { |
| 205 return m_channelCount; | 205 return m_channelCount; |
| 206 } | 206 } |
| 207 | 207 |
| 208 void AudioHandler::setChannelCount(unsigned long channelCount, ExceptionState& e
xceptionState) | 208 void AudioHandler::setChannelCount(unsigned long channelCount, ExceptionState& e
xceptionState) |
| 209 { | 209 { |
| 210 ASSERT(isMainThread()); | 210 ASSERT(isMainThread()); |
| 211 AbstractAudioContext::AutoLocker locker(context()); | 211 BaseAudioContext::AutoLocker locker(context()); |
| 212 | 212 |
| 213 if (channelCount > 0 && channelCount <= AbstractAudioContext::maxNumberOfCha
nnels()) { | 213 if (channelCount > 0 && channelCount <= BaseAudioContext::maxNumberOfChannel
s()) { |
| 214 if (m_channelCount != channelCount) { | 214 if (m_channelCount != channelCount) { |
| 215 m_channelCount = channelCount; | 215 m_channelCount = channelCount; |
| 216 if (m_channelCountMode != Max) | 216 if (m_channelCountMode != Max) |
| 217 updateChannelsForInputs(); | 217 updateChannelsForInputs(); |
| 218 } | 218 } |
| 219 } else { | 219 } else { |
| 220 exceptionState.throwDOMException( | 220 exceptionState.throwDOMException( |
| 221 NotSupportedError, | 221 NotSupportedError, |
| 222 ExceptionMessages::indexOutsideRange<unsigned long>( | 222 ExceptionMessages::indexOutsideRange<unsigned long>( |
| 223 "channel count", | 223 "channel count", |
| 224 channelCount, | 224 channelCount, |
| 225 1, | 225 1, |
| 226 ExceptionMessages::InclusiveBound, | 226 ExceptionMessages::InclusiveBound, |
| 227 AbstractAudioContext::maxNumberOfChannels(), | 227 BaseAudioContext::maxNumberOfChannels(), |
| 228 ExceptionMessages::InclusiveBound)); | 228 ExceptionMessages::InclusiveBound)); |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 | 231 |
| 232 String AudioHandler::channelCountMode() | 232 String AudioHandler::channelCountMode() |
| 233 { | 233 { |
| 234 switch (m_channelCountMode) { | 234 switch (m_channelCountMode) { |
| 235 case Max: | 235 case Max: |
| 236 return "max"; | 236 return "max"; |
| 237 case ClampedMax: | 237 case ClampedMax: |
| 238 return "clamped-max"; | 238 return "clamped-max"; |
| 239 case Explicit: | 239 case Explicit: |
| 240 return "explicit"; | 240 return "explicit"; |
| 241 } | 241 } |
| 242 ASSERT_NOT_REACHED(); | 242 ASSERT_NOT_REACHED(); |
| 243 return ""; | 243 return ""; |
| 244 } | 244 } |
| 245 | 245 |
| 246 void AudioHandler::setChannelCountMode(const String& mode, ExceptionState& excep
tionState) | 246 void AudioHandler::setChannelCountMode(const String& mode, ExceptionState& excep
tionState) |
| 247 { | 247 { |
| 248 ASSERT(isMainThread()); | 248 ASSERT(isMainThread()); |
| 249 AbstractAudioContext::AutoLocker locker(context()); | 249 BaseAudioContext::AutoLocker locker(context()); |
| 250 | 250 |
| 251 ChannelCountMode oldMode = m_channelCountMode; | 251 ChannelCountMode oldMode = m_channelCountMode; |
| 252 | 252 |
| 253 if (mode == "max") { | 253 if (mode == "max") { |
| 254 m_newChannelCountMode = Max; | 254 m_newChannelCountMode = Max; |
| 255 } else if (mode == "clamped-max") { | 255 } else if (mode == "clamped-max") { |
| 256 m_newChannelCountMode = ClampedMax; | 256 m_newChannelCountMode = ClampedMax; |
| 257 } else if (mode == "explicit") { | 257 } else if (mode == "explicit") { |
| 258 m_newChannelCountMode = Explicit; | 258 m_newChannelCountMode = Explicit; |
| 259 } else { | 259 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 272 case AudioBus::Discrete: | 272 case AudioBus::Discrete: |
| 273 return "discrete"; | 273 return "discrete"; |
| 274 } | 274 } |
| 275 ASSERT_NOT_REACHED(); | 275 ASSERT_NOT_REACHED(); |
| 276 return ""; | 276 return ""; |
| 277 } | 277 } |
| 278 | 278 |
| 279 void AudioHandler::setChannelInterpretation(const String& interpretation, Except
ionState& exceptionState) | 279 void AudioHandler::setChannelInterpretation(const String& interpretation, Except
ionState& exceptionState) |
| 280 { | 280 { |
| 281 ASSERT(isMainThread()); | 281 ASSERT(isMainThread()); |
| 282 AbstractAudioContext::AutoLocker locker(context()); | 282 BaseAudioContext::AutoLocker locker(context()); |
| 283 | 283 |
| 284 AudioBus::ChannelInterpretation oldMode = m_channelInterpretation; | 284 AudioBus::ChannelInterpretation oldMode = m_channelInterpretation; |
| 285 | 285 |
| 286 if (interpretation == "speakers") { | 286 if (interpretation == "speakers") { |
| 287 m_newChannelInterpretation = AudioBus::Speakers; | 287 m_newChannelInterpretation = AudioBus::Speakers; |
| 288 } else if (interpretation == "discrete") { | 288 } else if (interpretation == "discrete") { |
| 289 m_newChannelInterpretation = AudioBus::Discrete; | 289 m_newChannelInterpretation = AudioBus::Discrete; |
| 290 } else { | 290 } else { |
| 291 ASSERT_NOT_REACHED(); | 291 ASSERT_NOT_REACHED(); |
| 292 } | 292 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 void AudioHandler::unsilenceOutputs() | 388 void AudioHandler::unsilenceOutputs() |
| 389 { | 389 { |
| 390 for (auto& output : m_outputs) | 390 for (auto& output : m_outputs) |
| 391 output->bus()->clearSilentFlag(); | 391 output->bus()->clearSilentFlag(); |
| 392 } | 392 } |
| 393 | 393 |
| 394 void AudioHandler::enableOutputsIfNecessary() | 394 void AudioHandler::enableOutputsIfNecessary() |
| 395 { | 395 { |
| 396 if (m_isDisabled && m_connectionRefCount > 0) { | 396 if (m_isDisabled && m_connectionRefCount > 0) { |
| 397 ASSERT(isMainThread()); | 397 ASSERT(isMainThread()); |
| 398 AbstractAudioContext::AutoLocker locker(context()); | 398 BaseAudioContext::AutoLocker locker(context()); |
| 399 | 399 |
| 400 m_isDisabled = false; | 400 m_isDisabled = false; |
| 401 for (auto& output : m_outputs) | 401 for (auto& output : m_outputs) |
| 402 output->enable(); | 402 output->enable(); |
| 403 } | 403 } |
| 404 } | 404 } |
| 405 | 405 |
| 406 void AudioHandler::disableOutputsIfNecessary() | 406 void AudioHandler::disableOutputsIfNecessary() |
| 407 { | 407 { |
| 408 // Disable outputs if appropriate. We do this if the number of connections i
s 0 or 1. The case | 408 // Disable outputs if appropriate. We do this if the number of connections i
s 0 or 1. The case |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 unsigned AudioHandler::numberOfOutputChannels() const | 520 unsigned AudioHandler::numberOfOutputChannels() const |
| 521 { | 521 { |
| 522 // This should only be called for ScriptProcessorNodes which are the only no
des where you can | 522 // This should only be called for ScriptProcessorNodes which are the only no
des where you can |
| 523 // have an output with 0 channels. All other nodes have have at least one o
utput channel, so | 523 // have an output with 0 channels. All other nodes have have at least one o
utput channel, so |
| 524 // there's no reason other nodes should ever call this function. | 524 // there's no reason other nodes should ever call this function. |
| 525 DCHECK(0) << "numberOfOutputChannels() not valid for node type " << getNodeT
ype(); | 525 DCHECK(0) << "numberOfOutputChannels() not valid for node type " << getNodeT
ype(); |
| 526 return 1; | 526 return 1; |
| 527 } | 527 } |
| 528 // ---------------------------------------------------------------- | 528 // ---------------------------------------------------------------- |
| 529 | 529 |
| 530 AudioNode::AudioNode(AbstractAudioContext& context) | 530 AudioNode::AudioNode(BaseAudioContext& context) |
| 531 : m_context(context) | 531 : m_context(context) |
| 532 , m_handler(nullptr) | 532 , m_handler(nullptr) |
| 533 { | 533 { |
| 534 ThreadState::current()->registerPreFinalizer(this); | 534 ThreadState::current()->registerPreFinalizer(this); |
| 535 } | 535 } |
| 536 | 536 |
| 537 void AudioNode::dispose() | 537 void AudioNode::dispose() |
| 538 { | 538 { |
| 539 ASSERT(isMainThread()); | 539 ASSERT(isMainThread()); |
| 540 AbstractAudioContext::AutoLocker locker(context()); | 540 BaseAudioContext::AutoLocker locker(context()); |
| 541 handler().dispose(); | 541 handler().dispose(); |
| 542 if (context()->contextState() == AbstractAudioContext::Running) | 542 if (context()->contextState() == BaseAudioContext::Running) |
| 543 context()->deferredTaskHandler().addRenderingOrphanHandler(m_handler.rel
ease()); | 543 context()->deferredTaskHandler().addRenderingOrphanHandler(m_handler.rel
ease()); |
| 544 } | 544 } |
| 545 | 545 |
| 546 void AudioNode::setHandler(PassRefPtr<AudioHandler> handler) | 546 void AudioNode::setHandler(PassRefPtr<AudioHandler> handler) |
| 547 { | 547 { |
| 548 ASSERT(handler); | 548 ASSERT(handler); |
| 549 m_handler = handler; | 549 m_handler = handler; |
| 550 } | 550 } |
| 551 | 551 |
| 552 AudioHandler& AudioNode::handler() const | 552 AudioHandler& AudioNode::handler() const |
| 553 { | 553 { |
| 554 return *m_handler; | 554 return *m_handler; |
| 555 } | 555 } |
| 556 | 556 |
| 557 DEFINE_TRACE(AudioNode) | 557 DEFINE_TRACE(AudioNode) |
| 558 { | 558 { |
| 559 visitor->trace(m_context); | 559 visitor->trace(m_context); |
| 560 visitor->trace(m_connectedNodes); | 560 visitor->trace(m_connectedNodes); |
| 561 visitor->trace(m_connectedParams); | 561 visitor->trace(m_connectedParams); |
| 562 EventTargetWithInlineData::trace(visitor); | 562 EventTargetWithInlineData::trace(visitor); |
| 563 } | 563 } |
| 564 | 564 |
| 565 AbstractAudioContext* AudioNode::context() const | 565 BaseAudioContext* AudioNode::context() const |
| 566 { | 566 { |
| 567 return m_context; | 567 return m_context; |
| 568 } | 568 } |
| 569 | 569 |
| 570 AudioNode* AudioNode::connect(AudioNode* destination, unsigned outputIndex, unsi
gned inputIndex, ExceptionState& exceptionState) | 570 AudioNode* AudioNode::connect(AudioNode* destination, unsigned outputIndex, unsi
gned inputIndex, ExceptionState& exceptionState) |
| 571 { | 571 { |
| 572 ASSERT(isMainThread()); | 572 ASSERT(isMainThread()); |
| 573 AbstractAudioContext::AutoLocker locker(context()); | 573 BaseAudioContext::AutoLocker locker(context()); |
| 574 | 574 |
| 575 if (context()->isContextClosed()) { | 575 if (context()->isContextClosed()) { |
| 576 exceptionState.throwDOMException( | 576 exceptionState.throwDOMException( |
| 577 InvalidStateError, | 577 InvalidStateError, |
| 578 "Cannot connect after the context has been closed."); | 578 "Cannot connect after the context has been closed."); |
| 579 return nullptr; | 579 return nullptr; |
| 580 } | 580 } |
| 581 | 581 |
| 582 if (!destination) { | 582 if (!destination) { |
| 583 exceptionState.throwDOMException( | 583 exceptionState.throwDOMException( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 | 625 |
| 626 // Let context know that a connection has been made. | 626 // Let context know that a connection has been made. |
| 627 context()->incrementConnectionCount(); | 627 context()->incrementConnectionCount(); |
| 628 | 628 |
| 629 return destination; | 629 return destination; |
| 630 } | 630 } |
| 631 | 631 |
| 632 void AudioNode::connect(AudioParam* param, unsigned outputIndex, ExceptionState&
exceptionState) | 632 void AudioNode::connect(AudioParam* param, unsigned outputIndex, ExceptionState&
exceptionState) |
| 633 { | 633 { |
| 634 ASSERT(isMainThread()); | 634 ASSERT(isMainThread()); |
| 635 AbstractAudioContext::AutoLocker locker(context()); | 635 BaseAudioContext::AutoLocker locker(context()); |
| 636 | 636 |
| 637 if (context()->isContextClosed()) { | 637 if (context()->isContextClosed()) { |
| 638 exceptionState.throwDOMException( | 638 exceptionState.throwDOMException( |
| 639 InvalidStateError, | 639 InvalidStateError, |
| 640 "Cannot connect after the context has been closed."); | 640 "Cannot connect after the context has been closed."); |
| 641 return; | 641 return; |
| 642 } | 642 } |
| 643 | 643 |
| 644 if (!param) { | 644 if (!param) { |
| 645 exceptionState.throwDOMException( | 645 exceptionState.throwDOMException( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 if (!output.isConnectedToAudioParam(param.handler())) | 692 if (!output.isConnectedToAudioParam(param.handler())) |
| 693 return false; | 693 return false; |
| 694 output.disconnectAudioParam(param.handler()); | 694 output.disconnectAudioParam(param.handler()); |
| 695 m_connectedParams[outputIndex]->remove(¶m); | 695 m_connectedParams[outputIndex]->remove(¶m); |
| 696 return true; | 696 return true; |
| 697 } | 697 } |
| 698 | 698 |
| 699 void AudioNode::disconnect() | 699 void AudioNode::disconnect() |
| 700 { | 700 { |
| 701 ASSERT(isMainThread()); | 701 ASSERT(isMainThread()); |
| 702 AbstractAudioContext::AutoLocker locker(context()); | 702 BaseAudioContext::AutoLocker locker(context()); |
| 703 | 703 |
| 704 // Disconnect all outgoing connections. | 704 // Disconnect all outgoing connections. |
| 705 for (unsigned i = 0; i < numberOfOutputs(); ++i) | 705 for (unsigned i = 0; i < numberOfOutputs(); ++i) |
| 706 disconnectAllFromOutput(i); | 706 disconnectAllFromOutput(i); |
| 707 } | 707 } |
| 708 | 708 |
| 709 void AudioNode::disconnect(unsigned outputIndex, ExceptionState& exceptionState) | 709 void AudioNode::disconnect(unsigned outputIndex, ExceptionState& exceptionState) |
| 710 { | 710 { |
| 711 ASSERT(isMainThread()); | 711 ASSERT(isMainThread()); |
| 712 AbstractAudioContext::AutoLocker locker(context()); | 712 BaseAudioContext::AutoLocker locker(context()); |
| 713 | 713 |
| 714 // Sanity check on the output index. | 714 // Sanity check on the output index. |
| 715 if (outputIndex >= numberOfOutputs()) { | 715 if (outputIndex >= numberOfOutputs()) { |
| 716 exceptionState.throwDOMException( | 716 exceptionState.throwDOMException( |
| 717 IndexSizeError, | 717 IndexSizeError, |
| 718 ExceptionMessages::indexOutsideRange( | 718 ExceptionMessages::indexOutsideRange( |
| 719 "output index", | 719 "output index", |
| 720 outputIndex, | 720 outputIndex, |
| 721 0u, | 721 0u, |
| 722 ExceptionMessages::InclusiveBound, | 722 ExceptionMessages::InclusiveBound, |
| 723 numberOfOutputs() - 1, | 723 numberOfOutputs() - 1, |
| 724 ExceptionMessages::InclusiveBound)); | 724 ExceptionMessages::InclusiveBound)); |
| 725 return; | 725 return; |
| 726 } | 726 } |
| 727 // Disconnect all outgoing connections from the given output. | 727 // Disconnect all outgoing connections from the given output. |
| 728 disconnectAllFromOutput(outputIndex); | 728 disconnectAllFromOutput(outputIndex); |
| 729 } | 729 } |
| 730 | 730 |
| 731 void AudioNode::disconnect(AudioNode* destination, ExceptionState& exceptionStat
e) | 731 void AudioNode::disconnect(AudioNode* destination, ExceptionState& exceptionStat
e) |
| 732 { | 732 { |
| 733 ASSERT(isMainThread()); | 733 ASSERT(isMainThread()); |
| 734 AbstractAudioContext::AutoLocker locker(context()); | 734 BaseAudioContext::AutoLocker locker(context()); |
| 735 | 735 |
| 736 unsigned numberOfDisconnections = 0; | 736 unsigned numberOfDisconnections = 0; |
| 737 | 737 |
| 738 // FIXME: Can this be optimized? ChannelSplitter and ChannelMerger can have | 738 // FIXME: Can this be optimized? ChannelSplitter and ChannelMerger can have |
| 739 // 32 ports and that requires 1024 iterations to validate entire connections
. | 739 // 32 ports and that requires 1024 iterations to validate entire connections
. |
| 740 for (unsigned outputIndex = 0; outputIndex < numberOfOutputs(); ++outputInde
x) { | 740 for (unsigned outputIndex = 0; outputIndex < numberOfOutputs(); ++outputInde
x) { |
| 741 for (unsigned inputIndex = 0; inputIndex < destination->handler().number
OfInputs(); ++inputIndex) { | 741 for (unsigned inputIndex = 0; inputIndex < destination->handler().number
OfInputs(); ++inputIndex) { |
| 742 if (disconnectFromOutputIfConnected(outputIndex, *destination, input
Index)) | 742 if (disconnectFromOutputIfConnected(outputIndex, *destination, input
Index)) |
| 743 numberOfDisconnections++; | 743 numberOfDisconnections++; |
| 744 } | 744 } |
| 745 } | 745 } |
| 746 | 746 |
| 747 // If there is no connection to the destination, throw an exception. | 747 // If there is no connection to the destination, throw an exception. |
| 748 if (numberOfDisconnections == 0) { | 748 if (numberOfDisconnections == 0) { |
| 749 exceptionState.throwDOMException( | 749 exceptionState.throwDOMException( |
| 750 InvalidAccessError, | 750 InvalidAccessError, |
| 751 "the given destination is not connected."); | 751 "the given destination is not connected."); |
| 752 return; | 752 return; |
| 753 } | 753 } |
| 754 } | 754 } |
| 755 | 755 |
| 756 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, Excepti
onState& exceptionState) | 756 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, Excepti
onState& exceptionState) |
| 757 { | 757 { |
| 758 ASSERT(isMainThread()); | 758 ASSERT(isMainThread()); |
| 759 AbstractAudioContext::AutoLocker locker(context()); | 759 BaseAudioContext::AutoLocker locker(context()); |
| 760 | 760 |
| 761 if (outputIndex >= numberOfOutputs()) { | 761 if (outputIndex >= numberOfOutputs()) { |
| 762 // The output index is out of range. Throw an exception. | 762 // The output index is out of range. Throw an exception. |
| 763 exceptionState.throwDOMException( | 763 exceptionState.throwDOMException( |
| 764 IndexSizeError, | 764 IndexSizeError, |
| 765 ExceptionMessages::indexOutsideRange( | 765 ExceptionMessages::indexOutsideRange( |
| 766 "output index", | 766 "output index", |
| 767 outputIndex, | 767 outputIndex, |
| 768 0u, | 768 0u, |
| 769 ExceptionMessages::InclusiveBound, | 769 ExceptionMessages::InclusiveBound, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 784 if (numberOfDisconnections == 0) { | 784 if (numberOfDisconnections == 0) { |
| 785 exceptionState.throwDOMException( | 785 exceptionState.throwDOMException( |
| 786 InvalidAccessError, | 786 InvalidAccessError, |
| 787 "output (" + String::number(outputIndex) + ") is not connected to th
e given destination."); | 787 "output (" + String::number(outputIndex) + ") is not connected to th
e given destination."); |
| 788 } | 788 } |
| 789 } | 789 } |
| 790 | 790 |
| 791 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, unsigne
d inputIndex, ExceptionState& exceptionState) | 791 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, unsigne
d inputIndex, ExceptionState& exceptionState) |
| 792 { | 792 { |
| 793 ASSERT(isMainThread()); | 793 ASSERT(isMainThread()); |
| 794 AbstractAudioContext::AutoLocker locker(context()); | 794 BaseAudioContext::AutoLocker locker(context()); |
| 795 | 795 |
| 796 if (outputIndex >= numberOfOutputs()) { | 796 if (outputIndex >= numberOfOutputs()) { |
| 797 exceptionState.throwDOMException( | 797 exceptionState.throwDOMException( |
| 798 IndexSizeError, | 798 IndexSizeError, |
| 799 ExceptionMessages::indexOutsideRange( | 799 ExceptionMessages::indexOutsideRange( |
| 800 "output index", | 800 "output index", |
| 801 outputIndex, | 801 outputIndex, |
| 802 0u, | 802 0u, |
| 803 ExceptionMessages::InclusiveBound, | 803 ExceptionMessages::InclusiveBound, |
| 804 numberOfOutputs() - 1, | 804 numberOfOutputs() - 1, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 824 exceptionState.throwDOMException( | 824 exceptionState.throwDOMException( |
| 825 InvalidAccessError, | 825 InvalidAccessError, |
| 826 "output (" + String::number(outputIndex) + ") is not connected to th
e input (" + String::number(inputIndex) + ") of the destination."); | 826 "output (" + String::number(outputIndex) + ") is not connected to th
e input (" + String::number(inputIndex) + ") of the destination."); |
| 827 return; | 827 return; |
| 828 } | 828 } |
| 829 } | 829 } |
| 830 | 830 |
| 831 void AudioNode::disconnect(AudioParam* destinationParam, ExceptionState& excepti
onState) | 831 void AudioNode::disconnect(AudioParam* destinationParam, ExceptionState& excepti
onState) |
| 832 { | 832 { |
| 833 ASSERT(isMainThread()); | 833 ASSERT(isMainThread()); |
| 834 AbstractAudioContext::AutoLocker locker(context()); | 834 BaseAudioContext::AutoLocker locker(context()); |
| 835 | 835 |
| 836 // The number of disconnection made. | 836 // The number of disconnection made. |
| 837 unsigned numberOfDisconnections = 0; | 837 unsigned numberOfDisconnections = 0; |
| 838 | 838 |
| 839 // Check if the node output is connected the destination AudioParam. | 839 // Check if the node output is connected the destination AudioParam. |
| 840 // Disconnect if connected and increase |numberOfDisconnectios| by 1. | 840 // Disconnect if connected and increase |numberOfDisconnectios| by 1. |
| 841 for (unsigned outputIndex = 0; outputIndex < handler().numberOfOutputs(); ++
outputIndex) { | 841 for (unsigned outputIndex = 0; outputIndex < handler().numberOfOutputs(); ++
outputIndex) { |
| 842 if (disconnectFromOutputIfConnected(outputIndex, *destinationParam)) | 842 if (disconnectFromOutputIfConnected(outputIndex, *destinationParam)) |
| 843 numberOfDisconnections++; | 843 numberOfDisconnections++; |
| 844 } | 844 } |
| 845 | 845 |
| 846 // Throw an exception when there is no valid connection to the destination. | 846 // Throw an exception when there is no valid connection to the destination. |
| 847 if (numberOfDisconnections == 0) { | 847 if (numberOfDisconnections == 0) { |
| 848 exceptionState.throwDOMException( | 848 exceptionState.throwDOMException( |
| 849 InvalidAccessError, | 849 InvalidAccessError, |
| 850 "the given AudioParam is not connected."); | 850 "the given AudioParam is not connected."); |
| 851 return; | 851 return; |
| 852 } | 852 } |
| 853 } | 853 } |
| 854 | 854 |
| 855 void AudioNode::disconnect(AudioParam* destinationParam, unsigned outputIndex, E
xceptionState& exceptionState) | 855 void AudioNode::disconnect(AudioParam* destinationParam, unsigned outputIndex, E
xceptionState& exceptionState) |
| 856 { | 856 { |
| 857 ASSERT(isMainThread()); | 857 ASSERT(isMainThread()); |
| 858 AbstractAudioContext::AutoLocker locker(context()); | 858 BaseAudioContext::AutoLocker locker(context()); |
| 859 | 859 |
| 860 if (outputIndex >= handler().numberOfOutputs()) { | 860 if (outputIndex >= handler().numberOfOutputs()) { |
| 861 // The output index is out of range. Throw an exception. | 861 // The output index is out of range. Throw an exception. |
| 862 exceptionState.throwDOMException( | 862 exceptionState.throwDOMException( |
| 863 IndexSizeError, | 863 IndexSizeError, |
| 864 ExceptionMessages::indexOutsideRange( | 864 ExceptionMessages::indexOutsideRange( |
| 865 "output index", | 865 "output index", |
| 866 outputIndex, | 866 outputIndex, |
| 867 0u, | 867 0u, |
| 868 ExceptionMessages::InclusiveBound, | 868 ExceptionMessages::InclusiveBound, |
| 869 numberOfOutputs() - 1, | 869 numberOfOutputs() - 1, |
| 870 ExceptionMessages::InclusiveBound)); | 870 ExceptionMessages::InclusiveBound)); |
| 871 return; | 871 return; |
| 872 } | 872 } |
| 873 | 873 |
| 874 // If the output index is valid, proceed to disconnect. | 874 // If the output index is valid, proceed to disconnect. |
| 875 if (!disconnectFromOutputIfConnected(outputIndex, *destinationParam)) { | 875 if (!disconnectFromOutputIfConnected(outputIndex, *destinationParam)) { |
| 876 exceptionState.throwDOMException( | 876 exceptionState.throwDOMException( |
| 877 InvalidAccessError, | 877 InvalidAccessError, |
| 878 "specified destination AudioParam and node output (" + String::numbe
r(outputIndex) + ") are not connected."); | 878 "specified destination AudioParam and node output (" + String::numbe
r(outputIndex) + ") are not connected."); |
| 879 return; | 879 return; |
| 880 } | 880 } |
| 881 } | 881 } |
| 882 | 882 |
| 883 void AudioNode::disconnectWithoutException(unsigned outputIndex) | 883 void AudioNode::disconnectWithoutException(unsigned outputIndex) |
| 884 { | 884 { |
| 885 ASSERT(isMainThread()); | 885 ASSERT(isMainThread()); |
| 886 AbstractAudioContext::AutoLocker locker(context()); | 886 BaseAudioContext::AutoLocker locker(context()); |
| 887 | 887 |
| 888 // Sanity check input and output indices. | 888 // Sanity check input and output indices. |
| 889 if (outputIndex >= handler().numberOfOutputs()) | 889 if (outputIndex >= handler().numberOfOutputs()) |
| 890 return; | 890 return; |
| 891 disconnectAllFromOutput(outputIndex); | 891 disconnectAllFromOutput(outputIndex); |
| 892 } | 892 } |
| 893 | 893 |
| 894 unsigned AudioNode::numberOfInputs() const | 894 unsigned AudioNode::numberOfInputs() const |
| 895 { | 895 { |
| 896 return handler().numberOfInputs(); | 896 return handler().numberOfInputs(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 void AudioNode::didAddOutput(unsigned numberOfOutputs) | 944 void AudioNode::didAddOutput(unsigned numberOfOutputs) |
| 945 { | 945 { |
| 946 m_connectedNodes.append(nullptr); | 946 m_connectedNodes.append(nullptr); |
| 947 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedNodes.size()); | 947 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedNodes.size()); |
| 948 m_connectedParams.append(nullptr); | 948 m_connectedParams.append(nullptr); |
| 949 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedParams.size()); | 949 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedParams.size()); |
| 950 } | 950 } |
| 951 | 951 |
| 952 } // namespace blink | 952 } // namespace blink |
| 953 | 953 |
| OLD | NEW |