15ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen/* 25ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * Copyright (C) 2010 Google Inc. All rights reserved. 35ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * 45ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * Redistribution and use in source and binary forms, with or without 55ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * modification, are permitted provided that the following conditions 65ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * are met: 75ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * 85ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * 1. Redistributions of source code must retain the above copyright 95ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * notice, this list of conditions and the following disclaimer. 105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * 2. Redistributions in binary form must reproduce the above copyright 115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * notice, this list of conditions and the following disclaimer in the 125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * documentation and/or other materials provided with the distribution. 135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * its contributors may be used to endorse or promote products derived 155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * from this software without specific prior written permission. 165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * 175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen */ 285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "config.h" 305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if ENABLE(WEB_AUDIO) 325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "ReverbAccumulationBuffer.h" 345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 35e14391e94c850b8bd03680c23b38978db68687a8John Reck#include "VectorMath.h" 365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsennamespace WebCore { 385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 39e14391e94c850b8bd03680c23b38978db68687a8John Reckusing namespace VectorMath; 40e14391e94c850b8bd03680c23b38978db68687a8John Reck 415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenReverbAccumulationBuffer::ReverbAccumulationBuffer(size_t length) 425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen : m_buffer(length) 435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen , m_readIndex(0) 445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen , m_readTimeFrame(0) 455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid ReverbAccumulationBuffer::readAndClear(float* destination, size_t numberOfFrames) 495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t bufferLength = m_buffer.size(); 515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen bool isCopySafe = m_readIndex <= bufferLength && numberOfFrames <= bufferLength; 525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen ASSERT(isCopySafe); 545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!isCopySafe) 555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return; 565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t framesAvailable = bufferLength - m_readIndex; 585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable); 595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t numberOfFrames2 = numberOfFrames - numberOfFrames1; 605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen float* source = m_buffer.data(); 625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen memcpy(destination, source + m_readIndex, sizeof(float) * numberOfFrames1); 635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen memset(source + m_readIndex, 0, sizeof(float) * numberOfFrames1); 645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Handle wrap-around if necessary 665ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (numberOfFrames2 > 0) { 675ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen memcpy(destination + numberOfFrames1, source, sizeof(float) * numberOfFrames2); 685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen memset(source, 0, sizeof(float) * numberOfFrames2); 695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_readIndex = (m_readIndex + numberOfFrames) % bufferLength; 725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_readTimeFrame += numberOfFrames; 735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 755ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid ReverbAccumulationBuffer::updateReadIndex(int* readIndex, size_t numberOfFrames) const 765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Update caller's readIndex 785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *readIndex = (*readIndex + numberOfFrames) % m_buffer.size(); 795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenint ReverbAccumulationBuffer::accumulate(float* source, size_t numberOfFrames, int* readIndex, size_t delayFrames) 825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t bufferLength = m_buffer.size(); 845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t writeIndex = (*readIndex + delayFrames) % bufferLength; 865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 875ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Update caller's readIndex 885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *readIndex = (*readIndex + numberOfFrames) % bufferLength; 895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t framesAvailable = bufferLength - writeIndex; 915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable); 925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen size_t numberOfFrames2 = numberOfFrames - numberOfFrames1; 935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen float* destination = m_buffer.data(); 955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen bool isSafe = writeIndex <= bufferLength && numberOfFrames1 + writeIndex <= bufferLength && numberOfFrames2 <= bufferLength; 975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen ASSERT(isSafe); 985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (!isSafe) 995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return 0; 1005ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen vadd(source, 1, destination + writeIndex, 1, destination + writeIndex, 1, numberOfFrames1); 1025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Handle wrap-around if necessary 1045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (numberOfFrames2 > 0) 1055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen vadd(source + numberOfFrames1, 1, destination, 1, destination, 1, numberOfFrames2); 1065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen return writeIndex; 1085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid ReverbAccumulationBuffer::reset() 1115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_buffer.zero(); 1135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_readIndex = 0; 1145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen m_readTimeFrame = 0; 1155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} // namespace WebCore 1185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif // ENABLE(WEB_AUDIO) 120