| 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 output->dispose(); | 102 output->dispose(); |
| 103 m_node = nullptr; | 103 m_node = nullptr; |
| 104 } | 104 } |
| 105 | 105 |
| 106 AudioNode* AudioHandler::node() const | 106 AudioNode* AudioHandler::node() const |
| 107 { | 107 { |
| 108 ASSERT(isMainThread()); | 108 ASSERT(isMainThread()); |
| 109 return m_node; | 109 return m_node; |
| 110 } | 110 } |
| 111 | 111 |
| 112 AbstractAudioContext* AudioHandler::context() const | 112 BaseAudioContext* AudioHandler::context() const |
| 113 { | 113 { |
| 114 return m_context; | 114 return m_context; |
| 115 } | 115 } |
| 116 | 116 |
| 117 String AudioHandler::nodeTypeName() const | 117 String AudioHandler::nodeTypeName() const |
| 118 { | 118 { |
| 119 switch (m_nodeType) { | 119 switch (m_nodeType) { |
| 120 case NodeTypeDestination: | 120 case NodeTypeDestination: |
| 121 return "AudioDestinationNode"; | 121 return "AudioDestinationNode"; |
| 122 case NodeTypeOscillator: | 122 case NodeTypeOscillator: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 } | 200 } |
| 201 | 201 |
| 202 unsigned long AudioHandler::channelCount() | 202 unsigned long AudioHandler::channelCount() |
| 203 { | 203 { |
| 204 return m_channelCount; | 204 return m_channelCount; |
| 205 } | 205 } |
| 206 | 206 |
| 207 void AudioHandler::setChannelCount(unsigned long channelCount, ExceptionState& e
xceptionState) | 207 void AudioHandler::setChannelCount(unsigned long channelCount, ExceptionState& e
xceptionState) |
| 208 { | 208 { |
| 209 ASSERT(isMainThread()); | 209 ASSERT(isMainThread()); |
| 210 AbstractAudioContext::AutoLocker locker(context()); | 210 BaseAudioContext::AutoLocker locker(context()); |
| 211 | 211 |
| 212 if (channelCount > 0 && channelCount <= AbstractAudioContext::maxNumberOfCha
nnels()) { | 212 if (channelCount > 0 && channelCount <= BaseAudioContext::maxNumberOfChannel
s()) { |
| 213 if (m_channelCount != channelCount) { | 213 if (m_channelCount != channelCount) { |
| 214 m_channelCount = channelCount; | 214 m_channelCount = channelCount; |
| 215 if (m_channelCountMode != Max) | 215 if (m_channelCountMode != Max) |
| 216 updateChannelsForInputs(); | 216 updateChannelsForInputs(); |
| 217 } | 217 } |
| 218 } else { | 218 } else { |
| 219 exceptionState.throwDOMException( | 219 exceptionState.throwDOMException( |
| 220 NotSupportedError, | 220 NotSupportedError, |
| 221 ExceptionMessages::indexOutsideRange<unsigned long>( | 221 ExceptionMessages::indexOutsideRange<unsigned long>( |
| 222 "channel count", | 222 "channel count", |
| 223 channelCount, | 223 channelCount, |
| 224 1, | 224 1, |
| 225 ExceptionMessages::InclusiveBound, | 225 ExceptionMessages::InclusiveBound, |
| 226 AbstractAudioContext::maxNumberOfChannels(), | 226 BaseAudioContext::maxNumberOfChannels(), |
| 227 ExceptionMessages::InclusiveBound)); | 227 ExceptionMessages::InclusiveBound)); |
| 228 } | 228 } |
| 229 } | 229 } |
| 230 | 230 |
| 231 String AudioHandler::channelCountMode() | 231 String AudioHandler::channelCountMode() |
| 232 { | 232 { |
| 233 switch (m_channelCountMode) { | 233 switch (m_channelCountMode) { |
| 234 case Max: | 234 case Max: |
| 235 return "max"; | 235 return "max"; |
| 236 case ClampedMax: | 236 case ClampedMax: |
| 237 return "clamped-max"; | 237 return "clamped-max"; |
| 238 case Explicit: | 238 case Explicit: |
| 239 return "explicit"; | 239 return "explicit"; |
| 240 } | 240 } |
| 241 ASSERT_NOT_REACHED(); | 241 ASSERT_NOT_REACHED(); |
| 242 return ""; | 242 return ""; |
| 243 } | 243 } |
| 244 | 244 |
| 245 void AudioHandler::setChannelCountMode(const String& mode, ExceptionState& excep
tionState) | 245 void AudioHandler::setChannelCountMode(const String& mode, ExceptionState& excep
tionState) |
| 246 { | 246 { |
| 247 ASSERT(isMainThread()); | 247 ASSERT(isMainThread()); |
| 248 AbstractAudioContext::AutoLocker locker(context()); | 248 BaseAudioContext::AutoLocker locker(context()); |
| 249 | 249 |
| 250 ChannelCountMode oldMode = m_channelCountMode; | 250 ChannelCountMode oldMode = m_channelCountMode; |
| 251 | 251 |
| 252 if (mode == "max") { | 252 if (mode == "max") { |
| 253 m_newChannelCountMode = Max; | 253 m_newChannelCountMode = Max; |
| 254 } else if (mode == "clamped-max") { | 254 } else if (mode == "clamped-max") { |
| 255 m_newChannelCountMode = ClampedMax; | 255 m_newChannelCountMode = ClampedMax; |
| 256 } else if (mode == "explicit") { | 256 } else if (mode == "explicit") { |
| 257 m_newChannelCountMode = Explicit; | 257 m_newChannelCountMode = Explicit; |
| 258 } else { | 258 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 271 case AudioBus::Discrete: | 271 case AudioBus::Discrete: |
| 272 return "discrete"; | 272 return "discrete"; |
| 273 } | 273 } |
| 274 ASSERT_NOT_REACHED(); | 274 ASSERT_NOT_REACHED(); |
| 275 return ""; | 275 return ""; |
| 276 } | 276 } |
| 277 | 277 |
| 278 void AudioHandler::setChannelInterpretation(const String& interpretation, Except
ionState& exceptionState) | 278 void AudioHandler::setChannelInterpretation(const String& interpretation, Except
ionState& exceptionState) |
| 279 { | 279 { |
| 280 ASSERT(isMainThread()); | 280 ASSERT(isMainThread()); |
| 281 AbstractAudioContext::AutoLocker locker(context()); | 281 BaseAudioContext::AutoLocker locker(context()); |
| 282 | 282 |
| 283 if (interpretation == "speakers") { | 283 if (interpretation == "speakers") { |
| 284 m_channelInterpretation = AudioBus::Speakers; | 284 m_channelInterpretation = AudioBus::Speakers; |
| 285 } else if (interpretation == "discrete") { | 285 } else if (interpretation == "discrete") { |
| 286 m_channelInterpretation = AudioBus::Discrete; | 286 m_channelInterpretation = AudioBus::Discrete; |
| 287 } else { | 287 } else { |
| 288 ASSERT_NOT_REACHED(); | 288 ASSERT_NOT_REACHED(); |
| 289 } | 289 } |
| 290 } | 290 } |
| 291 | 291 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 void AudioHandler::unsilenceOutputs() | 382 void AudioHandler::unsilenceOutputs() |
| 383 { | 383 { |
| 384 for (auto& output : m_outputs) | 384 for (auto& output : m_outputs) |
| 385 output->bus()->clearSilentFlag(); | 385 output->bus()->clearSilentFlag(); |
| 386 } | 386 } |
| 387 | 387 |
| 388 void AudioHandler::enableOutputsIfNecessary() | 388 void AudioHandler::enableOutputsIfNecessary() |
| 389 { | 389 { |
| 390 if (m_isDisabled && m_connectionRefCount > 0) { | 390 if (m_isDisabled && m_connectionRefCount > 0) { |
| 391 ASSERT(isMainThread()); | 391 ASSERT(isMainThread()); |
| 392 AbstractAudioContext::AutoLocker locker(context()); | 392 BaseAudioContext::AutoLocker locker(context()); |
| 393 | 393 |
| 394 m_isDisabled = false; | 394 m_isDisabled = false; |
| 395 for (auto& output : m_outputs) | 395 for (auto& output : m_outputs) |
| 396 output->enable(); | 396 output->enable(); |
| 397 } | 397 } |
| 398 } | 398 } |
| 399 | 399 |
| 400 void AudioHandler::disableOutputsIfNecessary() | 400 void AudioHandler::disableOutputsIfNecessary() |
| 401 { | 401 { |
| 402 // Disable outputs if appropriate. We do this if the number of connections i
s 0 or 1. The case | 402 // Disable outputs if appropriate. We do this if the number of connections i
s 0 or 1. The case |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 unsigned AudioHandler::numberOfOutputChannels() const | 509 unsigned AudioHandler::numberOfOutputChannels() const |
| 510 { | 510 { |
| 511 // This should only be called for ScriptProcessorNodes which are the only no
des where you can | 511 // This should only be called for ScriptProcessorNodes which are the only no
des where you can |
| 512 // have an output with 0 channels. All other nodes have have at least one o
utput channel, so | 512 // have an output with 0 channels. All other nodes have have at least one o
utput channel, so |
| 513 // there's no reason other nodes should ever call this function. | 513 // there's no reason other nodes should ever call this function. |
| 514 DCHECK(0) << "numberOfOutputChannels() not valid for node type " << getNodeT
ype(); | 514 DCHECK(0) << "numberOfOutputChannels() not valid for node type " << getNodeT
ype(); |
| 515 return 1; | 515 return 1; |
| 516 } | 516 } |
| 517 // ---------------------------------------------------------------- | 517 // ---------------------------------------------------------------- |
| 518 | 518 |
| 519 AudioNode::AudioNode(AbstractAudioContext& context) | 519 AudioNode::AudioNode(BaseAudioContext& context) |
| 520 : m_context(context) | 520 : m_context(context) |
| 521 , m_handler(nullptr) | 521 , m_handler(nullptr) |
| 522 { | 522 { |
| 523 ThreadState::current()->registerPreFinalizer(this); | 523 ThreadState::current()->registerPreFinalizer(this); |
| 524 } | 524 } |
| 525 | 525 |
| 526 void AudioNode::dispose() | 526 void AudioNode::dispose() |
| 527 { | 527 { |
| 528 ASSERT(isMainThread()); | 528 ASSERT(isMainThread()); |
| 529 AbstractAudioContext::AutoLocker locker(context()); | 529 BaseAudioContext::AutoLocker locker(context()); |
| 530 handler().dispose(); | 530 handler().dispose(); |
| 531 if (context()->contextState() == AbstractAudioContext::Running) | 531 if (context()->contextState() == BaseAudioContext::Running) |
| 532 context()->deferredTaskHandler().addRenderingOrphanHandler(m_handler.rel
ease()); | 532 context()->deferredTaskHandler().addRenderingOrphanHandler(m_handler.rel
ease()); |
| 533 } | 533 } |
| 534 | 534 |
| 535 void AudioNode::setHandler(PassRefPtr<AudioHandler> handler) | 535 void AudioNode::setHandler(PassRefPtr<AudioHandler> handler) |
| 536 { | 536 { |
| 537 ASSERT(handler); | 537 ASSERT(handler); |
| 538 m_handler = handler; | 538 m_handler = handler; |
| 539 } | 539 } |
| 540 | 540 |
| 541 AudioHandler& AudioNode::handler() const | 541 AudioHandler& AudioNode::handler() const |
| 542 { | 542 { |
| 543 return *m_handler; | 543 return *m_handler; |
| 544 } | 544 } |
| 545 | 545 |
| 546 DEFINE_TRACE(AudioNode) | 546 DEFINE_TRACE(AudioNode) |
| 547 { | 547 { |
| 548 visitor->trace(m_context); | 548 visitor->trace(m_context); |
| 549 visitor->trace(m_connectedNodes); | 549 visitor->trace(m_connectedNodes); |
| 550 visitor->trace(m_connectedParams); | 550 visitor->trace(m_connectedParams); |
| 551 RefCountedGarbageCollectedEventTargetWithInlineData<AudioNode>::trace(visito
r); | 551 RefCountedGarbageCollectedEventTargetWithInlineData<AudioNode>::trace(visito
r); |
| 552 } | 552 } |
| 553 | 553 |
| 554 AbstractAudioContext* AudioNode::context() const | 554 BaseAudioContext* AudioNode::context() const |
| 555 { | 555 { |
| 556 return m_context; | 556 return m_context; |
| 557 } | 557 } |
| 558 | 558 |
| 559 AudioNode* AudioNode::connect(AudioNode* destination, unsigned outputIndex, unsi
gned inputIndex, ExceptionState& exceptionState) | 559 AudioNode* AudioNode::connect(AudioNode* destination, unsigned outputIndex, unsi
gned inputIndex, ExceptionState& exceptionState) |
| 560 { | 560 { |
| 561 ASSERT(isMainThread()); | 561 ASSERT(isMainThread()); |
| 562 AbstractAudioContext::AutoLocker locker(context()); | 562 BaseAudioContext::AutoLocker locker(context()); |
| 563 | 563 |
| 564 if (context()->isContextClosed()) { | 564 if (context()->isContextClosed()) { |
| 565 exceptionState.throwDOMException( | 565 exceptionState.throwDOMException( |
| 566 InvalidStateError, | 566 InvalidStateError, |
| 567 "Cannot connect after the context has been closed."); | 567 "Cannot connect after the context has been closed."); |
| 568 return nullptr; | 568 return nullptr; |
| 569 } | 569 } |
| 570 | 570 |
| 571 if (!destination) { | 571 if (!destination) { |
| 572 exceptionState.throwDOMException( | 572 exceptionState.throwDOMException( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 614 |
| 615 // Let context know that a connection has been made. | 615 // Let context know that a connection has been made. |
| 616 context()->incrementConnectionCount(); | 616 context()->incrementConnectionCount(); |
| 617 | 617 |
| 618 return destination; | 618 return destination; |
| 619 } | 619 } |
| 620 | 620 |
| 621 void AudioNode::connect(AudioParam* param, unsigned outputIndex, ExceptionState&
exceptionState) | 621 void AudioNode::connect(AudioParam* param, unsigned outputIndex, ExceptionState&
exceptionState) |
| 622 { | 622 { |
| 623 ASSERT(isMainThread()); | 623 ASSERT(isMainThread()); |
| 624 AbstractAudioContext::AutoLocker locker(context()); | 624 BaseAudioContext::AutoLocker locker(context()); |
| 625 | 625 |
| 626 if (context()->isContextClosed()) { | 626 if (context()->isContextClosed()) { |
| 627 exceptionState.throwDOMException( | 627 exceptionState.throwDOMException( |
| 628 InvalidStateError, | 628 InvalidStateError, |
| 629 "Cannot connect after the context has been closed."); | 629 "Cannot connect after the context has been closed."); |
| 630 return; | 630 return; |
| 631 } | 631 } |
| 632 | 632 |
| 633 if (!param) { | 633 if (!param) { |
| 634 exceptionState.throwDOMException( | 634 exceptionState.throwDOMException( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 if (!output.isConnectedToAudioParam(param.handler())) | 681 if (!output.isConnectedToAudioParam(param.handler())) |
| 682 return false; | 682 return false; |
| 683 output.disconnectAudioParam(param.handler()); | 683 output.disconnectAudioParam(param.handler()); |
| 684 m_connectedParams[outputIndex]->remove(¶m); | 684 m_connectedParams[outputIndex]->remove(¶m); |
| 685 return true; | 685 return true; |
| 686 } | 686 } |
| 687 | 687 |
| 688 void AudioNode::disconnect() | 688 void AudioNode::disconnect() |
| 689 { | 689 { |
| 690 ASSERT(isMainThread()); | 690 ASSERT(isMainThread()); |
| 691 AbstractAudioContext::AutoLocker locker(context()); | 691 BaseAudioContext::AutoLocker locker(context()); |
| 692 | 692 |
| 693 // Disconnect all outgoing connections. | 693 // Disconnect all outgoing connections. |
| 694 for (unsigned i = 0; i < numberOfOutputs(); ++i) | 694 for (unsigned i = 0; i < numberOfOutputs(); ++i) |
| 695 disconnectAllFromOutput(i); | 695 disconnectAllFromOutput(i); |
| 696 } | 696 } |
| 697 | 697 |
| 698 void AudioNode::disconnect(unsigned outputIndex, ExceptionState& exceptionState) | 698 void AudioNode::disconnect(unsigned outputIndex, ExceptionState& exceptionState) |
| 699 { | 699 { |
| 700 ASSERT(isMainThread()); | 700 ASSERT(isMainThread()); |
| 701 AbstractAudioContext::AutoLocker locker(context()); | 701 BaseAudioContext::AutoLocker locker(context()); |
| 702 | 702 |
| 703 // Sanity check on the output index. | 703 // Sanity check on the output index. |
| 704 if (outputIndex >= numberOfOutputs()) { | 704 if (outputIndex >= numberOfOutputs()) { |
| 705 exceptionState.throwDOMException( | 705 exceptionState.throwDOMException( |
| 706 IndexSizeError, | 706 IndexSizeError, |
| 707 ExceptionMessages::indexOutsideRange( | 707 ExceptionMessages::indexOutsideRange( |
| 708 "output index", | 708 "output index", |
| 709 outputIndex, | 709 outputIndex, |
| 710 0u, | 710 0u, |
| 711 ExceptionMessages::InclusiveBound, | 711 ExceptionMessages::InclusiveBound, |
| 712 numberOfOutputs() - 1, | 712 numberOfOutputs() - 1, |
| 713 ExceptionMessages::InclusiveBound)); | 713 ExceptionMessages::InclusiveBound)); |
| 714 return; | 714 return; |
| 715 } | 715 } |
| 716 // Disconnect all outgoing connections from the given output. | 716 // Disconnect all outgoing connections from the given output. |
| 717 disconnectAllFromOutput(outputIndex); | 717 disconnectAllFromOutput(outputIndex); |
| 718 } | 718 } |
| 719 | 719 |
| 720 void AudioNode::disconnect(AudioNode* destination, ExceptionState& exceptionStat
e) | 720 void AudioNode::disconnect(AudioNode* destination, ExceptionState& exceptionStat
e) |
| 721 { | 721 { |
| 722 ASSERT(isMainThread()); | 722 ASSERT(isMainThread()); |
| 723 AbstractAudioContext::AutoLocker locker(context()); | 723 BaseAudioContext::AutoLocker locker(context()); |
| 724 | 724 |
| 725 unsigned numberOfDisconnections = 0; | 725 unsigned numberOfDisconnections = 0; |
| 726 | 726 |
| 727 // FIXME: Can this be optimized? ChannelSplitter and ChannelMerger can have | 727 // FIXME: Can this be optimized? ChannelSplitter and ChannelMerger can have |
| 728 // 32 ports and that requires 1024 iterations to validate entire connections
. | 728 // 32 ports and that requires 1024 iterations to validate entire connections
. |
| 729 for (unsigned outputIndex = 0; outputIndex < numberOfOutputs(); ++outputInde
x) { | 729 for (unsigned outputIndex = 0; outputIndex < numberOfOutputs(); ++outputInde
x) { |
| 730 for (unsigned inputIndex = 0; inputIndex < destination->handler().number
OfInputs(); ++inputIndex) { | 730 for (unsigned inputIndex = 0; inputIndex < destination->handler().number
OfInputs(); ++inputIndex) { |
| 731 if (disconnectFromOutputIfConnected(outputIndex, *destination, input
Index)) | 731 if (disconnectFromOutputIfConnected(outputIndex, *destination, input
Index)) |
| 732 numberOfDisconnections++; | 732 numberOfDisconnections++; |
| 733 } | 733 } |
| 734 } | 734 } |
| 735 | 735 |
| 736 // If there is no connection to the destination, throw an exception. | 736 // If there is no connection to the destination, throw an exception. |
| 737 if (numberOfDisconnections == 0) { | 737 if (numberOfDisconnections == 0) { |
| 738 exceptionState.throwDOMException( | 738 exceptionState.throwDOMException( |
| 739 InvalidAccessError, | 739 InvalidAccessError, |
| 740 "the given destination is not connected."); | 740 "the given destination is not connected."); |
| 741 return; | 741 return; |
| 742 } | 742 } |
| 743 } | 743 } |
| 744 | 744 |
| 745 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, Excepti
onState& exceptionState) | 745 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, Excepti
onState& exceptionState) |
| 746 { | 746 { |
| 747 ASSERT(isMainThread()); | 747 ASSERT(isMainThread()); |
| 748 AbstractAudioContext::AutoLocker locker(context()); | 748 BaseAudioContext::AutoLocker locker(context()); |
| 749 | 749 |
| 750 if (outputIndex >= numberOfOutputs()) { | 750 if (outputIndex >= numberOfOutputs()) { |
| 751 // The output index is out of range. Throw an exception. | 751 // The output index is out of range. Throw an exception. |
| 752 exceptionState.throwDOMException( | 752 exceptionState.throwDOMException( |
| 753 IndexSizeError, | 753 IndexSizeError, |
| 754 ExceptionMessages::indexOutsideRange( | 754 ExceptionMessages::indexOutsideRange( |
| 755 "output index", | 755 "output index", |
| 756 outputIndex, | 756 outputIndex, |
| 757 0u, | 757 0u, |
| 758 ExceptionMessages::InclusiveBound, | 758 ExceptionMessages::InclusiveBound, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 773 if (numberOfDisconnections == 0) { | 773 if (numberOfDisconnections == 0) { |
| 774 exceptionState.throwDOMException( | 774 exceptionState.throwDOMException( |
| 775 InvalidAccessError, | 775 InvalidAccessError, |
| 776 "output (" + String::number(outputIndex) + ") is not connected to th
e given destination."); | 776 "output (" + String::number(outputIndex) + ") is not connected to th
e given destination."); |
| 777 } | 777 } |
| 778 } | 778 } |
| 779 | 779 |
| 780 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, unsigne
d inputIndex, ExceptionState& exceptionState) | 780 void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, unsigne
d inputIndex, ExceptionState& exceptionState) |
| 781 { | 781 { |
| 782 ASSERT(isMainThread()); | 782 ASSERT(isMainThread()); |
| 783 AbstractAudioContext::AutoLocker locker(context()); | 783 BaseAudioContext::AutoLocker locker(context()); |
| 784 | 784 |
| 785 if (outputIndex >= numberOfOutputs()) { | 785 if (outputIndex >= numberOfOutputs()) { |
| 786 exceptionState.throwDOMException( | 786 exceptionState.throwDOMException( |
| 787 IndexSizeError, | 787 IndexSizeError, |
| 788 ExceptionMessages::indexOutsideRange( | 788 ExceptionMessages::indexOutsideRange( |
| 789 "output index", | 789 "output index", |
| 790 outputIndex, | 790 outputIndex, |
| 791 0u, | 791 0u, |
| 792 ExceptionMessages::InclusiveBound, | 792 ExceptionMessages::InclusiveBound, |
| 793 numberOfOutputs() - 1, | 793 numberOfOutputs() - 1, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 813 exceptionState.throwDOMException( | 813 exceptionState.throwDOMException( |
| 814 InvalidAccessError, | 814 InvalidAccessError, |
| 815 "output (" + String::number(outputIndex) + ") is not connected to th
e input (" + String::number(inputIndex) + ") of the destination."); | 815 "output (" + String::number(outputIndex) + ") is not connected to th
e input (" + String::number(inputIndex) + ") of the destination."); |
| 816 return; | 816 return; |
| 817 } | 817 } |
| 818 } | 818 } |
| 819 | 819 |
| 820 void AudioNode::disconnect(AudioParam* destinationParam, ExceptionState& excepti
onState) | 820 void AudioNode::disconnect(AudioParam* destinationParam, ExceptionState& excepti
onState) |
| 821 { | 821 { |
| 822 ASSERT(isMainThread()); | 822 ASSERT(isMainThread()); |
| 823 AbstractAudioContext::AutoLocker locker(context()); | 823 BaseAudioContext::AutoLocker locker(context()); |
| 824 | 824 |
| 825 // The number of disconnection made. | 825 // The number of disconnection made. |
| 826 unsigned numberOfDisconnections = 0; | 826 unsigned numberOfDisconnections = 0; |
| 827 | 827 |
| 828 // Check if the node output is connected the destination AudioParam. | 828 // Check if the node output is connected the destination AudioParam. |
| 829 // Disconnect if connected and increase |numberOfDisconnectios| by 1. | 829 // Disconnect if connected and increase |numberOfDisconnectios| by 1. |
| 830 for (unsigned outputIndex = 0; outputIndex < handler().numberOfOutputs(); ++
outputIndex) { | 830 for (unsigned outputIndex = 0; outputIndex < handler().numberOfOutputs(); ++
outputIndex) { |
| 831 if (disconnectFromOutputIfConnected(outputIndex, *destinationParam)) | 831 if (disconnectFromOutputIfConnected(outputIndex, *destinationParam)) |
| 832 numberOfDisconnections++; | 832 numberOfDisconnections++; |
| 833 } | 833 } |
| 834 | 834 |
| 835 // Throw an exception when there is no valid connection to the destination. | 835 // Throw an exception when there is no valid connection to the destination. |
| 836 if (numberOfDisconnections == 0) { | 836 if (numberOfDisconnections == 0) { |
| 837 exceptionState.throwDOMException( | 837 exceptionState.throwDOMException( |
| 838 InvalidAccessError, | 838 InvalidAccessError, |
| 839 "the given AudioParam is not connected."); | 839 "the given AudioParam is not connected."); |
| 840 return; | 840 return; |
| 841 } | 841 } |
| 842 } | 842 } |
| 843 | 843 |
| 844 void AudioNode::disconnect(AudioParam* destinationParam, unsigned outputIndex, E
xceptionState& exceptionState) | 844 void AudioNode::disconnect(AudioParam* destinationParam, unsigned outputIndex, E
xceptionState& exceptionState) |
| 845 { | 845 { |
| 846 ASSERT(isMainThread()); | 846 ASSERT(isMainThread()); |
| 847 AbstractAudioContext::AutoLocker locker(context()); | 847 BaseAudioContext::AutoLocker locker(context()); |
| 848 | 848 |
| 849 if (outputIndex >= handler().numberOfOutputs()) { | 849 if (outputIndex >= handler().numberOfOutputs()) { |
| 850 // The output index is out of range. Throw an exception. | 850 // The output index is out of range. Throw an exception. |
| 851 exceptionState.throwDOMException( | 851 exceptionState.throwDOMException( |
| 852 IndexSizeError, | 852 IndexSizeError, |
| 853 ExceptionMessages::indexOutsideRange( | 853 ExceptionMessages::indexOutsideRange( |
| 854 "output index", | 854 "output index", |
| 855 outputIndex, | 855 outputIndex, |
| 856 0u, | 856 0u, |
| 857 ExceptionMessages::InclusiveBound, | 857 ExceptionMessages::InclusiveBound, |
| 858 numberOfOutputs() - 1, | 858 numberOfOutputs() - 1, |
| 859 ExceptionMessages::InclusiveBound)); | 859 ExceptionMessages::InclusiveBound)); |
| 860 return; | 860 return; |
| 861 } | 861 } |
| 862 | 862 |
| 863 // If the output index is valid, proceed to disconnect. | 863 // If the output index is valid, proceed to disconnect. |
| 864 if (!disconnectFromOutputIfConnected(outputIndex, *destinationParam)) { | 864 if (!disconnectFromOutputIfConnected(outputIndex, *destinationParam)) { |
| 865 exceptionState.throwDOMException( | 865 exceptionState.throwDOMException( |
| 866 InvalidAccessError, | 866 InvalidAccessError, |
| 867 "specified destination AudioParam and node output (" + String::numbe
r(outputIndex) + ") are not connected."); | 867 "specified destination AudioParam and node output (" + String::numbe
r(outputIndex) + ") are not connected."); |
| 868 return; | 868 return; |
| 869 } | 869 } |
| 870 } | 870 } |
| 871 | 871 |
| 872 void AudioNode::disconnectWithoutException(unsigned outputIndex) | 872 void AudioNode::disconnectWithoutException(unsigned outputIndex) |
| 873 { | 873 { |
| 874 ASSERT(isMainThread()); | 874 ASSERT(isMainThread()); |
| 875 AbstractAudioContext::AutoLocker locker(context()); | 875 BaseAudioContext::AutoLocker locker(context()); |
| 876 | 876 |
| 877 // Sanity check input and output indices. | 877 // Sanity check input and output indices. |
| 878 if (outputIndex >= handler().numberOfOutputs()) | 878 if (outputIndex >= handler().numberOfOutputs()) |
| 879 return; | 879 return; |
| 880 disconnectAllFromOutput(outputIndex); | 880 disconnectAllFromOutput(outputIndex); |
| 881 } | 881 } |
| 882 | 882 |
| 883 unsigned AudioNode::numberOfInputs() const | 883 unsigned AudioNode::numberOfInputs() const |
| 884 { | 884 { |
| 885 return handler().numberOfInputs(); | 885 return handler().numberOfInputs(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 void AudioNode::didAddOutput(unsigned numberOfOutputs) | 933 void AudioNode::didAddOutput(unsigned numberOfOutputs) |
| 934 { | 934 { |
| 935 m_connectedNodes.append(nullptr); | 935 m_connectedNodes.append(nullptr); |
| 936 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedNodes.size()); | 936 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedNodes.size()); |
| 937 m_connectedParams.append(nullptr); | 937 m_connectedParams.append(nullptr); |
| 938 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedParams.size()); | 938 ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == m_connectedParams.size()); |
| 939 } | 939 } |
| 940 | 940 |
| 941 } // namespace blink | 941 } // namespace blink |
| 942 | 942 |
| OLD | NEW |