Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Unified Diff: Source/modules/webaudio/AudioNode.cpp

Issue 886173004: Fix AudioNode.disconnect() to support selective disconnection. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Test for AudioParam disconnection Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/modules/webaudio/AudioNode.cpp
diff --git a/Source/modules/webaudio/AudioNode.cpp b/Source/modules/webaudio/AudioNode.cpp
index 6ed72a2a57533123c7edd5d9af10d1b952ee6b3b..71a9058e9baf61ac4bdba2510d6c063787b6b480 100644
--- a/Source/modules/webaudio/AudioNode.cpp
+++ b/Source/modules/webaudio/AudioNode.cpp
@@ -277,12 +277,22 @@ void AudioNode::connect(AudioParam* param, unsigned outputIndex, ExceptionState&
param->connect(*output(outputIndex));
}
+void AudioNode::disconnect()
+{
+ ASSERT(isMainThread());
+ AudioContext::AutoLocker locker(context());
+
+ // Disconnect all outgoing connections.
+ for (unsigned i = 0; i < numberOfOutputs(); ++i)
+ this->output(i)->disconnectAll();
+}
+
void AudioNode::disconnect(unsigned outputIndex, ExceptionState& exceptionState)
{
ASSERT(isMainThread());
AudioContext::AutoLocker locker(context());
- // Sanity check input and output indices.
+ // Sanity check on the output index.
if (outputIndex >= numberOfOutputs()) {
exceptionState.throwDOMException(
IndexSizeError,
@@ -290,10 +300,158 @@ void AudioNode::disconnect(unsigned outputIndex, ExceptionState& exceptionState)
return;
}
+ // Disconnect all outgoing connections from the given output.
AudioNodeOutput* output = this->output(outputIndex);
output->disconnectAll();
}
+void AudioNode::disconnect(AudioNode* destination, ExceptionState& exceptionState)
+{
+ ASSERT(isMainThread());
+ AudioContext::AutoLocker locker(context());
+
+ bool isConnectedToDestination = false;
+
+ // TO FIX: Can this be optimized? ChannelSplitter and ChannelMerger can have
Raymond Toy 2015/02/11 21:31:18 s/TO FIX/FIXME/ according to http://www.webkit.org
hongchan 2015/02/12 18:38:01 Done.
+ // 32 ports and that requires 1024 iterations to validate entire connections.
+ for (unsigned i = 0; i < numberOfOutputs(); ++i) {
+ AudioNodeOutput* output = this->output(i);
+ for (unsigned j = 0; j < destination->numberOfInputs(); ++j) {
+ AudioNodeInput* input = destination->input(j);
+ if (output->isConnectedWithInput(*input)) {
+ output->disconnectInput(*input);
+ isConnectedToDestination = true;
+ }
+ }
+ }
+
+ // If there is no connection to the destination, throw an exception.
+ if (!isConnectedToDestination) {
+ exceptionState.throwDOMException(
+ InvalidAccessError,
+ "the given destination is not connected.");
+ return;
+ }
+}
+
+void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, ExceptionState& exceptionState)
+{
+ ASSERT(isMainThread());
+ AudioContext::AutoLocker locker(context());
+
+ // Sanity check on output index.
+ if (outputIndex >= numberOfOutputs()) {
+ exceptionState.throwDOMException(
+ IndexSizeError,
+ "output index (" + String::number(outputIndex) + ") exceeds number of outputs (" + String::number(numberOfOutputs()) + ").");
Raymond Toy 2015/02/11 21:31:18 Consider using IndexOutsideOfRange.
hongchan 2015/02/12 18:38:01 Acknowledged.
+ return;
+ }
+
+ bool isConnectedToDestination = false;
+ AudioNodeOutput* output = this->output(outputIndex);
+
+ // Sanity check on destination inputs and disconnect when possible.
+ for (unsigned i = 0; i < destination->numberOfInputs(); ++i) {
+ AudioNodeInput* input = destination->input(i);
+ if (output->isConnectedWithInput(*input)) {
+ output->disconnectInput(*input);
+ isConnectedToDestination = true;
+ }
+ }
+
+ // If there is no connection to the destination, throw an exception.
+ if (!isConnectedToDestination) {
+ exceptionState.throwDOMException(
+ InvalidAccessError,
+ "the given destination is not connected.");
Raymond Toy 2015/02/11 21:31:18 Give the output index with the message.
hongchan 2015/02/12 18:38:00 I will try to come up with the better error messag
+ return;
+ }
+}
+
+void AudioNode::disconnect(AudioNode* destination, unsigned outputIndex, unsigned inputIndex, ExceptionState& exceptionState)
+{
+ ASSERT(isMainThread());
+ AudioContext::AutoLocker locker(context());
+
+ // Sanity check input and output indices.
+ if (outputIndex >= numberOfOutputs()) {
+ exceptionState.throwDOMException(
+ IndexSizeError,
+ "output index (" + String::number(outputIndex) + ") exceeds number of outputs (" + String::number(numberOfOutputs()) + ").");
Raymond Toy 2015/02/11 21:31:18 Consider using IndexOutsideOfRange, here and below
hongchan 2015/02/12 18:38:01 Done.
+ return;
+ }
+
+ if (inputIndex >= destination->numberOfInputs()) {
+ exceptionState.throwDOMException(
+ IndexSizeError,
+ "input index (" + String::number(inputIndex) + ") exceeds number of inputs of destination node (" + String::number(destination->numberOfInputs()) + ").");
+ return;
+ }
+
+ AudioNodeOutput* output = this->output(outputIndex);
+ AudioNodeInput* input = destination->input(inputIndex);
+
+ // Sanity check on the connection between the output and the destination input.
+ if (!output->isConnectedWithInput(*input)) {
+ exceptionState.throwDOMException(
+ InvalidAccessError,
+ "the given destination input (" + String::number(inputIndex) + ") and node output (" + String::number(outputIndex) + ") are not connected.");
Raymond Toy 2015/02/11 21:31:18 I think it reads better to say output # is not con
hongchan 2015/02/12 18:38:01 Done.
+ return;
+ }
+
+ output->disconnectInput(*input);
+}
+
+void AudioNode::disconnect(AudioParam* destinationParam, ExceptionState& exceptionState)
+{
+ ASSERT(isMainThread());
+ AudioContext::AutoLocker locker(context());
+
+ bool isConnectedToDestination = false;
+
+ for (unsigned i = 0; i < numberOfOutputs(); ++i) {
+ AudioNodeOutput* output = this->output(i);
+ if (output->isConnectedWithAudioParam(*destinationParam)) {
+ output->disconnectAudioParam(*destinationParam);
+ isConnectedToDestination = true;
+ }
+ }
+
+ // Throw an exception when there is no valid connection to the destination.
+ if (!isConnectedToDestination) {
+ exceptionState.throwDOMException(
+ InvalidAccessError,
+ "the given destination AudioParam and the node are not connected.");
+ return;
+ }
+}
+
+void AudioNode::disconnect(AudioParam* destinationParam, unsigned outputIndex, ExceptionState& exceptionState)
+{
+ ASSERT(isMainThread());
+ AudioContext::AutoLocker locker(context());
+
+ // Sanity check input and output indices.
+ if (outputIndex >= numberOfOutputs()) {
+ exceptionState.throwDOMException(
+ IndexSizeError,
+ "output index (" + String::number(outputIndex) + ") exceeds number of outputs (" + String::number(numberOfOutputs()) + ").");
+ return;
+ }
+
+ AudioNodeOutput* output = this->output(outputIndex);
+
+ // Sanity check on the connection between the output and the destination.
+ if (!output->isConnectedWithAudioParam(*destinationParam)) {
+ exceptionState.throwDOMException(
+ InvalidAccessError,
+ "specified destination AudioParam and node output (" + String::number(outputIndex) + ") are not connected.");
+ return;
+ }
+
+ output->disconnectAudioParam(*destinationParam);
+}
+
void AudioNode::disconnectWithoutException(unsigned outputIndex)
{
ASSERT(isMainThread());

Powered by Google App Engine
This is Rietveld 408576698