1 /*
2  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/audio_processing/ns/fast_math.h"
12 
13 #include <math.h>
14 #include <stdint.h>
15 
16 #include "rtc_base/checks.h"
17 
18 namespace webrtc {
19 
20 namespace {
21 
FastLog2f(float in)22 float FastLog2f(float in) {
23   RTC_DCHECK_GT(in, .0f);
24   // Read and interpret float as uint32_t and then cast to float.
25   // This is done to extract the exponent (bits 30 - 23).
26   // "Right shift" of the exponent is then performed by multiplying
27   // with the constant (1/2^23). Finally, we subtract a constant to
28   // remove the bias (https://en.wikipedia.org/wiki/Exponent_bias).
29   union {
30     float dummy;
31     uint32_t a;
32   } x = {in};
33   float out = x.a;
34   out *= 1.1920929e-7f;  // 1/2^23
35   out -= 126.942695f;    // Remove bias.
36   return out;
37 }
38 
39 }  // namespace
40 
SqrtFastApproximation(float f)41 float SqrtFastApproximation(float f) {
42   // TODO(peah): Add fast approximate implementation.
43   return sqrtf(f);
44 }
45 
Pow2Approximation(float p)46 float Pow2Approximation(float p) {
47   // TODO(peah): Add fast approximate implementation.
48   return powf(2.f, p);
49 }
50 
PowApproximation(float x,float p)51 float PowApproximation(float x, float p) {
52   return Pow2Approximation(p * FastLog2f(x));
53 }
54 
LogApproximation(float x)55 float LogApproximation(float x) {
56   constexpr float kLogOf2 = 0.69314718056f;
57   return FastLog2f(x) * kLogOf2;
58 }
59 
LogApproximation(rtc::ArrayView<const float> x,rtc::ArrayView<float> y)60 void LogApproximation(rtc::ArrayView<const float> x, rtc::ArrayView<float> y) {
61   for (size_t k = 0; k < x.size(); ++k) {
62     y[k] = LogApproximation(x[k]);
63   }
64 }
65 
ExpApproximation(float x)66 float ExpApproximation(float x) {
67   constexpr float kLog10Ofe = 0.4342944819f;
68   return PowApproximation(10.f, x * kLog10Ofe);
69 }
70 
ExpApproximation(rtc::ArrayView<const float> x,rtc::ArrayView<float> y)71 void ExpApproximation(rtc::ArrayView<const float> x, rtc::ArrayView<float> y) {
72   for (size_t k = 0; k < x.size(); ++k) {
73     y[k] = ExpApproximation(x[k]);
74   }
75 }
76 
ExpApproximationSignFlip(rtc::ArrayView<const float> x,rtc::ArrayView<float> y)77 void ExpApproximationSignFlip(rtc::ArrayView<const float> x,
78                               rtc::ArrayView<float> y) {
79   for (size_t k = 0; k < x.size(); ++k) {
80     y[k] = ExpApproximation(-x[k]);
81   }
82 }
83 
84 }  // namespace webrtc
85