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/AudioBasicProcessorNode.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/audio/AudioBus.h" 321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/audio/AudioProcessor.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioContext.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioNodeInput.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/webaudio/AudioNodeOutput.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)AudioBasicProcessorNode::AudioBasicProcessorNode(AudioContext* context, float sampleRate) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : AudioNode(context, sampleRate) 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch addInput(); 43197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch addOutput(AudioNodeOutput::create(this, 1)); 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The subclass must create m_processor. 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)AudioBasicProcessorNode::~AudioBasicProcessorNode() 49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(!isInitialized()); 51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void AudioBasicProcessorNode::trace(Visitor* visitor) 54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) visitor->trace(m_processor); 56c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) AudioNode::trace(visitor); 57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void AudioBasicProcessorNode::dispose() 60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) uninitialize(); 62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) AudioNode::dispose(); 63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicProcessorNode::initialize() 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isInitialized()) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(processor()); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) processor()->initialize(); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioNode::initialize(); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicProcessorNode::uninitialize() 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInitialized()) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(processor()); 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) processor()->uninitialize(); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioNode::uninitialize(); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicProcessorNode::process(size_t framesToProcess) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioBus* destinationBus = output(0)->bus(); 9002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!isInitialized() || !processor() || processor()->numberOfChannels() != numberOfChannels()) 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationBus->zero(); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioBus* sourceBus = input(0)->bus(); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: if we take "tail time" into account, then we can avoid calling processor()->process() once the tail dies down. 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!input(0)->isConnected()) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sourceBus->zero(); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch processor()->process(sourceBus, destinationBus, framesToProcess); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Nice optimization in the very common case allowing for "in-place" processing 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicProcessorNode::pullInputs(size_t framesToProcess) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Render input stream - suggest to the input to render directly into output bus for in-place processing in process() if possible. 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) input(0)->pull(output(0)->bus(), framesToProcess); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// As soon as we know the channel count of our input, we can lazily initialize. 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Sometimes this may be called more than once with different channel counts, in which case we must safely 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// uninitialize and then re-initialize with the new channel count. 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioBasicProcessorNode::checkNumberOfChannelsForInput(AudioNodeInput* input) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(context()->isAudioThread() && context()->isGraphOwner()); 11702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(input == this->input(0)); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (input != this->input(0)) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(processor()); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!processor()) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned numberOfChannels = input->numberOfChannels(); 12702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isInitialized() && numberOfChannels != output(0)->numberOfChannels()) { 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We're already initialized but the channel count has changed. 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uninitialize(); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInitialized()) { 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This will propagate the channel count to any nodes connected further down the chain... 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output(0)->setNumberOfChannels(numberOfChannels); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Re-initialize the processor with the new channel count. 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) processor()->setNumberOfChannels(numberOfChannels); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) initialize(); 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AudioNode::checkNumberOfChannelsForInput(input); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned AudioBasicProcessorNode::numberOfChannels() 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return output(0)->numberOfChannels(); 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double AudioBasicProcessorNode::tailTime() const 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_processor->tailTime(); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double AudioBasicProcessorNode::latencyTime() const 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_processor->latencyTime(); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 160c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // ENABLE(WEB_AUDIO) 163