xref: /aosp_15_r20/external/armnn/samples/common/src/Audio/MathUtils.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #include "MathUtils.hpp"
7*89c4ff92SAndroid Build Coastguard Worker #include <vector>
8*89c4ff92SAndroid Build Coastguard Worker #include <cmath>
9*89c4ff92SAndroid Build Coastguard Worker #include <cstdio>
10*89c4ff92SAndroid Build Coastguard Worker 
FftF32(std::vector<float> & input,std::vector<float> & fftOutput)11*89c4ff92SAndroid Build Coastguard Worker void MathUtils::FftF32(std::vector<float>& input,
12*89c4ff92SAndroid Build Coastguard Worker                        std::vector<float>& fftOutput)
13*89c4ff92SAndroid Build Coastguard Worker {
14*89c4ff92SAndroid Build Coastguard Worker     const int inputLength = input.size();
15*89c4ff92SAndroid Build Coastguard Worker 
16*89c4ff92SAndroid Build Coastguard Worker     for (int k = 0; k <= inputLength / 2; k++)
17*89c4ff92SAndroid Build Coastguard Worker     {
18*89c4ff92SAndroid Build Coastguard Worker         float sumReal = 0, sumImag = 0;
19*89c4ff92SAndroid Build Coastguard Worker 
20*89c4ff92SAndroid Build Coastguard Worker         for (int t = 0; t < inputLength; t++)
21*89c4ff92SAndroid Build Coastguard Worker         {
22*89c4ff92SAndroid Build Coastguard Worker             float angle = 2 * M_PI * t * k / inputLength;
23*89c4ff92SAndroid Build Coastguard Worker             sumReal += input[t] * cosf(angle);
24*89c4ff92SAndroid Build Coastguard Worker             sumImag += -input[t] * sinf(angle);
25*89c4ff92SAndroid Build Coastguard Worker         }
26*89c4ff92SAndroid Build Coastguard Worker 
27*89c4ff92SAndroid Build Coastguard Worker         /* Arrange output to [real0, realN/2, real1, im1, real2, im2, ...] */
28*89c4ff92SAndroid Build Coastguard Worker         if (k == 0)
29*89c4ff92SAndroid Build Coastguard Worker         {
30*89c4ff92SAndroid Build Coastguard Worker             fftOutput[0] = sumReal;
31*89c4ff92SAndroid Build Coastguard Worker         }
32*89c4ff92SAndroid Build Coastguard Worker         else if (k == inputLength / 2)
33*89c4ff92SAndroid Build Coastguard Worker         {
34*89c4ff92SAndroid Build Coastguard Worker             fftOutput[1] = sumReal;
35*89c4ff92SAndroid Build Coastguard Worker         }
36*89c4ff92SAndroid Build Coastguard Worker         else
37*89c4ff92SAndroid Build Coastguard Worker         {
38*89c4ff92SAndroid Build Coastguard Worker             fftOutput[k*2] = sumReal;
39*89c4ff92SAndroid Build Coastguard Worker             fftOutput[k*2 + 1] = sumImag;
40*89c4ff92SAndroid Build Coastguard Worker         };
41*89c4ff92SAndroid Build Coastguard Worker     }
42*89c4ff92SAndroid Build Coastguard Worker }
43*89c4ff92SAndroid Build Coastguard Worker 
DotProductF32(const float * srcPtrA,float * srcPtrB,const int srcLen)44*89c4ff92SAndroid Build Coastguard Worker float MathUtils::DotProductF32(const float* srcPtrA, float* srcPtrB,
45*89c4ff92SAndroid Build Coastguard Worker                                const int srcLen)
46*89c4ff92SAndroid Build Coastguard Worker {
47*89c4ff92SAndroid Build Coastguard Worker     float output = 0.f;
48*89c4ff92SAndroid Build Coastguard Worker 
49*89c4ff92SAndroid Build Coastguard Worker     for (int i = 0; i < srcLen; ++i)
50*89c4ff92SAndroid Build Coastguard Worker     {
51*89c4ff92SAndroid Build Coastguard Worker         output += *srcPtrA++ * *srcPtrB++;
52*89c4ff92SAndroid Build Coastguard Worker     }
53*89c4ff92SAndroid Build Coastguard Worker     return output;
54*89c4ff92SAndroid Build Coastguard Worker }
55*89c4ff92SAndroid Build Coastguard Worker 
ComplexMagnitudeSquaredF32(const float * ptrSrc,int srcLen,float * ptrDst,int dstLen)56*89c4ff92SAndroid Build Coastguard Worker bool MathUtils::ComplexMagnitudeSquaredF32(const float* ptrSrc,
57*89c4ff92SAndroid Build Coastguard Worker                                            int srcLen,
58*89c4ff92SAndroid Build Coastguard Worker                                            float* ptrDst,
59*89c4ff92SAndroid Build Coastguard Worker                                            int dstLen)
60*89c4ff92SAndroid Build Coastguard Worker {
61*89c4ff92SAndroid Build Coastguard Worker     if (dstLen < srcLen/2)
62*89c4ff92SAndroid Build Coastguard Worker     {
63*89c4ff92SAndroid Build Coastguard Worker         printf("dstLen must be greater than srcLen/2");
64*89c4ff92SAndroid Build Coastguard Worker         return false;
65*89c4ff92SAndroid Build Coastguard Worker     }
66*89c4ff92SAndroid Build Coastguard Worker 
67*89c4ff92SAndroid Build Coastguard Worker     for (int j = 0; j < dstLen; ++j)
68*89c4ff92SAndroid Build Coastguard Worker     {
69*89c4ff92SAndroid Build Coastguard Worker         const float real = *ptrSrc++;
70*89c4ff92SAndroid Build Coastguard Worker         const float im = *ptrSrc++;
71*89c4ff92SAndroid Build Coastguard Worker         *ptrDst++ = real*real + im*im;
72*89c4ff92SAndroid Build Coastguard Worker     }
73*89c4ff92SAndroid Build Coastguard Worker     return true;
74*89c4ff92SAndroid Build Coastguard Worker }
75*89c4ff92SAndroid Build Coastguard Worker 
VecLogarithmF32(std::vector<float> & input,std::vector<float> & output)76*89c4ff92SAndroid Build Coastguard Worker void MathUtils::VecLogarithmF32(std::vector <float>& input,
77*89c4ff92SAndroid Build Coastguard Worker                                 std::vector <float>& output)
78*89c4ff92SAndroid Build Coastguard Worker {
79*89c4ff92SAndroid Build Coastguard Worker     for (auto in = input.begin(), out = output.begin();
80*89c4ff92SAndroid Build Coastguard Worker          in != input.end(); ++in, ++out)
81*89c4ff92SAndroid Build Coastguard Worker     {
82*89c4ff92SAndroid Build Coastguard Worker         *out = logf(*in);
83*89c4ff92SAndroid Build Coastguard Worker     }
84*89c4ff92SAndroid Build Coastguard Worker }
85*89c4ff92SAndroid Build Coastguard Worker 
MeanF32(const float * ptrSrc,const uint32_t srcLen)86*89c4ff92SAndroid Build Coastguard Worker float MathUtils::MeanF32(const float* ptrSrc, const uint32_t srcLen)
87*89c4ff92SAndroid Build Coastguard Worker {
88*89c4ff92SAndroid Build Coastguard Worker     if (!srcLen)
89*89c4ff92SAndroid Build Coastguard Worker     {
90*89c4ff92SAndroid Build Coastguard Worker         return 0.f;
91*89c4ff92SAndroid Build Coastguard Worker     }
92*89c4ff92SAndroid Build Coastguard Worker 
93*89c4ff92SAndroid Build Coastguard Worker     float acc = std::accumulate(ptrSrc, ptrSrc + srcLen, 0.0);
94*89c4ff92SAndroid Build Coastguard Worker     return acc/srcLen;
95*89c4ff92SAndroid Build Coastguard Worker }
96*89c4ff92SAndroid Build Coastguard Worker 
StdDevF32(const float * ptrSrc,uint32_t srcLen,float mean)97*89c4ff92SAndroid Build Coastguard Worker float MathUtils::StdDevF32(const float* ptrSrc, uint32_t srcLen, float mean)
98*89c4ff92SAndroid Build Coastguard Worker {
99*89c4ff92SAndroid Build Coastguard Worker     if (!srcLen)
100*89c4ff92SAndroid Build Coastguard Worker     {
101*89c4ff92SAndroid Build Coastguard Worker         return 0.f;
102*89c4ff92SAndroid Build Coastguard Worker     }
103*89c4ff92SAndroid Build Coastguard Worker     auto VarianceFunction = [mean, srcLen](float acc, const float value) {
104*89c4ff92SAndroid Build Coastguard Worker         return acc + (((value - mean) * (value - mean))/ srcLen);
105*89c4ff92SAndroid Build Coastguard Worker     };
106*89c4ff92SAndroid Build Coastguard Worker 
107*89c4ff92SAndroid Build Coastguard Worker     float acc = std::accumulate(ptrSrc, ptrSrc + srcLen, 0.0,
108*89c4ff92SAndroid Build Coastguard Worker                                 VarianceFunction);
109*89c4ff92SAndroid Build Coastguard Worker     return sqrtf(acc);
110*89c4ff92SAndroid Build Coastguard Worker }
111*89c4ff92SAndroid Build Coastguard Worker 
112