Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdint.h>
34 : #include "options.h"
35 : #include "ivas_cnst.h"
36 : #include "prot_fx.h"
37 : #include "wmc_auto.h"
38 : #include <assert.h>
39 : #include "stat_enc.h"
40 : #include "ivas_prot_fx.h"
41 :
42 : /*----------------------------------------------------------*
43 : * indexToChannelPair()
44 : *
45 : * get the index of each channel pair
46 : *----------------------------------------------------------*/
47 :
48 89017 : static void indexToChannelPair_fx(
49 : MCT_DEC_BLOCK_DATA_HANDLE hBlock,
50 : const Word16 nChannels,
51 : const Word16 pairIdx )
52 : {
53 : Word16 ch1, ch2;
54 89017 : Word16 tmpIdx = 0;
55 89017 : move16();
56 :
57 336812 : FOR( ch2 = 1; ch2 < nChannels; ch2++ )
58 : {
59 1085680 : FOR( ch1 = 0; ch1 < ch2; ch1++ )
60 : {
61 837885 : IF( EQ_16( tmpIdx, pairIdx ) )
62 : {
63 89017 : hBlock->ch1 = ch1;
64 89017 : move16();
65 89017 : hBlock->ch2 = ch2;
66 89017 : move16();
67 :
68 89017 : return;
69 : }
70 : ELSE
71 : {
72 748868 : tmpIdx = add( tmpIdx, 1 );
73 : }
74 : }
75 : }
76 :
77 0 : return;
78 : }
79 :
80 :
81 : /*-------------------------------------------------------------------*
82 : * ivas_mct_dec_mct()
83 : *
84 : * decode core and mct information
85 : *-------------------------------------------------------------------*/
86 :
87 96687 : void ivas_mct_dec_mct_fx(
88 : MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */
89 : Decoder_State **sts, /* i/o: decoder state structure */
90 : const Word16 nchan /* i : number of channels */
91 : )
92 : {
93 : Word16 pair, ch, channelPairIndex;
94 : MCT_DEC_BLOCK_DATA_HANDLE hBlock;
95 : Decoder_State *p_st[CPE_CHANNELS];
96 96687 : Word16 nchan_active = 0;
97 96687 : move16();
98 :
99 96687 : hMCT->currBlockDataCnt = get_next_indice_fx( sts[0], MCT_NUM_BLOCK_DATA_BITS );
100 96687 : move16();
101 :
102 : /*first get core and overlap info for all channels*/
103 554629 : FOR( ch = 0; ch < nchan; ch++ )
104 : {
105 457942 : test();
106 457942 : IF( hMCT->currBlockDataCnt && NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
107 : {
108 277020 : hMCT->mc_global_ild[ch] = get_next_indice_fx( sts[0], SMDCT_GLOBAL_ILD_BITS );
109 277020 : move16();
110 : }
111 : ELSE
112 : {
113 180922 : hMCT->mc_global_ild[ch] = 0;
114 180922 : move16();
115 : }
116 : }
117 :
118 96687 : IF( hMCT->currBlockDataCnt )
119 : {
120 334378 : FOR( ch = 0; ch < nchan; ch++ )
121 : {
122 280268 : IF( NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
123 : {
124 277020 : hMCT->lowE_ch[ch] = get_next_indice_fx( sts[0], 1 );
125 277020 : move16();
126 : }
127 : }
128 : }
129 :
130 554629 : FOR( ch = 0; ch < nchan; ch++ )
131 : {
132 457942 : if ( NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
133 : {
134 449471 : nchan_active = add( nchan_active, 1 );
135 : }
136 : }
137 :
138 185704 : FOR( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
139 : {
140 89017 : assert( GE_16( nchan_active, 2 ) );
141 89017 : hBlock = hMCT->hBlockData[pair];
142 :
143 : /*get channel pair index from BS*/
144 89017 : channelPairIndex = get_next_indice_fx( sts[0], hMCT->bitsChannelPairIndex );
145 89017 : indexToChannelPair_fx( hBlock, nchan, channelPairIndex );
146 :
147 : /*point to decoder states of actual channels to read block pair bits*/
148 89017 : p_st[0] = sts[hBlock->ch1];
149 89017 : p_st[1] = sts[hBlock->ch2];
150 :
151 89017 : parse_stereo_from_bitstream( hBlock->hStereoMdct, p_st, 1, 0, sts[0], hBlock->mask );
152 : }
153 :
154 96687 : return;
155 : }
156 :
157 :
158 : /*----------------------------------------------------------*
159 : * applyGlobalILD()
160 : *
161 : * revert to initial channel energy levels using the ratios
162 : * sent from the encoder
163 : *----------------------------------------------------------*/
164 :
165 96687 : static void applyGlobalILD_fx(
166 : Decoder_State **sts,
167 : MCT_DEC_HANDLE hMCT,
168 : Word32 *x[MCT_MAX_CHANNELS][NB_DIV] )
169 : {
170 : Word16 ch, k;
171 : Word16 nSubframes, L_subframeTCX;
172 : Word32 qratio;
173 : Word16 q_qratio;
174 : Word16 tmp, tmp_e;
175 :
176 554629 : FOR( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
177 : {
178 457942 : IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
179 : {
180 447805 : nSubframes = 1;
181 447805 : move16();
182 : }
183 : ELSE
184 : {
185 10137 : nSubframes = NB_DIV;
186 10137 : move16();
187 : }
188 457942 : tmp = BASOP_Util_Divide1616_Scale( sts[ch]->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
189 457942 : L_subframeTCX = shr( tmp, add( 15, negate( tmp_e ) ) );
190 :
191 457942 : IF( hMCT->mc_global_ild[ch] )
192 : {
193 178034 : IF( hMCT->lowE_ch[ch] )
194 : {
195 : /* qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE; */
196 110607 : qratio = L_shl( hMCT->mc_global_ild[ch], Q26 - SMDCT_GLOBAL_ILD_BITS ); /* Q26 */
197 : }
198 : ELSE
199 : {
200 67427 : tmp = BASOP_Util_Divide3216_Scale( ( SMDCT_ILD_RANGE << Q26 ), hMCT->mc_global_ild[ch], &tmp_e );
201 67427 : qratio = L_shr( (Word32) tmp, negate( add( 1, tmp_e ) ) ); // Q26
202 : }
203 :
204 178034 : q_qratio = norm_l( qratio );
205 178034 : qratio = L_shl( qratio, q_qratio );
206 359954 : FOR( k = 0; k < nSubframes; k++ )
207 : {
208 181920 : v_multc_fixed( x[ch][k], qratio, x[ch][k], L_subframeTCX ); // Qx - 5 + q_qratio
209 181920 : scale_sig32( x[ch][k], L_subframeTCX, sub( 5, q_qratio ) );
210 : }
211 : }
212 : ELSE
213 : {
214 279908 : CONTINUE;
215 : }
216 : }
217 :
218 96687 : return;
219 : }
220 :
221 :
222 : /*----------------------------------------------------------*
223 : * apply_MCT_dec()
224 : *
225 : * main MCT decoding function
226 : *----------------------------------------------------------*/
227 :
228 96687 : void apply_MCT_dec_fx(
229 : MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */
230 : Decoder_State **sts, /* i/o: decoder state structure */
231 : Word32 *x[MCT_MAX_CHANNELS][NB_DIV] /* i/o: decoded and dequan. spect. input to MCT */
232 : )
233 : {
234 : Word16 pair;
235 : MCT_DEC_BLOCK_DATA_HANDLE hBlock;
236 :
237 185704 : FOR( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
238 : {
239 89017 : hBlock = hMCT->hBlockData[pair];
240 :
241 89017 : stereo_decoder_tcx_fx( hBlock->hStereoMdct, hBlock->mask, &x[hBlock->ch2][0], &x[hBlock->ch1][0], &x[hBlock->ch2][0], hBlock->hStereoMdct->mdct_stereo_mode, sts[hBlock->ch1]->core, sts[hBlock->ch2]->core, sts[0]->igf, sts[0]->hTcxDec->L_frameTCX, sts[1]->hTcxDec->L_frameTCX, 1, TCX_20_CORE, TCX_20_CORE, 0 );
242 : }
243 :
244 96687 : applyGlobalILD_fx( sts, hMCT, x );
245 :
246 96687 : return;
247 : }
248 :
249 : /*----------------------------------------------------------*
250 : * mctStereoIGF_dec()
251 : *
252 : * apply IGF to MCT stereo block pairs
253 : *----------------------------------------------------------*/
254 :
255 33709 : void mctStereoIGF_dec_fx(
256 : MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */
257 : Decoder_State **stm, /* i/o: decoder state structure */
258 : Word32 *x[MCT_MAX_CHANNELS][NB_DIV], /* i/o: decoded and dequantized spectrum i:Q12*/
259 : const Word16 bfi /* i : bad frame flag */
260 : )
261 : {
262 : Word16 b, core, nSubframes, k, ch, p_ch[CPE_CHANNELS], ch1, ch2;
263 33709 : Decoder_State *sts[CPE_CHANNELS], *st = NULL;
264 : Word16 tcx_offset[CPE_CHANNELS];
265 : Word16 tcx_offsetFB[CPE_CHANNELS];
266 : Word16 left_rect[CPE_CHANNELS];
267 : Word16 L_spec[CPE_CHANNELS];
268 : Word16 L_frame[CPE_CHANNELS];
269 : Word16 L_frameTCX[CPE_CHANNELS];
270 : Word32 *p_x[CPE_CHANNELS][NB_DIV]; // Q(31 - p_x_e)
271 : Word16 p_x_e[CPE_CHANNELS][NB_DIV];
272 : Word16 p_x_len[CPE_CHANNELS][NB_DIV];
273 : Word16 singleChEle[MCT_MAX_CHANNELS];
274 : Word16 tmp_e;
275 : Word16 L_frame_nSubframe, L_frameTCX_nSubframe, tmp;
276 :
277 :
278 33709 : set16_fx( singleChEle, 1, ( hMCT->nchan_out_woLFE ) );
279 :
280 91683 : FOR( b = 0; b < hMCT->currBlockDataCnt; b++ )
281 : {
282 57974 : ch1 = hMCT->hBlockData[b]->ch1;
283 57974 : move16();
284 57974 : ch2 = hMCT->hBlockData[b]->ch2;
285 57974 : move16();
286 :
287 57974 : sts[0] = stm[ch1];
288 57974 : sts[1] = stm[ch2];
289 57974 : core = sts[0]->core;
290 57974 : move16();
291 57974 : nSubframes = core;
292 57974 : move16();
293 57974 : p_ch[0] = ch1;
294 57974 : move16();
295 57974 : p_ch[1] = ch2;
296 57974 : move16();
297 57974 : singleChEle[hMCT->hBlockData[b]->ch1] = 0;
298 57974 : move16();
299 57974 : singleChEle[hMCT->hBlockData[b]->ch2] = 0;
300 57974 : move16();
301 :
302 : // Using input Q-factor as 12
303 57974 : set16_fx( p_x_e[0], 31 - Q11, CPE_CHANNELS ); // Q12
304 57974 : set16_fx( p_x_e[1], 31 - Q11, CPE_CHANNELS ); // Q12
305 :
306 117395 : FOR( k = 0; k < nSubframes; k++ )
307 : {
308 59421 : p_x[0][k] = x[ch1][k]; // Q12
309 59421 : p_x[1][k] = x[ch2][k]; // Q12
310 :
311 59421 : test();
312 59421 : IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[k], SMDCT_DUAL_MONO ) || NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[k], SMDCT_DUAL_MONO ) )
313 59401 : {
314 : Word16 shr_div, shr_k;
315 :
316 59401 : assert( nSubframes == 1 || nSubframes == 2 );
317 : /* Note: nSubframes is in limited range [1, 2] for this function */
318 :
319 59401 : shr_div = sub( nSubframes, 1 ); /* 2 -> 1, 1 -> 0 */
320 59401 : L_spec[0] = shr( sts[0]->hTcxCfg->tcx_coded_lines, shr_div );
321 59401 : move16();
322 59401 : L_frame_nSubframe = shr( sts[0]->L_frame, shr_div );
323 59401 : L_frameTCX_nSubframe = shr( sts[0]->hTcxDec->L_frameTCX, shr_div );
324 :
325 59401 : init_tcx_info_fx( sts[0], L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[0], &tcx_offsetFB[0], &L_frame[0], &L_frameTCX[0], &left_rect[0], &L_spec[0] );
326 :
327 : /* stereo IGF decoding */
328 59401 : assert( ( EQ_16( sts[0]->core, sts[1]->core ) ) || ( ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ) );
329 :
330 59401 : decoder_tcx_IGF_stereo_fx( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, p_x_e, p_x_len, L_frame[0], left_rect[0], k, bfi, 1 /* MCT_flag */ );
331 :
332 : // Shifting output with variable exponent back to Q12
333 59401 : shr_k = sub( 31 - Q11, p_x_e[0][k] );
334 45284361 : FOR( Word16 i = 0; i < p_x_len[0][k]; i++ )
335 : {
336 45224960 : p_x[0][k][i] = L_shr( p_x[0][k][i], shr_k );
337 45224960 : move32();
338 : }
339 59401 : shr_k = sub( 31 - Q11, p_x_e[1][k] );
340 45284361 : FOR( Word16 i = 0; i < p_x_len[1][k]; i++ )
341 : {
342 45224960 : p_x[1][k][i] = L_shr( p_x[1][k][i], shr_k );
343 45224960 : move32();
344 : }
345 : }
346 : ELSE
347 : {
348 60 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
349 : {
350 : Word16 x_e, x_len;
351 :
352 40 : st = sts[ch];
353 40 : test();
354 40 : if ( bfi && ( st->core == ACELP_CORE ) ) /*no igf processing needed*/
355 : {
356 0 : CONTINUE;
357 : }
358 40 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e );
359 40 : L_spec[ch] = shr( tmp, add( 15, negate( tmp_e ) ) );
360 40 : move32();
361 :
362 40 : tmp = BASOP_Util_Divide1616_Scale( st->L_frame, nSubframes, &tmp_e );
363 40 : L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
364 :
365 40 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
366 40 : L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
367 :
368 40 : init_tcx_info_fx( st, L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[ch], &tcx_offsetFB[ch], &L_frame[ch], &L_frameTCX[ch], &left_rect[ch], &L_spec[ch] );
369 :
370 : /* mono or dual mono IGF decoding */
371 :
372 40 : x_e = 31 - Q11; // input q-factor of x[p_ch[ch]][k] is Q12
373 40 : move16();
374 :
375 40 : decoder_tcx_IGF_mono_fx( st, x[p_ch[ch]][k], &x_e, &x_len, L_frame[ch], left_rect[ch], bfi, k );
376 :
377 15720 : FOR( Word16 i = 0; i < x_len; i++ )
378 : {
379 : // Converting from variable exponent to Fixed q-factor (Q12)
380 15680 : x[p_ch[ch]][k][i] = L_shr( x[p_ch[ch]][k][i], sub( 31 - Q11, x_e ) );
381 15680 : move32();
382 : }
383 : }
384 : }
385 : }
386 : }
387 :
388 33709 : IF( sum16_fx( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 )
389 : {
390 195648 : FOR( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
391 : {
392 161943 : IF( singleChEle[ch] )
393 : {
394 46011 : st = stm[ch];
395 46011 : test();
396 46011 : if ( bfi && ( st->core == ACELP_CORE ) ) /*no igf processing needed*/
397 : {
398 0 : CONTINUE;
399 : }
400 46011 : if ( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
401 : {
402 1215 : CONTINUE;
403 : }
404 :
405 44796 : IF( EQ_16( st->core, TCX_10_CORE ) )
406 : {
407 1400 : nSubframes = NB_DIV;
408 : }
409 : ELSE
410 : {
411 43396 : nSubframes = 1;
412 : }
413 44796 : move16();
414 :
415 90992 : FOR( k = 0; k < nSubframes; k++ )
416 : {
417 : Word16 x_e, x_len;
418 :
419 46196 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e );
420 46196 : L_spec[0] = shr( tmp, add( 15, negate( tmp_e ) ) );
421 46196 : move32();
422 :
423 46196 : tmp = BASOP_Util_Divide1616_Scale( st->L_frame, nSubframes, &tmp_e );
424 46196 : L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
425 :
426 46196 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
427 46196 : L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
428 :
429 46196 : init_tcx_info_fx( st, L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[0], &tcx_offsetFB[0], &L_frame[0], &L_frameTCX[0], &left_rect[0], &L_spec[0] );
430 :
431 : /* mono or dual mono IGF decoding */
432 46196 : x_e = 31 - Q11; // Input Q-factor is Q12.
433 46196 : move16();
434 :
435 46196 : decoder_tcx_IGF_mono_fx( st, x[ch][k], &x_e, &x_len, L_frame[0], left_rect[0], bfi, k );
436 :
437 34858516 : FOR( Word16 i = 0; i < x_len; i++ )
438 : {
439 : // Converting from variable exponent to Fixed q-factor (Q12)
440 34812320 : x[ch][k][i] = L_shr( x[ch][k][i], sub( 31 - Q11, x_e ) );
441 34812320 : move32();
442 : }
443 : }
444 : }
445 : }
446 : }
447 :
448 33709 : return;
449 : }
|