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