LCOV - code coverage report
Current view: top level - lib_enc - ivas_tcx_core_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 269 286 94.1 %
Date: 2025-05-23 08:37:30 Functions: 3 3 100.0 %

          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 <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #ifdef DEBUGGING
      37             : #include "debug.h"
      38             : #endif
      39             : #include <math.h>
      40             : #include "cnst.h"
      41             : #include "prot.h"
      42             : #include "rom_com.h"
      43             : #include "basop_proto_func.h"
      44             : #include "wmc_auto.h"
      45             : #include "ivas_prot.h"
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * stereo_tcx_init_enc()
      49             :  *
      50             :  * Initialize stereo TCX encoder
      51             :  *-------------------------------------------------------------------*/
      52             : 
      53      941110 : void stereo_tcx_init_enc(
      54             :     Encoder_State *st /* i/o: encoder state structure */
      55             : )
      56             : {
      57             :     int16_t prev_IsTNSAllowed;
      58      941110 :     assert( st->core_brate != SID_2k40 && st->core_brate != FRAME_NO_DATA );
      59             : 
      60             :     /* Get the raw coder type from signal analysis*/
      61      941110 :     st->coder_type = st->coder_type_raw;
      62      941110 :     if ( !st->localVAD )
      63             :     {
      64      117028 :         st->coder_type = INACTIVE;
      65             :     }
      66      824082 :     else if ( st->coder_type > GENERIC )
      67             :     {
      68           0 :         st->coder_type = GENERIC;
      69             :     }
      70             : 
      71      941110 :     if ( st->tcxonly )
      72             :     {
      73      812796 :         st->coder_type = GENERIC;
      74             :     }
      75             : 
      76      941110 :     st->hTcxCfg->coder_type = st->coder_type;
      77      941110 :     if ( !st->tcxonly && !st->localVAD && st->hTcxCfg->coder_type == GENERIC )
      78             :     {
      79           0 :         st->hTcxCfg->coder_type = UNVOICED;
      80             :     }
      81             : 
      82             :     /*sampling rate*/
      83      941110 :     st->sr_core = getCoreSamplerateMode2( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format );
      84      941110 :     st->fscale = sr2fscale( st->sr_core );
      85             : 
      86             :     /*frame size*/
      87      941110 :     st->L_frame = (int16_t) ( st->sr_core / FRAMES_PER_SEC );
      88      941110 :     st->hTcxEnc->L_frameTCX = (int16_t) ( st->input_Fs / FRAMES_PER_SEC );
      89             : 
      90      941110 :     if ( ( st->L_frame == L_FRAME16k && ( st->bits_frame_nominal * FRAMES_PER_SEC ) <= MAX_ACELP_BRATE ) || ( st->tcxonly && ( st->sr_core == INT_FS_16k || st->sr_core == INT_FS_16k ) ) )
      91             :     {
      92      140482 :         st->nb_subfr = NB_SUBFR16k;
      93             :     }
      94             :     else
      95             :     {
      96      800628 :         st->nb_subfr = NB_SUBFR;
      97             :     }
      98             : 
      99             :     /*TCX tools*/
     100      941110 :     st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->rf_mode );
     101      941110 :     st->hTcxCfg->resq = getResq( st->bits_frame_nominal * FRAMES_PER_SEC );
     102      941110 :     st->hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->bits_frame_nominal * FRAMES_PER_SEC, st->rf_mode, st->element_mode );
     103      941110 :     st->igf = getIgfPresent( st->element_mode, st->bits_frame_nominal * FRAMES_PER_SEC, st->bwidth, st->rf_mode );
     104      941110 :     prev_IsTNSAllowed = st->hTcxCfg->fIsTNSAllowed;
     105      941110 :     if ( st->element_mode != EVS_MONO )
     106             :     {
     107      941110 :         st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( st->bits_frame_nominal * FRAMES_PER_SEC, st->igf, st->element_mode );
     108             :     }
     109      941110 :     if ( !prev_IsTNSAllowed && st->hTcxCfg->fIsTNSAllowed && st->element_mode == IVAS_CPE_DFT ) /* may happen in unified stereo when switching stereo technologies */
     110             :     {
     111           1 :         InitTnsConfigs( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->bits_frame_nominal * FRAMES_PER_SEC, st->element_mode, 0 );
     112             : 
     113           1 :         SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, 0 );
     114             :     }
     115      941110 :     st->core_brate = st->total_brate;
     116             : 
     117      941110 :     return;
     118             : }
     119             : 
     120             : 
     121             : /*-------------------------------------------------------------------*
     122             :  * stereo_tcx_core_enc()
     123             :  *
     124             :  * Stereo TCX encoder
     125             :  *-------------------------------------------------------------------*/
     126             : 
     127      235212 : void stereo_tcx_core_enc(
     128             :     Encoder_State *st,               /* i/o: encoder state structure             */
     129             :     const float new_samples_12k8[],  /* i  : buffer of input signal @12.8 kHz    */
     130             :     const float new_samples_16k[],   /* i  : buffer of input signal @16 kHz      */
     131             :     const float Aw[],                /* i  : weighted A(z) unquant. for subframes*/
     132             :     float lsp_new[],                 /* i  : LSPs at the end of the frame        */
     133             :     float lsp_mid[],                 /* i  : LSPs in the middle of the frame     */
     134             :     float pitch_buf[NB_SUBFR16k],    /* o  : floating pitch for each subframe    */
     135             :     const int16_t last_element_mode, /* i  : last element mode                   */
     136             :     const int16_t vad_hover_flag     /* i  : VAD hangover flag                   */
     137             : )
     138             : {
     139             :     TCX_ENC_HANDLE hTcxEnc;
     140             :     int16_t i, n;
     141             : 
     142             :     /*size and windowing*/
     143             :     const float *p_new_samples;
     144             :     int16_t n_subframes;
     145             :     int16_t last_core_orig;
     146             : 
     147             :     /*Bits*/
     148             :     int16_t nbits_start, total_nbbits, nbits_header;
     149             :     int16_t target_bits[2], bitsAvailable;
     150             :     int16_t nbits_lpc[2];
     151             :     int16_t tnsSize[2]; /* number of tns parameters put into prm */
     152             :     int16_t tnsBits[2]; /* number of tns bits in the frame */
     153             :     int16_t ltpBits;
     154             : 
     155             :     /*Parameters*/
     156             :     int16_t param_lpc[NPRM_LPC_NEW];
     157             :     int16_t param_core[2 * NPRM_DIV];
     158             :     int16_t bits_param_lpc[10], no_param_lpc;
     159             : 
     160             :     /*LPC*/
     161             :     float lsf_q[M], lsp_q[M], lsp[M], lsf[M];
     162             :     float lspmid_q[M];
     163             :     float A_q[M + 1];
     164             :     float gainlpc[2][FDNS_NPTS];
     165             :     float lsp_tcx_q[M], lsf_tcx_q[M];
     166             :     int16_t tcx_lpc_cdk;
     167             :     Word16 A_q_ind[M + 1]; /*for LPC-based AC*/
     168             :     Word16 lspq_ind[M];    /*for LPC-based AC*/
     169             : 
     170             :     /*TCX-LTP*/
     171             :     int16_t T_op[3];
     172             : 
     173             :     /*HM*/
     174             :     int16_t indexBuffer[2 * ( ( N_MAX / 2 ) + 1 )];
     175             :     CONTEXT_HM_CONFIG hm_cfg[2];
     176             : 
     177             :     /* bitstream */
     178      235212 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     179             : 
     180             : #ifdef DEBUG_MODE_TCX
     181             :     static FILE *pF = NULL;
     182             :     if ( pF == NULL )
     183             :         pF = fopen( "./res/stereo_tcx_enc_ind.txt", "w" );
     184             : #endif
     185             : 
     186      235212 :     push_wmops( "stereo_tcx_core_enc" );
     187             : 
     188             :     /*Sanity check*/
     189      235212 :     assert( st->mdct_sw == MODE1 && "MDCT switching should be in TCX MODE 1\n" );
     190      235212 :     assert( st->rf_mode == 0 && "Channel aware not supported! " );
     191             : 
     192      235212 :     no_param_lpc = 0;
     193      235212 :     n_subframes = 1;
     194             : 
     195      235212 :     hTcxEnc = st->hTcxEnc;
     196             : 
     197             :     /*--------------------------------------------------------------*
     198             :      * Configuration of TCX
     199             :      *---------------------------------------------------------------*/
     200             : 
     201      235212 :     stereo_tcx_init_enc( st );
     202             : 
     203             :     /*--------------------------------------------------------------*
     204             :      * Initialization
     205             :      *---------------------------------------------------------------*/
     206             : 
     207             :     /* Subtract the bits of common header */
     208      235212 :     st->bits_frame_core = (int16_t) ( st->total_brate / FRAMES_PER_SEC ) - hBstr->nb_bits_tot;
     209             : 
     210             :     /*Get Bits of TCX header*/
     211      235212 :     nbits_header = 3; /* Coder types (2) + last_core for bfi (1) */
     212             : 
     213      235212 :     if ( st->tcxonly )
     214             :     {
     215             :         /* TCX20/10 flag */
     216      106898 :         nbits_header++;
     217             :     }
     218             : 
     219             :     /* bits for TCX overlap mode (1 bit: full, 2 bits: half or no overlap) */
     220      235212 :     nbits_header += ( st->hTcxCfg->tcx_curr_overlap_mode == HALF_OVERLAP || st->hTcxCfg->tcx_curr_overlap_mode == MIN_OVERLAP ) ? 2 : 1;
     221             : 
     222      235212 :     hm_cfg[0].indexBuffer = &indexBuffer[0];
     223      235212 :     hm_cfg[1].indexBuffer = &indexBuffer[N_MAX / 2 + 1];
     224             : 
     225      235212 :     set_s( tnsSize, 0, 2 );
     226      235212 :     set_s( tnsBits, 0, 2 );
     227      235212 :     set_s( nbits_lpc, 0, 2 );
     228      235212 :     ltpBits = 0;
     229             : 
     230      940848 :     for ( i = 0; i < 3; i++ )
     231             :     {
     232      705636 :         T_op[i] = st->pitch[i];
     233             : 
     234             :         /* check minimum pitch for quantization */
     235      705636 :         if ( T_op[i] < PIT_MIN_SHORTER )
     236             :         {
     237       83952 :             T_op[i] *= 2;
     238             :         }
     239             : 
     240             :         /* convert pitch values to core sampling-rate */
     241      705636 :         if ( st->L_frame != L_FRAME )
     242             :         {
     243      542736 :             T_op[i] = (int16_t) ( T_op[i] * (float) st->L_frame / (float) L_FRAME + 0.5f );
     244             :         }
     245             :     }
     246             : 
     247      235212 :     if ( st->L_frame == L_FRAME )
     248             :     {
     249       54300 :         p_new_samples = new_samples_12k8;
     250             :     }
     251             :     else
     252             :     {
     253      180912 :         p_new_samples = new_samples_16k;
     254             :     }
     255             : 
     256             :     /*--------------------------------------------------------------*
     257             :      * TCX20/TCX10 switching decision
     258             :      *---------------------------------------------------------------*/
     259             : 
     260      235212 :     if ( hTcxEnc->tcxMode == TCX_10 )
     261             :     {
     262        2077 :         st->core = TCX_10_CORE;
     263        2077 :         n_subframes = 2;
     264        2077 :         nbits_header += ( st->hTcxCfg->tcx_last_overlap_mode == HALF_OVERLAP || st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? 2 : 1;
     265             :     }
     266      233135 :     else if ( hTcxEnc->tcxMode == TCX_20 )
     267             :     {
     268      233135 :         st->core = TCX_20_CORE;
     269      233135 :         n_subframes = 1;
     270             :     }
     271             : 
     272             : #ifdef DEBUG_MODE_TCX
     273             :     fprintf( pF, "== stereo Chan %d - Nominal Bits %d - Allocated Bits %d ==\n", st->idchan, st->bits_frame_nominal, (int16_t) ( st->total_brate / FRAMES_PER_SEC ) );
     274             :     fprintf( pF, "stereo Common Header: %d bits\n", hBstr->nb_bits_tot );
     275             : #endif
     276      235212 :     nbits_start = hBstr->nb_bits_tot;
     277             : 
     278             :     /*--------------------------------------------------------------------------------*
     279             :      * Write TCX signaling
     280             :      *--------------------------------------------------------------------------------*/
     281             : 
     282             :     /* TCX20/TCX10 and coder type */
     283      235212 :     writeTCXMode( st, hBstr, 0, /* MCT_flag */ &nbits_start );
     284             : 
     285             :     /* write last_core for error concealment */
     286      235212 :     push_next_indice( hBstr, ( st->last_core != ACELP_CORE || st->core == TCX_10_CORE ), 1 );
     287             : 
     288             :     /* write TCX overlap mode (1 bit: full, 2 bits: half or no overlap) */
     289      235212 :     writeTCXWindowing( hBstr, st->hTcxCfg->tcx_curr_overlap_mode );
     290      235212 :     if ( st->core == TCX_10_CORE )
     291             :     {
     292        2077 :         writeTCXWindowing( hBstr, st->hTcxCfg->tcx_last_overlap_mode );
     293             :     }
     294             : 
     295      235212 :     assert( nbits_header == ( hBstr->nb_bits_tot - nbits_start ) );
     296             : #ifdef DEBUG_MODE_TCX
     297             :     fprintf( pF, "\t TCX Header: %d bits: %d %d %d %d\n", hBstr->nb_bits_tot - nbits_start, st->tcxonly, st->core, st->tcxonly ? st->clas : st->hTcxCfg->coder_type, st->hTcxCfg->tcx_curr_overlap_mode );
     298             : #endif
     299             : 
     300             :     /*--------------------------------------------------------------*
     301             :      * Core Signal Analysis: MDCT, TNS, LPC analysis
     302             :      *---------------------------------------------------------------*/
     303             : 
     304      235212 :     core_signal_analysis_high_bitrate( p_new_samples, T_op, lsp_new, lsp_mid, st, NULL, tnsSize, tnsBits, param_core, &ltpBits, NULL, st->L_frame, hTcxEnc->L_frameTCX, last_element_mode, vad_hover_flag );
     305             : 
     306      235212 :     bitsAvailable = st->bits_frame_core - nbits_header;
     307      235212 :     if ( st->igf )
     308             :     {
     309      224617 :         bitsAvailable -= st->hIGFEnc->infoTotalBitsWritten;
     310             :     }
     311             : 
     312             :     /*--------------------------------------------------------------*
     313             :      * Envelope Quantization and FDNS
     314             :      *---------------------------------------------------------------*/
     315             : 
     316      235212 :     if ( !st->enableTcxLpc )
     317             :     {
     318      217755 :         if ( st->envWeighted )
     319             :         {
     320             :             /* Unweight the envelope */
     321           0 :             E_LPC_lsp_unweight( st->lsp_old, st->lsp_old, st->lsf_old, 1.0f / st->gamma );
     322           0 :             st->envWeighted = 0;
     323             :         }
     324             : 
     325      217755 :         lpc_quantization( st, lsp_new, lsp_mid, lsp_q, lsf_q, lspmid_q, AUDIO, 0, /*No acelp->no need to compute any mid-LPC*/
     326             :                           param_lpc, nbits_lpc, bits_param_lpc, &no_param_lpc );
     327             : 
     328             :         /*--------------------------------------------------------------*
     329             :          * Rate switching
     330             :          *--------------------------------------------------------------*/
     331             : 
     332      217755 :         if ( st->rate_switching_reset )
     333             :         {
     334        1484 :             mvr2r( lsp_q, st->lsp_old, M );
     335        1484 :             mvr2r( lsf_q, st->lsf_old, M );
     336             :         }
     337             :     }
     338             : 
     339      235212 :     last_core_orig = st->last_core;
     340      472501 :     for ( n = 0; n < n_subframes; n++ )
     341             :     {
     342             :         /* Get the envelope */
     343      237289 :         if ( st->enableTcxLpc )
     344             :         {
     345       17457 :             tcx_lpc_cdk = tcxlpc_get_cdk( st->hTcxCfg->coder_type );
     346             : 
     347             :             /* Get the envelope corresponding to the current frame */
     348       17457 :             E_LPC_int_lpc_tcx( st->lspold_enc, lsp_new, A_q );
     349             : 
     350             :             /* Weight the envelope */
     351       17457 :             weight_a( A_q, A_q, st->gamma, M );
     352             : 
     353             :             /* Convert to lsp and lsf */
     354       17457 :             a2lsp_stab( A_q, lsp, lsp_new );
     355       17457 :             lsp2lsf( lsp, lsf, M, INT_FS_12k8 );
     356             : 
     357             :             /* Quantize */
     358       17457 :             Q_lsf_tcxlpc( lsf, lsf_tcx_q, lspq_ind, param_lpc, st->narrowBand, tcx_lpc_cdk, st->mem_MA, st->hTcxCfg->coder_type, st->Bin_E );
     359             : 
     360             :             /* Account for consumed bits */
     361       17457 :             nbits_lpc[0] = TCXLPC_NUMBITS;
     362       17457 :             if ( param_lpc[0] )
     363             :             {
     364        4832 :                 nbits_lpc[0] += TCXLPC_IND_NUMBITS;
     365             :             }
     366             : 
     367             :             /* Convert quantized lsf to lsp and A */
     368       17457 :             lsf2lsp( lsf_tcx_q, lsp_tcx_q, M, INT_FS_12k8 );
     369       17457 :             lsp2a_stab( lsp_tcx_q, A_q, M );
     370             :         }
     371      219832 :         else if ( !st->tcxonly )
     372             :         {
     373      110857 :             E_LPC_int_lpc_tcx( st->lsp_old, lsp_q, A_q );
     374             :         }
     375      108975 :         else if ( n + 2 == n_subframes ) /* First TCX10/5 subframe */
     376             :         {
     377        2077 :             lsp2a_stab( lspmid_q, A_q, M );
     378             :         }
     379             :         else
     380             :         {
     381      106898 :             lsp2a_stab( lsp_q, A_q, M );
     382             :         }
     383             : 
     384      237289 :         if ( hTcxEnc->tcx_lpc_shaped_ari )
     385             :         {
     386       17457 :             basop_E_LPC_f_lsp_a_conversion( lspq_ind, A_q_ind, M );
     387             :         }
     388             : 
     389      237289 :         bitsAvailable -= nbits_lpc[n];
     390             : 
     391             :         /* Shape spectrum */
     392      237289 :         ShapeSpectrum( st->hTcxCfg, A_q, gainlpc[n], st->L_frame / n_subframes, st->hTcxCfg->tcx_coded_lines / n_subframes, hTcxEnc->spectrum[n], hTcxEnc->fUseTns[n], st, NULL );
     393             : 
     394      237289 :         st->last_core = st->core;
     395             :     }
     396             : 
     397      235212 :     st->last_core = last_core_orig;
     398             : 
     399             :     /*--------------------------------------------------------------------------------*
     400             :      * Write LPC parameters
     401             :      *--------------------------------------------------------------------------------*/
     402             : 
     403      235212 :     writeLPCparam( st, hBstr, param_lpc, bits_param_lpc, no_param_lpc, &total_nbbits );
     404             : 
     405      235212 :     assert( total_nbbits == ( nbits_lpc[0] + nbits_lpc[1] ) );
     406             : #ifdef DEBUG_MODE_TCX
     407             :     fprintf( pF, "\t TCX LPC: %d bits\n", total_nbbits );
     408             : #endif
     409             : 
     410             :     /*--------------------------------------------------------------*
     411             :      * Run TCX10/20 Core
     412             :      *---------------------------------------------------------------*/
     413             : 
     414      235212 :     hTcxEnc->measuredBwRatio = 1.f;
     415             : 
     416      472501 :     for ( n = 0; n < n_subframes; n++ )
     417             :     {
     418      237289 :         target_bits[n] = ( bitsAvailable + ( n_subframes - 1 ) - n ) / n_subframes - tnsBits[n];
     419             : 
     420      237289 :         if ( st->enablePlcWaveadjust && ( n == n_subframes - 1 ) )
     421             :         {
     422           0 :             target_bits[n] -= 1;
     423             :         }
     424      237289 :         if ( n == 0 )
     425             :         {
     426      235212 :             target_bits[n] -= ltpBits;
     427             :         }
     428             : 
     429             :         /* Run TCX20/10 encoder */
     430      237289 :         QuantizeSpectrum( st, A_q, A_q_ind, gainlpc[n], st->synth + n * st->L_frame / n_subframes, target_bits[n], tnsSize[n], param_core + n * NPRM_DIV, n, &hm_cfg[n], vad_hover_flag );
     431             :     }
     432             : 
     433             :     /* Update tcx overlap mode */
     434      235212 :     st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode;
     435             : 
     436      235212 :     coder_tcx_post( st, A_q, Aw );
     437             : 
     438      235212 :     if ( st->enableTcxLpc )
     439             :     {
     440       17457 :         E_LPC_lsp_unweight( lsp_tcx_q, lsp_q, lsf_q, 1.0f / st->gamma ); /* Update lsf_q for encoderSideLossSimulation() */
     441             :     }
     442             : 
     443             :     /* Update lsp/lsf memory */
     444      235212 :     if ( st->enableTcxLpc && st->core != ACELP_CORE )
     445             :     {
     446             :         /* Update lsf / lsp memory */
     447       17457 :         mvr2r( lsf_tcx_q, st->lsf_old, M );
     448       17457 :         mvr2r( lsp_tcx_q, st->lsp_old, M );
     449       17457 :         st->envWeighted = 1;
     450             : 
     451             :         /* Update ACELP quantizer state */
     452       17457 :         lsf_update_memory( st->narrowBand, st->lsf_old, st->mem_MA, st->mem_MA );
     453       17457 :         st->pstreaklen = 0;
     454       17457 :         st->streaklimit = 1.0f;
     455             :         /* check resonance for pitch clipping algorithm */
     456       17457 :         gp_clip_test_lsf( st->element_mode, st->core_brate, st->lsf_old, st->clip_var, 0 );
     457       17457 :         mvr2r( st->lsf_old, st->mem_AR, M );
     458             :     }
     459             :     else
     460             :     {
     461      217755 :         mvr2r( lsf_q, st->lsf_old, M );
     462      217755 :         mvr2r( lsp_q, st->lsp_old, M );
     463             :     }
     464             : 
     465      235212 :     if ( st->Opt_DTX_ON && !st->tcxonly && st->hTdCngEnc != NULL )
     466             :     {
     467             :         /* update CNG parameters in active frames */
     468       11367 :         if ( st->bwidth == NB && st->enableTcxLpc && st->core != ACELP_CORE )
     469           0 :         {
     470             :             float buf[L_LP], res[L_FRAME], A[M + 1], r[M + 1], tmp, lsptmp[M];
     471             : 
     472           0 :             assert( st->L_frame == L_FRAME );
     473             : 
     474           0 :             mvr2r( st->synth + L_FRAME - L_LP, buf, L_LP );
     475           0 :             tmp = st->synth[L_FRAME - L_LP - 1];
     476           0 :             preemph( buf, st->preemph_fac, L_LP, &tmp );
     477           0 :             autocorr( buf, r, M, L_LP, LP_assym_window, 0, 0, 0 );
     478           0 :             lag_wind( r, M, INT_FS_12k8, LAGW_WEAK );
     479           0 :             lev_dur( A, r, M, NULL );
     480           0 :             a2lsp_stab( A, lsptmp, lsp_new );
     481             : 
     482           0 :             residu( A, M, buf + L_LP - L_FRAME, res, L_FRAME );
     483             : 
     484           0 :             cng_params_upd( lsptmp, res, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ, &st->hTdCngEnc->ho_circ_size, st->hTdCngEnc->ho_lsp_circ, ENC, st->hTdCngEnc->ho_env_circ, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth );
     485             :         }
     486             :         else
     487             :         {
     488       11367 :             cng_params_upd( lsp_new, st->hLPDmem->old_exc + L_EXC_MEM - st->L_frame, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ, &st->hTdCngEnc->ho_circ_size, st->hTdCngEnc->ho_lsp_circ, ENC, st->hTdCngEnc->ho_env_circ, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth );
     489             :         }
     490             : 
     491       11367 :         if ( st->L_frame == L_FRAME )
     492             :         {
     493             :             /* store LSPs@16k, potentially to be used in CNG@16k */
     494        3355 :             mvr2r( st->lsp_old16k, &( st->hTdCngEnc->ho_lsp_circ2[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M );
     495             :         }
     496             : 
     497             :         /* Set 16k LSP flag for CNG buffer */
     498       11367 :         st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = ( st->L_frame == L_FRAME ? 0 : 1 );
     499             : 
     500             :         /* efficient DTX hangover control */
     501       11367 :         if ( st->hTdCngEnc->burst_ho_cnt > 1 )
     502             :         {
     503         685 :             dtx_hangover_control( st, lsp_new );
     504             :         }
     505             :     }
     506             : 
     507             : #ifdef DEBUG_MODE_TCX
     508             :     {
     509             :         int16_t tmp[L_FRAME48k];
     510             : 
     511             :         for ( i = 0; i < st->L_frame; i++ )
     512             :         {
     513             :             tmp[i] = (int16_t) ( st->synth[i] + 0.5f );
     514             :         }
     515             :         dbgwrite( tmp, sizeof( int16_t ), st->L_frame, 1, "./res/stereo_tcx_enc_synth.pcm" );
     516             : 
     517             :         for ( i = 0; i < st->L_frame; i++ )
     518             :         {
     519             :             tmp[i] = (int16_t) ( st->speech_enc[i] + 0.5f );
     520             :         }
     521             :         dbgwrite( tmp, sizeof( int16_t ), st->L_frame, 1, "./res/stereo_tcx_enc_inLB.pcm" );
     522             : 
     523             :         for ( i = 0; i < hTcxEnc->L_frameTCX; i++ )
     524             :         {
     525             :             tmp[i] = (int16_t) ( st->hTcxEnc->speech_TCX[i] + 0.5f );
     526             :         }
     527             :         dbgwrite( tmp, sizeof( int16_t ), hTcxEnc->L_frameTCX, 1, "./res/stereo_tcx_enc_inFB.pcm" );
     528             :     }
     529             : #endif
     530             : 
     531             :     /*--------------------------------------------------------------------------------*
     532             :      * Encode TCX20/10 parameters
     533             :      *--------------------------------------------------------------------------------*/
     534             : 
     535      235212 :     writeTCXparam( st, hBstr, hm_cfg, param_core, nbits_header, nbits_start, nbits_lpc[0] + nbits_lpc[1], NULL, NULL, NULL, -1 );
     536             : 
     537      235212 :     total_nbbits = hBstr->nb_bits_tot - nbits_start;
     538             : 
     539             : #ifdef DEBUG_MODE_TCX
     540             :     {
     541             :         static FILE *sP = NULL;
     542             : 
     543             :         if ( sP == NULL )
     544             :             sP = fopen( "./res/stereo_tcx_core_enc_swicthes.txt", "w" );
     545             : 
     546             :         fprintf( sP, "frame:%d\t mdct_sw=%d\t rf_mode=%d tcxonly=%d\t tcxMode=%d\t core=%d\t, enableTcxLpc=%d\t igf=%d\t envWeighted=%d\t lpcQuantization=%d\t enablePlcWaveadjust=%d\t tcxltp=%d\t fIsTNSAllowed=%d\t tcx_lpc_shaped_ari=%d\t ctx_hm=%d\t \n", frame, st->mdct_sw, st->rf_mode, st->tcxonly, hTcxEnc->tcxMode, st->core, st->enableTcxLpc, st->igf, st->envWeighted, st->lpcQuantization, st->enablePlcWaveadjust, hTcxEnc->tcxltp, st->hTcxCfg->fIsTNSAllowed, hTcxEnc->tcx_lpc_shaped_ari, st->hTcxCfg->ctx_hm );
     547             :     }
     548             : #endif
     549             : 
     550      235212 :     if ( param_core[1 + NOISE_FILL_RANGES] != 0 )
     551             :     {
     552      116831 :         set_f( pitch_buf, hTcxEnc->tcxltp_pitch_int + (float) hTcxEnc->tcxltp_pitch_fr / (float) st->pit_res_max, NB_SUBFR16k );
     553             :     }
     554             :     else
     555             :     {
     556      118381 :         set_f( pitch_buf, L_SUBFR, NB_SUBFR16k );
     557             :     }
     558             : 
     559      235212 :     pop_wmops();
     560      235212 :     return;
     561             : }
     562             : 
     563             : 
     564             : /*-------------------------------------------------------------------*
     565             :  * ivas_acelp_tcx20_switching()
     566             :  *
     567             :  * Open-loop ACELP/TCX20 core decision
     568             :  *-------------------------------------------------------------------*/
     569             : 
     570             : /*! r: S/M decision (0=speech or noise,1=unclear,2=music) */
     571      340560 : int16_t ivas_acelp_tcx20_switching(
     572             :     Encoder_State *st,        /* i/o: encoder state structure                 */
     573             :     const float *inp,         /* i  : new input signal                        */
     574             :     const float *wsp,         /* i  : input weighted signal                   */
     575             :     const float non_staX,     /* i  : unbound non-stationarity for sp/mu clas.*/
     576             :     const float *pitch_fr,    /* i  : fraction pitch values                   */
     577             :     const float *voicing_fr,  /* i  : fractional voicing values               */
     578             :     const float currFlatness, /* i  : flatness                                */
     579             :     const float lsp_mid[M],   /* i  : LSPs at the middle of the frame         */
     580             :     const float stab_fac,     /* i  : LP filter stability                     */
     581             :     float *res_cod_SNR_M,
     582             :     const int16_t flag_16k_smc /* i  : flag to compute parameters with 16kHz core */
     583             : )
     584             : {
     585      340560 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     586             :     int16_t i, j;
     587             :     float A_q_tcx[NB_SUBFR16k * ( M + 1 )];
     588             :     float dsnr, snr_tcx, snr_acelp;
     589             :     int16_t iter;
     590             :     float xn_buf[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
     591             :     float window[L_LOOK_16k];
     592             :     float Ap[M + 1];
     593             :     float gainlpc[FDNS_NPTS];
     594             :     float en[N_MAX / 4];
     595             :     float sqGain, ener, tmp, fac, offset;
     596             :     int16_t L_frame, L_frame_tmp, L_loop;
     597             :     int16_t overlap;
     598             :     int16_t tcx_offset;
     599             :     float *x;
     600             :     float target;
     601             :     int16_t T0;
     602             :     float gain, noise, scale;
     603             :     float *pt_ener_sfr, ener_sfr[NB_SUBFR16k];
     604             :     float pitch_fr_local[4], voicing_fr_local[4];
     605             :     int16_t smc_dec_ol;
     606             :     float y[N_MAX];
     607             : 
     608             :     /* Initialization */
     609      340560 :     L_frame = flag_16k_smc ? st->L_frame : L_FRAME;
     610      340560 :     L_frame_tmp = L_frame;
     611             : 
     612      340560 :     x = hTcxEnc->spectrum_long;
     613             : 
     614             :     /* Check minimum pitch for quantization */
     615     1702800 :     for ( i = 0; i < 4; i++ )
     616             :     {
     617     1362240 :         pitch_fr_local[i] = pitch_fr[i];
     618     1362240 :         voicing_fr_local[i] = voicing_fr[i];
     619             :     }
     620             : 
     621      340560 :     lsp2a_stab( lsp_mid, A_q_tcx, M );
     622             : 
     623             :     /*--------------------------------------------------------------*
     624             :      * Estimate TCX SNR
     625             :      *---------------------------------------------------------------*/
     626             : 
     627      340560 :     target = 850.f;
     628      340560 :     if ( flag_16k_smc )
     629             :     {
     630       26562 :         tcx_offset = st->hTcxCfg->tcx_offset;
     631             : 
     632       26562 :         if ( st->last_core == ACELP_CORE )
     633             :         {
     634       15358 :             L_frame += tcx_offset;
     635             : 
     636       15358 :             if ( st->hTcxCfg->lfacNext < 0 )
     637             :             {
     638       15358 :                 L_frame -= st->hTcxCfg->lfacNext;
     639       15358 :                 tcx_offset = st->hTcxCfg->lfacNext;
     640             :             }
     641             :             else
     642             :             {
     643           0 :                 tcx_offset = 0;
     644             :             }
     645             :         }
     646             : 
     647       26562 :         overlap = st->hTcxCfg->tcx_mdct_window_delay;
     648       26562 :         mvr2r( st->hTcxCfg->tcx_mdct_window, window, L_LOOK_16k );
     649             :     }
     650             :     else
     651             :     {
     652      313998 :         overlap = L_LOOK_12k8;
     653      313998 :         tcx_offset = ( overlap >> 1 );
     654      313998 :         mdct_window_sine( window, INT_FS_12k8, overlap, FULL_OVERLAP, st->element_mode );
     655             : 
     656      313998 :         if ( st->last_core == ACELP_CORE )
     657             :         {
     658       98828 :             L_frame += L_frame / 4;
     659       98828 :             tcx_offset -= L_frame / 4;
     660             :         }
     661             :     }
     662      340560 :     mvr2r( inp - ( overlap >> 1 ) + tcx_offset, xn_buf, L_frame + overlap );
     663             : 
     664      340560 :     if ( st->last_core == ACELP_CORE )
     665             :     {
     666      114186 :         if ( ( tcx_offset < 0 && flag_16k_smc ) || !flag_16k_smc )
     667             :         {
     668      114186 :             set_f( xn_buf, 0.0f, overlap >> 1 );
     669             :         }
     670             :     }
     671             :     else
     672             :     {
     673    25893974 :         for ( i = 0; i < overlap; i++ )
     674             :         {
     675    25667600 :             xn_buf[i] *= window[i];
     676             :         }
     677             :     }
     678             : 
     679    39227016 :     for ( i = 0; i < overlap; i++ )
     680             :     {
     681    38886456 :         xn_buf[L_frame + i] *= window[overlap - 1 - i];
     682             :     }
     683             : 
     684      340560 :     TCX_MDCT( xn_buf, x, overlap, L_frame - overlap, overlap, st->element_mode );
     685             : 
     686    96777520 :     for ( i = 0; i < L_frame; i++ )
     687             :     {
     688    96436960 :         x[i] *= (float) L_frame * inv_sqrt( 2 * NORM_MDCT_FACTOR );
     689    96436960 :         y[i] = x[i];
     690             :     }
     691             : 
     692      340560 :     weight_a( A_q_tcx, Ap, GAMMA1, M );
     693             : 
     694      340560 :     lpc2mdct( Ap, M, gainlpc, FDNS_NPTS, 0 );
     695             : 
     696      340560 :     mdct_preShaping( x, L_frame, gainlpc );
     697             : 
     698    24449800 :     for ( i = 0; i < L_frame; i += 4 )
     699             :     {
     700    24109240 :         ener = 0.01f + x[i] * x[i] + x[i + 1] * x[i + 1] + x[i + 2] * x[i + 2] + x[i + 3] * x[i + 3];
     701    24109240 :         en[i / 4] = 9.0f + 10.0f * log10f( ener );
     702             :     }
     703             : 
     704      340560 :     fac = 128.0f;
     705      340560 :     offset = fac;
     706             : 
     707     3746160 :     for ( iter = 0; iter < 10; iter++ )
     708             :     {
     709     3405600 :         fac *= 0.5f;
     710     3405600 :         offset -= fac;
     711     3405600 :         ener = 0.0f;
     712             : 
     713   221611893 :         for ( i = 0; i < L_frame / 4; i++ )
     714             :         {
     715   219871181 :             tmp = en[i] - offset;
     716             : 
     717   219871181 :             if ( tmp > 3.0f )
     718             :             {
     719   182239985 :                 ener += tmp;
     720             :             }
     721             : 
     722   219871181 :             if ( ener > target )
     723             :             {
     724     1664888 :                 offset += fac;
     725     1664888 :                 break;
     726             :             }
     727             :         }
     728             :     }
     729             : 
     730      340560 :     if ( offset <= 32.f )
     731             :     {
     732       29731 :         offset = -128.f;
     733             :     }
     734             : 
     735      340560 :     sqGain = powf( 10.0f, offset / 20.0f );
     736      340560 :     ener = sqGain * sqGain / 12.f * sqrtf( 2.f ) / (float) L_frame;
     737             : 
     738      340560 :     if ( !flag_16k_smc )
     739             :     {
     740             :         const int16_t *bands;
     741      313998 :         const int16_t bands_20[8] = { 0, 5, 9, 19, 34, 51, 81, 111 };
     742      313998 :         const int16_t bands_25[8] = { 0, 4, 7, 15, 28, 40, 65, 89 };
     743             :         float nrg_s, nrg_n;
     744             : 
     745             :         /*Approximate SNR of TCX*/
     746      313998 :         set_f( x, sqrtf( ener ), L_frame );
     747      313998 :         mdct_noiseShaping( x, L_frame, gainlpc, FDNS_NPTS );
     748             : 
     749      313998 :         if ( st->last_core != ACELP_CORE )
     750             :         {
     751             :             /*25Hz resolution*/
     752      215170 :             bands = bands_25;
     753             :         }
     754             :         else
     755             :         {
     756             :             /*20Hz resolution*/
     757       98828 :             bands = bands_20;
     758             :         }
     759             : 
     760     2511984 :         for ( iter = 0; iter < 7; iter++ )
     761             :         {
     762     2197986 :             nrg_s = 1e-6f;
     763     2197986 :             nrg_n = 1e-6f;
     764    32318024 :             for ( i = bands[iter]; i < bands[iter + 1]; i++ )
     765             :             {
     766    30120038 :                 nrg_s += y[i] * y[i];
     767    30120038 :                 nrg_n += x[i] * x[i];
     768             :             }
     769     2197986 :             res_cod_SNR_M[iter] = nrg_s / nrg_n;
     770             :         }
     771             :     }
     772             : 
     773      340560 :     snr_tcx = 0.0f;
     774      340560 :     pt_ener_sfr = ener_sfr;
     775             : 
     776      340560 :     L_loop = flag_16k_smc ? L_frame_tmp : L_frame;
     777             : 
     778     1828190 :     for ( i = 0; i < L_loop; i += L_SUBFR )
     779             :     {
     780     1487630 :         *pt_ener_sfr = sum2_f( wsp + i, L_SUBFR ) + 1e-6f;
     781     1487630 :         snr_tcx += log10f( *pt_ener_sfr / ( ener * L_SUBFR ) );
     782     1487630 :         pt_ener_sfr++;
     783             :     }
     784      340560 :     snr_tcx *= ( (float) ( 10 * L_SUBFR ) ) / (float) L_loop;
     785             : 
     786             : 
     787             :     /*--------------------------------------------------------------*
     788             :      * Estimate ACELP SNR
     789             :      *---------------------------------------------------------------*/
     790             : 
     791      340560 :     if ( flag_16k_smc )
     792             :     {
     793       26562 :         scale = 0.092f;
     794             :     }
     795             :     else
     796             :     {
     797      313998 :         scale = 0.059f;
     798             :     }
     799             : 
     800      340560 :     snr_acelp = 0.0f;
     801      340560 :     fac = flag_16k_smc ? (float) st->sr_core / (float) INT_FS_12k8 : 1.0f;
     802      340560 :     L_loop = flag_16k_smc ? L_frame_tmp : L_FRAME;
     803             : 
     804      340560 :     pt_ener_sfr = ener_sfr;
     805     1729362 :     for ( i = 0; i < L_loop; i += L_SUBFR )
     806             :     {
     807     1388802 :         T0 = (int16_t) ( ( fac * pitch_fr_local[(int16_t) ( (float) ( i / L_SUBFR ) / fac + 0.5f )] ) + 0.5f );
     808     1388802 :         gain = get_gain( wsp + i, wsp + i - T0, L_SUBFR, NULL );
     809     1388802 :         noise = 1e-6f;
     810    90272130 :         for ( j = 0; j < L_SUBFR; j++ )
     811             :         {
     812    88883328 :             tmp = wsp[i + j] - gain * wsp[i + j - T0];
     813    88883328 :             noise += tmp * tmp;
     814             :         }
     815             : 
     816     1388802 :         noise *= scale;
     817     1388802 :         snr_acelp += log10f( *pt_ener_sfr / noise );
     818     1388802 :         pt_ener_sfr++;
     819             :     }
     820             : 
     821      340560 :     snr_acelp *= ( (float) ( 10 * L_SUBFR ) ) / (float) L_loop;
     822             : 
     823             : 
     824             :     /*--------------------------------------------------------------*
     825             :      * Switching Decision
     826             :      *---------------------------------------------------------------*/
     827             : 
     828      340560 :     dsnr = 0.0f;
     829             :     /* hysteresis for very small SNR differences between ACELP and TCX */
     830             : 
     831             :     /* try to use TCX instead of ACELP on temporally stationary frames */
     832      340560 :     if ( ( snr_acelp > snr_tcx ) && ( snr_acelp < snr_tcx + 2.0f ) &&
     833       54858 :          ( st->prevTempFlatness + currFlatness < 3.25f || stab_fac == 1.0f ||
     834       17264 :            ( !flag_16k_smc && st->sp_aud_decision0 > 0 && st->prevTempFlatness + currFlatness < 20.f ) ) &&
     835       39225 :          ( st->Nb_ACELP_frames <= 6 ) )
     836             :     {
     837       17618 :         dsnr = -2.0f;
     838             :     }
     839             : 
     840             :     /* try to use ACELP instead of TCX on transient and "buzzy" frames */
     841      340560 :     if ( ( snr_acelp < snr_tcx ) &&
     842      227271 :          ( snr_acelp > snr_tcx - 2.0f ) &&
     843       63912 :          ( st->prevTempFlatness + currFlatness > 3.25f ) &&
     844       23287 :          ( st->Nb_ACELP_frames >= 6 ) )
     845             :     {
     846        2390 :         dsnr = 2.0f;
     847             :     }
     848      340560 :     if ( ( !flag_16k_smc ) && ( offset < 74.0f ) && ( non_staX > 5.0f ) && ( snr_acelp >= snr_tcx - 4 ) && st->Nb_ACELP_frames >= 1 && ( ( ( st->hSpMusClas->lps > st->hSpMusClas->lpm ) && mean( voicing_fr_local, 4 ) >= 0.3f ) || ( st->Nb_ACELP_frames >= 6 && ( st->hSpMusClas->lps > st->hSpMusClas->lpm - 1.5f ) ) ) && ( st->sp_aud_decision0 == 0 ) && st->vad_flag )
     849             :     {
     850             :         /* Fine tuned across various databases based on various metrics to detect TCX frames in speech.*/
     851       38610 :         dsnr = 4.0f;
     852             :     }
     853             : 
     854      340560 :     if ( st->flag_noisy_speech_snr )
     855             :     {
     856             : 
     857       94595 :         if ( st->vad_flag || st->Opt_DTX_ON )
     858             :         {
     859       76124 :             dsnr += 2.f;
     860             :         }
     861             :         else
     862             :         {
     863       18471 :             dsnr -= 2.f;
     864             :         }
     865             :     }
     866             : 
     867             :     /* Select ACELP or TCX */
     868      340560 :     if ( ( snr_acelp + dsnr > snr_tcx ) && ( st->sp_aud_decision0 == 0 || st->prevTempFlatness + currFlatness > 3.25f ) )
     869             :     {
     870      110330 :         smc_dec_ol = 0;
     871             :     }
     872             :     else
     873             :     {
     874      230230 :         smc_dec_ol = 2;
     875             :     }
     876             : 
     877             : #ifdef DEBUGGING
     878             :     if ( st->force == FORCE_SPEECH )
     879             :     {
     880             :         /* enforce ACELP */
     881             :         smc_dec_ol = 0;
     882             :     }
     883             :     else if ( st->force == FORCE_MUSIC )
     884             :     {
     885             :         /* enforce TCX */
     886             :         smc_dec_ol = 2;
     887             :     }
     888             : #endif
     889             : 
     890      340560 :     st->prevTempFlatness = currFlatness;
     891             : 
     892      340560 :     return smc_dec_ol;
     893             : }

Generated by: LCOV version 1.14