15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012, Intel Corporation. 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/AudioBasicInspectorNode.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioContext.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioNodeInput.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioNodeOutput.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)AudioBasicInspectorNode::AudioBasicInspectorNode(AudioContext* context, float sampleRate, unsigned outputChannelCount) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : AudioNode(context, sampleRate) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_needAutomaticPull(false) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch addInput(); 42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch addOutput(AudioNodeOutput::create(this, outputChannelCount)); 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// We override pullInputs() as an optimization allowing this node to take advantage of in-place processing, 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// where the input is simply passed through unprocessed to the output. 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Note: this only applies if the input and output channel counts match. 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicInspectorNode::pullInputs(size_t framesToProcess) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Render input stream - try to render directly into output bus for pass-through processing where process() doesn't need to do anything... 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) input(0)->pull(output(0)->bus(), framesToProcess); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void AudioBasicInspectorNode::connect(AudioNode* destination, unsigned outputIndex, unsigned inputIndex, ExceptionState& exceptionState) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioContext::AutoLocker locker(context()); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) AudioNode::connect(destination, outputIndex, inputIndex, exceptionState); 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updatePullStatus(); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void AudioBasicInspectorNode::disconnect(unsigned outputIndex, ExceptionState& exceptionState) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioContext::AutoLocker locker(context()); 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) AudioNode::disconnect(outputIndex, exceptionState); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updatePullStatus(); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicInspectorNode::checkNumberOfChannelsForInput(AudioNodeInput* input) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(context()->isAudioThread() && context()->isGraphOwner()); 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(input == this->input(0)); 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (input != this->input(0)) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned numberOfChannels = input->numberOfChannels(); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (numberOfChannels != output(0)->numberOfChannels()) { 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This will propagate the channel count to any nodes connected further downstream in the graph. 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output(0)->setNumberOfChannels(numberOfChannels); 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioNode::checkNumberOfChannelsForInput(input); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updatePullStatus(); 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicInspectorNode::updatePullStatus() 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(context()->isGraphOwner()); 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (output(0)->isConnected()) { 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // When an AudioBasicInspectorNode is connected to a downstream node, it will get pulled by the 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // downstream node, thus remove it from the context's automatic pull list. 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_needAutomaticPull) { 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context()->removeAutomaticPullNode(this); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needAutomaticPull = false; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned numberOfInputConnections = input(0)->numberOfRenderingConnections(); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (numberOfInputConnections && !m_needAutomaticPull) { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // When an AudioBasicInspectorNode is not connected to any downstream node while still connected from 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // upstream node(s), add it to the context's automatic pull list. 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context()->addAutomaticPullNode(this); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needAutomaticPull = true; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (!numberOfInputConnections && m_needAutomaticPull) { 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The AudioBasicInspectorNode is connected to nothing, remove it from the context's automatic pull list. 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context()->removeAutomaticPullNode(this); 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_needAutomaticPull = false; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // ENABLE(WEB_AUDIO) 123