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 "third_party/blink/renderer/platform/audio/distance_effect.h"
30 
31 #include <math.h>
32 #include <algorithm>
33 #include "third_party/blink/renderer/platform/wtf/assertions.h"
34 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
35 
36 namespace blink {
37 
DistanceEffect()38 DistanceEffect::DistanceEffect()
39     : model_(kModelInverse),
40       ref_distance_(1.0),
41       max_distance_(10000.0),
42       rolloff_factor_(1.0) {}
43 
Gain(double distance)44 double DistanceEffect::Gain(double distance) {
45   switch (model_) {
46     case kModelLinear:
47       return LinearGain(distance);
48     case kModelInverse:
49       return InverseGain(distance);
50     case kModelExponential:
51       return ExponentialGain(distance);
52   }
53   NOTREACHED();
54   return 0.0;
55 }
56 
LinearGain(double distance)57 double DistanceEffect::LinearGain(double distance) {
58   // Clamp refDistance and distance according to the spec.
59   double dref = std::min(ref_distance_, max_distance_);
60   double dmax = std::max(ref_distance_, max_distance_);
61   distance = clampTo(distance, dref, dmax);
62 
63   if (dref == dmax)
64     return 1 - rolloff_factor_;
65 
66   // We want a gain that decreases linearly from m_refDistance to
67   // m_maxDistance. The gain is 1 at m_refDistance.
68   return (1.0 - clampTo(rolloff_factor_, 0.0, 1.0) * (distance - dref) /
69                     (dmax - dref));
70 }
71 
InverseGain(double distance)72 double DistanceEffect::InverseGain(double distance) {
73   if (ref_distance_ == 0)
74     return 0;
75 
76   // Clamp distance according to spec
77   distance = clampTo(distance, ref_distance_);
78 
79   return ref_distance_ / (ref_distance_ + clampTo(rolloff_factor_, 0.0) *
80                                               (distance - ref_distance_));
81 }
82 
ExponentialGain(double distance)83 double DistanceEffect::ExponentialGain(double distance) {
84   if (ref_distance_ == 0)
85     return 0;
86 
87   // Clamp distance according to spec
88   distance = clampTo(distance, ref_distance_);
89 
90   return pow(distance / ref_distance_, -clampTo(rolloff_factor_, 0.0));
91 }
92 
93 }  // namespace blink
94