Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.6.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 "options.h"
11 : #include "wmc_auto.h"
12 : #include "functions.h"
13 :
14 1174108 : static LC3_INT32 change_bit_at_position(LC3_INT32 value, LC3_UINT8 bit_position, LC3_INT8 bit)
15 : {
16 1174108 : LC3_INT32 helper_mask = ~(1 << bit_position);
17 1174108 : LC3_INT32 tmp = value & helper_mask;
18 1174108 : tmp = tmp | (bit << bit_position);
19 1174108 : return tmp;
20 : }
21 :
22 587054 : static void update_bit_and_byte_positions(LC3_INT16 longterm_analysis_counter_max_bytebuffer, LC3_INT8 *byte_position, LC3_INT8 *bit_position)
23 : {
24 587054 : if (*bit_position == 29)
25 : {
26 19246 : *bit_position = 0;
27 :
28 19246 : if ((*byte_position - longterm_analysis_counter_max_bytebuffer) < -1)
29 : {
30 18058 : *byte_position = *byte_position + 1;
31 : } else {
32 1188 : *byte_position = 0;
33 : }
34 : } else {
35 567808 : *bit_position = *bit_position + 1;
36 : }
37 587054 : }
38 :
39 1174108 : static void array_insert_and_shift(LC3_INT32 *array, LC3_UINT8 value, LC3_INT16 longterm_analysis_counter_max, LC3_INT16 *overall_counter, LC3_INT8 *byte_position, LC3_INT8 *bit_position)
40 : {
41 1174108 : LC3_INT32 current_byte = 0;
42 :
43 1174108 : if (overall_counter != NULL)
44 : {
45 587054 : *overall_counter = MIN(*overall_counter + 1, longterm_analysis_counter_max);
46 : }
47 :
48 1174108 : current_byte = array[*byte_position];
49 :
50 1174108 : current_byte = change_bit_at_position(current_byte, *bit_position, value);
51 :
52 1174108 : array[*byte_position] = current_byte;
53 1174108 : }
54 :
55 587054 : static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int length, LC3_INT16 *counter_tdc, LC3_INT16 *counter_ns, LC3_INT16 longterm_analysis_counter_max)
56 : {
57 : int i, k;
58 587054 : LC3_INT32 current_byte_tdc = 0, current_byte_ns = 0;
59 587054 : LC3_INT16 counter_loc_tdc = 0, counter_loc_ns = 0, counter_tmp = 0;
60 :
61 8581810 : for (i = length - 1; i >= 0; i--)
62 : {
63 7994756 : current_byte_tdc = array_tdc[i];
64 7994756 : current_byte_ns = array_ns[i];
65 :
66 235829302 : for (k = 0; k < 30; k++)
67 : {
68 228421600 : counter_loc_tdc += ((current_byte_tdc >> k) & 1);
69 228421600 : counter_loc_ns += ((current_byte_ns >> k) & 1);
70 228421600 : counter_tmp++;
71 :
72 : /* Break from both loops if full 2s buffer has been evaluated */
73 228421600 : if (counter_tmp >= longterm_analysis_counter_max)
74 : {
75 587054 : i = -1;
76 587054 : k = 30;
77 587054 : break;
78 : }
79 : }
80 : }
81 :
82 587054 : *counter_tdc = counter_loc_tdc;
83 587054 : *counter_ns = counter_loc_ns;
84 587054 : }
85 :
86 : static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, LC3PLUS_FrameDuration frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr);
87 : static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *bands_offset, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc);
88 :
89 590506 : void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *nbLostCmpt, LC3_INT32 bfi,
90 : LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3PLUS_FrameDuration frame_dms, LC3_INT32 pitch_int,
91 : LC3_INT32 fs, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 tilt, PlcAdvSetup *plcAd
92 : , LC3_INT32 hrmode
93 : )
94 : {
95 : LC3_FLOAT sc, class;
96 : int fs_idx_tmp;
97 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
98 590506 : LC3_INT16 resetClassifierThreshold = 0;
99 590506 : LC3_INT16 updateStatistics = 0;
100 : #endif
101 :
102 590506 : if (plcAd)
103 : {
104 590506 : *xcorr = 0;
105 : }
106 :
107 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
108 590506 : switch (frame_dms)
109 : {
110 : #ifdef CR9_C_ADD_1p25MS
111 0 : case LC3PLUS_FRAME_DURATION_1p25MS:
112 0 : resetClassifierThreshold = 16;
113 0 : break;
114 : #endif
115 0 : case LC3PLUS_FRAME_DURATION_2p5MS:
116 0 : resetClassifierThreshold = 8;
117 0 : break;
118 558314 : case LC3PLUS_FRAME_DURATION_5MS:
119 558314 : resetClassifierThreshold = 4;
120 558314 : break;
121 0 : case LC3PLUS_FRAME_DURATION_7p5MS:
122 0 : resetClassifierThreshold = 3;
123 0 : break;
124 32192 : case LC3PLUS_FRAME_DURATION_10MS:
125 32192 : resetClassifierThreshold = 2;
126 32192 : break;
127 0 : case LC3PLUS_FRAME_DURATION_UNDEFINED: assert(0);
128 : }
129 :
130 590506 : if (plcAd->numberOfGoodFrames > resetClassifierThreshold)
131 : {
132 587054 : updateStatistics = 1;
133 : } else {
134 3452 : updateStatistics = 0;
135 : }
136 : #endif
137 :
138 590506 : fs_idx_tmp = FS2FS_IDX(fs);
139 : /* Save statistics for 24 kHz, 48 kHz and 96 kHz */
140 590506 : if ((bfi == 1) || ((bfi >= 0) && (bfi <= 2) && ((fs_idx_tmp == 2) || (fs_idx_tmp == 4) || (fs_idx_tmp == 5)))) /* Partial Concealment PC(bfi==2) requires allowing value 2 to pass thru as well */
141 : {
142 590506 : if (bfi == 1)
143 : {
144 0 : *nbLostCmpt = *nbLostCmpt + 1;
145 : }
146 :
147 : /* Use pitch correlation at ltpf integer lag if available */
148 590506 : if ((*nbLostCmpt == 1) || (bfi != 1) )/* PC(bfi==2) requires allowing 2 to pass thru as well */
149 : {
150 590506 : *concealMethod = 4; /* Noise Substitution */
151 : UNUSED(plcMeth);
152 :
153 : /* Advanced PLC */
154 590506 : if (pitch_int > 0)
155 : {
156 490406 : *concealMethod = 3; /* Timedomain PLC assumed */
157 490406 : plc_xcorr_lc(plcAd->pcmbufHist, plcAd->max_len_pcm_plc, pitch_int, framelength, frame_dms, fs, xcorr);
158 :
159 490406 : spectral_centroid_lc(plcAd->scf_q_old, tilt, band_offsets, bands_number, framelength, fs, &sc);
160 490406 : class = *xcorr * 7640.0 / 32768.0 - sc - 5112.0 / 32768.0;
161 :
162 490406 : if (class <= 0)
163 : {
164 159232 : if (frame_dms == LC3PLUS_FRAME_DURATION_10MS && hrmode == 0)
165 : {
166 7344 : *concealMethod = 2; /* PhaseEcu selected */
167 :
168 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
169 7344 : if (updateStatistics == 1)
170 : #endif
171 : {
172 7344 : array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
173 7344 : array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
174 : }
175 : }
176 : else
177 : {
178 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
179 151888 : if (updateStatistics == 1)
180 : #endif
181 : {
182 151631 : array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
183 151631 : array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
184 : }
185 : }
186 : }
187 : else {
188 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
189 331174 : if (updateStatistics == 1)
190 : #endif
191 : {
192 331101 : array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
193 331101 : array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
194 : }
195 : }
196 : }
197 : else
198 : {
199 100100 : *concealMethod = 4; /* Noise Substitution */
200 :
201 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
202 100100 : if (updateStatistics == 1)
203 : #endif
204 : {
205 96978 : array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
206 96978 : array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
207 : }
208 : }
209 :
210 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
211 590506 : if (updateStatistics == 1)
212 : #endif
213 : {
214 587054 : array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max);
215 587054 : update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position);
216 : }
217 : }
218 : }
219 :
220 : #ifdef CR13_C_RESET_CLASSIFIER_AFTER_BAD_FRAMES
221 590506 : if (bfi == 1)
222 : {
223 0 : plcAd->numberOfGoodFrames = 0;
224 : } else {
225 590506 : plcAd->numberOfGoodFrames = plcAd->numberOfGoodFrames + 1;
226 : }
227 : #endif
228 590506 : }
229 :
230 490406 : static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc)
231 : {
232 : LC3_FLOAT gains_lin[M], gains_dee[M], numerator, denumerator;
233 : LC3_INT32 i, j, sum, len, start, stop;
234 : LC3_INT band_offsets_local[MAX_BANDS_NUMBER + 1];
235 :
236 490406 : numerator = 0;
237 :
238 8336902 : for (i = 0; i < M; i++)
239 : {
240 7846496 : gains_lin[i] = LC3_POW(2, gains[i]);
241 : }
242 :
243 8336902 : for (i = 0; i < M; i++)
244 : {
245 7846496 : gains_dee[i] = gains_lin[i] / LC3_POW(10, i * (LC3_FLOAT) tilt / (LC3_FLOAT) (M - 1) / 10.0);
246 : }
247 :
248 490406 : if (bands_number == 64)
249 : {
250 27884 : memmove(band_offsets_local, band_offsets, (bands_number + 1) * sizeof(LC3_INT));
251 : }
252 :
253 490406 : if (bands_number < 32)
254 : {
255 0 : band_offsets_local[0] = 0;
256 0 : j = 32 - bands_number;
257 0 : for (i = bands_number - 1; i >= j; i--)
258 : {
259 0 : band_offsets_local[(i + j) * 2 + 1 + 1] = band_offsets[i + 1];
260 0 : band_offsets_local[(i + j) * 2 + 0 + 1] = band_offsets[i + 1];
261 : }
262 0 : for (i = j - 1; i >= 0; i--)
263 : {
264 0 : band_offsets_local[i * 4 + 3 + 1] = band_offsets[i + 1];
265 0 : band_offsets_local[i * 4 + 2 + 1] = band_offsets[i + 1];
266 0 : band_offsets_local[i * 4 + 1 + 1] = band_offsets[i + 1];
267 0 : band_offsets_local[i * 4 + 0 + 1] = band_offsets[i + 1];
268 : }
269 : }
270 : else
271 490406 : if (bands_number < 64)
272 : {
273 462522 : band_offsets_local[0] = 0;
274 462522 : j = 64 - bands_number;
275 21738534 : for (i = bands_number - 1; i >= j; i--)
276 : {
277 21276012 : band_offsets_local[i + j + 1] = band_offsets[i + 1];
278 : }
279 4625220 : for (i = j - 1; i >= 0; i--)
280 : {
281 4162698 : band_offsets_local[i * 2 + 1 + 1] = band_offsets[i + 1];
282 4162698 : band_offsets_local[i * 2 + 0 + 1] = band_offsets[i + 1];
283 : }
284 : }
285 :
286 490406 : denumerator = 0.001;
287 :
288 8336902 : for (i = 0; i < M; i++)
289 : {
290 7846496 : sum = 0; len = 0;
291 7846496 : start = band_offsets_local[i * 4] + 1; stop = band_offsets_local[i * 4 + 4];
292 :
293 111504496 : for (j = stop; j >= start; j--)
294 : {
295 103658000 : sum += j;
296 103658000 : len++;
297 : }
298 :
299 7846496 : numerator += gains_dee[i] * ((LC3_FLOAT) sum / (LC3_FLOAT) framelength);
300 7846496 : denumerator += gains_dee[i] * len;
301 : }
302 :
303 490406 : *sc = numerator / denumerator;
304 490406 : *sc = *sc * (LC3_FLOAT) fs / 48000.0; /* scaling, because training is for 48kHz */
305 490406 : }
306 :
307 490406 : static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength,
308 : LC3PLUS_FrameDuration frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr)
309 : {
310 : LC3_INT32 max_corr_len, pitch_min, corr_len, min_corr_len, pcm_max_corr_len, range1Start, range2Start, i;
311 : LC3_FLOAT norm_w, norm_w_t;
312 :
313 490406 : norm_w_t = 0; norm_w = 0;
314 :
315 490406 : assert(pitch_int >= 0);
316 490406 : assert(pitch_int <= MAX_LEN*100*MAX_PITCH_12K8/12800);
317 :
318 490406 : *xcorr = 0;
319 :
320 490406 : if (pitch_int > 0)
321 : {
322 490406 : pitch_min = fs * MIN_PITCH_12K8/12800;
323 490406 : pcm_max_corr_len = max_len_pcm_plc - pitch_int;
324 :
325 490406 : min_corr_len = 2 * pitch_min; /* at least 5 ms (=2*pitchmin*) corr length */
326 490406 : max_corr_len = framelength*100/(frame_dms*1.25*10); /* maximum 10 ms */
327 490406 : max_corr_len = MIN( max_corr_len, pcm_max_corr_len );
328 :
329 490406 : corr_len = MIN( max_corr_len, pitch_int ); /* pitch_int is prefered, but maximum 10ms or left pcm buf size */
330 490406 : corr_len = MAX( min_corr_len, corr_len );
331 :
332 490406 : range1Start = max_len_pcm_plc - corr_len;
333 490406 : range2Start = range1Start - pitch_int;
334 :
335 490406 : assert( corr_len >= min_corr_len );
336 490406 : assert( corr_len <= max_corr_len );
337 490406 : assert( range2Start >= 0 );
338 :
339 166273062 : for (i = 0; i < corr_len; i++)
340 : {
341 165782656 : norm_w += pcmbufHist[range1Start + i] * pcmbufHist[range1Start + i];
342 : }
343 :
344 166273062 : for (i = 0; i < corr_len; i++)
345 : {
346 165782656 : norm_w_t += pcmbufHist[range2Start + i] * pcmbufHist[range2Start + i];
347 : }
348 :
349 166273062 : for (i = 0; i < corr_len; i++)
350 : {
351 165782656 : *xcorr = *xcorr + pcmbufHist[range1Start + i] * pcmbufHist[range2Start + i];
352 : }
353 :
354 490406 : *xcorr = *xcorr / sqrt(norm_w * norm_w_t + 0.1);
355 490406 : *xcorr = MAX(0, *xcorr);
356 : } else {
357 0 : *xcorr = 0;
358 : }
359 490406 : }
360 :
|