content/media/webaudio/blink/HRTFDatabase.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * Copyright (C) 2010 Google Inc. All rights reserved.
michael@0 3 *
michael@0 4 * Redistribution and use in source and binary forms, with or without
michael@0 5 * modification, are permitted provided that the following conditions
michael@0 6 * are met:
michael@0 7 *
michael@0 8 * 1. Redistributions of source code must retain the above copyright
michael@0 9 * notice, this list of conditions and the following disclaimer.
michael@0 10 * 2. Redistributions in binary form must reproduce the above copyright
michael@0 11 * notice, this list of conditions and the following disclaimer in the
michael@0 12 * documentation and/or other materials provided with the distribution.
michael@0 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
michael@0 14 * its contributors may be used to endorse or promote products derived
michael@0 15 * from this software without specific prior written permission.
michael@0 16 *
michael@0 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
michael@0 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
michael@0 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
michael@0 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
michael@0 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
michael@0 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
michael@0 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
michael@0 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
michael@0 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 27 */
michael@0 28
michael@0 29 #include "HRTFDatabase.h"
michael@0 30
michael@0 31 #include "HRTFElevation.h"
michael@0 32
michael@0 33 using namespace std;
michael@0 34
michael@0 35 namespace WebCore {
michael@0 36
michael@0 37 const int HRTFDatabase::MinElevation = -45;
michael@0 38 const int HRTFDatabase::MaxElevation = 90;
michael@0 39 const unsigned HRTFDatabase::RawElevationAngleSpacing = 15;
michael@0 40 const unsigned HRTFDatabase::NumberOfRawElevations = 10; // -45 -> +90 (each 15 degrees)
michael@0 41 const unsigned HRTFDatabase::InterpolationFactor = 1;
michael@0 42 const unsigned HRTFDatabase::NumberOfTotalElevations = NumberOfRawElevations * InterpolationFactor;
michael@0 43
michael@0 44 nsReturnRef<HRTFDatabase> HRTFDatabase::create(float sampleRate)
michael@0 45 {
michael@0 46 return nsReturnRef<HRTFDatabase>(new HRTFDatabase(sampleRate));
michael@0 47 }
michael@0 48
michael@0 49 HRTFDatabase::HRTFDatabase(float sampleRate)
michael@0 50 : m_sampleRate(sampleRate)
michael@0 51 {
michael@0 52 m_elevations.SetLength(NumberOfTotalElevations);
michael@0 53
michael@0 54 unsigned elevationIndex = 0;
michael@0 55 for (int elevation = MinElevation; elevation <= MaxElevation; elevation += RawElevationAngleSpacing) {
michael@0 56 nsAutoRef<HRTFElevation> hrtfElevation(HRTFElevation::createBuiltin(elevation, sampleRate));
michael@0 57 MOZ_ASSERT(hrtfElevation.get());
michael@0 58 if (!hrtfElevation.get())
michael@0 59 return;
michael@0 60
michael@0 61 m_elevations[elevationIndex] = hrtfElevation.out();
michael@0 62 elevationIndex += InterpolationFactor;
michael@0 63 }
michael@0 64
michael@0 65 // Now, go back and interpolate elevations.
michael@0 66 if (InterpolationFactor > 1) {
michael@0 67 for (unsigned i = 0; i < NumberOfTotalElevations; i += InterpolationFactor) {
michael@0 68 unsigned j = (i + InterpolationFactor);
michael@0 69 if (j >= NumberOfTotalElevations)
michael@0 70 j = i; // for last elevation interpolate with itself
michael@0 71
michael@0 72 // Create the interpolated convolution kernels and delays.
michael@0 73 for (unsigned jj = 1; jj < InterpolationFactor; ++jj) {
michael@0 74 float x = static_cast<float>(jj) / static_cast<float>(InterpolationFactor);
michael@0 75 m_elevations[i + jj] = HRTFElevation::createByInterpolatingSlices(m_elevations[i].get(), m_elevations[j].get(), x, sampleRate);
michael@0 76 MOZ_ASSERT(m_elevations[i + jj].get());
michael@0 77 }
michael@0 78 }
michael@0 79 }
michael@0 80 }
michael@0 81
michael@0 82 size_t HRTFDatabase::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
michael@0 83 {
michael@0 84 size_t amount = aMallocSizeOf(this);
michael@0 85 amount += m_elevations.SizeOfExcludingThis(aMallocSizeOf);
michael@0 86 for (size_t i = 0; i < m_elevations.Length(); i++) {
michael@0 87 amount += m_elevations[i]->sizeOfIncludingThis(aMallocSizeOf);
michael@0 88 }
michael@0 89
michael@0 90 return amount;
michael@0 91 }
michael@0 92
michael@0 93 void HRTFDatabase::getKernelsFromAzimuthElevation(double azimuthBlend, unsigned azimuthIndex, double elevationAngle, HRTFKernel* &kernelL, HRTFKernel* &kernelR,
michael@0 94 double& frameDelayL, double& frameDelayR)
michael@0 95 {
michael@0 96 unsigned elevationIndex = indexFromElevationAngle(elevationAngle);
michael@0 97 MOZ_ASSERT(elevationIndex < m_elevations.Length() && m_elevations.Length() > 0);
michael@0 98
michael@0 99 if (!m_elevations.Length()) {
michael@0 100 kernelL = 0;
michael@0 101 kernelR = 0;
michael@0 102 return;
michael@0 103 }
michael@0 104
michael@0 105 if (elevationIndex > m_elevations.Length() - 1)
michael@0 106 elevationIndex = m_elevations.Length() - 1;
michael@0 107
michael@0 108 HRTFElevation* hrtfElevation = m_elevations[elevationIndex].get();
michael@0 109 MOZ_ASSERT(hrtfElevation);
michael@0 110 if (!hrtfElevation) {
michael@0 111 kernelL = 0;
michael@0 112 kernelR = 0;
michael@0 113 return;
michael@0 114 }
michael@0 115
michael@0 116 hrtfElevation->getKernelsFromAzimuth(azimuthBlend, azimuthIndex, kernelL, kernelR, frameDelayL, frameDelayR);
michael@0 117 }
michael@0 118
michael@0 119 unsigned HRTFDatabase::indexFromElevationAngle(double elevationAngle)
michael@0 120 {
michael@0 121 // Clamp to allowed range.
michael@0 122 elevationAngle = mozilla::clamped(elevationAngle,
michael@0 123 static_cast<double>(MinElevation),
michael@0 124 static_cast<double>(MaxElevation));
michael@0 125
michael@0 126 unsigned elevationIndex = static_cast<int>(InterpolationFactor * (elevationAngle - MinElevation) / RawElevationAngleSpacing);
michael@0 127 return elevationIndex;
michael@0 128 }
michael@0 129
michael@0 130 } // namespace WebCore

mercurial