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 590506 : void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi,
15 : PlcAdvSetup *PlcAdvSetup, PlcSetup *PlcSetup, LC3_INT plcMeth, LC3_INT ltpf_pitch_int, LC3_INT ltpf_pitch_fr,
16 : LC3_INT tilt, const LC3_INT *bands_offset, LC3_INT bands_number, const LC3_INT *bands_offsetPLC,
17 : LC3_INT n_bandsPLC, LC3_INT16 hrmode, pcState *statePC
18 : )
19 : {
20 : LC3_FLOAT r[MAX_BANDS_NUMBER_PLC], A[M + 1], synth[MAX_LEN + MDCT_MEM_LEN_MAX], energies[MAX_BANDS_NUMBER_PLC];
21 : LC3_INT32 pitch_classifier;
22 : LC3_FLOAT xcorr;
23 : LC3_INT32 yLen;
24 : LC3_INT16 prev_bfi_plc2;
25 : LC3_FLOAT phEcu_env_stab_local[1];
26 : LC3_FLOAT phEcu_pfind_sens[1];
27 :
28 590506 : LC3_INT16 consecutiveLostThreshold = 0;
29 :
30 : LC3_INT16 thresh_tdc_cnt;
31 : LC3_INT16 thresh_ns_cnt;
32 : LC3_INT16 thresh_tdc_ns_cnt;
33 :
34 590506 : prev_bfi_plc2 = 1;
35 590506 : if (PlcSetup->nbLostCmpt == 0)
36 : {
37 590506 : prev_bfi_plc2 = 0;
38 : }
39 590506 : assert((h_DecSetup->PlcSetup.prevBfi == 1) == (prev_bfi_plc2 == 1));
40 :
41 590506 : if (bfi == 1 && PlcAdvSetup)
42 : {
43 : /* FFLC increases the PFLC counter */
44 0 : statePC->ns_nbLostCmpt_pc = statePC->ns_nbLostCmpt_pc + 1;
45 : }
46 :
47 590506 : pitch_classifier = ltpf_pitch_int;
48 :
49 590506 : processPlcClassify_fl(plcMeth, &h_DecSetup->concealMethod, &PlcSetup->nbLostCmpt, bfi, &xcorr,
50 : decoder->frame_length, decoder->frame_dms, pitch_classifier, decoder->fs,
51 : bands_offset, bands_number, tilt, PlcAdvSetup, hrmode
52 : );
53 :
54 590506 : if (bfi == 1)
55 : {
56 0 : switch(decoder->frame_dms)
57 : {
58 : #ifdef FIX_ADDITONAL_1p25_ISSUES
59 0 : case LC3PLUS_FRAME_DURATION_1p25MS: consecutiveLostThreshold = 32;
60 0 : thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT;
61 0 : thresh_ns_cnt = THRESH_025_DMS_NS_CNT;
62 0 : thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT;
63 0 : break;
64 : #endif
65 0 : case LC3PLUS_FRAME_DURATION_2p5MS: consecutiveLostThreshold = 16;
66 0 : thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT;
67 0 : thresh_ns_cnt = THRESH_025_DMS_NS_CNT;
68 0 : thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT;
69 0 : break;
70 0 : case LC3PLUS_FRAME_DURATION_5MS: consecutiveLostThreshold = 8;
71 0 : thresh_tdc_cnt = THRESH_050_DMS_TDC_CNT;
72 0 : thresh_ns_cnt = THRESH_050_DMS_NS_CNT;
73 0 : thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT;
74 0 : break;
75 0 : case LC3PLUS_FRAME_DURATION_7p5MS: consecutiveLostThreshold = 6;
76 0 : thresh_tdc_cnt = THRESH_075_DMS_TDC_CNT;
77 0 : thresh_ns_cnt = THRESH_075_DMS_NS_CNT;
78 0 : thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT;
79 0 : break;
80 0 : case LC3PLUS_FRAME_DURATION_10MS: consecutiveLostThreshold = 4;
81 0 : thresh_tdc_cnt = THRESH_100_DMS_TDC_CNT;
82 0 : thresh_ns_cnt = THRESH_100_DMS_NS_CNT;
83 0 : thresh_tdc_ns_cnt = THRESH_100_DMS_TDC_NS_CNT;
84 0 : break;
85 0 : default: assert(0);
86 : }
87 :
88 0 : if (decoder->fs_idx == 2 || decoder->fs_idx >= 4)
89 : {
90 0 : if (PlcAdvSetup->longterm_counter_plcTdc < thresh_tdc_cnt){
91 0 : PlcAdvSetup->plc_fadeout_type = 1;
92 : }
93 0 : else if (PlcAdvSetup->longterm_counter_plcNsAdv < thresh_ns_cnt){
94 0 : PlcAdvSetup->plc_fadeout_type = 1;
95 : }
96 0 : else if (PlcAdvSetup->longterm_counter_plcTdc + PlcAdvSetup->longterm_counter_plcNsAdv < thresh_tdc_ns_cnt){
97 0 : PlcAdvSetup->plc_fadeout_type = 1;
98 : }
99 : else {
100 0 : PlcAdvSetup->plc_fadeout_type = 0;
101 : }
102 :
103 0 : if ((PlcAdvSetup->overall_counter - (int)(PLC_LONGTERM_ANALYSIS_STARTUP_FILL * PlcAdvSetup->longterm_analysis_counter_max)) < 0)
104 : {
105 0 : PlcAdvSetup->plc_fadeout_type = 0;
106 : }
107 0 : if (h_DecSetup->rel_pitch_change > REL_PITCH_THRESH && hrmode == 1 && (decoder->frame_dms == LC3PLUS_FRAME_DURATION_5MS || decoder->frame_dms == LC3PLUS_FRAME_DURATION_2p5MS) ){
108 0 : PlcAdvSetup->plc_fadeout_type = 2;
109 : } else
110 0 : if ( h_DecSetup->concealMethod != 2 ) {
111 : /* not PhECU */
112 0 : if (PlcSetup->nbLostCmpt < consecutiveLostThreshold )
113 : {
114 0 : PlcAdvSetup->plc_fadeout_type = 0;
115 : }
116 : }
117 : } else {
118 0 : PlcAdvSetup->plc_fadeout_type = 0;
119 : }
120 :
121 0 : switch (h_DecSetup->concealMethod)
122 : {
123 0 : case 2:
124 : {
125 : LC3_FLOAT pitch_fl_c;
126 :
127 0 : assert(decoder->fs_idx == floor(decoder->fs / 10000));
128 : /* phaseECU supports only 10ms framing*/
129 0 : assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == LC3PLUS_FRAME_DURATION_10MS);
130 :
131 0 : if (decoder->frame_dms != LC3PLUS_FRAME_DURATION_10MS)
132 : {
133 : /* muting, if frame size changed during phaseECU concealment */
134 0 : memset(q_d_fl_c, 0, sizeof(LC3_FLOAT) * decoder->frame_length);
135 0 : h_DecSetup->alpha = 0;
136 0 : break;
137 : }
138 :
139 : /* call phaseEcu */
140 0 : pitch_fl_c = (LC3_FLOAT)ltpf_pitch_int + (LC3_FLOAT)ltpf_pitch_fr / 4.0; /* use non-rounded pitch indeces */
141 :
142 :
143 0 : if (prev_bfi_plc2 == 0)
144 : {
145 : /* convert fractional pitch lag info at current fs to a normalized fractional bin-frequency */
146 0 : PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin = plc_phEcuSetF0Hz(decoder->fs, &pitch_fl_c);
147 : /* several buffers used in Cflt , a copy pcmbufHist, right before calling PhEcu in bad frames */
148 0 : assert(bfi == 1);
149 0 : move_float(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp,
150 0 : &(PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot]),
151 : PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot);
152 :
153 : /* a first bfi frame:: calc windowed 16 ms energy twice in a 26 ms buffer separated by 10 ms*/
154 : {
155 : const LC3_FLOAT *w, *prev_xfp;
156 : LC3_INT32 i, oold_start;
157 :
158 0 : oold_start = PlcAdvSetup->max_len_pcm_plc - (decoder->frame_length + PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot);
159 0 : assert(oold_start > 0);
160 0 : w = PhECU_whr16ms_wins[decoder->fs_idx]; /* hammrect table */
161 0 : prev_xfp = &(PlcAdvSetup->pcmbufHist[oold_start + 0]);
162 :
163 0 : PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E = 0;
164 0 : PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E = 0;
165 0 : for (i = 0; i < PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot; i++)
166 : {
167 0 : PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E += sqrf(prev_xfp[i] * w[i]);
168 0 : PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E += sqrf(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp[i] * w[i]);
169 : }
170 :
171 : }
172 :
173 : } /* (prev_bfi_plc2 == 0)*/
174 : else
175 : {
176 : /* overwrite last 3.75 ms of xfp with most recent pcmbufHist tail , right before calling PhEcu in bursts of bad frames */
177 0 : LC3_INT32 lenCopyOla = decoder->la_zeroes; /*copy_part + ola_part = 3.75 ms for 10 ms frame*/
178 :
179 0 : assert(bfi == 1 && prev_bfi_plc2);
180 0 : move_float(&(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp[PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot-lenCopyOla]),
181 0 : &(PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - lenCopyOla]), lenCopyOla);
182 :
183 : }
184 :
185 : {
186 : LC3_FLOAT x_tda[MAX_LEN]; /* 960/2 */
187 0 : PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr = xcorr;
188 0 : phEcu_env_stab_local[0] = (LC3_FLOAT)PHECU_ENV_STAB_LOCAL;
189 0 : phEcu_pfind_sens[0] = (LC3_FLOAT)PHECU_PFIND_SENS;
190 :
191 0 : plc_phEcu_hq_ecu(&(PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin),
192 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr),
193 : PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp,
194 : prev_bfi_plc2,
195 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev),
196 : decoder->fs,
197 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_time_offs),
198 : PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m, /* Complex */
199 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs),
200 : PlcAdvSetup->PlcPhEcuSetup.PhECU_plocs,
201 : PlcAdvSetup->PlcPhEcuSetup.PhECU_f0est,
202 0 : MDCT_WINS_10ms[hrmode][decoder->fs_idx],
203 :
204 : phEcu_env_stab_local,
205 : PHECU_DELTA_CORR,
206 : phEcu_pfind_sens,
207 : PHECU_LA,
208 : PlcAdvSetup->PlcPhEcuSetup.PhECU_t_adv,
209 0 : PhECU_whr16ms_wins[decoder->fs_idx],
210 : PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape,
211 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E),
212 : PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape,
213 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E),
214 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_beta_mute),
215 : PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st,
216 : PlcAdvSetup->PlcPhEcuSetup.PhECU_Xavg,
217 : decoder->la_zeroes,
218 : x_tda, /* time domain aliased output */
219 : NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
220 : ,
221 : &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft),
222 : &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft)
223 0 : ,PlcAdvSetup->plc_fadeout_type,
224 : &(PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag) /* nonpure tone flag */
225 : );
226 :
227 :
228 0 : ProcessingITDA_WIN_OLA_fl(x_tda, decoder->frame_length, decoder->imdct_win, decoder->imdct_winLen, decoder->imdct_laZeros,
229 0 : h_DecSetup->imdct_mem, synth);
230 0 : move_float(syntM_fl_c, synth, decoder->frame_length);
231 :
232 :
233 : }
234 : }
235 0 : break;
236 0 : case 3:
237 0 : if (PlcSetup->nbLostCmpt == 1)
238 : {
239 0 : PlcAdvSetup->PlcTdcSetup.fract = ltpf_pitch_fr;
240 : }
241 :
242 0 : processPerBandEnergy_fl(n_bandsPLC, bands_offsetPLC, hrmode, decoder->frame_dms, energies, PlcSetup->q_d_prev);
243 0 : processTdcPreemphasis_fl(energies, &PlcAdvSetup->PlcTdcSetup.preemphFac, n_bandsPLC);
244 0 : processTdcInverseOdft_fl(energies, n_bandsPLC, r, PlcAdvSetup->PlcTdcSetup.lpcorder);
245 0 : processTdcLpcEstimation_fl(r, decoder->fs_idx, PlcAdvSetup->PlcTdcSetup.lpcorder + 1, A, decoder->frame_dms);
246 0 : processTdcApply_fl(ltpf_pitch_int, &PlcAdvSetup->PlcTdcSetup.preemphFac, A, PlcAdvSetup->PlcTdcSetup.lpcorder, PlcAdvSetup->pcmbufHist, PlcAdvSetup->max_len_pcm_plc, decoder->frame_length,
247 0 : decoder->frame_dms, decoder->fs, PlcSetup->nbLostCmpt, decoder->frame_length - decoder->la_zeroes, &PlcAdvSetup->stabFac, PlcAdvSetup->PlcTdcSetup.harmonicBuf,
248 0 : PlcAdvSetup->PlcTdcSetup.synthHist, &PlcAdvSetup->PlcTdcSetup.fract, &PlcAdvSetup->PlcTdcSetup.seed, &PlcAdvSetup->PlcTdcSetup.gain_c,
249 : &h_DecSetup->alpha, synth
250 0 : , PlcAdvSetup->plc_fadeout_type
251 0 : , decoder->alpha_type_2_table
252 : );
253 :
254 0 : processTdcTdac_fl(synth, decoder->imdct_win, decoder->frame_length, decoder->la_zeroes, h_DecSetup->imdct_mem);
255 0 : memmove(syntM_fl_c, synth, sizeof(LC3_FLOAT) * decoder->frame_length);
256 0 : break;
257 0 : case 4:
258 0 : processNoiseSubstitution_fl(q_d_fl_c, PlcSetup->q_d_prev, decoder->yLen);
259 0 : break;
260 590506 : default:
261 : assert("Invalid PLC method!");
262 : }
263 : }
264 :
265 590506 : if (bfi == 0)
266 : {
267 590506 : processPlcUpdateSpec_fl(PlcSetup->q_d_prev, q_d_fl_c, decoder->yLen);
268 : }
269 :
270 590506 : yLen = MIN(decoder->frame_length, MAX_PLC_LMEM);
271 590506 : if (PlcAdvSetup != NULL && (decoder->frame_dms == LC3PLUS_FRAME_DURATION_10MS) && (hrmode == 0))
272 : {
273 : /* BASOP processPLCspec2shape_fx(prev_bfi, bfi, q_old_d_fx, yLen, plcAd->PhECU_oold_grp_shape_fx, plcAd->PhECU_old_grp_shape_fx);*/
274 32192 : plc_phEcu_processPLCspec2shape(prev_bfi_plc2, bfi, q_d_fl_c, yLen,
275 : PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape);
276 : }
277 590506 : }
278 :
|