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 "setup_dec_lc3.h"
13 : #include "functions.h"
14 : #include <stdio.h>
15 : #include <assert.h>
16 :
17 : /* if decoder is null only size is reported */
18 : #include "fft/iis_fft.h"
19 :
20 0 : int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels)
21 : {
22 0 : int ch = 0;
23 0 : size_t size = sizeof(LC3PLUS_Dec);
24 0 : size_t frame_len = DYN_MAX_LEN_EXT(samplerate);
25 :
26 0 : void *PlcAdvSetup = NULL;
27 : LC3_FLOAT *pcmbufHist, *harmonicBuf;
28 : LC3_FLOAT *PhECU_oold_grp_shape, *PhECU_old_grp_shape;
29 : LC3_FLOAT *PhECU_xfp;
30 : Complex *PhECU_X_sav_m;
31 : LC3_INT32 *PhECU_plocs;
32 : LC3_FLOAT *PhECU_f0est, *PhECU_mag_chg_1st, *PhECU_Xavg;
33 : LC3_FLOAT *sine_table1_phecu, *sine_table2_phecu;
34 : HANDLE_IIS_FFT handle_fft_phaseecu;
35 : HANDLE_IIS_FFT handle_ifft_phaseecu;
36 : LC3_FLOAT *q_old_res;
37 :
38 0 : LC3_INT32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL;
39 0 : LC3_INT16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0;
40 :
41 0 : for (ch = 0; ch < channels; ch++) {
42 0 : DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup));
43 :
44 0 : size_t max_pitch = ceilf(228.0 * CODEC_FS(samplerate) / 12800.0);
45 0 : size_t pcm_plc_len = max_pitch + frame_len;
46 0 : pcmbufHist = balloc(decoder, &size, sizeof(LC3_FLOAT) * pcm_plc_len);
47 0 : harmonicBuf = balloc(decoder, &size, sizeof(LC3_FLOAT) * max_pitch);
48 0 : PlcAdvSetup = balloc(decoder, &size, sizeof(*setup->PlcAdvSetup));
49 0 : PhECU_oold_grp_shape = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_oold_grp_shape_fx[MAX_LGW]; */
50 0 : PhECU_old_grp_shape = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_old_grp_shape_fx[MAX_LGW] ; */
51 0 : PhECU_xfp = balloc(decoder, &size, sizeof(LC3_FLOAT) *(frame_len * 16 / 10));
52 0 : PhECU_X_sav_m = balloc(decoder, &size, sizeof(Complex) *(((frame_len * 16 / 10) / 2) + 1));/*MAX_PLC_LMSPEC*/
53 0 : PhECU_plocs = balloc(decoder, &size, sizeof(LC3_INT32) * (((frame_len * 16 / 10) / 4) + 1 + 1)); /* BASOP Word16 *PhECU_plocs; */
54 :
55 0 : handle_fft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1);
56 0 : handle_ifft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1);
57 0 : PhECU_f0est = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((frame_len * 16 / 10) / 4) + 1)); /*BASOP Word32 *PhECU_f0est;*/
58 0 : PhECU_mag_chg_1st = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_mag_chg_1st[MAX_LGW];*/
59 0 : PhECU_Xavg = balloc(decoder, &size, sizeof(LC3_FLOAT) * MAX_LGW); /* BASOP Word16 PhECU_Xavg[MAX_LGW] ; */
60 :
61 0 : sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1));
62 0 : sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1));
63 :
64 0 : longterm_analysis_counter_max = plc_fadeout_param_maxlen[0];
65 0 : longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0];
66 :
67 0 : plc_longterm_advc_tdc = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer);
68 0 : plc_longterm_advc_ns = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer);
69 :
70 0 : q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len);
71 :
72 0 : if (decoder) {
73 0 : decoder->channel_setup[ch] = setup;
74 :
75 0 : setup->PlcAdvSetup = PlcAdvSetup;
76 :
77 0 : setup->PlcAdvSetup->pcmbufHist = pcmbufHist;
78 0 : setup->PlcAdvSetup->PlcTdcSetup.harmonicBuf = harmonicBuf;
79 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape = PhECU_oold_grp_shape;
80 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape = PhECU_old_grp_shape;
81 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp = PhECU_xfp;
82 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m = PhECU_X_sav_m;
83 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_plocs = PhECU_plocs;
84 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_f0est = PhECU_f0est;
85 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st = PhECU_mag_chg_1st;
86 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Xavg = PhECU_Xavg;
87 0 : setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu = handle_fft_phaseecu;
88 0 : setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu = handle_ifft_phaseecu;
89 :
90 0 : setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu->sine_table = sine_table1_phecu;
91 0 : setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu->sine_table = sine_table2_phecu;
92 :
93 0 : setup->PlcAdvSetup->longterm_analysis_counter_max = longterm_analysis_counter_max;
94 0 : setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer;
95 :
96 0 : setup->PlcAdvSetup->plc_longterm_advc_tdc = plc_longterm_advc_tdc;
97 0 : setup->PlcAdvSetup->plc_longterm_advc_ns = plc_longterm_advc_ns;
98 :
99 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (CODEC_FS(samplerate) * 16) / 1000;
100 0 : real_fft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu));
101 0 : real_ifft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu));
102 0 : setup->statePC.q_old_res = q_old_res;
103 : }
104 : }
105 :
106 0 : return (int)size;
107 : }
108 :
109 0 : LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode
110 : , int hrmode
111 : )
112 : {
113 0 : memset(decoder, 0, lc3plus_dec_get_size(samplerate, channels));
114 0 : alloc_decoder(decoder, samplerate, channels);
115 :
116 0 : decoder->fs = CODEC_FS(samplerate);
117 0 : decoder->fs_out = samplerate;
118 0 : decoder->fs_idx = FS2FS_IDX(decoder->fs);
119 0 : decoder->plcMeth = plc_mode;
120 :
121 0 : decoder->hrmode = hrmode != 0;
122 :
123 0 : decoder->channels = channels;
124 0 : decoder->frame_ms = 10;
125 0 : decoder->frame_dms = 100;
126 0 : decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx];
127 :
128 0 : if (decoder->fs == 8000) {
129 0 : decoder->tilt = 14;
130 0 : } else if (decoder->fs == 16000) {
131 0 : decoder->tilt = 18;
132 0 : } else if (decoder->fs == 24000) {
133 0 : decoder->tilt = 22;
134 0 : } else if (decoder->fs == 32000) {
135 0 : decoder->tilt = 26;
136 0 : } else if (decoder->fs == 48000) {
137 0 : decoder->tilt = 30;
138 : }
139 0 : else if (decoder->fs == 96000) {
140 0 : decoder->tilt = 34;
141 : }
142 :
143 0 : set_dec_frame_params(decoder);
144 :
145 0 : lc3plus_dec_set_ep_enabled(decoder, 0);
146 :
147 0 : return LC3PLUS_OK;
148 : }
149 :
150 : /* set frame config params */
151 0 : void set_dec_frame_params(LC3PLUS_Dec* decoder)
152 : {
153 0 : int ch = 0;
154 : int n;
155 :
156 0 : if (decoder->fs_idx == 5)
157 : {
158 0 : decoder->hrmode = 1;
159 : }
160 :
161 0 : decoder->frame_length = ceil(decoder->fs * 10 / 1000); /* fs * 0.01*2^6 */
162 0 : if (decoder->hrmode == 1)
163 : {
164 0 : decoder->yLen = decoder->frame_length;
165 : }
166 : else
167 : {
168 0 : decoder->yLen = MIN(MAX_BW, decoder->frame_length);
169 : }
170 :
171 0 : decoder->bands_number = 64;
172 0 : if (decoder->frame_ms == 2.5)
173 : {
174 0 : decoder->frame_length = decoder->frame_length >> 2;
175 0 : decoder->yLen /= 4;
176 0 : if (decoder->hrmode)
177 : {
178 0 : decoder->bands_number = bands_number_2_5ms_HR[decoder->fs_idx];
179 : }
180 : else
181 : {
182 0 : decoder->bands_number = bands_number_2_5ms[decoder->fs_idx];
183 : }
184 : }
185 0 : if (decoder->frame_ms == 5)
186 : {
187 0 : decoder->frame_length = decoder->frame_length >> 1;
188 0 : decoder->yLen /= 2;
189 0 : decoder->bands_number = bands_number_5ms[decoder->fs_idx];
190 : }
191 0 : if (decoder->frame_ms == 7.5)
192 : {
193 0 : decoder->frame_length = (decoder->frame_length >> 2) * 3;
194 0 : decoder->yLen = (decoder->yLen / 4) * 3;
195 0 : if (decoder->hrmode)
196 : {
197 0 : decoder->bands_number = bands_number_7_5ms_HR[decoder->fs_idx];
198 : }
199 : else
200 : {
201 0 : decoder->bands_number = bands_number_7_5ms[decoder->fs_idx];
202 : }
203 : }
204 :
205 0 : if (decoder->hrmode)
206 : {
207 0 : decoder->BW_cutoff_bits = 0;
208 : }
209 : else
210 : {
211 0 : decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx];
212 : }
213 :
214 0 : if (decoder->frame_ms == 10)
215 : {
216 0 : if (decoder->hrmode)
217 : {
218 0 : decoder->bands_offset = ACC_COEFF_PER_BAND_HR[decoder->fs_idx];
219 : }
220 : else
221 : {
222 0 : decoder->bands_offset = ACC_COEFF_PER_BAND[decoder->fs_idx];
223 : }
224 0 : decoder->cutoffBins = BW_cutoff_bin_all;
225 : }
226 0 : else if (decoder->frame_ms == 2.5)
227 : {
228 0 : if (decoder->hrmode)
229 : {
230 0 : decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[decoder->fs_idx];
231 : }
232 : else
233 : {
234 0 : decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[decoder->fs_idx];
235 : }
236 0 : decoder->cutoffBins = BW_cutoff_bin_all_2_5ms;
237 : }
238 0 : else if (decoder->frame_ms == 5)
239 : {
240 0 : if (decoder->hrmode)
241 : {
242 0 : decoder->bands_offset = ACC_COEFF_PER_BAND_5ms_HR[decoder->fs_idx];
243 : }
244 : else
245 : {
246 0 : decoder->bands_offset = ACC_COEFF_PER_BAND_5ms[decoder->fs_idx];
247 : }
248 0 : decoder->cutoffBins = BW_cutoff_bin_all_5ms;
249 : }
250 0 : else if (decoder->frame_ms == 7.5)
251 : {
252 0 : if (decoder->hrmode)
253 : {
254 0 : decoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[decoder->fs_idx];
255 : }
256 : else
257 : {
258 0 : decoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms[decoder->fs_idx];
259 : }
260 0 : decoder->cutoffBins = BW_cutoff_bin_all_7_5ms;
261 : }
262 :
263 0 : decoder->n_bandsPLC = MIN(decoder->frame_length, 80);
264 :
265 0 : if (decoder->frame_ms == 10)
266 : {
267 0 : decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC[decoder->fs_idx];
268 : }
269 0 : else if (decoder->frame_ms == 5)
270 : {
271 0 : decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_5ms[decoder->fs_idx];
272 :
273 0 : if (decoder->fs == 24000)
274 : {
275 0 : decoder->n_bandsPLC = 40;
276 : }
277 : }
278 0 : else if (decoder->frame_ms == 2.5)
279 : {
280 0 : decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_2_5ms[decoder->fs_idx];
281 :
282 0 : if (decoder->fs == 48000)
283 : {
284 0 : decoder->n_bandsPLC = 60;
285 : }
286 : }
287 0 : else if (decoder->frame_ms == 7.5)
288 : {
289 0 : decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_7_5ms[decoder->fs_idx];
290 :
291 0 : if (decoder->fs != 32000 && decoder->fs != 96000)
292 : {
293 0 : decoder->n_bandsPLC = 60;
294 : }
295 : }
296 :
297 0 : assert(decoder->bands_offsetPLC);
298 :
299 0 : if (decoder->frame_ms == 10) {
300 0 : decoder->imdct_win = MDCT_WINS_10ms[decoder->hrmode][decoder->fs_idx];
301 0 : decoder->imdct_laZeros = MDCT_la_zeroes[decoder->fs_idx];
302 0 : decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_10ms[decoder->fs_idx];
303 : }
304 0 : else if (decoder->frame_ms == 2.5) {
305 0 : decoder->imdct_win = MDCT_WINS_2_5ms[decoder->hrmode][decoder->fs_idx];
306 0 : decoder->imdct_laZeros = MDCT_la_zeroes_2_5ms[decoder->fs_idx];
307 0 : decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_2_5ms[decoder->fs_idx];
308 : }
309 0 : else if (decoder->frame_ms == 5) {
310 0 : decoder->imdct_win = MDCT_WINS_5ms[decoder->hrmode][decoder->fs_idx];
311 0 : decoder->imdct_laZeros = MDCT_la_zeroes_5ms[decoder->fs_idx];
312 0 : decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_5ms[decoder->fs_idx];
313 : }
314 0 : else if (decoder->frame_ms == 7.5) {
315 0 : decoder->imdct_win = MDCT_WINS_7_5ms[decoder->hrmode][decoder->fs_idx];
316 0 : decoder->imdct_laZeros = MDCT_la_zeroes_7_5ms[decoder->fs_idx];
317 0 : decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_7_5ms[decoder->fs_idx];
318 : }
319 :
320 0 : decoder->la_zeroes = decoder->imdct_laZeros;
321 :
322 0 : decoder->imdct_memLen = decoder->frame_length - decoder->imdct_laZeros;
323 :
324 0 : for (ch = 0; ch < decoder->channels; ch++) {
325 0 : DecSetup* setup = decoder->channel_setup[ch];
326 :
327 0 : setup->ltpf_mem_beta_idx = -1;
328 :
329 0 : setup->statePC.seed = 24607;
330 :
331 0 : if (decoder) {
332 : /* Init DCT4 structs */
333 0 : if (setup->dct4structImdct.length != 0) {
334 0 : dct4_free(&setup->dct4structImdct);
335 0 : dct4_init(&setup->dct4structImdct, decoder->frame_length);
336 : } else {
337 0 : dct4_init(&setup->dct4structImdct, decoder->frame_length);
338 : }
339 :
340 0 : setup->PlcNsSetup.cum_alpha = 1;
341 0 : setup->PlcNsSetup.seed = 24607;
342 0 : setup->alpha = 1;
343 0 : if (setup->PlcAdvSetup)
344 : {
345 0 : LC3_INT32 pitch_max = 0, pitch_ana_len = 0, tdc_synt_len = 0;
346 0 : pitch_max = ceil(228.0 * (LC3_FLOAT) decoder->fs / 12800.0);
347 0 : pitch_ana_len = pitch_max + decoder->frame_length * (LC3_FLOAT) 100 / decoder->frame_dms;
348 0 : tdc_synt_len = 16 + 1 + pitch_max + ceil(decoder->frame_length / 2);
349 0 : setup->PlcAdvSetup->max_len_pcm_plc = MAX(pitch_ana_len, tdc_synt_len);
350 0 : setup->PlcAdvSetup->PlcTdcSetup.preemphFac = plc_preemph_fac[decoder->fs_idx];
351 0 : setup->PlcAdvSetup->PlcTdcSetup.seed = 24607;
352 0 : setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 16;
353 :
354 0 : if (decoder->fs_idx == 0 && decoder->frame_dms == 25)
355 : {
356 0 : setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 8;
357 : }
358 :
359 0 : setup->PlcAdvSetup->stabFac = 1;
360 0 : setup->PlcAdvSetup->cum_fading_fast = 1;
361 0 : setup->PlcAdvSetup->cum_fading_slow = 1;
362 0 : setup->PlcAdvSetup->cum_fflcAtten = 1;
363 :
364 0 : setup->PlcAdvSetup->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1];
365 0 : setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1];
366 :
367 0 : if (decoder->fs_idx <= 4 && decoder->frame_dms == 100)
368 : {
369 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (decoder->fs * 16) / 1000; /* 16 ms of samples at fs*/
370 :
371 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin = 0;
372 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr = 0;
373 :
374 0 : set_vec(PHECU_GRP_SHAPE_INIT, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, MAX_LGW);
375 0 : set_vec(PHECU_GRP_SHAPE_INIT, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape, MAX_LGW);
376 :
377 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E = (LC3_FLOAT)PHECU_LTOT_MIN_MAN * LC3_POW(2.0, PHECU_LTOT_MIN_EXP - 31);
378 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E = (LC3_FLOAT)PHECU_LTOT_MIN_MAN * LC3_POW(2.0, PHECU_LTOT_MIN_EXP - 31);
379 :
380 : /* CFL uses separate buffers for pcmHist, xfp and Xsav and q_d , BASOP uses an optimized joint buffer*/
381 0 : zero_float(setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot);
382 0 : zero_cmplx(setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m, (setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot/2 + 1));
383 :
384 0 : set_vec(POS_ONE_Q15, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st, MAX_LGW);
385 :
386 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_beta_mute = (16384.0/32768.0);
387 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_seed = 21845;
388 :
389 0 : assert(decoder->frame_dms == 100);
390 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_LDWIN_OLAP = (decoder->frame_length / 4 ); /* 2.5 ms for regular 10 ms MDCT */
391 :
392 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_t_adv = (
393 0 : decoder->frame_length
394 0 : + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot
395 0 : + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_LDWIN_OLAP )/ 2;
396 : }
397 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev = 0; /* fullband transient */
398 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs = 0;
399 0 : setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag = -1; /* nonpure tone flag, -1==new calc., 0==pure, 1==nonpure */
400 : }
401 : }
402 : }
403 0 : for (n=0; n < LC3_ROUND(PLC_FADEOUT_TYPE_1_IN_MS*10/decoder->frame_dms);n++){
404 0 : decoder->alpha_type_2_table[n] = type_2_fadeout(n, decoder->frame_dms);
405 : }
406 0 : }
407 :
408 0 : LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes)
409 : {
410 0 : int totalBits = 0, bitsTmp = 0, channel_bytes = 0, maxBytes = 0, minBytes = 0;
411 : DecSetup* setup;
412 :
413 0 : if (decoder->hrmode)
414 : {
415 0 : switch (decoder->frame_dms)
416 : {
417 0 : case 25:
418 0 : maxBytes = 210;
419 0 : minBytes = MIN_NBYTES;
420 0 : break;
421 0 : case 50:
422 0 : maxBytes = 375;
423 0 : minBytes = MIN_NBYTES;
424 0 : break;
425 0 : case 75:
426 0 : maxBytes = 625;
427 0 : minBytes = MIN_NBYTES;
428 0 : break;
429 0 : case 100:
430 0 : maxBytes = 625;
431 0 : minBytes = MIN_NBYTES;
432 0 : break;
433 0 : default:
434 0 : return LC3PLUS_HRMODE_ERROR;
435 : }
436 : }
437 : else
438 : {
439 0 : minBytes = MIN_NBYTES;
440 0 : maxBytes = MAX_NBYTES_100; /* for backward compatibility, MAX_NBYTES_100 is used for all frame lengths */
441 : }
442 :
443 0 : channel_bytes = nBytes;
444 :
445 0 : setup = decoder->channel_setup[ch];
446 :
447 0 : if (channel_bytes < minBytes || channel_bytes > maxBytes)
448 : {
449 0 : return LC3PLUS_NUMBYTES_ERROR;
450 : }
451 :
452 0 : setup->targetBytes = channel_bytes;
453 0 : setup->total_bits = setup->targetBytes << 3;
454 0 : setup->enable_lpc_weighting = (setup->total_bits < 480);
455 0 : setup->quantizedGainOff =
456 0 : -(MIN(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1));
457 :
458 0 : if (decoder->hrmode && decoder->fs_idx == 5)
459 : {
460 0 : setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181);
461 : }
462 :
463 0 : totalBits = setup->total_bits;
464 :
465 0 : if (decoder->frame_ms == 2.5) {
466 0 : setup->enable_lpc_weighting = setup->total_bits < 120;
467 0 : totalBits = setup->total_bits * 4.0 * (1.0 - 0.4);
468 : }
469 0 : if (decoder->frame_ms == 5) {
470 0 : setup->enable_lpc_weighting = (setup->total_bits < 240);
471 0 : totalBits = setup->total_bits * 2 - 160;
472 : }
473 0 : if (decoder->frame_ms == 7.5) {
474 0 : setup->enable_lpc_weighting = (setup->total_bits < 360);
475 0 : totalBits = round(setup->total_bits * 10 / 7.5);
476 : }
477 :
478 0 : if (decoder->frame_length > 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0)) {
479 0 : setup->N_red_tns = 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0);
480 0 : setup->fs_red_tns = 40000;
481 : } else {
482 0 : setup->N_red_tns = decoder->frame_length;
483 0 : setup->fs_red_tns = decoder->fs;
484 : }
485 :
486 0 : bitsTmp = totalBits;
487 :
488 0 : if (bitsTmp < 400 + (decoder->fs_idx - 1) * 80) {
489 0 : setup->ltpf_conf_beta = 0.4;
490 0 : setup->ltpf_conf_beta_idx = 0;
491 0 : } else if (bitsTmp < 480 + (decoder->fs_idx - 1) * 80) {
492 0 : setup->ltpf_conf_beta = 0.35;
493 0 : setup->ltpf_conf_beta_idx = 1;
494 0 : } else if (bitsTmp < 560 + (decoder->fs_idx - 1) * 80) {
495 0 : setup->ltpf_conf_beta = 0.3;
496 0 : setup->ltpf_conf_beta_idx = 2;
497 0 : } else if (bitsTmp < 640 + (decoder->fs_idx - 1) * 80) {
498 0 : setup->ltpf_conf_beta = 0.25;
499 0 : setup->ltpf_conf_beta_idx = 3;
500 : } else {
501 0 : setup->ltpf_conf_beta = 0;
502 0 : setup->ltpf_conf_beta_idx = -1;
503 : }
504 :
505 : /* No LTPF in hrmode */
506 0 : if (decoder->hrmode == 1) {
507 0 : setup->ltpf_conf_beta = 0;
508 0 : setup->ltpf_conf_beta_idx = -1;
509 : }
510 :
511 0 : return LC3PLUS_OK;
512 : }
|