ReverbConvolverStage.cpp (3894B)
1 /* 2 * Copyright (C) 2010 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 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "ReverbConvolverStage.h" 30 31 #include "ReverbAccumulationBuffer.h" 32 #include "ReverbConvolver.h" 33 #include "ReverbInputBuffer.h" 34 35 using namespace mozilla; 36 37 namespace WebCore { 38 39 ReverbConvolverStage::ReverbConvolverStage( 40 const float* impulseResponse, size_t, size_t reverbTotalLatency, 41 size_t stageOffset, size_t stageLength, size_t fftSize, size_t renderPhase, 42 ReverbAccumulationBuffer* accumulationBuffer) 43 : m_accumulationBuffer(accumulationBuffer), 44 m_accumulationReadIndex(0), 45 m_inputReadIndex(0) { 46 MOZ_ASSERT(impulseResponse); 47 MOZ_ASSERT(accumulationBuffer); 48 49 m_fftKernel = MakeUnique<FFTBlock>(fftSize); 50 m_fftKernel->PadAndMakeScaledDFT(impulseResponse + stageOffset, stageLength); 51 m_fftConvolver = MakeUnique<FFTConvolver>(fftSize, renderPhase); 52 53 // The convolution stage at offset stageOffset needs to have a corresponding 54 // delay to cancel out the offset. 55 size_t totalDelay = stageOffset + reverbTotalLatency; 56 57 // But, the FFT convolution itself incurs latency, so subtract this out... 58 size_t fftLatency = m_fftConvolver->latencyFrames(); 59 MOZ_ASSERT(totalDelay >= fftLatency); 60 totalDelay -= fftLatency; 61 62 m_postDelayLength = totalDelay; 63 } 64 65 size_t ReverbConvolverStage::sizeOfIncludingThis( 66 mozilla::MallocSizeOf aMallocSizeOf) const { 67 size_t amount = aMallocSizeOf(this); 68 69 if (m_fftKernel) { 70 amount += m_fftKernel->SizeOfIncludingThis(aMallocSizeOf); 71 } 72 73 if (m_fftConvolver) { 74 amount += m_fftConvolver->sizeOfIncludingThis(aMallocSizeOf); 75 } 76 77 return amount; 78 } 79 80 void ReverbConvolverStage::processInBackground(ReverbConvolver* convolver) { 81 ReverbInputBuffer* inputBuffer = convolver->inputBuffer(); 82 float* source = 83 inputBuffer->directReadFrom(&m_inputReadIndex, WEBAUDIO_BLOCK_SIZE); 84 process(source); 85 } 86 87 void ReverbConvolverStage::process(const float* source) { 88 MOZ_ASSERT(source); 89 if (!source) return; 90 91 // Now, run the convolution (into the delay buffer). 92 // An expensive FFT will happen every fftSize / 2 frames. 93 const float* output = m_fftConvolver->process(m_fftKernel.get(), source); 94 95 // Now accumulate into reverb's accumulation buffer. 96 m_accumulationBuffer->accumulate(output, WEBAUDIO_BLOCK_SIZE, 97 &m_accumulationReadIndex, m_postDelayLength); 98 } 99 100 } // namespace WebCore