Home | History | Annotate | Download | only in audio
      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 "config.h"
     30 
     31 #if ENABLE(WEB_AUDIO)
     32 
     33 #include "ReverbAccumulationBuffer.h"
     34 
     35 #include "VectorMath.h"
     36 
     37 namespace WebCore {
     38 
     39 using namespace VectorMath;
     40 
     41 ReverbAccumulationBuffer::ReverbAccumulationBuffer(size_t length)
     42     : m_buffer(length)
     43     , m_readIndex(0)
     44     , m_readTimeFrame(0)
     45 {
     46 }
     47 
     48 void ReverbAccumulationBuffer::readAndClear(float* destination, size_t numberOfFrames)
     49 {
     50     size_t bufferLength = m_buffer.size();
     51     bool isCopySafe = m_readIndex <= bufferLength && numberOfFrames <= bufferLength;
     52 
     53     ASSERT(isCopySafe);
     54     if (!isCopySafe)
     55         return;
     56 
     57     size_t framesAvailable = bufferLength - m_readIndex;
     58     size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable);
     59     size_t numberOfFrames2 = numberOfFrames - numberOfFrames1;
     60 
     61     float* source = m_buffer.data();
     62     memcpy(destination, source + m_readIndex, sizeof(float) * numberOfFrames1);
     63     memset(source + m_readIndex, 0, sizeof(float) * numberOfFrames1);
     64 
     65     // Handle wrap-around if necessary
     66     if (numberOfFrames2 > 0) {
     67         memcpy(destination + numberOfFrames1, source, sizeof(float) * numberOfFrames2);
     68         memset(source, 0, sizeof(float) * numberOfFrames2);
     69     }
     70 
     71     m_readIndex = (m_readIndex + numberOfFrames) % bufferLength;
     72     m_readTimeFrame += numberOfFrames;
     73 }
     74 
     75 void ReverbAccumulationBuffer::updateReadIndex(int* readIndex, size_t numberOfFrames) const
     76 {
     77     // Update caller's readIndex
     78     *readIndex = (*readIndex + numberOfFrames) % m_buffer.size();
     79 }
     80 
     81 int ReverbAccumulationBuffer::accumulate(float* source, size_t numberOfFrames, int* readIndex, size_t delayFrames)
     82 {
     83     size_t bufferLength = m_buffer.size();
     84 
     85     size_t writeIndex = (*readIndex + delayFrames) % bufferLength;
     86 
     87     // Update caller's readIndex
     88     *readIndex = (*readIndex + numberOfFrames) % bufferLength;
     89 
     90     size_t framesAvailable = bufferLength - writeIndex;
     91     size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable);
     92     size_t numberOfFrames2 = numberOfFrames - numberOfFrames1;
     93 
     94     float* destination = m_buffer.data();
     95 
     96     bool isSafe = writeIndex <= bufferLength && numberOfFrames1 + writeIndex <= bufferLength && numberOfFrames2 <= bufferLength;
     97     ASSERT(isSafe);
     98     if (!isSafe)
     99         return 0;
    100 
    101     vadd(source, 1, destination + writeIndex, 1, destination + writeIndex, 1, numberOfFrames1);
    102 
    103     // Handle wrap-around if necessary
    104     if (numberOfFrames2 > 0)
    105         vadd(source + numberOfFrames1, 1, destination, 1, destination, 1, numberOfFrames2);
    106 
    107     return writeIndex;
    108 }
    109 
    110 void ReverbAccumulationBuffer::reset()
    111 {
    112     m_buffer.zero();
    113     m_readIndex = 0;
    114     m_readTimeFrame = 0;
    115 }
    116 
    117 } // namespace WebCore
    118 
    119 #endif // ENABLE(WEB_AUDIO)
    120