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 <math.h>
36 : #include "ivas_cnst.h"
37 : #include "ivas_prot.h"
38 : #include "prot.h"
39 : #include "wmc_auto.h"
40 : #include <assert.h>
41 :
42 :
43 : /*--------------------------------------------------------------*
44 : * Local constants
45 : *---------------------------------------------------------------*/
46 :
47 : #define SPAR_CORR_THRES 0.9f
48 : #define DEFAULT_CORR_THRES 0.3f
49 :
50 : /*-------------------------------------------------------------------------
51 : * getChannelEnergies()
52 : *
53 : * Calculate energy for each cahnnel
54 : *-------------------------------------------------------------------------*/
55 :
56 201407 : void getChannelEnergies(
57 : Encoder_State **sts, /* i/o: Encoder state structure */
58 : float nrg[MCT_MAX_CHANNELS], /* o : buffer with energies for each channel */
59 : const int16_t nchan /* i : number of channels */
60 : )
61 : {
62 : int16_t ch, n;
63 : int16_t nSubframes, L_subframe;
64 : Encoder_State *st;
65 :
66 : /* Calculate energies per channel */
67 1162903 : for ( ch = 0; ch < nchan; ch++ )
68 : {
69 961496 : st = sts[ch];
70 961496 : if ( st->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
71 : {
72 946118 : nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
73 946118 : L_subframe = st->hTcxEnc->L_frameTCX / nSubframes;
74 :
75 946118 : nrg[ch] = 0;
76 1913528 : for ( n = 0; n < nSubframes; n++ )
77 : {
78 967410 : nrg[ch] += sum2_f( st->hTcxEnc->spectrum[n], L_subframe );
79 : }
80 946118 : nrg[ch] = sqrtf( nrg[ch] );
81 : }
82 : }
83 :
84 201407 : return;
85 : }
86 :
87 :
88 : /*-------------------------------------------------------------------------
89 : * getNextBestCorrelation()
90 : *
91 : * find channel pair with highest cross-correlation
92 : *-------------------------------------------------------------------------*/
93 :
94 101093 : static void getNextBestCorrelation(
95 : float xCorrMatrix[][MCT_MAX_CHANNELS], /* i : cross-correlation matrix */
96 : int16_t *_ch1, /* o : first channel of selected channel-pair */
97 : int16_t *_ch2, /* o : second channel of selected channel-pair */
98 : float *max_corr, /* o : normalized cross correlation value of selected channel pair */
99 : const int16_t sortInd,
100 : const int16_t nChannels )
101 : {
102 : float tmp_corrVals[( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2];
103 : int16_t i;
104 : int16_t ch1, ch2;
105 :
106 101093 : set_f( tmp_corrVals, 0, ( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2 );
107 :
108 : /* first sort correlation matrix */
109 101093 : i = 0;
110 594411 : for ( ch1 = 0; ch1 < nChannels; ch1++ )
111 : {
112 1658169 : for ( ch2 = ch1 + 1; ch2 < nChannels; ch2++ )
113 : {
114 1164851 : if ( fabsf( xCorrMatrix[ch1][ch2] ) > 0 )
115 : {
116 726828 : assert( i < ( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2 );
117 726828 : tmp_corrVals[i] = fabsf( xCorrMatrix[ch1][ch2] );
118 726828 : i++;
119 : }
120 : }
121 : }
122 :
123 : /* sort values */
124 101093 : v_sort( tmp_corrVals, 0, ( ( nChannels * ( nChannels - 1 ) ) / 2 ) - 1 );
125 :
126 : /* get max, or 2nd max and so on depending on sortInd value */
127 101093 : *max_corr = tmp_corrVals[( nChannels * ( nChannels - 1 ) ) / 2 - 1 - sortInd];
128 :
129 : /*find channel pair for this max_corr*/
130 594411 : for ( ch1 = 0; ch1 < nChannels; ch1++ )
131 : {
132 1378190 : for ( ch2 = ch1 + 1; ch2 < nChannels; ch2++ )
133 : {
134 1013839 : if ( fabsf( xCorrMatrix[ch1][ch2] ) == *max_corr )
135 : {
136 128967 : *_ch1 = ch1;
137 128967 : *_ch2 = ch2;
138 128967 : *max_corr = xCorrMatrix[ch1][ch2]; /* assign to max_corr its actual value */
139 128967 : break;
140 : }
141 : }
142 : }
143 :
144 101093 : return;
145 : }
146 :
147 :
148 : /*-----------------------------------------------------------------------*
149 : * getCorrelationMatrix()
150 : *
151 : * calculates the cross correlation matrix for all active
152 : * channels
153 : *-----------------------------------------------------------------------*/
154 :
155 100468 : static void getCorrelationMatrix(
156 : Encoder_State **sts, /* i : core coder handle */
157 : MCT_ENC_HANDLE hMCT, /* i : MCT handle */
158 : float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS] /* o : cross-correlation matrix */
159 : )
160 : {
161 : int16_t ch1, ch2, n, nchan;
162 : float tmp;
163 :
164 100468 : nchan = hMCT->nchan_out_woLFE;
165 :
166 : /* correlation */
167 580177 : for ( ch1 = 0; ch1 < nchan; ch1++ )
168 : {
169 2017070 : for ( ch2 = ch1; ch2 < nchan; ch2++ )
170 : {
171 1537361 : xCorrMatrix[ch1][ch2] = 0;
172 :
173 1537361 : if ( sts[ch1]->core == sts[ch2]->core && sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
174 1501804 : sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
175 : {
176 1473396 : int16_t nSubframes = ( sts[ch1]->core == TCX_20_CORE ? 1 : NB_DIV );
177 1473396 : int16_t L_subframe = sts[ch1]->hTcxEnc->L_frameTCX / nSubframes;
178 :
179 2970404 : for ( n = 0; n < nSubframes; n++ )
180 : {
181 1497008 : xCorrMatrix[ch1][ch2] += dotp( sts[ch1]->hTcxEnc->spectrum[n], sts[ch2]->hTcxEnc->spectrum[n], L_subframe );
182 : }
183 : }
184 : }
185 : }
186 :
187 : /* normalize */
188 580177 : for ( ch1 = 0; ch1 < nchan; ch1++ )
189 : {
190 1537361 : for ( ch2 = ch1 + 1; ch2 < nchan; ch2++ )
191 : {
192 1057652 : tmp = sqrtf( xCorrMatrix[ch1][ch1] * xCorrMatrix[ch2][ch2] );
193 :
194 1057652 : if ( tmp > 0.f )
195 : {
196 1026725 : xCorrMatrix[ch1][ch2] /= tmp;
197 : }
198 : else
199 : {
200 30927 : xCorrMatrix[ch1][ch2] = 0.f;
201 : }
202 :
203 : #ifdef DEBUG_MODE_MDCT
204 : dbgwrite( &xCorrMatrix[ch1][ch2], sizeof( float ), 1, 1, "./res/xCorrMatrix" );
205 : #endif
206 : }
207 : }
208 :
209 100468 : return;
210 : }
211 :
212 :
213 : /*-----------------------------------------------------------------*
214 : * getBestCorrelation()
215 : *
216 : * searches for the best correlated channel pair
217 : *------------------------------------------------------------------*/
218 :
219 96286 : static void getBestCorrelation(
220 : MCT_ENC_HANDLE hMCT, /* i : MCT handle */
221 : int16_t *_ch1, /* o : first channel of selected channel-pair */
222 : int16_t *_ch2, /* o : second channel of selected channel-pair */
223 : float *max_corr, /* o : normalized cross correlation value of selected channel pair */
224 : float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS] ) /* i : cross-correlation matrix */
225 : {
226 : int16_t ch1, ch2;
227 :
228 96286 : *_ch1 = -1;
229 96286 : *_ch2 = -1;
230 96286 : *max_corr = 0.f;
231 :
232 640090 : for ( ch1 = 0; ch1 < ( hMCT->nchan_out_woLFE ); ch1++ )
233 : {
234 1984954 : for ( ch2 = ch1 + 1; ch2 < ( hMCT->nchan_out_woLFE ); ch2++ )
235 : {
236 1441150 : if ( fabsf( *max_corr ) < fabsf( xCorrMatrix[ch1][ch2] ) )
237 : {
238 198940 : *max_corr = xCorrMatrix[ch1][ch2];
239 :
240 198940 : *_ch1 = ch1;
241 198940 : *_ch2 = ch2;
242 : }
243 : }
244 : }
245 :
246 96286 : return;
247 : }
248 :
249 :
250 : /*----------------------------------------------------------------------*
251 : * getBlockValues()
252 : * stereo processing for the channels of current block
253 : *----------------------------------------------------------------------*/
254 :
255 97008 : static void getBlockValues(
256 : Encoder_State **sts, /* i/o: core coder handle */
257 : const int16_t ch1, /* i : first channel of channel-pair */
258 : const int16_t ch2, /* i : second channel of channel-pair */
259 : MCT_BLOCK_DATA *hBlock, /* i : stereo block handle */
260 : float *mdst_spectrum[MCT_MAX_CHANNELS][2], /* i/o: MDST spectrum */
261 : float *inv_spectrum[MCT_MAX_CHANNELS][2], /* i/o: inverse spectrum */
262 : float *inv_mdst_spectrum[MCT_MAX_CHANNELS][2] /* i/o: invers MDST spectrum */
263 : )
264 : {
265 : int16_t n;
266 : float *p_mdst_spectrum[2][2];
267 : float *p_inv_spectrum[2][2];
268 : float *p_inv_mdst_spectrum[2][2];
269 : Encoder_State *p_st[2];
270 :
271 : /* init return values: */
272 97008 : hBlock->isActive = 1;
273 :
274 : /* map vectors to current block channels */
275 291024 : for ( n = 0; n < 2; n++ )
276 : {
277 194016 : p_mdst_spectrum[0][n] = mdst_spectrum[ch1][n];
278 194016 : p_mdst_spectrum[1][n] = mdst_spectrum[ch2][n];
279 194016 : p_inv_spectrum[0][n] = inv_spectrum[ch1][n];
280 194016 : p_inv_spectrum[1][n] = inv_spectrum[ch2][n];
281 194016 : p_inv_mdst_spectrum[0][n] = inv_mdst_spectrum[ch1][n];
282 194016 : p_inv_mdst_spectrum[1][n] = inv_mdst_spectrum[ch2][n];
283 : }
284 97008 : p_st[0] = sts[ch1];
285 97008 : p_st[1] = sts[ch2];
286 :
287 97008 : stereo_coder_tcx( hBlock->hStereoMdct, p_st, hBlock->mask, p_mdst_spectrum, p_inv_spectrum, p_inv_mdst_spectrum, 1 );
288 :
289 97008 : if ( ( sts[ch1]->core == TCX_20_CORE && hBlock->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) || ( sts[ch1]->core == TCX_10_CORE && hBlock->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO && hBlock->hStereoMdct->mdct_stereo_mode[1] == SMDCT_DUAL_MONO ) )
290 : {
291 4906 : hBlock->isActive = 0;
292 : }
293 :
294 97008 : return;
295 : }
296 :
297 :
298 : /*-------------------------------------------------------------------*
299 : * updateCorrelationMatrix()
300 : *
301 : * updates the cross correlation matrix with modified spectra after
302 : * stereo block processing
303 : *-------------------------------------------------------------------*/
304 :
305 92102 : static void updateCorrelationMatrix(
306 : Encoder_State **sts,
307 : MCT_ENC_HANDLE hMCT,
308 : const int16_t _ch1,
309 : const int16_t _ch2,
310 : float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS] )
311 : {
312 : int16_t ch1, ch2, n;
313 :
314 : /* correlation: */
315 618787 : for ( ch1 = 0; ch1 < ( hMCT->nchan_out_woLFE ); ch1++ )
316 : {
317 2511266 : for ( ch2 = ch1; ch2 < ( hMCT->nchan_out_woLFE ); ch2++ )
318 : {
319 1984581 : if ( sts[ch1]->core == sts[ch2]->core && sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
320 1932027 : sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
321 : {
322 1915937 : int16_t nSubframes = ( sts[ch1]->core == TCX_20_CORE ? 1 : NB_DIV );
323 :
324 1915937 : if ( ch1 == _ch1 || ch2 == _ch2 || ch1 == _ch2 || ch2 == _ch1 )
325 : {
326 1883885 : for ( n = 0; n < nSubframes; n++ )
327 : {
328 950099 : xCorrMatrix[ch1][ch2] = 0; /*disable combinations with channels already processed */
329 : }
330 : }
331 : }
332 : }
333 : }
334 :
335 92102 : return;
336 : }
337 :
338 :
339 : /*----------------------------------------------------------*
340 : * channelPairToIndex()
341 : * get the index of each channel pair
342 : *----------------------------------------------------------*/
343 :
344 92102 : static int16_t channelPairToIndex(
345 : const int16_t chIdx1,
346 : const int16_t chIdx2,
347 : const int16_t nChannels )
348 : {
349 : int16_t ch1, ch2;
350 : int16_t pairIdx;
351 :
352 92102 : pairIdx = 0;
353 :
354 351148 : for ( ch2 = 1; ch2 < nChannels; ch2++ )
355 : {
356 1141182 : for ( ch1 = 0; ch1 < ch2; ch1++ )
357 : {
358 882136 : if ( ch1 == chIdx1 && ch2 == chIdx2 )
359 : {
360 92102 : return pairIdx;
361 : }
362 : else
363 : {
364 790034 : pairIdx++;
365 : }
366 : }
367 : }
368 :
369 0 : return -1;
370 : }
371 :
372 :
373 : /*--------------------------------------------------------------------*
374 : * getGlobalILD()
375 : * get broadband ILD to mean energy and normalize channels with ratio
376 : *--------------------------------------------------------------------*/
377 :
378 100468 : static void getGlobalILD(
379 : Encoder_State **sts,
380 : MCT_ENC_HANDLE hMCT,
381 : float *mdst_spectrum[MCT_MAX_CHANNELS][2],
382 : const int16_t nchan )
383 : {
384 : int16_t k, ch, nSubframes, L_subframe;
385 : float nrg[MCT_MAX_CHANNELS];
386 100468 : float meanE = 0.f, ratio, qratio;
387 100468 : int16_t cnt = 0;
388 :
389 : /*Initializations*/
390 100468 : set_s( hMCT->lowE_ch, 0, nchan );
391 :
392 100468 : getChannelEnergies( sts, nrg, nchan );
393 :
394 : /*calculate total energy without LFE*/
395 580177 : for ( ch = 0; ch < nchan; ch++ )
396 : {
397 479709 : if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
398 : {
399 472896 : meanE += nrg[ch];
400 472896 : cnt++;
401 : }
402 : }
403 :
404 : /*calculate mean energy*/
405 100468 : assert( cnt >= 2 );
406 100468 : meanE = max( meanE / cnt, EPSILON );
407 580177 : for ( ch = 0; ch < nchan; ch++ )
408 : {
409 479709 : if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
410 : {
411 472896 : nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
412 472896 : L_subframe = sts[ch]->hTcxEnc->L_frameTCX / nSubframes;
413 :
414 472896 : if ( nrg[ch] > meanE ) /*change it to meanE if final solution*/
415 : {
416 174586 : ratio = meanE / nrg[ch];
417 174586 : hMCT->mc_global_ild[ch] = max( 1, min( SMDCT_ILD_RANGE - 1, (int16_t) ( SMDCT_ILD_RANGE * ratio + 0.5f ) ) );
418 174586 : qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE;
419 : }
420 : else
421 : {
422 298310 : ratio = nrg[ch] / meanE;
423 298310 : hMCT->lowE_ch[ch] = 1;
424 298310 : hMCT->mc_global_ild[ch] = max( 1, min( SMDCT_ILD_RANGE - 1, (int16_t) ( SMDCT_ILD_RANGE * ratio + 0.5f ) ) );
425 298310 : qratio = (float) SMDCT_ILD_RANGE / hMCT->mc_global_ild[ch];
426 : }
427 :
428 956438 : for ( k = 0; k < nSubframes; k++ )
429 : {
430 483542 : v_multc( sts[ch]->hTcxEnc->spectrum[k], qratio, sts[ch]->hTcxEnc->spectrum[k], L_subframe );
431 483542 : v_multc( mdst_spectrum[ch][k], qratio, mdst_spectrum[ch][k], L_subframe );
432 : }
433 : }
434 : }
435 :
436 : #ifdef DEBUG_MODE_MDCT
437 : /*check if energy levels are comparable*/
438 : getChannelEnergies( sts, nrg, nchan );
439 : dbgwrite( nrg, sizeof( float ), 6, 1, "./res/nrgGlobalILD" );
440 : #endif
441 :
442 100468 : return;
443 : }
444 :
445 :
446 : /*--------------------------------------------------------------------*
447 : * apply_MCT_enc()
448 : *
449 : * apply MCT algorithm to input channels
450 : *--------------------------------------------------------------------*/
451 :
452 100939 : void apply_MCT_enc(
453 : MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */
454 : Encoder_State **sts, /* i/o: encoder state structure */
455 : float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: MDST spectrum */
456 : float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse spectrum */
457 : float *inv_mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */
458 : const int16_t nchan /* i : number of channels */
459 : )
460 : {
461 : int16_t ch, k, ch1, ch2, nSubframes, L_subframeTCX;
462 : float max_corr, qratio;
463 : int16_t forceKeepTree, pair;
464 : float sumCorrDiff, thr;
465 : float xCorrMatrix[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS];
466 : int16_t currBlockDataCnt;
467 : int16_t cpEle[MCT_MAX_CHANNELS];
468 : int16_t inactiveBlockDetected;
469 : int16_t tmp_ch1, tmp_ch2;
470 : float tmp_max_corr;
471 100939 : int16_t count_active_ch = 0;
472 :
473 100939 : push_wmops( "mct_core_enc_mct" );
474 :
475 100939 : forceKeepTree = 1;
476 100939 : inactiveBlockDetected = 0;
477 100939 : set_s( cpEle, 0, MCT_MAX_CHANNELS );
478 :
479 : /*Determine active channels*/
480 582726 : for ( ch = 0; ch < nchan; ch++ )
481 : {
482 481787 : if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
483 : {
484 473222 : count_active_ch++;
485 : }
486 : else
487 : {
488 8565 : hMCT->mc_global_ild[ch] = 0;
489 : }
490 : }
491 :
492 : /*there should be at least one cp*/
493 100939 : if ( count_active_ch >= CPE_CHANNELS )
494 : {
495 : /*Normalize energies with global ILD*/
496 100468 : getGlobalILD( sts, hMCT, mdst_spectrum, nchan );
497 : #ifndef DEBUG_FORCE_MCT_CP
498 100468 : getCorrelationMatrix( sts, hMCT, xCorrMatrix );
499 :
500 : /*check if previous tree should be kept*/
501 100468 : sumCorrDiff = 0.0f;
502 100468 : thr = 0.15f * (float) ( count_active_ch ) * ( count_active_ch - 1 ) / 2.0f;
503 479709 : for ( ch2 = 1; ch2 < nchan; ch2++ )
504 : {
505 1436893 : for ( ch1 = 0; ch1 < ch2; ch1++ )
506 : {
507 1057652 : if ( sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE &&
508 1055622 : sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
509 : {
510 1026725 : sumCorrDiff += fabsf( hMCT->lastxCorrMatrix[ch1][ch2] - xCorrMatrix[ch1][ch2] );
511 : }
512 : }
513 : }
514 :
515 100468 : if ( sumCorrDiff > thr )
516 : {
517 40758 : forceKeepTree = 0;
518 : }
519 :
520 : /* check if keepTree is applied on unallowed blocks (e.g. channel pairs with different cores) */
521 100468 : if ( forceKeepTree )
522 : {
523 59710 : if ( !hMCT->currBlockDataCnt )
524 : {
525 22670 : forceKeepTree = 0;
526 : }
527 : else
528 : {
529 102366 : for ( pair = 0; pair < hMCT->currBlockDataCnt; pair++ )
530 : {
531 65326 : if ( xCorrMatrix[hMCT->hBlockData[pair]->ch1][hMCT->hBlockData[pair]->ch2] == 0.0f )
532 : {
533 127 : forceKeepTree = 0;
534 : }
535 : }
536 : }
537 : }
538 :
539 : /*save initial correlation matrix for next frame*/
540 580177 : for ( ch1 = 0; ch1 < nchan; ch1++ )
541 : {
542 2017070 : for ( ch2 = ch1; ch2 < nchan; ch2++ )
543 : {
544 1537361 : hMCT->lastxCorrMatrix[ch1][ch2] = xCorrMatrix[ch1][ch2];
545 : }
546 : }
547 :
548 : #ifdef DEBUG_MODE_MDCT
549 : dbgwrite( &forceKeepTree, sizeof( int16_t ), 1, 1, "./res/keepTree" );
550 : #endif
551 :
552 100468 : currBlockDataCnt = 0;
553 197379 : while ( currBlockDataCnt < hMCT->nchan_out_woLFE )
554 : {
555 : /* find best fitting channel pair: */
556 197379 : ch1 = -1;
557 197379 : ch2 = -1;
558 197379 : max_corr = 0.f;
559 :
560 197379 : if ( !forceKeepTree )
561 : {
562 101093 : getNextBestCorrelation( xCorrMatrix, &ch1, &ch2, &max_corr, inactiveBlockDetected, nchan );
563 : }
564 : else
565 : {
566 96286 : getBestCorrelation( hMCT, &tmp_ch1, &tmp_ch2, &tmp_max_corr, xCorrMatrix );
567 :
568 96286 : if ( currBlockDataCnt == hMCT->currBlockDataCnt )
569 : {
570 31380 : break;
571 : }
572 : else
573 : {
574 64906 : ch1 = hMCT->hBlockData[currBlockDataCnt]->ch1;
575 64906 : ch2 = hMCT->hBlockData[currBlockDataCnt]->ch2;
576 :
577 : /*don't allow forcing of channel-pair if their correlation is under the threshold*/
578 64906 : max_corr = xCorrMatrix[ch1][ch2];
579 64906 : if ( fabsf( max_corr ) <= 0.3f )
580 : {
581 5007 : ch1 = tmp_ch1;
582 5007 : ch2 = tmp_ch2;
583 5007 : max_corr = tmp_max_corr;
584 5007 : forceKeepTree = 0;
585 : }
586 : }
587 : }
588 :
589 165999 : if ( ( fabsf( max_corr ) > DEFAULT_CORR_THRES && !hMCT->hbr_mct ) || ( fabsf( max_corr ) > SPAR_CORR_THRES && hMCT->hbr_mct ) )
590 : {
591 97008 : if ( !forceKeepTree )
592 : {
593 : /*save channel pair*/
594 37126 : hMCT->hBlockData[currBlockDataCnt]->ch1 = ch1;
595 37126 : hMCT->hBlockData[currBlockDataCnt]->ch2 = ch2;
596 : }
597 :
598 : /* calculate all related values: */
599 97008 : assert( sts[ch1]->mct_chan_mode != MCT_CHAN_MODE_IGNORE && sts[ch2]->mct_chan_mode != MCT_CHAN_MODE_IGNORE );
600 :
601 97008 : getBlockValues( sts, ch1, ch2, hMCT->hBlockData[currBlockDataCnt], mdst_spectrum, inv_spectrum, inv_mdst_spectrum );
602 :
603 97008 : if ( hMCT->hBlockData[currBlockDataCnt]->isActive == 0 )
604 : {
605 4906 : inactiveBlockDetected++;
606 4906 : if ( inactiveBlockDetected > hMCT->nchan_out_woLFE / 2 )
607 : {
608 97 : break;
609 : }
610 4809 : forceKeepTree = 0;
611 :
612 4809 : continue; /* skip inactive blocks where stereo mode is dual-mono */
613 : }
614 :
615 92102 : updateCorrelationMatrix( sts, hMCT, ch1, ch2, xCorrMatrix );
616 92102 : cpEle[ch1] = 1;
617 92102 : cpEle[ch2] = 1;
618 :
619 92102 : currBlockDataCnt++;
620 : }
621 : else
622 : {
623 : break;
624 : }
625 : }
626 :
627 : /*save number of blocks for next frame*/
628 100468 : hMCT->currBlockDataCnt = currBlockDataCnt;
629 : #else
630 : forceKeepTree = 1;
631 : if ( nchan == 3 ) /*3 TCs*/
632 : {
633 : #ifdef DEBUG_SINGLE_CODE_OMNI
634 : ch1 = 1;
635 : ch2 = 2;
636 : cpEle[0] = 0;
637 : #else
638 : /* one stereo pair for first and second channel (W,Y)*/
639 : ch1 = 0;
640 : ch2 = 1;
641 : cpEle[2] = 0;
642 : #endif
643 : hMCT->currBlockDataCnt = 1;
644 : hMCT->hBlockData[0]->ch1 = ch1;
645 : hMCT->hBlockData[0]->ch2 = ch2;
646 :
647 : getBlockValues( sts, ch1, ch2, hMCT->hBlockData[0], mdst_spectrum, inv_spectrum, inv_mdst_spectrum );
648 :
649 : if ( hMCT->hBlockData[0]->isActive )
650 : {
651 : cpEle[ch1] = 1;
652 : cpEle[ch2] = 1;
653 : }
654 : else
655 : {
656 : hMCT->currBlockDataCnt = 0;
657 : }
658 : }
659 : else
660 : {
661 : assert( nchan == 4 ); /*4 TCs*/
662 : /* 2 Stereo Pairs W-Y and X-Z */
663 : hMCT->currBlockDataCnt = nchan * 0.5;
664 : for ( currBlockDataCnt = 0; currBlockDataCnt < hMCT->currBlockDataCnt; currBlockDataCnt++ )
665 : {
666 : hMCT->hBlockData[currBlockDataCnt]->ch1 = currBlockDataCnt * CPE_CHANNELS;
667 : hMCT->hBlockData[currBlockDataCnt]->ch2 = currBlockDataCnt * CPE_CHANNELS + 1;
668 : getBlockValues( sts, hMCT->hBlockData[currBlockDataCnt]->ch1, hMCT->hBlockData[currBlockDataCnt]->ch2, hMCT->hBlockData[currBlockDataCnt], mdst_spectrum, inv_spectrum, inv_mdst_spectrum );
669 : if ( hMCT->hBlockData[0]->isActive )
670 : {
671 : cpEle[hMCT->hBlockData[currBlockDataCnt]->ch1] = 1;
672 : cpEle[hMCT->hBlockData[currBlockDataCnt]->ch2] = 1;
673 : }
674 : else
675 : {
676 : hMCT->currBlockDataCnt -= 1;
677 : }
678 : }
679 : }
680 : #endif
681 :
682 580177 : for ( ch = 0; ch < nchan; ch++ )
683 : {
684 479709 : if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
685 : {
686 472896 : if ( ( !cpEle[ch] ) || hMCT->currBlockDataCnt == 0 )
687 : {
688 288692 : nSubframes = ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV;
689 288692 : L_subframeTCX = sts[ch]->hTcxEnc->L_frameTCX / nSubframes;
690 :
691 288692 : if ( hMCT->lowE_ch[ch] )
692 : {
693 183258 : qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE;
694 : }
695 : else
696 : {
697 105434 : qratio = (float) SMDCT_ILD_RANGE / hMCT->mc_global_ild[ch];
698 : }
699 :
700 584016 : for ( k = 0; k < nSubframes; k++ )
701 : {
702 295324 : v_multc( sts[ch]->hTcxEnc->spectrum[k], qratio, sts[ch]->hTcxEnc->spectrum[k], L_subframeTCX );
703 295324 : v_multc( mdst_spectrum[ch][k], qratio, mdst_spectrum[ch][k], L_subframeTCX );
704 295324 : set_zero( inv_spectrum[ch][k], L_subframeTCX );
705 : }
706 288692 : hMCT->mc_global_ild[ch] = 0;
707 : }
708 : }
709 : }
710 : }
711 : else
712 : {
713 471 : hMCT->currBlockDataCnt = 0;
714 2549 : for ( ch = 0; ch < nchan; ch++ )
715 : {
716 2078 : hMCT->mc_global_ild[ch] = 0;
717 : }
718 : }
719 : #ifdef DEBUG_MODE_MDCT
720 : dbgwrite( &hMCT->currBlockDataCnt, sizeof( int16_t ), 1, 1, "./res/blockCnt" );
721 :
722 : {
723 : int16_t pair, k;
724 : for ( pair = 0; pair < (int16_t) ( hMCT->nchan_out_woLFE * 0.5 ); pair++ )
725 : {
726 : dbgwrite( &hMCT->hBlockData[pair]->ch1, sizeof( int16_t ), 1, 1, "./res/CP_in_blocks" );
727 : dbgwrite( &hMCT->hBlockData[pair]->ch2, sizeof( int16_t ), 1, 1, "./res/CP_in_blocks" );
728 : for ( k = 0; k < 2; k++ )
729 : {
730 : dbgwrite( &hMCT->hBlockData[pair]->hStereoMdct->global_ild[k], sizeof( int16_t ), 1, 1, "./res/ILD_p_block" );
731 : dbgwrite( &hMCT->hBlockData[pair]->hStereoMdct->mdct_stereo_mode[k], sizeof( int16_t ), 1, 1, "./res/stereo_mode_p_block" );
732 : dbgwrite( &hMCT->hBlockData[pair]->mask[k], sizeof( int16_t ), MAX_SFB, 1, "./res/ms_mask_p_block" );
733 : }
734 : }
735 : }
736 : #endif
737 :
738 100939 : pop_wmops();
739 :
740 100939 : return;
741 : }
742 :
743 :
744 : /*--------------------------------------------------------------------*
745 : * write_mct_bitstream()
746 : *
747 : * write mct metadata to bitstream
748 : *--------------------------------------------------------------------*/
749 :
750 100939 : void write_mct_bitstream(
751 : Encoder_State **sts, /* i/o: encoder state structure */
752 : MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */
753 : const int16_t nchan /* i : number of channels */
754 : )
755 : {
756 : int16_t pair, ch;
757 : int16_t channelPairIndex;
758 : int16_t nbits_start;
759 : MCT_BLOCK_DATA_HANDLE hBlock;
760 : Encoder_State *p_st[2];
761 100939 : BSTR_ENC_HANDLE hBstr = sts[0]->hBstr;
762 :
763 100939 : nbits_start = hBstr->nb_bits_tot;
764 :
765 100939 : push_next_indice( hBstr, hMCT->currBlockDataCnt, MCT_NUM_BLOCK_DATA_BITS );
766 :
767 : /* first write core info and overlap mode for all channels */
768 582726 : for ( ch = 0; ch < nchan; ch++ )
769 : {
770 481787 : if ( hMCT->currBlockDataCnt && sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
771 : {
772 291749 : push_next_indice( hBstr, hMCT->mc_global_ild[ch], SMDCT_GLOBAL_ILD_BITS );
773 : }
774 : }
775 :
776 100939 : if ( hMCT->currBlockDataCnt )
777 : {
778 351591 : for ( ch = 0; ch < nchan; ch++ )
779 : {
780 295035 : if ( sts[ch]->mct_chan_mode != MCT_CHAN_MODE_IGNORE )
781 : {
782 291749 : push_next_indice( hBstr, hMCT->lowE_ch[ch], 1 );
783 : }
784 : }
785 : }
786 :
787 : /* Do for each stereo block */
788 193041 : for ( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
789 : {
790 92102 : hBlock = hMCT->hBlockData[pair];
791 :
792 : /*calculate channel pair index and write it to BS*/
793 92102 : channelPairIndex = channelPairToIndex( hBlock->ch1, hBlock->ch2, nchan );
794 92102 : push_next_indice( hBstr, channelPairIndex, hMCT->bitsChannelPairIndex );
795 :
796 : /*point to encoder states of actual channels to write block pair bits*/
797 92102 : p_st[0] = sts[hBlock->ch1];
798 92102 : p_st[1] = sts[hBlock->ch2];
799 :
800 : /*then business as usual for each block pair */
801 92102 : write_stereo_to_bitstream( hMCT->hBlockData[pair]->hStereoMdct, p_st, hBlock->mask, 1, hBstr );
802 : }
803 :
804 100939 : hMCT->nBitsMCT = hBstr->nb_bits_tot - nbits_start;
805 :
806 100939 : return;
807 : }
808 :
809 :
810 : /*--------------------------------------------------------------------*
811 : * mctStereoIGF_enc()
812 : *
813 : * IGF analysis of channels after MCT processing
814 : *--------------------------------------------------------------------*/
815 :
816 35766 : void mctStereoIGF_enc(
817 : MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */
818 : Encoder_State **sts, /* i/o: encoder state structure */
819 : float *orig_spectrum[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */
820 : float *powerSpec[MCT_MAX_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/
821 : float *powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/
822 : float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */
823 : const int16_t sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */
824 : )
825 : {
826 : int16_t b, nSubframes, L_subframeTCX;
827 : int16_t p_ch[2], n, ch, ch1, ch2;
828 : Encoder_State *p_st[NB_DIV];
829 : Encoder_State *st;
830 : float *p_powerSpecMsInv[CPE_CHANNELS][NB_DIV];
831 : float *p_inv_spectrum[CPE_CHANNELS][NB_DIV];
832 : float *p_orig_spectrum[CPE_CHANNELS][NB_DIV];
833 : float *p_powerSpec[NB_DIV];
834 : int16_t singleChEle[MCT_MAX_CHANNELS];
835 :
836 35766 : L_subframeTCX = 0; /* to avoid compilation warning */
837 35766 : set_s( singleChEle, 1, hMCT->nchan_out_woLFE );
838 :
839 96336 : for ( b = 0; b < hMCT->currBlockDataCnt; b++ )
840 : {
841 60570 : ch1 = hMCT->hBlockData[b]->ch1;
842 60570 : ch2 = hMCT->hBlockData[b]->ch2;
843 :
844 60570 : p_ch[0] = ch1;
845 60570 : p_ch[1] = ch2;
846 :
847 60570 : singleChEle[hMCT->hBlockData[b]->ch1] = 0;
848 60570 : singleChEle[hMCT->hBlockData[b]->ch2] = 0;
849 :
850 : /* point to encoder states of actual channels to write block pair bits */
851 60570 : p_st[0] = sts[ch1];
852 60570 : p_st[1] = sts[ch2];
853 :
854 60570 : if ( ch1 > 0 )
855 : {
856 37210 : sts[ch1]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
857 : }
858 :
859 60570 : if ( ch2 > 0 )
860 : {
861 60570 : sts[ch2]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
862 : }
863 :
864 60570 : p_powerSpec[0] = powerSpec[ch1];
865 60570 : p_powerSpec[1] = powerSpec[ch2];
866 :
867 : /* Band-wise M/S for MDST */
868 60570 : nSubframes = p_st[0]->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV;
869 122637 : for ( n = 0; n < nSubframes; n++ )
870 : {
871 62067 : p_orig_spectrum[0][n] = orig_spectrum[ch1][n];
872 62067 : p_orig_spectrum[1][n] = orig_spectrum[ch2][n];
873 62067 : p_powerSpecMsInv[0][n] = powerSpecMsInv[ch1][n];
874 62067 : p_powerSpecMsInv[1][n] = powerSpecMsInv[ch2][n];
875 62067 : p_inv_spectrum[0][n] = inv_spectrum[ch1][n];
876 62067 : p_inv_spectrum[1][n] = inv_spectrum[ch2][n];
877 :
878 62067 : if ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] != hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] ||
879 31153 : hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS )
880 : {
881 32949 : ProcessStereoIGF( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, p_orig_spectrum, p_powerSpec, p_powerSpecMsInv, p_inv_spectrum, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 );
882 : }
883 : else
884 : {
885 87354 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
886 : {
887 58236 : st = p_st[ch];
888 :
889 58236 : L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes;
890 :
891 58236 : ProcessIGF( st, st->hTcxEnc->spectrum[n], (float *) orig_spectrum[p_ch[ch]][n], &powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch1], 0 );
892 : }
893 : }
894 : }
895 : }
896 :
897 : /* channel elements that are coded separately detected */
898 35766 : if ( sum_s( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 )
899 : {
900 210593 : for ( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
901 : {
902 174831 : if ( singleChEle[ch] )
903 : {
904 53707 : st = sts[ch];
905 :
906 53707 : if (
907 53707 : st->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
908 : {
909 1253 : continue;
910 : }
911 :
912 52454 : if ( ch > 0 )
913 : {
914 40048 : st->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
915 : }
916 :
917 52454 : nSubframes = st->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV;
918 106448 : for ( n = 0; n < nSubframes; n++ )
919 : {
920 53994 : ProcessIGF( st, st->hTcxEnc->spectrum[n], (float *) orig_spectrum[ch][n], &powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 );
921 : }
922 : }
923 : }
924 : }
925 :
926 35766 : return;
927 : }
|