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 are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if ENABLE(WEB_AUDIO) 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/audio/AudioDSPKernelProcessor.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/audio/AudioDSPKernel.h" 388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "wtf/MainThread.h" 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// setNumberOfChannels() may later be called if the object is not yet in an "initialized" state. 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)AudioDSPKernelProcessor::AudioDSPKernelProcessor(float sampleRate, unsigned numberOfChannels) 44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : AudioProcessor(sampleRate, numberOfChannels) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_hasJustReset(true) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)AudioDSPKernelProcessor::~AudioDSPKernelProcessor() 50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioDSPKernelProcessor::initialize() 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isInitialized()) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MutexLocker locker(m_processLock); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_kernels.size()); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Create processing kernels, one per channel. 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < numberOfChannels(); ++i) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_kernels.append(createKernel()); 6402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_initialized = true; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasJustReset = true; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioDSPKernelProcessor::uninitialize() 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInitialized()) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 7302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MutexLocker locker(m_processLock); 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_kernels.clear(); 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_initialized = false; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioDSPKernelProcessor::process(const AudioBus* source, AudioBus* destination, size_t framesToProcess) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(source && destination); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!source || !destination) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 8502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInitialized()) { 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destination->zero(); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MutexTryLocker tryLocker(m_processLock); 928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (tryLocker.locked()) { 938abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) bool channelCountMatches = source->numberOfChannels() == destination->numberOfChannels() && source->numberOfChannels() == m_kernels.size(); 948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(channelCountMatches); 958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (!channelCountMatches) 968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return; 978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 988abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) for (unsigned i = 0; i < m_kernels.size(); ++i) 998abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) m_kernels[i]->process(source->channel(i)->data(), destination->channel(i)->mutableData(), framesToProcess); 1008abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } else { 1018abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Unfortunately, the kernel is being processed by another thread. 1028abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // See also ConvolverNode::process(). 1038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) destination->zero(); 1048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Resets filter state 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioDSPKernelProcessor::reset() 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(isMainThread()); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInitialized()) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Forces snap to parameter values - first time. 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Any processing depending on this value must set it to false at the appropriate time. 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_hasJustReset = true; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1188abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MutexLocker locker(m_processLock); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < m_kernels.size(); ++i) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_kernels[i]->reset(); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void AudioDSPKernelProcessor::setNumberOfChannels(unsigned numberOfChannels) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (numberOfChannels == m_numberOfChannels) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 12702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!isInitialized()); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isInitialized()) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_numberOfChannels = numberOfChannels; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double AudioDSPKernelProcessor::tailTime() const 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(!isMainThread()); 1368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MutexTryLocker tryLocker(m_processLock); 1378abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (tryLocker.locked()) { 1388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // It is expected that all the kernels have the same tailTime. 1398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return !m_kernels.isEmpty() ? m_kernels.first()->tailTime() : 0; 1408abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } 1418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Since we don't want to block the Audio Device thread, we return a large value 1428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // instead of trying to acquire the lock. 1438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return std::numeric_limits<double>::infinity(); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double AudioDSPKernelProcessor::latencyTime() const 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1488abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ASSERT(!isMainThread()); 1498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) MutexTryLocker tryLocker(m_processLock); 1508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (tryLocker.locked()) { 1518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // It is expected that all the kernels have the same latencyTime. 1528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return !m_kernels.isEmpty() ? m_kernels.first()->latencyTime() : 0; 1538abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) } 1548abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Since we don't want to block the Audio Device thread, we return a large value 1558abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // instead of trying to acquire the lock. 1568abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return std::numeric_limits<double>::infinity(); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 159c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // ENABLE(WEB_AUDIO) 162