void AudioNode::Disconnect(AudioNode& aDestination, uint32_t aOutput, uint32_t aInput, ErrorResult& aRv) { if (aOutput >= NumberOfOutputs()) { aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return; } if (aInput >= aDestination.NumberOfInputs()) { aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return; } bool wasConnected = false; for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t inputIndex = aDestination.mInputNodes.Length() - 1; inputIndex >= 0; --inputIndex) { InputNode& input = aDestination.mInputNodes[inputIndex]; if (input.mOutputPort == aOutput && input.mInputPort == aInput) { wasConnected |= DisconnectFromOutputIfConnected(aDestination, outputIndex, inputIndex); break; } } } if (!wasConnected) { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return; } // This disconnection may have disconnected a panner and a source. Context()->UpdatePannerSource(); }
void AudioNode::Connect(AudioNode& aDestination, uint32_t aOutput, uint32_t aInput, ErrorResult& aRv) { if (aOutput >= NumberOfOutputs() || aInput >= aDestination.NumberOfInputs()) { aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return; } if (Context() != aDestination.Context()) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return; } if (FindIndexOfNodeWithPorts(aDestination.mInputNodes, this, aInput, aOutput) != nsTArray<AudioNode::InputNode>::NoIndex) { // connection already exists. return; } // The MediaStreamGraph will handle cycle detection. We don't need to do it // here. mOutputNodes.AppendElement(&aDestination); InputNode* input = aDestination.mInputNodes.AppendElement(); input->mInputNode = this; input->mInputPort = aInput; input->mOutputPort = aOutput; AudioNodeStream* destinationStream = aDestination.mStream; if (mStream && destinationStream) { // Connect streams in the MediaStreamGraph MOZ_ASSERT(aInput <= UINT16_MAX, "Unexpected large input port number"); MOZ_ASSERT(aOutput <= UINT16_MAX, "Unexpected large output port number"); input->mStreamPort = destinationStream-> AllocateInputPort(mStream, AudioNodeStream::AUDIO_TRACK, static_cast<uint16_t>(aInput), static_cast<uint16_t>(aOutput)); } aDestination.NotifyInputsChanged(); // This connection may have connected a panner and a source. Context()->UpdatePannerSource(); }
void AudioNode::Disconnect(AudioNode& aDestination, uint32_t aOutput, uint32_t aInput, ErrorResult& aRv) { if (aOutput >= NumberOfOutputs()) { aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return; } if (aInput >= aDestination.NumberOfInputs()) { aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return; } bool wasConnected = false; for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) { if (mOutputNodes[outputIndex] != &aDestination) { continue; } wasConnected |= DisconnectMatchingDestinationInputs<AudioNode>( outputIndex, [aOutput, aInput](const InputNode& aInputNode) { return aInputNode.mOutputPort == aOutput && aInputNode.mInputPort == aInput; }); } if (!wasConnected) { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return; } // This disconnection may have disconnected a panner and a source. Context()->UpdatePannerSource(); }