2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
33 #include "platform/audio/HRTFDatabase.h"
37 const int HRTFDatabase::MinElevation
= -45;
38 const int HRTFDatabase::MaxElevation
= 90;
39 const unsigned HRTFDatabase::RawElevationAngleSpacing
= 15;
40 const unsigned HRTFDatabase::NumberOfRawElevations
= 10; // -45 -> +90 (each 15 degrees)
41 const unsigned HRTFDatabase::InterpolationFactor
= 1;
42 const unsigned HRTFDatabase::NumberOfTotalElevations
= NumberOfRawElevations
* InterpolationFactor
;
44 PassOwnPtr
<HRTFDatabase
> HRTFDatabase::create(float sampleRate
)
46 OwnPtr
<HRTFDatabase
> hrtfDatabase
= adoptPtr(new HRTFDatabase(sampleRate
));
47 return hrtfDatabase
.release();
50 HRTFDatabase::HRTFDatabase(float sampleRate
)
51 : m_elevations(NumberOfTotalElevations
)
52 , m_sampleRate(sampleRate
)
54 unsigned elevationIndex
= 0;
55 for (int elevation
= MinElevation
; elevation
<= MaxElevation
; elevation
+= RawElevationAngleSpacing
) {
56 OwnPtr
<HRTFElevation
> hrtfElevation
= HRTFElevation::createForSubject("Composite", elevation
, sampleRate
);
57 ASSERT(hrtfElevation
.get());
58 if (!hrtfElevation
.get())
61 m_elevations
[elevationIndex
] = hrtfElevation
.release();
62 elevationIndex
+= InterpolationFactor
;
65 // Now, go back and interpolate elevations.
66 if (InterpolationFactor
> 1) {
67 for (unsigned i
= 0; i
< NumberOfTotalElevations
; i
+= InterpolationFactor
) {
68 unsigned j
= (i
+ InterpolationFactor
);
69 if (j
>= NumberOfTotalElevations
)
70 j
= i
; // for last elevation interpolate with itself
72 // Create the interpolated convolution kernels and delays.
73 for (unsigned jj
= 1; jj
< InterpolationFactor
; ++jj
) {
74 float x
= static_cast<float>(jj
) / static_cast<float>(InterpolationFactor
);
75 m_elevations
[i
+ jj
] = HRTFElevation::createByInterpolatingSlices(m_elevations
[i
].get(), m_elevations
[j
].get(), x
, sampleRate
);
76 ASSERT(m_elevations
[i
+ jj
].get());
82 void HRTFDatabase::getKernelsFromAzimuthElevation(double azimuthBlend
, unsigned azimuthIndex
, double elevationAngle
, HRTFKernel
* &kernelL
, HRTFKernel
* &kernelR
,
83 double& frameDelayL
, double& frameDelayR
)
85 unsigned elevationIndex
= indexFromElevationAngle(elevationAngle
);
86 ASSERT_WITH_SECURITY_IMPLICATION(elevationIndex
< m_elevations
.size() && m_elevations
.size() > 0);
88 if (!m_elevations
.size()) {
94 if (elevationIndex
> m_elevations
.size() - 1)
95 elevationIndex
= m_elevations
.size() - 1;
97 HRTFElevation
* hrtfElevation
= m_elevations
[elevationIndex
].get();
98 ASSERT(hrtfElevation
);
105 hrtfElevation
->getKernelsFromAzimuth(azimuthBlend
, azimuthIndex
, kernelL
, kernelR
, frameDelayL
, frameDelayR
);
108 unsigned HRTFDatabase::indexFromElevationAngle(double elevationAngle
)
110 // Clamp to allowed range.
111 elevationAngle
= std::max(static_cast<double>(MinElevation
), elevationAngle
);
112 elevationAngle
= std::min(static_cast<double>(MaxElevation
), elevationAngle
);
114 unsigned elevationIndex
= static_cast<int>(InterpolationFactor
* (elevationAngle
- MinElevation
) / RawElevationAngleSpacing
);
115 return elevationIndex
;
120 #endif // ENABLE(WEB_AUDIO)