1 /* 2 * Copyright (C) 2011, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #include "config.h" 26 27 #if ENABLE(WEB_AUDIO) 28 29 #include "modules/webaudio/WaveShaperProcessor.h" 30 31 #include "modules/webaudio/WaveShaperDSPKernel.h" 32 33 namespace blink { 34 35 WaveShaperProcessor::WaveShaperProcessor(float sampleRate, size_t numberOfChannels) 36 : AudioDSPKernelProcessor(sampleRate, numberOfChannels) 37 , m_oversample(OverSampleNone) 38 { 39 } 40 41 WaveShaperProcessor::~WaveShaperProcessor() 42 { 43 if (isInitialized()) 44 uninitialize(); 45 } 46 47 PassOwnPtr<AudioDSPKernel> WaveShaperProcessor::createKernel() 48 { 49 return adoptPtr(new WaveShaperDSPKernel(this)); 50 } 51 52 void WaveShaperProcessor::setCurve(Float32Array* curve) 53 { 54 // This synchronizes with process(). 55 MutexLocker processLocker(m_processLock); 56 57 m_curve = curve; 58 } 59 60 void WaveShaperProcessor::setOversample(OverSampleType oversample) 61 { 62 // This synchronizes with process(). 63 MutexLocker processLocker(m_processLock); 64 65 m_oversample = oversample; 66 67 if (oversample != OverSampleNone) { 68 for (unsigned i = 0; i < m_kernels.size(); ++i) { 69 WaveShaperDSPKernel* kernel = static_cast<WaveShaperDSPKernel*>(m_kernels[i].get()); 70 kernel->lazyInitializeOversampling(); 71 } 72 } 73 } 74 75 void WaveShaperProcessor::process(const AudioBus* source, AudioBus* destination, size_t framesToProcess) 76 { 77 if (!isInitialized()) { 78 destination->zero(); 79 return; 80 } 81 82 bool channelCountMatches = source->numberOfChannels() == destination->numberOfChannels() && source->numberOfChannels() == m_kernels.size(); 83 ASSERT(channelCountMatches); 84 if (!channelCountMatches) 85 return; 86 87 // The audio thread can't block on this lock, so we call tryLock() instead. 88 MutexTryLocker tryLocker(m_processLock); 89 if (tryLocker.locked()) { 90 // For each channel of our input, process using the corresponding WaveShaperDSPKernel into the output channel. 91 for (unsigned i = 0; i < m_kernels.size(); ++i) 92 m_kernels[i]->process(source->channel(i)->data(), destination->channel(i)->mutableData(), framesToProcess); 93 } else { 94 // Too bad - the tryLock() failed. We must be in the middle of a setCurve() call. 95 destination->zero(); 96 } 97 } 98 99 } // namespace blink 100 101 #endif // ENABLE(WEB_AUDIO) 102