1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/webaudio/blink/HRTFDatabase.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,130 @@ 1.4 +/* 1.5 + * Copyright (C) 2010 Google Inc. All rights reserved. 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions 1.9 + * are met: 1.10 + * 1.11 + * 1. Redistributions of source code must retain the above copyright 1.12 + * notice, this list of conditions and the following disclaimer. 1.13 + * 2. Redistributions in binary form must reproduce the above copyright 1.14 + * notice, this list of conditions and the following disclaimer in the 1.15 + * documentation and/or other materials provided with the distribution. 1.16 + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 1.17 + * its contributors may be used to endorse or promote products derived 1.18 + * from this software without specific prior written permission. 1.19 + * 1.20 + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 1.21 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1.22 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1.23 + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 1.24 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 1.25 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 1.26 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 1.27 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.28 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.29 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.30 + */ 1.31 + 1.32 +#include "HRTFDatabase.h" 1.33 + 1.34 +#include "HRTFElevation.h" 1.35 + 1.36 +using namespace std; 1.37 + 1.38 +namespace WebCore { 1.39 + 1.40 +const int HRTFDatabase::MinElevation = -45; 1.41 +const int HRTFDatabase::MaxElevation = 90; 1.42 +const unsigned HRTFDatabase::RawElevationAngleSpacing = 15; 1.43 +const unsigned HRTFDatabase::NumberOfRawElevations = 10; // -45 -> +90 (each 15 degrees) 1.44 +const unsigned HRTFDatabase::InterpolationFactor = 1; 1.45 +const unsigned HRTFDatabase::NumberOfTotalElevations = NumberOfRawElevations * InterpolationFactor; 1.46 + 1.47 +nsReturnRef<HRTFDatabase> HRTFDatabase::create(float sampleRate) 1.48 +{ 1.49 + return nsReturnRef<HRTFDatabase>(new HRTFDatabase(sampleRate)); 1.50 +} 1.51 + 1.52 +HRTFDatabase::HRTFDatabase(float sampleRate) 1.53 + : m_sampleRate(sampleRate) 1.54 +{ 1.55 + m_elevations.SetLength(NumberOfTotalElevations); 1.56 + 1.57 + unsigned elevationIndex = 0; 1.58 + for (int elevation = MinElevation; elevation <= MaxElevation; elevation += RawElevationAngleSpacing) { 1.59 + nsAutoRef<HRTFElevation> hrtfElevation(HRTFElevation::createBuiltin(elevation, sampleRate)); 1.60 + MOZ_ASSERT(hrtfElevation.get()); 1.61 + if (!hrtfElevation.get()) 1.62 + return; 1.63 + 1.64 + m_elevations[elevationIndex] = hrtfElevation.out(); 1.65 + elevationIndex += InterpolationFactor; 1.66 + } 1.67 + 1.68 + // Now, go back and interpolate elevations. 1.69 + if (InterpolationFactor > 1) { 1.70 + for (unsigned i = 0; i < NumberOfTotalElevations; i += InterpolationFactor) { 1.71 + unsigned j = (i + InterpolationFactor); 1.72 + if (j >= NumberOfTotalElevations) 1.73 + j = i; // for last elevation interpolate with itself 1.74 + 1.75 + // Create the interpolated convolution kernels and delays. 1.76 + for (unsigned jj = 1; jj < InterpolationFactor; ++jj) { 1.77 + float x = static_cast<float>(jj) / static_cast<float>(InterpolationFactor); 1.78 + m_elevations[i + jj] = HRTFElevation::createByInterpolatingSlices(m_elevations[i].get(), m_elevations[j].get(), x, sampleRate); 1.79 + MOZ_ASSERT(m_elevations[i + jj].get()); 1.80 + } 1.81 + } 1.82 + } 1.83 +} 1.84 + 1.85 +size_t HRTFDatabase::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const 1.86 +{ 1.87 + size_t amount = aMallocSizeOf(this); 1.88 + amount += m_elevations.SizeOfExcludingThis(aMallocSizeOf); 1.89 + for (size_t i = 0; i < m_elevations.Length(); i++) { 1.90 + amount += m_elevations[i]->sizeOfIncludingThis(aMallocSizeOf); 1.91 + } 1.92 + 1.93 + return amount; 1.94 +} 1.95 + 1.96 +void HRTFDatabase::getKernelsFromAzimuthElevation(double azimuthBlend, unsigned azimuthIndex, double elevationAngle, HRTFKernel* &kernelL, HRTFKernel* &kernelR, 1.97 + double& frameDelayL, double& frameDelayR) 1.98 +{ 1.99 + unsigned elevationIndex = indexFromElevationAngle(elevationAngle); 1.100 + MOZ_ASSERT(elevationIndex < m_elevations.Length() && m_elevations.Length() > 0); 1.101 + 1.102 + if (!m_elevations.Length()) { 1.103 + kernelL = 0; 1.104 + kernelR = 0; 1.105 + return; 1.106 + } 1.107 + 1.108 + if (elevationIndex > m_elevations.Length() - 1) 1.109 + elevationIndex = m_elevations.Length() - 1; 1.110 + 1.111 + HRTFElevation* hrtfElevation = m_elevations[elevationIndex].get(); 1.112 + MOZ_ASSERT(hrtfElevation); 1.113 + if (!hrtfElevation) { 1.114 + kernelL = 0; 1.115 + kernelR = 0; 1.116 + return; 1.117 + } 1.118 + 1.119 + hrtfElevation->getKernelsFromAzimuth(azimuthBlend, azimuthIndex, kernelL, kernelR, frameDelayL, frameDelayR); 1.120 +} 1.121 + 1.122 +unsigned HRTFDatabase::indexFromElevationAngle(double elevationAngle) 1.123 +{ 1.124 + // Clamp to allowed range. 1.125 + elevationAngle = mozilla::clamped(elevationAngle, 1.126 + static_cast<double>(MinElevation), 1.127 + static_cast<double>(MaxElevation)); 1.128 + 1.129 + unsigned elevationIndex = static_cast<int>(InterpolationFactor * (elevationAngle - MinElevation) / RawElevationAngleSpacing); 1.130 + return elevationIndex; 1.131 +} 1.132 + 1.133 +} // namespace WebCore