Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.5.1 *
3 : * Low Complexity Communication Codec Plus (LC3plus) *
4 : * *
5 : * Copyright licence is solely granted through ETSI Intellectual Property *
6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
7 : * estoppel or otherwise. *
8 : ******************************************************************************/
9 :
10 : #include "functions.h"
11 : #include "rom_basop_util_lc3plus.h"
12 :
13 0 : void processPerBandEnergy_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word32 *d_fx, Word16 d_fx_exp,
14 : const Word16 *band_offsets, Word16 fs_idx, Word16 n_bands, Word16 linear, Word16 frame_dms,
15 : Word8 *scratchBuffer
16 : #ifdef ENABLE_HR_MODE
17 : , Word16 hrmode
18 : #endif
19 : )
20 : {
21 : Dyn_Mem_Deluxe_In(Counter i, k, band; Word16 s; Word16 s1; Word16 s2; Word32 nrg; Word16 smax; Word16 tmp16;
22 : Word16 nbands; Word16 maxBwBin; Word16 stopBand; Word16 bandsOffsetOne; Word16 bandsOffsetTwo;
23 : Word16 * d2_band_fx_exp;);
24 :
25 :
26 0 : d2_band_fx_exp = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER_PLC bytes */
27 :
28 : #ifdef ENABLE_HR_MODE
29 0 : if (hrmode)
30 : {
31 0 : maxBwBin = MAX_BW_HR;
32 0 : fs_idx = fs_idx + 1;
33 0 : move16();
34 : }
35 : else
36 : #endif
37 : {
38 0 : maxBwBin = MAX_BW;
39 0 : move16();
40 : }
41 :
42 0 : SWITCH (frame_dms)
43 : {
44 0 : case 25: maxBwBin = maxBwBin >> 2; move16();
45 : {
46 0 : bandsOffsetOne = bands_offset_with_one_max_2_5ms[fs_idx];
47 0 : move16();
48 0 : bandsOffsetTwo = bands_offset_with_two_max_2_5ms[fs_idx];
49 0 : move16();
50 : }
51 0 : BREAK;
52 0 : case 50: maxBwBin = maxBwBin >> 1; move16();
53 : {
54 0 : bandsOffsetOne = bands_offset_with_one_max_5ms[fs_idx];
55 0 : move16();
56 0 : bandsOffsetTwo = bands_offset_with_two_max_5ms[fs_idx];
57 0 : move16();
58 : }
59 0 : BREAK;
60 0 : case 75:
61 0 : maxBwBin = (maxBwBin >> 2) * 3; move16();
62 0 : bandsOffsetOne = bands_offset_with_one_max_7_5ms[fs_idx];
63 0 : move16();
64 0 : bandsOffsetTwo = bands_offset_with_two_max_7_5ms[fs_idx];
65 0 : move16();
66 0 : BREAK;
67 0 : default: /* 100 */
68 : {
69 0 : bandsOffsetOne = bands_offset_with_one_max[fs_idx];
70 0 : move16();
71 0 : bandsOffsetTwo = bands_offset_with_two_max[fs_idx];
72 0 : move16();
73 : }
74 0 : BREAK;
75 : }
76 :
77 0 : IF (sub(linear, 1) == 0)
78 : {
79 :
80 : #ifdef ENABLE_HR_MODE
81 0 : if (hrmode)
82 : {
83 0 : fs_idx = fs_idx - 1;
84 : }
85 : #endif
86 :
87 0 : SWITCH (frame_dms)
88 : {
89 0 : case 25:
90 0 : bandsOffsetOne = bands_offset_with_one_max_lin_2_5ms[fs_idx];
91 0 : move16();
92 0 : bandsOffsetTwo = bands_offset_with_two_max_lin_2_5ms[fs_idx];
93 0 : move16();
94 0 : BREAK;
95 0 : case 50:
96 0 : bandsOffsetOne = bands_offset_with_one_max_lin_5ms[fs_idx];
97 0 : move16();
98 0 : bandsOffsetTwo = bands_offset_with_two_max_lin_5ms[fs_idx];
99 0 : move16();
100 0 : BREAK;
101 0 : case 75:
102 0 : bandsOffsetOne = bands_offset_with_one_max_lin_7_5ms[fs_idx];
103 0 : move16();
104 0 : bandsOffsetTwo = bands_offset_with_two_max_lin_7_5ms[fs_idx];
105 0 : move16();
106 0 : BREAK;
107 0 : case 100:
108 0 : bandsOffsetOne = bands_offset_with_one_max_lin[fs_idx];
109 0 : move16();
110 0 : bandsOffsetTwo = bands_offset_with_two_max_lin[fs_idx];
111 0 : move16();
112 0 : BREAK;
113 : }
114 0 : }
115 :
116 : /* start processing with band offsets == 1 */
117 0 : FOR (band = 0; band < bandsOffsetOne; band++)
118 : {
119 0 : ASSERT((band_offsets[band + 1] - band_offsets[band]) == 1);
120 0 : ASSERT(band < maxBwBin);
121 :
122 0 : s2 = 15;
123 0 : move16();
124 0 : s = norm_l(d_fx[band]);
125 0 : if (d_fx[band] != 0)
126 0 : s2 = s_min(s2, s);
127 :
128 0 : tmp16 = extract_h(L_shl_pos(d_fx[band], s2));
129 :
130 0 : d2_fx[band] = L_mult0(tmp16, tmp16);
131 0 : move32();
132 0 : d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1));
133 0 : move16();
134 : }
135 :
136 : /* start processing with band offsets == 2 */
137 0 : i = bandsOffsetOne;
138 0 : move16();
139 0 : FOR (; band < bandsOffsetTwo; band++)
140 : {
141 0 : ASSERT((band_offsets[band + 1] - band_offsets[band]) == 2);
142 0 : IF (sub(add(i, 1), maxBwBin) >= 0)
143 : {
144 0 : IF (sub(i, maxBwBin) >= 0)
145 : {
146 0 : d2_fx[band] = 0;
147 0 : move32();
148 0 : d2_band_fx_exp[band] = sub(1, shl_pos(15, 1));
149 0 : move16();
150 : }
151 : ELSE
152 : {
153 0 : s2 = 15;
154 0 : move16();
155 0 : s = norm_l(d_fx[band]);
156 0 : if (d_fx[band] != 0)
157 0 : s2 = s_min(s2, s);
158 :
159 0 : tmp16 = extract_h(L_shl_pos(d_fx[band], s2));
160 :
161 0 : d2_fx[band] = L_mult0(tmp16, tmp16);
162 0 : move32();
163 0 : d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1));
164 0 : move16();
165 : }
166 : }
167 : ELSE
168 : {
169 0 : ASSERT(i + 1 < maxBwBin);
170 :
171 0 : s2 = 15;
172 0 : move16();
173 0 : s = norm_l(d_fx[i]);
174 0 : if (d_fx[i] != 0)
175 0 : s2 = s_min(s2, s);
176 0 : s = norm_l(d_fx[i + 1]);
177 0 : if (d_fx[i + 1] != 0)
178 0 : s2 = s_min(s2, s);
179 :
180 0 : tmp16 = extract_h(L_shl_pos(d_fx[i], s2));
181 0 : nrg = L_mult0(tmp16, tmp16);
182 0 : nrg = L_min(nrg, 0x3FFFFFFF);
183 0 : tmp16 = extract_h(L_shl_pos(d_fx[i + 1], s2));
184 :
185 0 : d2_fx[band] = L_shr_pos(L_mac0(nrg, tmp16, tmp16), 1);
186 0 : move32();
187 0 : d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1));
188 0 : move16();
189 : }
190 0 : i = add(i, 2);
191 : }
192 :
193 : /* proceed with band offsets > 2 */
194 0 : FOR (; band < n_bands; band++)
195 : {
196 : /* normalization */
197 0 : k = i;
198 0 : move16();
199 0 : s1 = 15;
200 0 : move16();
201 :
202 0 : stopBand = s_min(band_offsets[band + 1], maxBwBin);
203 0 : FOR (; k < stopBand; k++)
204 : {
205 0 : s = norm_l(d_fx[k]);
206 0 : if (d_fx[k] != 0)
207 0 : s1 = s_min(s1, s);
208 : }
209 :
210 0 : nbands = sub(band_offsets[band + 1], band_offsets[band]);
211 : #ifdef ENABLE_HR_MODE
212 0 : if (nbands < 32)
213 : {
214 0 : nbands = s_min(s_max(0, nbands), 31);
215 : /* specify headroom, it can be reduced by one due to use of L_mac0 */
216 0 : s2 = sub(s1, bands_nrg_scale[nbands]);
217 : }
218 : else
219 : {
220 : /* Active only in the 96 kHz case */
221 0 : s2 = sub(s1, 5);
222 : }
223 : #else
224 : ASSERT(nbands < 32);
225 : nbands = s_min(s_max(0, nbands), 31);
226 : /* specify headroom, it can be reduced by one due to use of L_mac0 */
227 : s2 = sub(s1, bands_nrg_scale[nbands]);
228 : #endif
229 :
230 : /* calculate energy per band */
231 0 : nrg = 0;
232 0 : move32();
233 :
234 0 : FOR (; i < stopBand; i++)
235 : {
236 0 : tmp16 = extract_h(L_shl(d_fx[i], s2));
237 0 : nrg = L_mac0(nrg, tmp16, tmp16);
238 : }
239 0 : i = band_offsets[band + 1];
240 :
241 : /* calculate mean value of energy */
242 0 : nrg = Mpy_32_16_lc3plus(nrg, InvIntTable[nbands]);
243 :
244 : /* store normalized energy */
245 0 : s = norm_l(nrg);
246 0 : d2_fx[band] = L_shl_pos(nrg, s);
247 0 : move32();
248 0 : d2_band_fx_exp[band] = sub(1, add(shl_pos(s2, 1), s));
249 0 : move16();
250 : }
251 :
252 : /* Determine maximum exponent and rescale band energies */
253 0 : smax = -31;
254 0 : move16();
255 0 : FOR (band = 0; band < n_bands; band++)
256 : {
257 0 : smax = s_max(smax, d2_band_fx_exp[band]);
258 : }
259 0 : FOR (band = 0; band < n_bands; band++)
260 : {
261 0 : d2_fx[band] = L_shr_pos(d2_fx[band], s_min(sub(smax, d2_band_fx_exp[band]), 31));
262 0 : move32();
263 : }
264 :
265 : /* Save exponent for all bands */
266 0 : *d2_fx_exp = s_max(add(shl_pos(d_fx_exp, 1), smax), -32);
267 0 : move16();
268 :
269 : Dyn_Mem_Deluxe_Out();
270 0 : }
271 :
|