content/media/webaudio/blink/FFTConvolver.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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  */
    29 #include "FFTConvolver.h"
    30 #include "mozilla/PodOperations.h"
    32 using namespace mozilla;
    34 namespace WebCore {
    36 FFTConvolver::FFTConvolver(size_t fftSize)
    37     : m_frame(fftSize)
    38     , m_readWriteIndex(0)
    39 {
    40   m_inputBuffer.SetLength(fftSize);
    41   PodZero(m_inputBuffer.Elements(), fftSize);
    42   m_outputBuffer.SetLength(fftSize);
    43   PodZero(m_outputBuffer.Elements(), fftSize);
    44   m_lastOverlapBuffer.SetLength(fftSize / 2);
    45   PodZero(m_lastOverlapBuffer.Elements(), fftSize / 2);
    46 }
    48 size_t FFTConvolver::sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
    49 {
    50     size_t amount = 0;
    51     amount += m_frame.SizeOfExcludingThis(aMallocSizeOf);
    52     amount += m_inputBuffer.SizeOfExcludingThis(aMallocSizeOf);
    53     amount += m_outputBuffer.SizeOfExcludingThis(aMallocSizeOf);
    54     amount += m_lastOverlapBuffer.SizeOfExcludingThis(aMallocSizeOf);
    55     return amount;
    56 }
    58 size_t FFTConvolver::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
    59 {
    60   return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf);
    61 }
    63 void FFTConvolver::process(FFTBlock* fftKernel, const float* sourceP, float* destP, size_t framesToProcess)
    64 {
    65     size_t halfSize = fftSize() / 2;
    67     // framesToProcess must be an exact multiple of halfSize,
    68     // or halfSize is a multiple of framesToProcess when halfSize > framesToProcess.
    69     bool isGood = !(halfSize % framesToProcess && framesToProcess % halfSize);
    70     MOZ_ASSERT(isGood);
    71     if (!isGood)
    72         return;
    74     size_t numberOfDivisions = halfSize <= framesToProcess ? (framesToProcess / halfSize) : 1;
    75     size_t divisionSize = numberOfDivisions == 1 ? framesToProcess : halfSize;
    77     for (size_t i = 0; i < numberOfDivisions; ++i, sourceP += divisionSize, destP += divisionSize) {
    78         // Copy samples to input buffer (note contraint above!)
    79         float* inputP = m_inputBuffer.Elements();
    81         // Sanity check
    82         bool isCopyGood1 = sourceP && inputP && m_readWriteIndex + divisionSize <= m_inputBuffer.Length();
    83         MOZ_ASSERT(isCopyGood1);
    84         if (!isCopyGood1)
    85             return;
    87         memcpy(inputP + m_readWriteIndex, sourceP, sizeof(float) * divisionSize);
    89         // Copy samples from output buffer
    90         float* outputP = m_outputBuffer.Elements();
    92         // Sanity check
    93         bool isCopyGood2 = destP && outputP && m_readWriteIndex + divisionSize <= m_outputBuffer.Length();
    94         MOZ_ASSERT(isCopyGood2);
    95         if (!isCopyGood2)
    96             return;
    98         memcpy(destP, outputP + m_readWriteIndex, sizeof(float) * divisionSize);
    99         m_readWriteIndex += divisionSize;
   101         // Check if it's time to perform the next FFT
   102         if (m_readWriteIndex == halfSize) {
   103             // The input buffer is now filled (get frequency-domain version)
   104             m_frame.PerformFFT(m_inputBuffer.Elements());
   105             m_frame.Multiply(*fftKernel);
   106             m_frame.GetInverseWithoutScaling(m_outputBuffer.Elements());
   108             // Overlap-add 1st half from previous time
   109             AudioBufferAddWithScale(m_lastOverlapBuffer.Elements(), 1.0f,
   110                                     m_outputBuffer.Elements(), halfSize);
   112             // Finally, save 2nd half of result
   113             bool isCopyGood3 = m_outputBuffer.Length() == 2 * halfSize && m_lastOverlapBuffer.Length() == halfSize;
   114             MOZ_ASSERT(isCopyGood3);
   115             if (!isCopyGood3)
   116                 return;
   118             memcpy(m_lastOverlapBuffer.Elements(), m_outputBuffer.Elements() + halfSize, sizeof(float) * halfSize);
   120             // Reset index back to start for next time
   121             m_readWriteIndex = 0;
   122         }
   123     }
   124 }
   126 void FFTConvolver::reset()
   127 {
   128     PodZero(m_lastOverlapBuffer.Elements(), m_lastOverlapBuffer.Length());
   129     m_readWriteIndex = 0;
   130 }
   132 } // namespace WebCore

mercurial