xref: /aosp_15_r20/external/libldac/src/sigana_fixp_ldac.c (revision aef9bcd9217ad2365ebc8e70efaf94b64e04df14)
1*aef9bcd9SKiyoung Kim /*
2*aef9bcd9SKiyoung Kim  * Copyright (C) 2003 - 2016 Sony Corporation
3*aef9bcd9SKiyoung Kim  *
4*aef9bcd9SKiyoung Kim  * Licensed under the Apache License, Version 2.0 (the "License");
5*aef9bcd9SKiyoung Kim  * you may not use this file except in compliance with the License.
6*aef9bcd9SKiyoung Kim  * You may obtain a copy of the License at
7*aef9bcd9SKiyoung Kim  *
8*aef9bcd9SKiyoung Kim  *      http://www.apache.org/licenses/LICENSE-2.0
9*aef9bcd9SKiyoung Kim  *
10*aef9bcd9SKiyoung Kim  * Unless required by applicable law or agreed to in writing, software
11*aef9bcd9SKiyoung Kim  * distributed under the License is distributed on an "AS IS" BASIS,
12*aef9bcd9SKiyoung Kim  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*aef9bcd9SKiyoung Kim  * See the License for the specific language governing permissions and
14*aef9bcd9SKiyoung Kim  * limitations under the License.
15*aef9bcd9SKiyoung Kim  */
16*aef9bcd9SKiyoung Kim 
17*aef9bcd9SKiyoung Kim #include "ldac.h"
18*aef9bcd9SKiyoung Kim 
19*aef9bcd9SKiyoung Kim 
20*aef9bcd9SKiyoung Kim #define LDAC_Q_LOWENERGY    11
21*aef9bcd9SKiyoung Kim #define LDAC_Q_ADD_LOWENERGY 4
22*aef9bcd9SKiyoung Kim 
23*aef9bcd9SKiyoung Kim #define LDAC_TH_LOWENERGY_L (0x070bc28f>>LDAC_Q_ADD_LOWENERGY) /* Q15, _scalar(225.47)(Q19)>>4 */
24*aef9bcd9SKiyoung Kim #define LDAC_TH_LOWENERGY_M (0x1c0ce148>>LDAC_Q_ADD_LOWENERGY) /* Q15, _scalar(897.61)(Q19)>>4 */
25*aef9bcd9SKiyoung Kim #define LDAC_TH_LOWENERGY_H (0x6fab851f>>LDAC_Q_ADD_LOWENERGY) /* Q15, _scalar(3573.44)(Q19)>>4 */
26*aef9bcd9SKiyoung Kim 
27*aef9bcd9SKiyoung Kim #define LDAC_TH_CENTROID 0x00168000 /* Q15, _scalar(45.0) */
28*aef9bcd9SKiyoung Kim 
29*aef9bcd9SKiyoung Kim /***************************************************************************************************
30*aef9bcd9SKiyoung Kim     Lookup Table for Calculating Square Root Value
31*aef9bcd9SKiyoung Kim ***************************************************************************************************/
32*aef9bcd9SKiyoung Kim static INT16 sa_sqrt_ldac[97] = { /* Q14 */
33*aef9bcd9SKiyoung Kim     0x2d41, 0x2df4, 0x2ea5, 0x2f54, 0x3000, 0x30a9, 0x3150, 0x31f5,
34*aef9bcd9SKiyoung Kim     0x3298, 0x3339, 0x33d8, 0x3475, 0x3510, 0x35aa, 0x3642, 0x36d8,
35*aef9bcd9SKiyoung Kim     0x376c, 0x3800, 0x3891, 0x3921, 0x39b0, 0x3a3d, 0x3ac9, 0x3b54,
36*aef9bcd9SKiyoung Kim     0x3bdd, 0x3c66, 0x3ced, 0x3d72, 0x3df7, 0x3e7b, 0x3efd, 0x3f7f,
37*aef9bcd9SKiyoung Kim     0x4000, 0x407f, 0x40fe, 0x417b, 0x41f8, 0x4273, 0x42ee, 0x4368,
38*aef9bcd9SKiyoung Kim     0x43e1, 0x445a, 0x44d1, 0x4548, 0x45be, 0x4633, 0x46a7, 0x471b,
39*aef9bcd9SKiyoung Kim     0x478d, 0x4800, 0x4871, 0x48e2, 0x4952, 0x49c1, 0x4a30, 0x4a9e,
40*aef9bcd9SKiyoung Kim     0x4b0b, 0x4b78, 0x4be5, 0x4c50, 0x4cbb, 0x4d26, 0x4d90, 0x4df9,
41*aef9bcd9SKiyoung Kim     0x4e62, 0x4eca, 0x4f32, 0x4f99, 0x5000, 0x5066, 0x50cb, 0x5130,
42*aef9bcd9SKiyoung Kim     0x5195, 0x51f9, 0x525d, 0x52c0, 0x5323, 0x5385, 0x53e7, 0x5449,
43*aef9bcd9SKiyoung Kim     0x54a9, 0x550a, 0x556a, 0x55ca, 0x5629, 0x5688, 0x56e6, 0x5745,
44*aef9bcd9SKiyoung Kim     0x57a2, 0x5800, 0x585c, 0x58b9, 0x5915, 0x5971, 0x59cc, 0x5a27,
45*aef9bcd9SKiyoung Kim     0x5a82,
46*aef9bcd9SKiyoung Kim };
47*aef9bcd9SKiyoung Kim 
48*aef9bcd9SKiyoung Kim /***************************************************************************************************
49*aef9bcd9SKiyoung Kim     Subfunction: Multiply
50*aef9bcd9SKiyoung Kim ***************************************************************************************************/
mul_ldac(INT32 in1,INT32 in2)51*aef9bcd9SKiyoung Kim __inline static INT32 mul_ldac(
52*aef9bcd9SKiyoung Kim INT32 in1,
53*aef9bcd9SKiyoung Kim INT32 in2)
54*aef9bcd9SKiyoung Kim {
55*aef9bcd9SKiyoung Kim     INT32 out;
56*aef9bcd9SKiyoung Kim     INT64 acc;
57*aef9bcd9SKiyoung Kim 
58*aef9bcd9SKiyoung Kim     /* Q30 <- Q30 * Q30 */
59*aef9bcd9SKiyoung Kim     acc = (INT64)in1 * in2;
60*aef9bcd9SKiyoung Kim     acc >>= 30;
61*aef9bcd9SKiyoung Kim 
62*aef9bcd9SKiyoung Kim     if (acc > LDAC_MAX_32BIT) {
63*aef9bcd9SKiyoung Kim         out = LDAC_MAX_32BIT;
64*aef9bcd9SKiyoung Kim     }
65*aef9bcd9SKiyoung Kim     else if (acc < LDAC_MIN_32BIT) {
66*aef9bcd9SKiyoung Kim         out = LDAC_MIN_32BIT;
67*aef9bcd9SKiyoung Kim     }
68*aef9bcd9SKiyoung Kim     else {
69*aef9bcd9SKiyoung Kim         out = (INT32)acc;
70*aef9bcd9SKiyoung Kim     }
71*aef9bcd9SKiyoung Kim 
72*aef9bcd9SKiyoung Kim     return out;
73*aef9bcd9SKiyoung Kim }
74*aef9bcd9SKiyoung Kim 
75*aef9bcd9SKiyoung Kim /***************************************************************************************************
76*aef9bcd9SKiyoung Kim     Subfunction: Subtract
77*aef9bcd9SKiyoung Kim ***************************************************************************************************/
sub_ldac(INT32 in1,INT32 in2)78*aef9bcd9SKiyoung Kim __inline static INT32 sub_ldac(
79*aef9bcd9SKiyoung Kim INT32 in1,
80*aef9bcd9SKiyoung Kim INT32 in2)
81*aef9bcd9SKiyoung Kim {
82*aef9bcd9SKiyoung Kim     INT32 out;
83*aef9bcd9SKiyoung Kim 
84*aef9bcd9SKiyoung Kim     out = in1 - in2;
85*aef9bcd9SKiyoung Kim 
86*aef9bcd9SKiyoung Kim     return out;
87*aef9bcd9SKiyoung Kim }
88*aef9bcd9SKiyoung Kim 
89*aef9bcd9SKiyoung Kim /***************************************************************************************************
90*aef9bcd9SKiyoung Kim     Subfunction: Add
91*aef9bcd9SKiyoung Kim ***************************************************************************************************/
add_ldac(INT32 in1,INT32 in2)92*aef9bcd9SKiyoung Kim __inline static INT32 add_ldac(
93*aef9bcd9SKiyoung Kim INT32 in1,
94*aef9bcd9SKiyoung Kim INT32 in2)
95*aef9bcd9SKiyoung Kim {
96*aef9bcd9SKiyoung Kim     INT32 out;
97*aef9bcd9SKiyoung Kim 
98*aef9bcd9SKiyoung Kim     out = in1 + in2;
99*aef9bcd9SKiyoung Kim 
100*aef9bcd9SKiyoung Kim     return out;
101*aef9bcd9SKiyoung Kim }
102*aef9bcd9SKiyoung Kim 
103*aef9bcd9SKiyoung Kim /***************************************************************************************************
104*aef9bcd9SKiyoung Kim     Subfunction: Multiply and Add
105*aef9bcd9SKiyoung Kim ***************************************************************************************************/
mad_ldac(INT32 in1,INT32 in2,INT32 in3)106*aef9bcd9SKiyoung Kim __inline static INT32 mad_ldac(
107*aef9bcd9SKiyoung Kim INT32 in1,
108*aef9bcd9SKiyoung Kim INT32 in2,
109*aef9bcd9SKiyoung Kim INT32 in3)
110*aef9bcd9SKiyoung Kim {
111*aef9bcd9SKiyoung Kim     INT32 out;
112*aef9bcd9SKiyoung Kim 
113*aef9bcd9SKiyoung Kim     out = mul_ldac(in2, in3);
114*aef9bcd9SKiyoung Kim     out = add_ldac(in1, out);
115*aef9bcd9SKiyoung Kim 
116*aef9bcd9SKiyoung Kim     return out;
117*aef9bcd9SKiyoung Kim }
118*aef9bcd9SKiyoung Kim 
119*aef9bcd9SKiyoung Kim /***************************************************************************************************
120*aef9bcd9SKiyoung Kim     Subfunction: Normalize
121*aef9bcd9SKiyoung Kim ***************************************************************************************************/
norm_ldac(UINT32 val)122*aef9bcd9SKiyoung Kim __inline static INT16 norm_ldac(
123*aef9bcd9SKiyoung Kim UINT32 val)
124*aef9bcd9SKiyoung Kim {
125*aef9bcd9SKiyoung Kim     INT16 len;
126*aef9bcd9SKiyoung Kim 
127*aef9bcd9SKiyoung Kim     len = 0;
128*aef9bcd9SKiyoung Kim     while (val > 0) {
129*aef9bcd9SKiyoung Kim         val >>= 1;
130*aef9bcd9SKiyoung Kim         len++;
131*aef9bcd9SKiyoung Kim     }
132*aef9bcd9SKiyoung Kim 
133*aef9bcd9SKiyoung Kim     return len;
134*aef9bcd9SKiyoung Kim }
135*aef9bcd9SKiyoung Kim 
136*aef9bcd9SKiyoung Kim /***************************************************************************************************
137*aef9bcd9SKiyoung Kim     Subfunction: Calculate Exponential
138*aef9bcd9SKiyoung Kim ***************************************************************************************************/
calc_exp_ldac(INT32 in_h,UINT32 in_l)139*aef9bcd9SKiyoung Kim __inline static INT16 calc_exp_ldac(
140*aef9bcd9SKiyoung Kim INT32 in_h,
141*aef9bcd9SKiyoung Kim UINT32 in_l)
142*aef9bcd9SKiyoung Kim {
143*aef9bcd9SKiyoung Kim     INT16 e;
144*aef9bcd9SKiyoung Kim 
145*aef9bcd9SKiyoung Kim     if (in_h) {
146*aef9bcd9SKiyoung Kim         e = norm_ldac((UINT32)in_h) + 32;
147*aef9bcd9SKiyoung Kim     }
148*aef9bcd9SKiyoung Kim     else {
149*aef9bcd9SKiyoung Kim         e = norm_ldac(in_l);
150*aef9bcd9SKiyoung Kim     }
151*aef9bcd9SKiyoung Kim     e = (63 - e) & 0xfffe;
152*aef9bcd9SKiyoung Kim 
153*aef9bcd9SKiyoung Kim     return e;
154*aef9bcd9SKiyoung Kim }
155*aef9bcd9SKiyoung Kim 
156*aef9bcd9SKiyoung Kim /***************************************************************************************************
157*aef9bcd9SKiyoung Kim     Subfunction: Calculate Square Root
158*aef9bcd9SKiyoung Kim ***************************************************************************************************/
calc_sqrt_ldac(INT32 in,INT16 e)159*aef9bcd9SKiyoung Kim __inline static INT32 calc_sqrt_ldac(
160*aef9bcd9SKiyoung Kim INT32 in,
161*aef9bcd9SKiyoung Kim INT16 e)
162*aef9bcd9SKiyoung Kim {
163*aef9bcd9SKiyoung Kim     INT16 i;
164*aef9bcd9SKiyoung Kim     INT32 val, dif, a;
165*aef9bcd9SKiyoung Kim 
166*aef9bcd9SKiyoung Kim     if (in <= 0) {
167*aef9bcd9SKiyoung Kim         return 0;
168*aef9bcd9SKiyoung Kim     }
169*aef9bcd9SKiyoung Kim 
170*aef9bcd9SKiyoung Kim     i = (INT16)(in >> 24);
171*aef9bcd9SKiyoung Kim     a = in & 0x00ffffffL;
172*aef9bcd9SKiyoung Kim 
173*aef9bcd9SKiyoung Kim     i = i - 32;
174*aef9bcd9SKiyoung Kim     val = sa_sqrt_ldac[i] << 16; /* Q30 <- Q14 << 16 */
175*aef9bcd9SKiyoung Kim     dif = sub_ldac(sa_sqrt_ldac[i+1]<<16, val); /* Q30 */
176*aef9bcd9SKiyoung Kim     a = (INT32)(((INT64)a << 30) >> 24); /* Q30 a = a / 0x1000000 */
177*aef9bcd9SKiyoung Kim     val = mad_ldac(val, dif, a);
178*aef9bcd9SKiyoung Kim     val = val >> (e >> 1);
179*aef9bcd9SKiyoung Kim 
180*aef9bcd9SKiyoung Kim     return val;
181*aef9bcd9SKiyoung Kim }
182*aef9bcd9SKiyoung Kim 
183*aef9bcd9SKiyoung Kim /***************************************************************************************************
184*aef9bcd9SKiyoung Kim     Calculate Pseudo Spectrum and Low Band Energy
185*aef9bcd9SKiyoung Kim ***************************************************************************************************/
calc_mdct_pseudo_spectrum_ldac(INT32 * p_spec,INT32 * p_psd,UINT32 nsp)186*aef9bcd9SKiyoung Kim static INT32 calc_mdct_pseudo_spectrum_ldac(
187*aef9bcd9SKiyoung Kim INT32 *p_spec,
188*aef9bcd9SKiyoung Kim INT32 *p_psd,
189*aef9bcd9SKiyoung Kim UINT32 nsp)
190*aef9bcd9SKiyoung Kim {
191*aef9bcd9SKiyoung Kim     UINT32 isp;
192*aef9bcd9SKiyoung Kim     INT16 e;
193*aef9bcd9SKiyoung Kim     INT32 y0, y1, y2;
194*aef9bcd9SKiyoung Kim     INT32 tmp;
195*aef9bcd9SKiyoung Kim     INT64 low_energy;
196*aef9bcd9SKiyoung Kim     INT64 acc1, acc2;
197*aef9bcd9SKiyoung Kim 
198*aef9bcd9SKiyoung Kim     {
199*aef9bcd9SKiyoung Kim         y1 = p_spec[0];
200*aef9bcd9SKiyoung Kim         y2 = p_spec[1];
201*aef9bcd9SKiyoung Kim         acc1 = (INT64)y1 * (INT64)y1;
202*aef9bcd9SKiyoung Kim         acc2 = (INT64)y2 * (INT64)y2;
203*aef9bcd9SKiyoung Kim         acc1 = acc1 + acc2;
204*aef9bcd9SKiyoung Kim         low_energy = acc1 >> LDAC_Q_ADD_LOWENERGY; /* Q26 <- (Q15 * Q15) >> 4 */
205*aef9bcd9SKiyoung Kim         e = calc_exp_ldac((INT32)(acc1>>32), (UINT32)(acc1&0xffffffff));
206*aef9bcd9SKiyoung Kim         tmp = (INT32)((acc1 << e) >> 32);
207*aef9bcd9SKiyoung Kim         *p_psd++ = calc_sqrt_ldac(tmp, e);
208*aef9bcd9SKiyoung Kim     }
209*aef9bcd9SKiyoung Kim 
210*aef9bcd9SKiyoung Kim     for (isp = 1; isp < LDAC_NSP_LOWENERGY; isp++) {
211*aef9bcd9SKiyoung Kim         y0 = y1;
212*aef9bcd9SKiyoung Kim         y1 = y2;
213*aef9bcd9SKiyoung Kim         y2 = p_spec[isp+1];
214*aef9bcd9SKiyoung Kim         acc1 = (INT64)y1 * (INT64)y1;
215*aef9bcd9SKiyoung Kim         acc2 = (INT64)(y0-y2) * (INT64)(y0-y2);
216*aef9bcd9SKiyoung Kim         acc1 = acc1 + acc2;
217*aef9bcd9SKiyoung Kim         low_energy += acc1 >> LDAC_Q_ADD_LOWENERGY; /* Q26 <- (Q15 * Q15) >> 4 */
218*aef9bcd9SKiyoung Kim         e = calc_exp_ldac((INT32)(acc1>>32), (UINT32)(acc1&0xffffffff));
219*aef9bcd9SKiyoung Kim         tmp = (INT32)((acc1 << e) >> 32);
220*aef9bcd9SKiyoung Kim         *p_psd++ = calc_sqrt_ldac(tmp, e);
221*aef9bcd9SKiyoung Kim     }
222*aef9bcd9SKiyoung Kim 
223*aef9bcd9SKiyoung Kim     for (isp = LDAC_NSP_LOWENERGY; isp < nsp-1; isp++) {
224*aef9bcd9SKiyoung Kim         y0 = y1;
225*aef9bcd9SKiyoung Kim         y1 = y2;
226*aef9bcd9SKiyoung Kim         y2 = p_spec[isp+1];
227*aef9bcd9SKiyoung Kim         acc1 = (INT64)y1 * (INT64)y1;
228*aef9bcd9SKiyoung Kim         acc2 = (INT64)(y0-y2) * (INT64)(y0-y2);
229*aef9bcd9SKiyoung Kim         acc1 = acc1 + acc2;
230*aef9bcd9SKiyoung Kim         e = calc_exp_ldac((INT32)(acc1 >> 32), (UINT32)(acc1&0xffffffff));
231*aef9bcd9SKiyoung Kim         tmp = (INT32) ((acc1 << e) >> 32);
232*aef9bcd9SKiyoung Kim         *p_psd++ = calc_sqrt_ldac(tmp, e);
233*aef9bcd9SKiyoung Kim     }
234*aef9bcd9SKiyoung Kim 
235*aef9bcd9SKiyoung Kim     {
236*aef9bcd9SKiyoung Kim         acc1 = (INT64)y1 * (INT64)y1;
237*aef9bcd9SKiyoung Kim         acc2 = (INT64)y2 * (INT64)y2;
238*aef9bcd9SKiyoung Kim         acc1 = acc1 + acc2;
239*aef9bcd9SKiyoung Kim         e = calc_exp_ldac((INT32)(acc1 >> 32), (UINT32)(acc1&0xffffffff));
240*aef9bcd9SKiyoung Kim         tmp = (INT32)((acc1 << e) >> 32);
241*aef9bcd9SKiyoung Kim         *p_psd++ = calc_sqrt_ldac(tmp, e);
242*aef9bcd9SKiyoung Kim     }
243*aef9bcd9SKiyoung Kim 
244*aef9bcd9SKiyoung Kim     low_energy >>= LDAC_Q_LOWENERGY; /* Q15 <- Q26 >> 11 */
245*aef9bcd9SKiyoung Kim     if (low_energy > LDAC_MAX_32BIT) {
246*aef9bcd9SKiyoung Kim         low_energy = LDAC_MAX_32BIT;
247*aef9bcd9SKiyoung Kim     }
248*aef9bcd9SKiyoung Kim 
249*aef9bcd9SKiyoung Kim     return (INT32)low_energy;
250*aef9bcd9SKiyoung Kim }
251*aef9bcd9SKiyoung Kim 
252*aef9bcd9SKiyoung Kim /***************************************************************************************************
253*aef9bcd9SKiyoung Kim     Calculate Pseudo Spectrum Centroid
254*aef9bcd9SKiyoung Kim ***************************************************************************************************/
calc_spectral_centroid_ldac(INT32 * p_spec,UINT32 nsp)255*aef9bcd9SKiyoung Kim static INT32 calc_spectral_centroid_ldac(
256*aef9bcd9SKiyoung Kim INT32 *p_spec,
257*aef9bcd9SKiyoung Kim UINT32 nsp)
258*aef9bcd9SKiyoung Kim {
259*aef9bcd9SKiyoung Kim     UINT32 isp;
260*aef9bcd9SKiyoung Kim     INT32 centroid = 0;
261*aef9bcd9SKiyoung Kim     INT64 s1, s2;
262*aef9bcd9SKiyoung Kim 
263*aef9bcd9SKiyoung Kim     s1 = s2 = 0;
264*aef9bcd9SKiyoung Kim     for (isp = 0; isp < nsp; isp++) {
265*aef9bcd9SKiyoung Kim         s1 += ((INT64)isp * (INT64)*p_spec); /* Q15 <- Q00 * Q15 */
266*aef9bcd9SKiyoung Kim         s2 += (INT64)*p_spec++; /* Q15 */
267*aef9bcd9SKiyoung Kim     }
268*aef9bcd9SKiyoung Kim 
269*aef9bcd9SKiyoung Kim     if (s2 != 0) {
270*aef9bcd9SKiyoung Kim         centroid = (INT32)((s1<<15) / s2); /* Q15 <- (Q15<<15) / Q15 */
271*aef9bcd9SKiyoung Kim     }
272*aef9bcd9SKiyoung Kim 
273*aef9bcd9SKiyoung Kim     return centroid;
274*aef9bcd9SKiyoung Kim }
275*aef9bcd9SKiyoung Kim 
276*aef9bcd9SKiyoung Kim /***************************************************************************************************
277*aef9bcd9SKiyoung Kim     Calculate Number of Zero Cross
278*aef9bcd9SKiyoung Kim ***************************************************************************************************/
calc_zero_cross_number_ldac(INT32 * p_time,UINT32 n)279*aef9bcd9SKiyoung Kim static UINT32 calc_zero_cross_number_ldac(
280*aef9bcd9SKiyoung Kim INT32 *p_time,
281*aef9bcd9SKiyoung Kim UINT32 n)
282*aef9bcd9SKiyoung Kim {
283*aef9bcd9SKiyoung Kim     UINT32 i;
284*aef9bcd9SKiyoung Kim     UINT32 zero_cross = 0;
285*aef9bcd9SKiyoung Kim     INT32 prev, tmp;
286*aef9bcd9SKiyoung Kim 
287*aef9bcd9SKiyoung Kim     prev = 0;
288*aef9bcd9SKiyoung Kim     for (i = 0; i < n; i++) {
289*aef9bcd9SKiyoung Kim         if ((prev == 0) || (*p_time == 0)) {
290*aef9bcd9SKiyoung Kim             tmp = 0;
291*aef9bcd9SKiyoung Kim         }
292*aef9bcd9SKiyoung Kim         else {
293*aef9bcd9SKiyoung Kim             tmp = prev ^ (*p_time);
294*aef9bcd9SKiyoung Kim         }
295*aef9bcd9SKiyoung Kim 
296*aef9bcd9SKiyoung Kim         if (tmp < 0) {
297*aef9bcd9SKiyoung Kim             zero_cross++;
298*aef9bcd9SKiyoung Kim         }
299*aef9bcd9SKiyoung Kim         prev = *p_time++;
300*aef9bcd9SKiyoung Kim     }
301*aef9bcd9SKiyoung Kim 
302*aef9bcd9SKiyoung Kim     return zero_cross;
303*aef9bcd9SKiyoung Kim }
304*aef9bcd9SKiyoung Kim 
305*aef9bcd9SKiyoung Kim /***************************************************************************************************
306*aef9bcd9SKiyoung Kim     Analyze Frame Status
307*aef9bcd9SKiyoung Kim ***************************************************************************************************/
ana_frame_status_ldac(SFINFO * p_sfinfo,int nlnn)308*aef9bcd9SKiyoung Kim DECLSPEC int ana_frame_status_ldac(
309*aef9bcd9SKiyoung Kim SFINFO *p_sfinfo,
310*aef9bcd9SKiyoung Kim int nlnn)
311*aef9bcd9SKiyoung Kim {
312*aef9bcd9SKiyoung Kim     AC *p_ac;
313*aef9bcd9SKiyoung Kim     int ich;
314*aef9bcd9SKiyoung Kim     int nchs = p_sfinfo->cfg.ch;
315*aef9bcd9SKiyoung Kim     int nsmpl = npow2_ldac(nlnn+1);
316*aef9bcd9SKiyoung Kim     int cnt;
317*aef9bcd9SKiyoung Kim     int a_status[LDAC_PRCNCH];
318*aef9bcd9SKiyoung Kim     UINT32 zero_cross;
319*aef9bcd9SKiyoung Kim     INT32 low_energy, centroid;
320*aef9bcd9SKiyoung Kim     INT32 a_psd_spec[LDAC_NSP_PSEUDOANA];
321*aef9bcd9SKiyoung Kim 
322*aef9bcd9SKiyoung Kim 
323*aef9bcd9SKiyoung Kim     for (ich = 0; ich < nchs; ich++) {
324*aef9bcd9SKiyoung Kim         p_ac = p_sfinfo->ap_ac[ich];
325*aef9bcd9SKiyoung Kim 
326*aef9bcd9SKiyoung Kim         low_energy = calc_mdct_pseudo_spectrum_ldac(p_ac->p_acsub->a_spec, a_psd_spec, LDAC_NSP_PSEUDOANA);
327*aef9bcd9SKiyoung Kim 
328*aef9bcd9SKiyoung Kim         centroid = calc_spectral_centroid_ldac(a_psd_spec, LDAC_NSP_PSEUDOANA);
329*aef9bcd9SKiyoung Kim 
330*aef9bcd9SKiyoung Kim         zero_cross = calc_zero_cross_number_ldac(p_ac->p_acsub->a_time, nsmpl);
331*aef9bcd9SKiyoung Kim 
332*aef9bcd9SKiyoung Kim         a_status[ich] = LDAC_FRMSTAT_LEV_0;
333*aef9bcd9SKiyoung Kim         if (low_energy < LDAC_TH_LOWENERGY_L) {
334*aef9bcd9SKiyoung Kim             a_status[ich] = LDAC_FRMSTAT_LEV_3;
335*aef9bcd9SKiyoung Kim         }
336*aef9bcd9SKiyoung Kim         else {
337*aef9bcd9SKiyoung Kim             if (low_energy < LDAC_TH_LOWENERGY_M) {
338*aef9bcd9SKiyoung Kim                 a_status[ich] = LDAC_FRMSTAT_LEV_2;
339*aef9bcd9SKiyoung Kim             }
340*aef9bcd9SKiyoung Kim             else if (low_energy < LDAC_TH_LOWENERGY_H) {
341*aef9bcd9SKiyoung Kim                 a_status[ich] = LDAC_FRMSTAT_LEV_1;
342*aef9bcd9SKiyoung Kim             }
343*aef9bcd9SKiyoung Kim 
344*aef9bcd9SKiyoung Kim             cnt = p_ac->frmana_cnt;
345*aef9bcd9SKiyoung Kim             if ((centroid > LDAC_TH_CENTROID) && (zero_cross >= LDAC_TH_ZCROSNUM)) {
346*aef9bcd9SKiyoung Kim                 cnt++;
347*aef9bcd9SKiyoung Kim 
348*aef9bcd9SKiyoung Kim                 if (cnt >= LDAC_MAXCNT_FRMANA) {
349*aef9bcd9SKiyoung Kim                     cnt = LDAC_MAXCNT_FRMANA;
350*aef9bcd9SKiyoung Kim                     a_status[ich] = LDAC_FRMSTAT_LEV_2;
351*aef9bcd9SKiyoung Kim                 }
352*aef9bcd9SKiyoung Kim                 else if (a_status[ich] <= LDAC_FRMSTAT_LEV_1) {
353*aef9bcd9SKiyoung Kim                     a_status[ich]++;
354*aef9bcd9SKiyoung Kim                 }
355*aef9bcd9SKiyoung Kim             }
356*aef9bcd9SKiyoung Kim             else {
357*aef9bcd9SKiyoung Kim                 cnt = 0;
358*aef9bcd9SKiyoung Kim             }
359*aef9bcd9SKiyoung Kim             p_ac->frmana_cnt = cnt;
360*aef9bcd9SKiyoung Kim         }
361*aef9bcd9SKiyoung Kim     }
362*aef9bcd9SKiyoung Kim 
363*aef9bcd9SKiyoung Kim     if (nchs == LDAC_CHANNEL_1CH) {
364*aef9bcd9SKiyoung Kim         return a_status[0];
365*aef9bcd9SKiyoung Kim     } else {
366*aef9bcd9SKiyoung Kim         return min_ldac(a_status[0], a_status[1]);
367*aef9bcd9SKiyoung Kim     }
368*aef9bcd9SKiyoung Kim }
369*aef9bcd9SKiyoung Kim 
370