15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010, Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if ENABLE(WEB_AUDIO)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioNodeInput.h"
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioContext.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioNodeOutput.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <algorithm>
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline AudioNodeInput::AudioNodeInput(AudioNode& node)
38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : AudioSummingJunction(node.context())
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_node(node)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Set to mono by default.
4281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_internalSummingBus = AudioBus::create(1, AudioNode::ProcessingSizeInFrames);
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)AudioNodeInput* AudioNodeInput::create(AudioNode& node)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return new AudioNodeInput(node);
48197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
4902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
50197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid AudioNodeInput::trace(Visitor* visitor)
51197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
52197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    visitor->trace(m_node);
53197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    AudioSummingJunction::trace(visitor);
54197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
55197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
56197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid AudioNodeInput::connect(AudioNodeOutput& output)
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(context()->isGraphOwner());
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Check if we're already connected to this output.
61197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (m_outputs.contains(&output))
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
64197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    output.addInput(*this);
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_outputs.add(&output);
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    changedOutputs();
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
69197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid AudioNodeInput::disconnect(AudioNodeOutput& output)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isGraphOwner());
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // First try to disconnect from "active" connections.
74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (m_outputs.contains(&output)) {
75197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_outputs.remove(&output);
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        changedOutputs();
77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        output.removeInput(*this);
78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Note: it's important to return immediately after removeInput() calls
79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // since the node may be deleted.
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Otherwise, try to disconnect from disabled connections.
84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (m_disabledOutputs.contains(&output)) {
85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_disabledOutputs.remove(&output);
86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        output.removeInput(*this);
87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // Note: it's important to return immediately after all removeInput() calls
88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // since the node may be deleted.
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
95197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid AudioNodeInput::disable(AudioNodeOutput& output)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isGraphOwner());
98197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(m_outputs.contains(&output));
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_disabledOutputs.add(&output);
101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_outputs.remove(&output);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    changedOutputs();
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Propagate disabled state to outputs.
105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    node().disableOutputsIfNecessary();
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
108197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid AudioNodeInput::enable(AudioNodeOutput& output)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isGraphOwner());
111197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(m_disabledOutputs.contains(&output));
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Move output from disabled list to active list.
114197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_outputs.add(&output);
115197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_disabledOutputs.remove(&output);
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    changedOutputs();
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Propagate enabled state to outputs.
119197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    node().enableOutputsIfNecessary();
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioNodeInput::didUpdate()
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    node().checkNumberOfChannelsForInput(this);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioNodeInput::updateInternalBus()
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isAudioThread() && context()->isGraphOwner());
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned numberOfInputChannels = numberOfChannels();
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (numberOfInputChannels == m_internalSummingBus->numberOfChannels())
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    m_internalSummingBus = AudioBus::create(numberOfInputChannels, AudioNode::ProcessingSizeInFrames);
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned AudioNodeInput::numberOfChannels() const
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    AudioNode::ChannelCountMode mode = node().internalChannelCountMode();
142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (mode == AudioNode::Explicit)
143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return node().channelCount();
144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Find the number of channels of the connection with the largest number of channels.
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned maxChannels = 1; // one channel is the minimum allowed
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (HashSet<AudioNodeOutput*>::iterator i = m_outputs.begin(); i != m_outputs.end(); ++i) {
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AudioNodeOutput* output = *i;
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Use output()->numberOfChannels() instead of output->bus()->numberOfChannels(),
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // because the calling of AudioNodeOutput::bus() is not safe here.
152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        maxChannels = std::max(maxChannels, output->numberOfChannels());
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (mode == AudioNode::ClampedMax)
156197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        maxChannels = std::min(maxChannels, static_cast<unsigned>(node().channelCount()));
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return maxChannels;
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)AudioBus* AudioNodeInput::bus()
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isAudioThread());
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle single connection specially to allow for in-place processing.
166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (numberOfRenderingConnections() == 1 && node().internalChannelCountMode() == AudioNode::Max)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return renderingOutput(0)->bus();
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Multiple connections case or complex ChannelCountMode (or no connections).
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return internalSummingBus();
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)AudioBus* AudioNodeInput::internalSummingBus()
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isAudioThread());
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_internalSummingBus.get();
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioNodeInput::sumAllConnections(AudioBus* summingBus, size_t framesToProcess)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isAudioThread());
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We shouldn't be calling this method if there's only one connection, since it's less efficient.
185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(numberOfRenderingConnections() > 1 || node().internalChannelCountMode() != AudioNode::Max);
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(summingBus);
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!summingBus)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
19002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    summingBus->zero();
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
193197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    AudioBus::ChannelInterpretation interpretation = node().internalChannelInterpretation();
194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < numberOfRenderingConnections(); ++i) {
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AudioNodeOutput* output = renderingOutput(i);
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(output);
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Render audio from this output.
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AudioBus* connectionBus = output->pull(0, framesToProcess);
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Sum, with unity-gain.
203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        summingBus->sumFrom(*connectionBus, interpretation);
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)AudioBus* AudioNodeInput::pull(AudioBus* inPlaceBus, size_t framesToProcess)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(context()->isAudioThread());
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle single connection case.
212197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (numberOfRenderingConnections() == 1 && node().internalChannelCountMode() == AudioNode::Max) {
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The output will optimize processing using inPlaceBus if it's able.
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        AudioNodeOutput* output = this->renderingOutput(0);
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return output->pull(inPlaceBus, framesToProcess);
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AudioBus* internalSummingBus = this->internalSummingBus();
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!numberOfRenderingConnections()) {
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // At least, generate silence if we're not connected to anything.
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: if we wanted to get fancy, we could propagate a 'silent hint' here to optimize the downstream graph processing.
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        internalSummingBus->zero();
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return internalSummingBus;
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle multiple connections case.
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    sumAllConnections(internalSummingBus, framesToProcess);
22902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return internalSummingBus;
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
233c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // ENABLE(WEB_AUDIO)
236