/src/libldac/src/sigana_ldac.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2003 - 2016 Sony Corporation |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include "ldac.h" |
18 | | |
19 | | |
20 | 44 | #define LDAC_TH_LOWENERGY_L _scalar(225.47) |
21 | 44 | #define LDAC_TH_LOWENERGY_M _scalar(897.61) |
22 | 44 | #define LDAC_TH_LOWENERGY_H _scalar(3573.44) |
23 | | |
24 | 44 | #define LDAC_TH_CENTROID _scalar(45.0) |
25 | 44 | #define LDAC_TH_ZERODIV _scalar(1.0e-6) |
26 | | |
27 | | /*************************************************************************************************** |
28 | | Calculate Pseudo Spectrum and Low Band Energy |
29 | | ***************************************************************************************************/ |
30 | | static SCALAR calc_mdct_pseudo_spectrum_ldac( |
31 | | SCALAR *p_spec, |
32 | | SCALAR *p_psd, |
33 | | int n) |
34 | 44 | { |
35 | 44 | int isp; |
36 | 44 | SCALAR low_energy, tmp; |
37 | 44 | SCALAR y0, y1, y2; |
38 | | |
39 | 44 | { |
40 | 44 | y1 = p_spec[0]; |
41 | 44 | y2 = p_spec[1]; |
42 | 44 | tmp = y1 * y1 + y2 * y2; |
43 | 44 | low_energy = tmp; |
44 | 44 | p_psd[0] = sqrt(tmp); |
45 | 44 | } |
46 | | |
47 | 528 | for (isp = 1; isp < LDAC_NSP_LOWENERGY; isp++) { |
48 | 484 | y0 = y1; |
49 | 484 | y1 = y2; |
50 | 484 | y2 = p_spec[isp+1]; |
51 | 484 | tmp = y1 * y1 + (y0-y2) * (y0-y2); |
52 | 484 | low_energy += tmp; |
53 | 484 | p_psd[isp] = sqrt(tmp); |
54 | 484 | } |
55 | | |
56 | 5.10k | for (isp = LDAC_NSP_LOWENERGY; isp < n-1; isp++) { |
57 | 5.06k | y0 = y1; |
58 | 5.06k | y1 = y2; |
59 | 5.06k | y2 = p_spec[isp+1]; |
60 | 5.06k | tmp = y1 * y1 + (y0-y2) * (y0-y2); |
61 | 5.06k | p_psd[isp] = sqrt(tmp); |
62 | 5.06k | } |
63 | | |
64 | 44 | { |
65 | 44 | tmp = y1 * y1 + y2 * y2; |
66 | 44 | p_psd[n-1] = sqrt(tmp); |
67 | 44 | } |
68 | | |
69 | 44 | return low_energy; |
70 | 44 | } |
71 | | |
72 | | /*************************************************************************************************** |
73 | | Calculate Pseudo Spectrum Centroid |
74 | | ***************************************************************************************************/ |
75 | | static SCALAR calc_spectral_centroid_ldac( |
76 | | SCALAR *p_spec, |
77 | | int nsp) |
78 | 44 | { |
79 | 44 | int isp; |
80 | 44 | SCALAR centroid; |
81 | 44 | SCALAR s1, s2; |
82 | | |
83 | 44 | s1 = s2 = _scalar(0.0); |
84 | 5.67k | for (isp = 0; isp < nsp; isp++) { |
85 | 5.63k | s1 += (SCALAR)isp * *p_spec; |
86 | 5.63k | s2 += *p_spec++; |
87 | 5.63k | } |
88 | | |
89 | 44 | if (s2 < LDAC_TH_ZERODIV) { |
90 | 0 | centroid = _scalar(0.0); |
91 | 0 | } |
92 | 44 | else { |
93 | 44 | centroid = s1 / s2; |
94 | 44 | } |
95 | | |
96 | 44 | return centroid; |
97 | 44 | } |
98 | | |
99 | | /*************************************************************************************************** |
100 | | Calculate Number of Zero Cross |
101 | | ***************************************************************************************************/ |
102 | | static int calc_zero_cross_number_ldac( |
103 | | SCALAR *p_time, |
104 | | int n) |
105 | 44 | { |
106 | 44 | int i; |
107 | 44 | int zero_cross = 0; |
108 | 44 | SCALAR prev; |
109 | | |
110 | 44 | prev = _scalar(0.0); |
111 | 11.3k | for (i = 0; i < n; i++) { |
112 | 11.2k | if (prev * *p_time < _scalar(0.0)) { |
113 | 550 | zero_cross++; |
114 | 550 | } |
115 | 11.2k | prev = *p_time++; |
116 | 11.2k | } |
117 | | |
118 | 44 | return zero_cross; |
119 | 44 | } |
120 | | |
121 | | /*************************************************************************************************** |
122 | | Analyze Frame Status |
123 | | ***************************************************************************************************/ |
124 | | DECLSPEC int ana_frame_status_ldac( |
125 | | SFINFO *p_sfinfo, |
126 | | int nlnn) |
127 | 22 | { |
128 | 22 | AC *p_ac; |
129 | 22 | int ich; |
130 | 22 | int nchs = p_sfinfo->cfg.ch; |
131 | 22 | int nsmpl = npow2_ldac(nlnn+1); |
132 | 22 | int cnt, zero_cross; |
133 | 22 | int a_status[LDAC_PRCNCH]; |
134 | 22 | SCALAR low_energy, centroid; |
135 | 22 | SCALAR a_psd_spec[LDAC_NSP_PSEUDOANA]; |
136 | | |
137 | 66 | for (ich = 0; ich < nchs; ich++) { |
138 | 44 | p_ac = p_sfinfo->ap_ac[ich]; |
139 | | |
140 | 44 | low_energy = calc_mdct_pseudo_spectrum_ldac(p_ac->p_acsub->a_spec, a_psd_spec, LDAC_NSP_PSEUDOANA); |
141 | | |
142 | 44 | centroid = calc_spectral_centroid_ldac(a_psd_spec, LDAC_NSP_PSEUDOANA); |
143 | | |
144 | 44 | zero_cross = calc_zero_cross_number_ldac(p_ac->p_acsub->a_time, nsmpl); |
145 | | |
146 | 44 | a_status[ich] = LDAC_FRMSTAT_LEV_0; |
147 | 44 | if (low_energy < LDAC_TH_LOWENERGY_L) { |
148 | 0 | a_status[ich] = LDAC_FRMSTAT_LEV_3; |
149 | 0 | } |
150 | 44 | else { |
151 | 44 | if (low_energy < LDAC_TH_LOWENERGY_M) { |
152 | 0 | a_status[ich] = LDAC_FRMSTAT_LEV_2; |
153 | 0 | } |
154 | 44 | else if (low_energy < LDAC_TH_LOWENERGY_H) { |
155 | 0 | a_status[ich] = LDAC_FRMSTAT_LEV_1; |
156 | 0 | } |
157 | | |
158 | 44 | cnt = p_ac->frmana_cnt; |
159 | 44 | if ((centroid > LDAC_TH_CENTROID) && (zero_cross >= LDAC_TH_ZCROSNUM)) { |
160 | 0 | cnt++; |
161 | |
|
162 | 0 | if (cnt >= LDAC_MAXCNT_FRMANA) { |
163 | 0 | cnt = LDAC_MAXCNT_FRMANA; |
164 | 0 | a_status[ich] = LDAC_FRMSTAT_LEV_2; |
165 | 0 | } |
166 | 0 | else if (a_status[ich] <= LDAC_FRMSTAT_LEV_1) { |
167 | 0 | a_status[ich]++; |
168 | 0 | } |
169 | 0 | } |
170 | 44 | else { |
171 | 44 | cnt = 0; |
172 | 44 | } |
173 | 44 | p_ac->frmana_cnt = cnt; |
174 | 44 | } |
175 | 44 | } |
176 | | |
177 | 22 | if (nchs == LDAC_CHANNEL_1CH) { |
178 | 0 | return a_status[0]; |
179 | 0 | } |
180 | 22 | else { |
181 | 22 | return min_ldac(a_status[0], a_status[1]); |
182 | 22 | } |
183 | 22 | } |
184 | | |