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