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 89593 : 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 89593 : Word16 tmpIdx = 0;
55 89593 : move16();
56 :
57 337801 : FOR( ch2 = 1; ch2 < nChannels; ch2++ )
58 : {
59 1086756 : FOR( ch1 = 0; ch1 < ch2; ch1++ )
60 : {
61 838548 : IF( EQ_16( tmpIdx, pairIdx ) )
62 : {
63 89593 : hBlock->ch1 = ch1;
64 89593 : move16();
65 89593 : hBlock->ch2 = ch2;
66 89593 : move16();
67 :
68 89593 : return;
69 : }
70 : ELSE
71 : {
72 748955 : 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 97687 : 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 97687 : Word16 nchan_active = 0;
97 97687 : move16();
98 :
99 97687 : hMCT->currBlockDataCnt = get_next_indice_fx( sts[0], MCT_NUM_BLOCK_DATA_BITS );
100 97687 : move16();
101 :
102 : /*first get core and overlap info for all channels*/
103 558629 : FOR( ch = 0; ch < nchan; ch++ )
104 : {
105 460942 : test();
106 460942 : IF( hMCT->currBlockDataCnt && NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
107 : {
108 278797 : hMCT->mc_global_ild[ch] = get_next_indice_fx( sts[0], SMDCT_GLOBAL_ILD_BITS );
109 278797 : move16();
110 : }
111 : ELSE
112 : {
113 182145 : hMCT->mc_global_ild[ch] = 0;
114 182145 : move16();
115 : }
116 : }
117 :
118 97687 : IF( hMCT->currBlockDataCnt )
119 : {
120 336722 : FOR( ch = 0; ch < nchan; ch++ )
121 : {
122 282041 : IF( NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
123 : {
124 278797 : hMCT->lowE_ch[ch] = get_next_indice_fx( sts[0], 1 );
125 278797 : move16();
126 : }
127 : }
128 : }
129 :
130 558629 : FOR( ch = 0; ch < nchan; ch++ )
131 : {
132 460942 : if ( NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
133 : {
134 452500 : nchan_active = add( nchan_active, 1 );
135 : }
136 : }
137 :
138 187280 : FOR( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
139 : {
140 89593 : assert( GE_16( nchan_active, 2 ) );
141 89593 : hBlock = hMCT->hBlockData[pair];
142 :
143 : /*get channel pair index from BS*/
144 89593 : channelPairIndex = get_next_indice_fx( sts[0], hMCT->bitsChannelPairIndex );
145 89593 : indexToChannelPair_fx( hBlock, nchan, channelPairIndex );
146 :
147 : /*point to decoder states of actual channels to read block pair bits*/
148 89593 : p_st[0] = sts[hBlock->ch1];
149 89593 : p_st[1] = sts[hBlock->ch2];
150 :
151 89593 : parse_stereo_from_bitstream( hBlock->hStereoMdct, p_st, 1, 0, sts[0], hBlock->mask );
152 : }
153 :
154 97687 : 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 97687 : 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 558629 : FOR( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
177 : {
178 460942 : IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
179 : {
180 450789 : nSubframes = 1;
181 450789 : move16();
182 : }
183 : ELSE
184 : {
185 10153 : nSubframes = NB_DIV;
186 10153 : move16();
187 : }
188 460942 : tmp = BASOP_Util_Divide1616_Scale( sts[ch]->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
189 460942 : L_subframeTCX = shr( tmp, add( 15, negate( tmp_e ) ) );
190 :
191 460942 : IF( hMCT->mc_global_ild[ch] )
192 : {
193 179186 : IF( hMCT->lowE_ch[ch] )
194 : {
195 : /* qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE; */
196 111715 : qratio = L_shl( hMCT->mc_global_ild[ch], Q26 - SMDCT_GLOBAL_ILD_BITS ); /* Q26 */
197 : }
198 : ELSE
199 : {
200 67471 : tmp = BASOP_Util_Divide3216_Scale( ( SMDCT_ILD_RANGE << Q26 ), hMCT->mc_global_ild[ch], &tmp_e );
201 67471 : qratio = L_shr( (Word32) tmp, negate( add( 1, tmp_e ) ) ); // Q26
202 : }
203 :
204 179186 : q_qratio = norm_l( qratio );
205 179186 : qratio = L_shl( qratio, q_qratio );
206 362272 : FOR( k = 0; k < nSubframes; k++ )
207 : {
208 183086 : v_multc_fixed( x[ch][k], qratio, x[ch][k], L_subframeTCX ); // Qx - 5 + q_qratio
209 183086 : scale_sig32( x[ch][k], L_subframeTCX, sub( 5, q_qratio ) );
210 : }
211 : }
212 : ELSE
213 : {
214 281756 : CONTINUE;
215 : }
216 : }
217 :
218 97687 : return;
219 : }
220 :
221 :
222 : /*----------------------------------------------------------*
223 : * apply_MCT_dec()
224 : *
225 : * main MCT decoding function
226 : *----------------------------------------------------------*/
227 :
228 97687 : 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 187280 : FOR( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
238 : {
239 89593 : hBlock = hMCT->hBlockData[pair];
240 :
241 89593 : 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 97687 : applyGlobalILD_fx( sts, hMCT, x );
245 :
246 97687 : return;
247 : }
248 :
249 : /*----------------------------------------------------------*
250 : * mctStereoIGF_dec()
251 : *
252 : * apply IGF to MCT stereo block pairs
253 : *----------------------------------------------------------*/
254 :
255 34261 : 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 34261 : 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 34261 : set16_fx( singleChEle, 1, ( hMCT->nchan_out_woLFE ) );
279 :
280 92787 : FOR( b = 0; b < hMCT->currBlockDataCnt; b++ )
281 : {
282 58526 : ch1 = hMCT->hBlockData[b]->ch1;
283 58526 : move16();
284 58526 : ch2 = hMCT->hBlockData[b]->ch2;
285 58526 : move16();
286 :
287 58526 : sts[0] = stm[ch1];
288 58526 : sts[1] = stm[ch2];
289 58526 : core = sts[0]->core;
290 58526 : move16();
291 58526 : nSubframes = core;
292 58526 : move16();
293 58526 : p_ch[0] = ch1;
294 58526 : move16();
295 58526 : p_ch[1] = ch2;
296 58526 : move16();
297 58526 : singleChEle[hMCT->hBlockData[b]->ch1] = 0;
298 58526 : move16();
299 58526 : singleChEle[hMCT->hBlockData[b]->ch2] = 0;
300 58526 : move16();
301 :
302 : // Using input Q-factor as 12
303 58526 : set16_fx( p_x_e[0], 31 - Q11, CPE_CHANNELS ); // Q12
304 58526 : set16_fx( p_x_e[1], 31 - Q11, CPE_CHANNELS ); // Q12
305 :
306 118505 : FOR( k = 0; k < nSubframes; k++ )
307 : {
308 59979 : p_x[0][k] = x[ch1][k]; // Q12
309 59979 : p_x[1][k] = x[ch2][k]; // Q12
310 :
311 59979 : test();
312 59979 : 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 59950 : {
314 : Word16 shr_div, shr_k;
315 :
316 59950 : assert( nSubframes == 1 || nSubframes == 2 );
317 : /* Note: nSubframes is in limited range [1, 2] for this function */
318 :
319 59950 : shr_div = sub( nSubframes, 1 ); /* 2 -> 1, 1 -> 0 */
320 59950 : L_spec[0] = shr( sts[0]->hTcxCfg->tcx_coded_lines, shr_div );
321 59950 : move16();
322 59950 : L_frame_nSubframe = shr( sts[0]->L_frame, shr_div );
323 59950 : L_frameTCX_nSubframe = shr( sts[0]->hTcxDec->L_frameTCX, shr_div );
324 :
325 59950 : 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 59950 : assert( ( EQ_16( sts[0]->core, sts[1]->core ) ) || ( ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ) );
329 :
330 59950 : 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 59950 : shr_k = sub( 31 - Q11, p_x_e[0][k] );
334 45722030 : FOR( Word16 i = 0; i < p_x_len[0][k]; i++ )
335 : {
336 45662080 : p_x[0][k][i] = L_shr( p_x[0][k][i], shr_k );
337 45662080 : move32();
338 : }
339 59950 : shr_k = sub( 31 - Q11, p_x_e[1][k] );
340 45722030 : FOR( Word16 i = 0; i < p_x_len[1][k]; i++ )
341 : {
342 45662080 : p_x[1][k][i] = L_shr( p_x[1][k][i], shr_k );
343 45662080 : move32();
344 : }
345 : }
346 : ELSE
347 : {
348 87 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
349 : {
350 : Word16 x_e, x_len;
351 :
352 58 : st = sts[ch];
353 58 : test();
354 58 : if ( bfi && ( st->core == ACELP_CORE ) ) /*no igf processing needed*/
355 : {
356 0 : CONTINUE;
357 : }
358 58 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e );
359 58 : L_spec[ch] = shr( tmp, add( 15, negate( tmp_e ) ) );
360 58 : move32();
361 :
362 58 : tmp = BASOP_Util_Divide1616_Scale( st->L_frame, nSubframes, &tmp_e );
363 58 : L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
364 :
365 58 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
366 58 : L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
367 :
368 58 : 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 58 : x_e = 31 - Q11; // input q-factor of x[p_ch[ch]][k] is Q12
373 58 : move16();
374 :
375 58 : 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 21818 : FOR( Word16 i = 0; i < x_len; i++ )
378 : {
379 : // Converting from variable exponent to Fixed q-factor (Q12)
380 21760 : x[p_ch[ch]][k][i] = L_shr( x[p_ch[ch]][k][i], sub( 31 - Q11, x_e ) );
381 21760 : move32();
382 : }
383 : }
384 : }
385 : }
386 : }
387 :
388 34261 : IF( sum16_fx( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 )
389 : {
390 197865 : FOR( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
391 : {
392 163608 : IF( singleChEle[ch] )
393 : {
394 46572 : st = stm[ch];
395 46572 : test();
396 46572 : if ( bfi && ( st->core == ACELP_CORE ) ) /*no igf processing needed*/
397 : {
398 0 : CONTINUE;
399 : }
400 46572 : if ( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
401 : {
402 1219 : CONTINUE;
403 : }
404 :
405 45353 : IF( EQ_16( st->core, TCX_10_CORE ) )
406 : {
407 1396 : nSubframes = NB_DIV;
408 : }
409 : ELSE
410 : {
411 43957 : nSubframes = 1;
412 : }
413 45353 : move16();
414 :
415 92102 : FOR( k = 0; k < nSubframes; k++ )
416 : {
417 : Word16 x_e, x_len;
418 :
419 46749 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e );
420 46749 : L_spec[0] = shr( tmp, add( 15, negate( tmp_e ) ) );
421 46749 : move32();
422 :
423 46749 : tmp = BASOP_Util_Divide1616_Scale( st->L_frame, nSubframes, &tmp_e );
424 46749 : L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
425 :
426 46749 : tmp = BASOP_Util_Divide1616_Scale( st->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
427 46749 : L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
428 :
429 46749 : 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 46749 : x_e = 31 - Q11; // Input Q-factor is Q12.
433 46749 : move16();
434 :
435 46749 : decoder_tcx_IGF_mono_fx( st, x[ch][k], &x_e, &x_len, L_frame[0], left_rect[0], bfi, k );
436 :
437 35304669 : FOR( Word16 i = 0; i < x_len; i++ )
438 : {
439 : // Converting from variable exponent to Fixed q-factor (Q12)
440 35257920 : x[ch][k][i] = L_shr( x[ch][k][i], sub( 31 - Q11, x_e ) );
441 35257920 : move32();
442 : }
443 : }
444 : }
445 : }
446 : }
447 :
448 34261 : return;
449 : }
|