LCOV - code coverage report
Current view: top level - lib_enc - cod4t64_fast.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 602 615 97.9 %
Date: 2025-05-03 01:55:50 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 <stdint.h>
      34             : #include "options.h"
      35             : #include <math.h>
      36             : #include "cnst.h"
      37             : #include "prot_fx.h"
      38             : #include "ivas_prot_fx.h"
      39             : #include "rom_com.h"
      40             : #include "wmc_auto.h"
      41             : 
      42             : /*-------------------------------------------------------------------*
      43             :  * Local constants
      44             :  *-------------------------------------------------------------------*/
      45             : 
      46             : #define BETA_BN1 2.0f
      47             : #define BETA_BN2 2.25f
      48             : 
      49             : #define BETA_BN1_FX 2 // Q0
      50             : #define BETA_BN2_FX 9 // Q2
      51             : 
      52             : #define L_SUBFR_MAX       2 * L_SUBFR
      53             : #define MAX_NUM_INTER     5
      54             : #define MAX_PULSES_STEREO 5
      55             : 
      56             : /*---------------------------------------------------------------------*
      57             :  * Quantization of 1 pulse with N+1 bits:                              *
      58             :  *---------------------------------------------------------------------*/
      59             : 
      60             : /*! r: return index (N+1 bits) */
      61       46128 : static Word16 quant_1p_N1_L_subfr_fx(
      62             :     const Word16 nb_pos, /* i  : number of positions         */
      63             :     const Word16 pos,    /* i  : position of the pulse       */
      64             :     const Word16 N       /* i  : number of bits for position */
      65             : )
      66             : {
      67             :     Word16 mask, index;
      68             : 
      69       46128 :     mask = extract_l( L_sub( L_shl( 1, N ), 1 ) );
      70             : 
      71       46128 :     index = s_and( pos, mask );
      72             : 
      73       46128 :     IF( s_and( pos, nb_pos ) != 0 )
      74             :     {
      75       23266 :         index = add( index, shl( 1, N ) );
      76             :     }
      77             : 
      78       46128 :     return index;
      79             : }
      80      105003 : static Word16 find_best_pulse_fx(
      81             :     const Word16 L_subfr,
      82             :     const Word16 nb_tracks,
      83             :     const Word16 track,
      84             :     const Word32 dn[],   // Qx
      85             :     const Word16 sign[], // Q0
      86             :     Word16 *s            // Q0
      87             : )
      88             : {
      89             :     Word16 m, i;
      90             :     Word32 temp, max_val;
      91             : 
      92      105003 :     max_val = EPSILLON_FX;
      93      105003 :     move32();
      94      105003 :     m = track;
      95      105003 :     move16();
      96     2468139 :     FOR( i = track; i < L_subfr; i += nb_tracks )
      97             :     {
      98     2363136 :         temp = imult3216( dn[i], sign[i] );
      99             : 
     100     2363136 :         IF( GE_32( temp, max_val ) )
     101             :         {
     102      341935 :             max_val = temp;
     103      341935 :             move32();
     104      341935 :             m = i;
     105      341935 :             move16();
     106             :         }
     107             :     }
     108             : 
     109      105003 :     *s = sign[m];
     110      105003 :     move16();
     111             : 
     112      105003 :     return m;
     113             : }
     114             : 
     115             : /*-------------------------------------------------------------------*
     116             :  * Function  acelp_fast()
     117             :  *
     118             :  * Fast algebraic codebook search.
     119             :  * Supports 10, 15, 17, 20, 24, and 26 bits codebooks.
     120             :  *-------------------------------------------------------------------*/
     121             : 
     122       28647 : void acelp_fast_fx(
     123             :     BSTR_ENC_HANDLE hBstr,  /* i/o: encoder bitstream handle                      */
     124             :     const Word16 cdk_index, /* i  : codebook index                                */
     125             :     const Word16 dn_orig[L_SUBFR],
     126             :     /* i  : corr. between target and h[].                 */ // Q_dn
     127             :     Word16 Q_dn,
     128             :     const Word16 cn[L_SUBFR],
     129             :     /* i  : residual after long term prediction           */ // q_cn
     130             :     const Word16 q_cn,
     131             :     const Word16 H[L_SUBFR],
     132             :     /* i  : impulse response of weighted synthesis filter */ // e(norm_s(H[0])+1)
     133             :     Word16 code[L_SUBFR],
     134             :     /* o  : algebraic (fixed) codebook excitation         */ // Q0
     135             :     Word16 y[],
     136             :     /* o  : filtered fixed codebook excitation            */ // e(norm_s(H[0])+1)
     137             :     const Word16 L_subfr                                     /* i  : subframe length                               */
     138             : )
     139             : {
     140             :     Word16 i, j, q, bits, bits_track, nb_pos, nb_pulse, track, nb_iter, nb_tracks;
     141             :     Word16 skip_track[MAX_NUM_INTER], skip_track_max;
     142             :     PulseConfig config;
     143             :     enum TRACKPOS codetrackpos;
     144             :     Word16 m[MAX_PULSES_STEREO], s[MAX_PULSES_STEREO], m_max[MAX_PULSES_STEREO], s_max[MAX_PULSES_STEREO];
     145             :     Word16 track_order[NB_TRACK_FCB_4T * MAX_NUM_INTER], m0_track[NB_TRACK_FCB_4T];
     146             :     Word16 ind_stream[NPMAXPT * NB_TRACK_FCB_4T], idx;
     147             :     Word16 G, G1, G2, G3, Gn, Gd;
     148             :     Word32 Gd32;
     149             :     Word16 y_tmp[L_SUBFR_MAX];
     150             :     Word32 dn[L_SUBFR_MAX];
     151             :     Word32 crit_num, crit_den, crit_num_max, crit_den_max, L_tmp1, L_tmp2;
     152             :     Word16 q_crit_num, q_crit_den, q_crit_num_max, q_crit_den_max;
     153             :     Word16 h_buf[4 * L_SUBFR_MAX], *h, *h_inv, *p_hn, alp_buf[2 * L_SUBFR_MAX], *alp, *alp_pos0, *alp_pos1, *alp_pos2, *alp_pos3;
     154             :     Word32 dndn_fx, cncn_fx, cncn_track[NB_TRACK_FCB_4T];
     155             :     Word16 dndn_e, cncn_e, cncn_track_e[NB_TRACK_FCB_4T];
     156             :     Word16 s_coef_fx;
     157             :     Word32 bn_orig_fx[L_SUBFR_MAX];
     158             :     Word32 max_val_fx, temp_fx, max_track[MAX_NUM_INTER];
     159             :     Word16 sign_fx[L_SUBFR_MAX];
     160             :     Word16 beta1_fx, beta2_fx;
     161             :     Word16 exp, exp1, shift, q_H;
     162             :     Word64 s64;
     163       28647 :     Word16 flag = 0;
     164       28647 :     move16();
     165             :     Word32 temp1, temp2, temp3, temp4, temp5, temp6;
     166             :     Word16 q_temp1, q_temp2;
     167             :     Word16 scale_temp1, scale_temp2;
     168             :     /*-----------------------------------------------------------------*
     169             :      * Initialization
     170             :      *-----------------------------------------------------------------*/
     171             : 
     172       28647 :     nb_iter = NB_TRACK_FCB_4T;
     173       28647 :     move16();
     174       28647 :     nb_tracks = NB_TRACK_FCB_4T;
     175       28647 :     move16();
     176       28647 :     nb_pulse = 0; /* to avoid compilation warnings */
     177       28647 :     move16();
     178             : 
     179       28647 :     IF( EQ_16( L_subfr, L_SUBFR ) )
     180             :     {
     181       24429 :         config = PulseConfTable[cdk_index];
     182       24429 :         bits = config.bits;
     183       24429 :         move16();
     184       24429 :         nb_pulse = config.nb_pulse;
     185       24429 :         move16();
     186       24429 :         codetrackpos = config.codetrackpos;
     187       24429 :         move16();
     188             : 
     189       24429 :         IF( EQ_16( cdk_index, 2 ) )
     190             :         {
     191             :             /* 12 bits, 2 pulses, 2 tracks:  11 (used all tracks) */
     192        8705 :             nb_tracks = NB_TRACK_FCB_2T;
     193        8705 :             move16();
     194        8705 :             nb_iter = NB_TRACK_FCB_2T;
     195        8705 :             move16();
     196             :         }
     197       15724 :         ELSE IF( EQ_16( nb_pulse, 2 ) )
     198             :         {
     199             :             /* 10 bits,  2 pulses, 4 tracks:  1010 (used only even tracks) */
     200        1467 :             nb_iter = NB_TRACK_FCB_4T - 2;
     201        1467 :             move16();
     202             :         }
     203       14257 :         ELSE IF( EQ_16( nb_pulse, 3 ) )
     204             :         {
     205       12910 :             IF( EQ_16( codetrackpos, TRACKPOS_FIXED_FIRST ) )
     206             :             {
     207             :                 /* 15 bits,  3 pulses, 4 tracks:  1110 (fixed track to first) */
     208       12213 :                 nb_iter = NB_TRACK_FCB_4T - 1;
     209       12213 :                 move16();
     210             :             }
     211         697 :             ELSE IF( EQ_16( codetrackpos, TRACKPOS_FREE_THREE ) )
     212             :             {
     213             :                 /* 17 bits,  3 pulses, 4 tracks  (used all tracks): 1110, 1101, 1011, 0111 */
     214         697 :                 nb_iter = NB_TRACK_FCB_4T;
     215         697 :                 move16();
     216             :             }
     217             :         }
     218             :     }
     219             :     ELSE /* L_subfr == 2*L_SUBFFR */
     220             :     {
     221        4218 :         bits = cdk_index;
     222        4218 :         move16();
     223        4218 :         codetrackpos = -1; /* to avoid compilation warnings */
     224        4218 :         move16();
     225             : 
     226             : 
     227        4218 :         IF( EQ_16( cdk_index, 14 ) )
     228             :         {
     229             :             /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */
     230        4208 :             nb_pulse = 2;
     231        4208 :             move16();
     232        4208 :             nb_iter = NB_TRACK_FCB_2T;
     233        4208 :             move16();
     234        4208 :             codetrackpos = TRACKPOS_FIXED_TWO;
     235        4208 :             move16();
     236        4208 :             nb_tracks = NB_TRACK_FCB_2T;
     237        4208 :             move16();
     238             :         }
     239          10 :         ELSE IF( EQ_16( cdk_index, 12 ) )
     240             :         {
     241             :             /* 12 bits, 2 pulses, 4 tracks: 1010 (used only even tracks) */
     242           0 :             nb_pulse = 2;
     243           0 :             move16();
     244           0 :             nb_iter = NB_TRACK_FCB_4T - 2;
     245           0 :             move16();
     246           0 :             codetrackpos = TRACKPOS_FIXED_EVEN;
     247           0 :             move16();
     248             :         }
     249          10 :         ELSE IF( EQ_16( cdk_index, 18 ) )
     250             :         {
     251             :             /* 18 bits, 3 pulses, 4 tracks: 1110 (used first three tracks) */
     252           5 :             nb_pulse = 3;
     253           5 :             move16();
     254           5 :             nb_iter = NB_TRACK_FCB_4T - 1;
     255           5 :             move16();
     256           5 :             codetrackpos = TRACKPOS_FIXED_FIRST;
     257           5 :             move16();
     258             :         }
     259           5 :         ELSE IF( EQ_16( cdk_index, 20 ) )
     260             :         {
     261             :             /* 20 bits, 3 pulses, 4 tracks (used all tracks): 1110, 1101, 1011, 0111 */
     262           5 :             nb_pulse = 3;
     263           5 :             move16();
     264           5 :             nb_iter = NB_TRACK_FCB_4T;
     265           5 :             move16();
     266           5 :             codetrackpos = TRACKPOS_FREE_THREE;
     267           5 :             move16();
     268             :         }
     269           0 :         ELSE IF( EQ_16( cdk_index, 24 ) )
     270             :         {
     271             :             /* 24 bits, 4 pulses, 4 tracks: 1111 */
     272           0 :             nb_pulse = 4;
     273           0 :             move16();
     274           0 :             nb_iter = NB_TRACK_FCB_4T;
     275           0 :             move16();
     276           0 :             codetrackpos = TRACKPOS_FIXED_FIRST;
     277           0 :             move16();
     278             :         }
     279             :     }
     280             : 
     281       28647 :     beta1_fx = BETA_BN1_FX; // Q0
     282       28647 :     move16();
     283       28647 :     beta2_fx = BETA_BN2_FX; // Q2
     284       28647 :     move16();
     285             : 
     286       28647 :     IF( LE_16( cdk_index, 2 ) )
     287             :     {
     288       10172 :         beta1_fx = BETA_BN1_FX * 2; // Q0
     289       10172 :         move16();
     290       10172 :         beta2_fx = BETA_BN2_FX * 2; // Q2
     291       10172 :         move16();
     292             :     }
     293             : 
     294             :     /*-----------------------------------------------------------------*
     295             :      * Find signal bn[] and sign pre-selection vector sign[].
     296             :      *-----------------------------------------------------------------*/
     297             : 
     298       28647 :     exp = sub( Q31, shl( Q_dn, 1 ) );
     299             : 
     300       28647 :     s64 = 0;
     301       28647 :     move64();
     302     2132007 :     FOR( i = 0; i < L_subfr; i++ )
     303             :     {
     304     2103360 :         s64 = W_mac_16_16( s64, dn_orig[i], dn_orig[i] ); // 2 * Q_dn + 1
     305             :     }
     306       28647 :     dndn_fx = 21474836 /*0.01f in Q31 */;
     307       28647 :     move32();
     308       28647 :     dndn_e = 0;
     309       28647 :     move16();
     310       28647 :     IF( s64 )
     311             :     {
     312       28541 :         Word16 new_exp1 = W_norm( s64 );
     313       28541 :         dndn_fx = W_extract_h( W_shl( s64, new_exp1 ) ); // 2 * Q_dyn + exp1 - 31
     314       28541 :         dndn_e = sub( 31, sub( add( add( shl( Q_dn, 1 ), 1 ), new_exp1 ), 32 ) );
     315             :     }
     316             : 
     317             : 
     318       28647 :     cncn_fx = 214748365 /* 0.1f in Q31 */;
     319       28647 :     move32();
     320       28647 :     cncn_e = 0;
     321       28647 :     move16();
     322             : 
     323      117409 :     FOR( q = 0; q < nb_tracks; q++ )
     324             :     {
     325       88762 :         s64 = 0;
     326       88762 :         move64();
     327     2192122 :         FOR( i = 0; i < L_subfr; i += nb_tracks )
     328             :         {
     329     2103360 :             s64 = W_mac_16_16( s64, cn[i + q], cn[i + q] ); // 2 * q_cn + 1
     330             :         }
     331             : 
     332       88762 :         cncn_track[q] = 214748365 /* 0.1f in Q31 */;
     333       88762 :         move32();
     334       88762 :         cncn_track_e[q] = 0;
     335       88762 :         move16();
     336       88762 :         IF( s64 )
     337             :         {
     338       88372 :             Word16 new_exp1 = W_norm( s64 );
     339       88372 :             cncn_track[q] = W_extract_h( W_shl( s64, new_exp1 ) ); // 2 * Q_dyn + exp1 - 31
     340       88372 :             cncn_track_e[q] = sub( 31, sub( add( add( shl( q_cn, 1 ), 1 ), new_exp1 ), 32 ) );
     341             :         }
     342       88762 :         cncn_fx = BASOP_Util_Add_Mant32Exp( cncn_fx, cncn_e, cncn_track[q], cncn_track_e[q], &cncn_e ); // Q(cncn_e)
     343             :     }
     344             : 
     345       28647 :     Word16 tmp = 0;
     346       28647 :     move16();
     347       28647 :     s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_fx, &tmp );
     348       28647 :     tmp = add( tmp, sub( dndn_e, cncn_e ) );
     349       28647 :     s_coef_fx = Sqrt16( s_coef_fx, &tmp ); // Q(15 - tmp)
     350             : 
     351       28647 :     q_temp1 = add( add( sub( Q15, tmp ), q_cn ), Q1 );
     352       28647 :     scale_temp1 = sub( q_temp1, Q_dn );
     353     2132007 :     FOR( i = 0; i < L_subfr; i++ )
     354             :     {
     355     2103360 :         temp1 = L_mult( s_coef_fx, cn[i] );     // Q(15 - tmp)+q_cn+1
     356     2103360 :         temp2 = L_mult( beta1_fx, dn_orig[i] ); // 1+Q_dn+1
     357             :         /* bn_orig_fx[i] is being used in Q_dn */
     358     2103360 :         temp2 = L_shr( temp2, 1 );
     359     2103360 :         temp1 = L_shr( temp1, scale_temp1 );
     360     2103360 :         bn_orig_fx[i] = L_add( temp1, temp2 ); // Q_dn
     361     2103360 :         move32();
     362             : 
     363     2103360 :         IF( bn_orig_fx[i] >= 0 )
     364             :         {
     365     1036604 :             sign_fx[i] = 1;
     366             :         }
     367             :         ELSE
     368             :         {
     369     1066756 :             sign_fx[i] = -1;
     370             :         }
     371     2103360 :         move16();
     372             :     }
     373             : 
     374             :     /*-----------------------------------------------------------------*
     375             :      * Compute buffer h_buf[].
     376             :      *-----------------------------------------------------------------*/
     377             : 
     378       28647 :     h = h_buf;
     379       28647 :     h_inv = h_buf + shl( L_subfr, 1 );
     380             : 
     381     2132007 :     FOR( i = 0; i < L_subfr; i++ )
     382             :     {
     383     2103360 :         *h++ = 0;
     384     2103360 :         move16();
     385     2103360 :         *h_inv++ = 0;
     386     2103360 :         move16();
     387             :     }
     388             : 
     389     2132007 :     FOR( i = 0; i < L_subfr; i++ )
     390             :     {
     391     2103360 :         h[i] = H[i];
     392     2103360 :         move16();
     393     2103360 :         h_inv[i] = negate( H[i] );
     394     2103360 :         move16();
     395             :     }
     396             : 
     397             :     /*-----------------------------------------------------------------*
     398             :      * Approximate FI[i][j] by alp[abs(i-j)] and compute buffer alp_buf[].
     399             :      *-----------------------------------------------------------------*/
     400       28647 :     q_H = sub( 14, norm_s( H[0] ) );
     401       28647 :     shift = sub( shl( q_H, 1 ), 6 );
     402             : 
     403       28647 :     alp = alp_buf + L_subfr;
     404             : 
     405     2132007 :     FOR( i = 0; i < L_subfr; i++ )
     406             :     {
     407     2103360 :         s64 = 0;
     408     2103360 :         move64();
     409             : 
     410    87739488 :         FOR( j = i; j < L_subfr; j++ )
     411             :         {
     412    85636128 :             s64 = W_mac0_16_16( s64, H[j], H[j - i] ); /* Q = shift + 6*/
     413             :         }
     414     2103360 :         *alp = extract_l( W_extract_l( W_shr( s64, shift ) ) ); /*Q6*/
     415     2103360 :         move16();
     416     2103360 :         alp_buf[L_subfr - i] = *alp++; /*Q6*/
     417     2103360 :         move16();
     418             :     }
     419             : 
     420       28647 :     alp = alp_buf + L_subfr;
     421             : 
     422      117409 :     FOR( q = 0; q < nb_tracks; q++ )
     423             :     {
     424       88762 :         max_track[q] = 0;
     425       88762 :         move32();
     426             : 
     427     2192122 :         FOR( i = q; i < L_subfr; i += nb_tracks )
     428             :         {
     429     2103360 :             temp_fx = imult3216( bn_orig_fx[i], sign_fx[i] ); // Q_dn
     430             : 
     431     2103360 :             IF( GE_32( temp_fx, max_track[q] ) )
     432             :             {
     433      304235 :                 max_track[q] = temp_fx; // Q_dn
     434      304235 :                 move32();
     435      304235 :                 m0_track[q] = i;
     436      304235 :                 move16();
     437             :             }
     438             :         }
     439             :     }
     440             : 
     441             :     /*-----------------------------------------------------------------*
     442             :      * Track re-order
     443             :      *-----------------------------------------------------------------*/
     444             : 
     445       28647 :     IF( EQ_16( nb_tracks, NB_TRACK_FCB_2T ) )
     446             :     {
     447       12913 :         track_order[0] = 0;
     448       12913 :         move16();
     449       12913 :         track_order[1] = 1;
     450       12913 :         move16();
     451       12913 :         track_order[2] = 1;
     452       12913 :         move16();
     453       12913 :         track_order[3] = 0;
     454       12913 :         move16();
     455             :     }
     456             :     ELSE
     457             :     {
     458       15734 :         test();
     459       15734 :         test();
     460             :         /* skip certain tracks if number of pulses is lower than number of tracks */
     461       15734 :         IF( EQ_16( nb_pulse, 2 ) && EQ_16( nb_tracks, NB_TRACK_FCB_4T ) )
     462             :         {
     463        1467 :             max_track[NB_TRACK_FCB_4T - 3] = L_shl( -1, Q_dn ); // Q_dn
     464        1467 :             move32();
     465        1467 :             max_track[NB_TRACK_FCB_4T - 1] = L_shl( -1, Q_dn ); // Q_dn
     466        1467 :             move32();
     467             :         }
     468       14267 :         ELSE IF( EQ_16( nb_pulse, 3 ) && EQ_16( codetrackpos, TRACKPOS_FIXED_FIRST ) )
     469             :         {
     470       12218 :             max_track[NB_TRACK_FCB_4T - 1] = L_shl( -1, Q_dn ); // Q_dn
     471       12218 :             move32();
     472             :         }
     473             : 
     474       78670 :         FOR( q = 0; q < nb_tracks; q++ )
     475             :         {
     476       62936 :             i = maximum_32_fx( max_track, nb_tracks, &L_tmp1 );
     477       62936 :             track_order[q] = i;
     478       62936 :             move16();
     479       62936 :             max_track[i] = L_shl( -1, Q_dn ); // Q_dn
     480       62936 :             move32();
     481             :         }
     482             : 
     483       15734 :         track_order[4] = track_order[1]; // Q0
     484       15734 :         move16();
     485       15734 :         track_order[5] = track_order[0]; // Q0
     486       15734 :         move16();
     487       15734 :         track_order[6] = track_order[2]; // Q0
     488       15734 :         move16();
     489       15734 :         track_order[7] = track_order[3]; // Q0
     490       15734 :         move16();
     491             : 
     492       15734 :         track_order[8] = track_order[2]; // Q0
     493       15734 :         move16();
     494       15734 :         track_order[9] = track_order[0]; // Q0
     495       15734 :         move16();
     496       15734 :         track_order[10] = track_order[1]; // Q0
     497       15734 :         move16();
     498       15734 :         track_order[11] = track_order[3]; // Q0
     499       15734 :         move16();
     500             : 
     501       15734 :         track_order[12] = track_order[3]; // Q0
     502       15734 :         move16();
     503       15734 :         track_order[13] = track_order[0]; // Q0
     504       15734 :         move16();
     505       15734 :         track_order[14] = track_order[1]; // Q0
     506       15734 :         move16();
     507       15734 :         track_order[15] = track_order[2]; // Q0
     508       15734 :         move16();
     509             : 
     510       15734 :         IF( EQ_16( cdk_index, 3 ) )
     511             :         {
     512       12213 :             track_order[12] = track_order[2]; // Q0
     513       12213 :             move16();
     514       12213 :             track_order[13] = track_order[1]; // Q0
     515       12213 :             move16();
     516       12213 :             track_order[14] = track_order[0]; // Q0
     517       12213 :             move16();
     518             : 
     519       12213 :             track_order[16] = track_order[1]; // Q0
     520       12213 :             move16();
     521       12213 :             track_order[17] = track_order[2]; // Q0
     522       12213 :             move16();
     523       12213 :             track_order[18] = track_order[0]; // Q0
     524       12213 :             move16();
     525       12213 :             nb_iter = 5;
     526       12213 :             move16();
     527             :         }
     528        3521 :         ELSE IF( EQ_16( cdk_index, 4 ) )
     529             :         {
     530         697 :             track_order[16] = track_order[2]; // Q0
     531         697 :             move16();
     532         697 :             track_order[17] = track_order[3]; // Q0
     533         697 :             move16();
     534         697 :             track_order[18] = track_order[1]; // Q0
     535         697 :             move16();
     536         697 :             track_order[19] = track_order[0]; // Q0
     537         697 :             move16();
     538         697 :             nb_iter = 5;
     539         697 :             move16();
     540             :         }
     541             :     }
     542             : 
     543             :     /*-----------------------------------------------------------------*
     544             :      * Main searching loop
     545             :      *-----------------------------------------------------------------*/
     546             : 
     547       28647 :     crit_num_max = MIN_32; // Q31
     548       28647 :     move32();
     549       28647 :     q_crit_num_max = Q31;
     550       28647 :     move16();
     551       28647 :     crit_den_max = MAX_32; // Q31
     552       28647 :     move32();
     553       28647 :     q_crit_den_max = Q31;
     554       28647 :     move16();
     555       28647 :     skip_track_max = -1;
     556       28647 :     move16();
     557             : 
     558      127380 :     FOR( q = 0; q < nb_iter; q++ )
     559             :     {
     560             :         /*-----------------------------------------------------------------*
     561             :          * First pulse search
     562             :          *-----------------------------------------------------------------*/
     563             : 
     564       98733 :         track = track_order[q * nb_tracks]; // Q0
     565       98733 :         move16();
     566       98733 :         m[0] = m0_track[track]; // Q0
     567       98733 :         move16();
     568       98733 :         s[0] = sign_fx[m[0]]; // Q0
     569       98733 :         move16();
     570             : 
     571             :         /*-----------------------------------------------------------------*
     572             :          * Second pulse search
     573             :          *-----------------------------------------------------------------*/
     574             : 
     575       98733 :         IF( EQ_16( nb_tracks, NB_TRACK_FCB_2T ) )
     576             :         {
     577       25826 :             Gn = i_mult( s[0], shr( dn_orig[m[0]], 1 ) ); // Q_dn - 1
     578       25826 :             Gd = alp[0];                                  // Q6
     579       25826 :             move16();
     580       25826 :             G = BASOP_Util_Divide1616_Scale( Gn, Gd, &exp1 ); // Q_dn -1 - 6 + 15 - exp1 = Q_dn - 6 + 14 - exp1
     581       25826 :             G = i_mult( G, s[0] );                            // Q_dn - 6 + 14 - exp1
     582       25826 :             shift = sub( 14, exp1 );
     583             : 
     584       25826 :             track = track_order[q * nb_tracks + 1]; // Q0
     585       25826 :             move16();
     586       25826 :             alp_pos0 = alp - m[0] + track;
     587             : 
     588     1121570 :             FOR( i = track; i < L_subfr; i += NB_TRACK_FCB_2T )
     589             :             {
     590     1095744 :                 dn[i] = L_sub( L_deposit_l( dn_orig[i] ), L_shr( L_mult0( G, *alp_pos0 ), shift ) ); // Q_dn
     591     1095744 :                 move32();
     592     1095744 :                 alp_pos0 = alp_pos0 + NB_TRACK_FCB_2T;
     593             :             }
     594             : 
     595       25826 :             m[1] = find_best_pulse_fx( L_subfr, NB_TRACK_FCB_2T, track, dn, sign_fx, &s[1] ); // Q0
     596       25826 :             move16();
     597             :         }
     598             :         ELSE
     599             :         {
     600       72907 :             Gn = i_mult( s[0], dn_orig[m[0]] ); // Q_dn
     601       72907 :             Gd = alp[0];                        // Q6
     602       72907 :             move16();
     603       72907 :             G = Gn; // Q_dn
     604       72907 :             move16();
     605       72907 :             G = i_mult( G, s[0] ); // Q_dn
     606             : 
     607       72907 :             track = track_order[q * nb_tracks + 1]; // Q0
     608       72907 :             move16();
     609       72907 :             alp_pos0 = alp - m[0] + track; // exp(shift)
     610             : 
     611       72907 :             dndn_fx = 214748365 /* 0.1f in Q31 */;
     612       72907 :             move32();
     613       72907 :             dndn_e = 0;
     614       72907 :             move16();
     615             : 
     616       72907 :             s64 = 0;
     617       72907 :             move64();
     618     1239979 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     619             :             {
     620     1167072 :                 temp1 = L_mult0( Gd, dn_orig[i] );
     621     1167072 :                 temp2 = L_mult0( G, *alp_pos0 );
     622     1167072 :                 temp3 = L_sub( temp1, temp2 );
     623     1167072 :                 dn[i] = L_shr( temp3, 6 );
     624     1167072 :                 move32();
     625     1167072 :                 alp_pos0 += nb_tracks;
     626     1167072 :                 s64 = W_mac_32_32( s64, dn[i], dn[i] ); // 2 * Q_dn + 1
     627             :             }
     628       72907 :             exp1 = W_norm( s64 );
     629       72907 :             dndn_fx = W_extract_h( W_shl( s64, exp1 ) ); // 2 * Q_dyn + exp1 - 31
     630       72907 :             dndn_e = sub( 31, sub( add( add( shl( Q_dn, 1 ), 1 ), exp1 ), 32 ) );
     631             : 
     632       72907 :             IF( dndn_fx == 0 )
     633             :             {
     634         445 :                 dndn_fx = 214748365 /* 0.1f in Q31 */;
     635         445 :                 move32();
     636         445 :                 dndn_e = 0;
     637         445 :                 move16();
     638             :             }
     639       72907 :             exp1 = 0;
     640       72907 :             move16();
     641       72907 :             s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_track[track], &exp1 );
     642       72907 :             exp1 = add( exp1, sub( dndn_e, cncn_track_e[track] ) );
     643       72907 :             s_coef_fx = Sqrt16( s_coef_fx, &exp1 );
     644       72907 :             max_val_fx = EPSILLON_FX;
     645       72907 :             move16();
     646       72907 :             m[1] = track; // Q0
     647       72907 :             move16();
     648       72907 :             q_temp1 = add( add( sub( Q15, exp1 ), q_cn ), 1 );
     649       72907 :             q_temp2 = add( Q_dn, Q2 );
     650       72907 :             scale_temp1 = sub( q_temp1, Q_dn );
     651       72907 :             scale_temp2 = sub( q_temp2, Q_dn );
     652     1239979 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     653             :             {
     654     1167072 :                 temp1 = L_mult( s_coef_fx, cn[i] );   // Q(15 - tmp)+q_cn+1
     655     1167072 :                 temp2 = imult3216( dn[i], beta2_fx ); // Q_dn + 2
     656             : 
     657             :                 /* bn_orig_fx[i] is being used in Q_dn */
     658     1167072 :                 temp2 = L_shr( temp2, scale_temp2 );
     659     1167072 :                 temp1 = L_shr( temp1, scale_temp1 );
     660     1167072 :                 dn[i] = L_add( temp1, temp2 ); // Q_dn
     661     1167072 :                 move32();
     662     1167072 :                 temp_fx = imult3216( dn[i], sign_fx[i] ); // Q_dn
     663             : 
     664     1167072 :                 IF( GE_32( temp_fx, max_val_fx ) )
     665             :                 {
     666      217232 :                     max_val_fx = temp_fx; // Q_dn
     667      217232 :                     move16();
     668      217232 :                     m[1] = i;
     669      217232 :                     move16();
     670             :                 }
     671             :             }
     672             : 
     673       72907 :             s[1] = sign_fx[m[1]];
     674       72907 :             move16();
     675             :         }
     676             : 
     677             :         /*-----------------------------------------------------------------*
     678             :          * Third pulse search
     679             :          *-----------------------------------------------------------------*/
     680             : 
     681       98733 :         IF( GE_16( nb_pulse, 3 ) )
     682             :         {
     683       69973 :             Gn = add( Gn, i_mult( s[1], dn_orig[m[1]] ) ); // Q_dn
     684       69973 :             Gd32 = Gd;
     685       69973 :             move16();
     686       69973 :             Gd32 = L_add( Gd32, L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[1] ), alp[m[0] - m[1]] ) ) ); // Q6
     687       69973 :             G = Gn;                                                                                             // Q_dn
     688       69973 :             move16();
     689       69973 :             G1 = i_mult( G, s[1] ); // Q_dn
     690       69973 :             G = i_mult( G, s[0] );  // Q_dn
     691             : 
     692       69973 :             track = track_order[q * nb_tracks + 2]; // Q0
     693       69973 :             move16();
     694       69973 :             alp_pos0 = alp - m[0] + track;
     695       69973 :             alp_pos1 = alp - m[1] + track;
     696             : 
     697     1190101 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     698             :             {
     699     1120128 :                 temp1 = imult3216( Gd32, dn_orig[i] );
     700     1120128 :                 temp2 = L_mult0( G, *alp_pos0 );
     701     1120128 :                 temp3 = L_mult0( G1, *alp_pos1 );
     702     1120128 :                 temp4 = L_sub( temp1, temp2 );
     703     1120128 :                 temp4 = L_sub( temp4, temp3 );
     704     1120128 :                 dn[i] = L_shr( temp4, 6 );
     705     1120128 :                 move32();
     706     1120128 :                 alp_pos0 += nb_tracks;
     707     1120128 :                 alp_pos1 += nb_tracks;
     708             :             }
     709             : 
     710       69973 :             m[2] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[2] ); // Q0
     711       69973 :             move16();
     712             :         }
     713             : 
     714             :         /*-----------------------------------------------------------------*
     715             :          * Fourth pulse search
     716             :          *-----------------------------------------------------------------*/
     717             : 
     718       98733 :         IF( GE_16( nb_pulse, 4 ) )
     719             :         {
     720        5388 :             Gn = add( Gn, i_mult( s[2], dn_orig[m[2]] ) ); // Q_dn
     721        5388 :             Gd32 = Gd;
     722        5388 :             move16();
     723        5388 :             temp1 = alp[0];
     724        5388 :             move32();
     725        5388 :             temp2 = L_mult0( i_mult( shl( s[0], 1 ), s[2] ), alp[m[0] - m[2]] );
     726        5388 :             temp3 = L_mult0( i_mult( shl( s[1], 1 ), s[2] ), alp[m[1] - m[2]] );
     727        5388 :             Gd32 = L_add( Gd32, L_add( L_add( temp1, temp2 ), temp3 ) ); // Q6
     728        5388 :             G = Gn;                                                      // Q_dn
     729        5388 :             move16();
     730        5388 :             G1 = i_mult( G, s[1] ); // Q_dn
     731        5388 :             G2 = i_mult( G, s[2] ); // Q_dn
     732        5388 :             G = i_mult( G, s[0] );  // Q_dn
     733             : 
     734        5388 :             track = track_order[q * nb_tracks + 3];
     735        5388 :             move16();
     736        5388 :             alp_pos0 = alp - m[0] + track;
     737        5388 :             alp_pos1 = alp - m[1] + track;
     738        5388 :             alp_pos2 = alp - m[2] + track;
     739             : 
     740       91596 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     741             :             {
     742             : 
     743       86208 :                 temp1 = imult3216( Gd32, dn_orig[i] );
     744       86208 :                 temp2 = L_mult0( G, *alp_pos0 );
     745       86208 :                 temp3 = L_mult0( G1, *alp_pos1 );
     746       86208 :                 temp4 = L_mult0( G2, *alp_pos2 );
     747       86208 :                 temp5 = L_sub( temp1, temp2 );
     748       86208 :                 temp5 = L_sub( temp5, temp3 );
     749       86208 :                 temp5 = L_sub( temp5, temp4 );
     750       86208 :                 dn[i] = L_shr( temp5, 6 );
     751       86208 :                 move32();
     752       86208 :                 alp_pos0 += nb_tracks;
     753       86208 :                 alp_pos1 += nb_tracks;
     754       86208 :                 alp_pos2 += nb_tracks;
     755             :             }
     756             : 
     757        5388 :             m[3] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[3] );
     758        5388 :             move16();
     759             :         }
     760             :         ELSE
     761             :         {
     762       93345 :             skip_track[q] = track_order[q * nb_tracks + 3];
     763       93345 :             move16();
     764             :         }
     765             : 
     766             :         /*-----------------------------------------------------------------*
     767             :          * Fifth pulse search
     768             :          *-----------------------------------------------------------------*/
     769             : 
     770       98733 :         IF( GE_16( nb_pulse, 5 ) )
     771             :         {
     772        3816 :             Gn = add( Gn, i_mult( s[3], dn_orig[m[3]] ) ); // Q_dn
     773        3816 :             Gd32 = Gd;
     774        3816 :             move16();
     775        3816 :             temp1 = alp[0];
     776        3816 :             move32();
     777        3816 :             temp2 = L_mult0( i_mult( shl( s[0], 1 ), s[3] ), alp[m[0] - m[3]] );
     778        3816 :             temp3 = L_mult0( i_mult( shl( s[1], 1 ), s[3] ), alp[m[1] - m[3]] );
     779        3816 :             temp4 = L_mult0( i_mult( shl( s[2], 1 ), s[3] ), alp[m[2] - m[3]] );
     780             : 
     781        3816 :             Gd32 = L_add( Gd32, L_add( L_add( L_add( temp1, temp2 ), temp3 ), temp4 ) ); // Q6
     782        3816 :             G = Gn;
     783        3816 :             move16();               // Q_dn
     784        3816 :             G1 = i_mult( G, s[1] ); // Q_dn
     785        3816 :             G2 = i_mult( G, s[2] ); // Q_dn
     786        3816 :             G3 = i_mult( G, s[3] ); // Q_dn
     787        3816 :             G = i_mult( G, s[0] );  // Q_dn
     788             : 
     789        3816 :             IF( EQ_16( cdk_index, 6 ) )
     790             :             {
     791        2204 :                 track = 0; /* always track 0 */
     792        2204 :                 move16();
     793             : 
     794        2204 :                 alp_pos0 = alp - m[0];
     795        2204 :                 alp_pos1 = alp - m[1];
     796        2204 :                 alp_pos2 = alp - m[2];
     797        2204 :                 alp_pos3 = alp - m[3];
     798             : 
     799       37468 :                 FOR( i = track; i < L_subfr; i += nb_tracks )
     800             :                 {
     801       35264 :                     temp1 = imult3216( Gd32, dn_orig[i] );
     802       35264 :                     temp2 = L_mult0( G, *alp_pos0 );
     803       35264 :                     temp3 = L_mult0( G1, *alp_pos1 );
     804       35264 :                     temp4 = L_mult0( G2, *alp_pos2 );
     805       35264 :                     temp5 = L_mult0( G3, *alp_pos3 );
     806       35264 :                     temp6 = L_sub( temp1, temp2 );
     807       35264 :                     temp6 = L_sub( temp6, temp3 );
     808       35264 :                     temp6 = L_sub( temp6, temp4 );
     809       35264 :                     temp6 = L_sub( temp6, temp5 );
     810       35264 :                     dn[i] = L_shr( temp6, 6 );
     811       35264 :                     move32();
     812       35264 :                     alp_pos0 += nb_tracks;
     813       35264 :                     alp_pos1 += nb_tracks;
     814       35264 :                     alp_pos2 += nb_tracks;
     815       35264 :                     alp_pos3 += nb_tracks;
     816             :                 }
     817             : 
     818        2204 :                 m[4] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[4] );
     819        2204 :                 move16();
     820             :             }
     821             :             ELSE /* cdk_index == 7 (26 bits codebook) */
     822             :             {
     823        1612 :                 alp_pos0 = alp - m[0];
     824        1612 :                 alp_pos1 = alp - m[1];
     825        1612 :                 alp_pos2 = alp - m[2];
     826        1612 :                 alp_pos3 = alp - m[3];
     827             : 
     828      104780 :                 FOR( i = 0; i < L_subfr; i++ )
     829             :                 {
     830      103168 :                     temp1 = imult3216( Gd32, dn_orig[i] );
     831      103168 :                     temp2 = L_mult0( G, *alp_pos0 );
     832      103168 :                     temp3 = L_mult0( G1, *alp_pos1 );
     833      103168 :                     temp4 = L_mult0( G2, *alp_pos2 );
     834      103168 :                     temp5 = L_mult0( G3, *alp_pos3 );
     835      103168 :                     temp6 = L_sub( temp1, temp2 );
     836      103168 :                     temp6 = L_sub( temp6, temp3 );
     837      103168 :                     temp6 = L_sub( temp6, temp4 );
     838      103168 :                     temp6 = L_sub( temp6, temp5 );
     839      103168 :                     dn[i] = L_shr( temp6, 6 );
     840      103168 :                     move16();
     841      103168 :                     alp_pos0++;
     842      103168 :                     alp_pos1++;
     843      103168 :                     alp_pos2++;
     844      103168 :                     alp_pos3++;
     845             :                 }
     846             : 
     847             :                 Word16 k;
     848             :                 Word64 W_tmp, W_tmp1;
     849             :                 Word64 emax;
     850             : 
     851        1612 :                 emax = W_mult0_32_32( dn[0], dn[0] );
     852        1612 :                 i = 0;
     853        1612 :                 move16();
     854             : 
     855      103168 :                 FOR( k = 1; k < L_subfr; k++ )
     856             :                 {
     857      101556 :                     W_tmp = W_mult0_32_32( dn[k], dn[k] );
     858      101556 :                     W_tmp1 = W_sub( W_tmp, emax );
     859      101556 :                     if ( W_tmp1 > 0 )
     860             :                     {
     861        9694 :                         i = k;
     862        9694 :                         move16();
     863             :                     }
     864      101556 :                     if ( LE_64( emax, W_tmp ) )
     865             :                     {
     866        9707 :                         emax = W_tmp;
     867        9707 :                         move64();
     868             :                     }
     869             :                 }
     870             : 
     871        1612 :                 track = i % nb_tracks;
     872        1612 :                 move16();
     873             : 
     874        1612 :                 m[4] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[4] );
     875        1612 :                 move16();
     876             :             }
     877        3816 :             skip_track[q] = track;
     878        3816 :             move16();
     879             :         }
     880             : 
     881             :         /*-----------------------------------------------------------------*
     882             :          * - Build the filtered codeword and criterion computing.
     883             :          * - Memorize the best code positions & signs, and the best filtered codevector.
     884             :          *-----------------------------------------------------------------*/
     885             : 
     886       98733 :         crit_num = 0;
     887       98733 :         move32();
     888       98733 :         set16_fx( y_tmp, 0, L_subfr );
     889             : 
     890      375376 :         FOR( j = 0; j < nb_pulse; j++ )
     891             :         {
     892      276643 :             IF( s[j] > 0 )
     893             :             {
     894      137186 :                 p_hn = h - m[j];
     895             :             }
     896             :             ELSE
     897             :             {
     898      139457 :                 p_hn = h_inv - m[j];
     899             :             }
     900             : 
     901    19065763 :             FOR( i = 0; i < L_subfr; i++ )
     902             :             {
     903    18789120 :                 y_tmp[i] = add_sat( y_tmp[i], *p_hn++ ); // q_H
     904    18789120 :                 move16();
     905             :             }
     906             : 
     907      276643 :             crit_num = L_mac0( crit_num, s[j], dn_orig[m[j]] ); // Q_dn
     908             :         }
     909             : 
     910       98733 :         s64 = W_mult0_32_32( crit_num, crit_num ); // 2*Q_dn
     911       98733 :         exp = W_norm( s64 );
     912       98733 :         crit_num = W_extract_h( W_shl( s64, exp ) ); // 2*Q_dn + exp - 32
     913       98733 :         q_crit_num = add( shl( Q_dn, 1 ), sub( exp, 32 ) );
     914             : 
     915             :         // crit_den = sum2_fx( y_tmp, L_subfr );                          // 2*q_H
     916       98733 :         s64 = 0;
     917       98733 :         move64();
     918     6958509 :         FOR( i = 0; i < L_subfr; i++ )
     919             :         {
     920     6859776 :             s64 = W_mac0_16_16( s64, y_tmp[i], y_tmp[i] );
     921             :         }
     922       98733 :         exp1 = W_norm( s64 );
     923       98733 :         crit_den = W_extract_h( W_shl( s64, exp1 ) ); // 2*q_H + exp1 - 32
     924       98733 :         q_crit_den = add( shl( q_H, 1 ), sub( exp1, 32 ) );
     925             : 
     926       98733 :         L_tmp1 = Mpy_32_32( crit_num, crit_den_max ); // q_crit_num+q_crit_den_max-31
     927       98733 :         exp = sub( add( q_crit_num, q_crit_den_max ), 31 );
     928       98733 :         L_tmp2 = Mpy_32_32( crit_den, crit_num_max ); // q_crit_den+q_crit_num_max-31
     929       98733 :         exp1 = sub( add( q_crit_den, q_crit_num_max ), 31 );
     930             : 
     931       98733 :         IF( GT_16( exp, exp1 ) )
     932             :         {
     933       12866 :             IF( GE_32( L_shr( L_tmp1, sub( exp, exp1 ) ), L_tmp2 ) )
     934             :             {
     935        1444 :                 flag = 1;
     936        1444 :                 move16();
     937             :             }
     938             :             ELSE
     939             :             {
     940       11422 :                 flag = 0;
     941       11422 :                 move16();
     942             :             }
     943             :         }
     944             :         ELSE
     945             :         {
     946       85867 :             IF( GE_32( L_tmp1, L_shr( L_tmp2, sub( exp1, exp ) ) ) )
     947             :             {
     948       57729 :                 flag = 1;
     949       57729 :                 move16();
     950             :             }
     951             :             ELSE
     952             :             {
     953       28138 :                 flag = 0;
     954       28138 :                 move16();
     955             :             }
     956             :         }
     957             : 
     958             : 
     959       98733 :         IF( flag )
     960             :         {
     961       59173 :             crit_num_max = crit_num;
     962       59173 :             move32();
     963       59173 :             q_crit_num_max = q_crit_num;
     964       59173 :             move16();
     965       59173 :             crit_den_max = crit_den;
     966       59173 :             move32();
     967       59173 :             q_crit_den_max = q_crit_den;
     968       59173 :             move16();
     969             : 
     970      219811 :             FOR( j = 0; j < nb_pulse; j++ )
     971             :             {
     972      160638 :                 m_max[j] = m[j];
     973      160638 :                 move16();
     974      160638 :                 s_max[j] = s[j];
     975      160638 :                 move16();
     976             :             }
     977             : 
     978       59173 :             Copy_Scale_sig( y_tmp, y, L_subfr, sub( 9, q_H ) ); // y in Q9
     979       59173 :             skip_track_max = skip_track[q];
     980       59173 :             move16();
     981             :         }
     982             :     }
     983             : 
     984             :     /*-----------------------------------------------------------------*
     985             :      * Reconstruct the best codevector,
     986             :      * compute index of codevector and write it into the bitstream.
     987             :      *-----------------------------------------------------------------*/
     988             : 
     989       28647 :     set16_fx( code, 0, L_subfr );
     990      102509 :     FOR( q = 0; q < nb_pulse; q++ )
     991             :     {
     992       73862 :         code[m_max[q]] = add( code[m_max[q]], shl( s_max[q], Q9 ) ); // Q9
     993       73862 :         move16();
     994             :     }
     995       28647 :     test();
     996       28647 :     IF( EQ_16( bits, 12 ) || EQ_16( bits, 14 ) )
     997             :     {
     998             :         /* 12 bits, 2 pulses, 2 tracks  11 used all tracks */
     999       12913 :         i = 6;
    1000       12913 :         move16();
    1001       12913 :         j = 0x800;
    1002       12913 :         move16();
    1003       12913 :         q = 0x20;
    1004       12913 :         move16();
    1005             : 
    1006       12913 :         IF( EQ_16( L_subfr, 2 * L_SUBFR ) )
    1007             :         {
    1008             :             /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */
    1009        4208 :             i = 7;
    1010        4208 :             move16();
    1011        4208 :             j = 0x2000;
    1012        4208 :             move16();
    1013        4208 :             q = 0x40;
    1014        4208 :             move16();
    1015             :         }
    1016             : 
    1017       12913 :         IF( EQ_16( m_max[0] % NB_TRACK_FCB_2T, 1 ) )
    1018             :         {
    1019        7214 :             idx = add( shl( shr( m_max[1], 1 ), i ), shr( m_max[0], 1 ) );
    1020             : 
    1021        7214 :             if ( s_max[1] < 0 )
    1022             :             {
    1023        3626 :                 idx = add( idx, j );
    1024             :             }
    1025             : 
    1026        7214 :             if ( s_max[0] < 0 )
    1027             :             {
    1028        3584 :                 idx = add( idx, q );
    1029             :             }
    1030             :         }
    1031             :         ELSE
    1032             :         {
    1033        5699 :             idx = add( shl( shr( m_max[0], 1 ), i ), shr( m_max[1], 1 ) );
    1034             : 
    1035        5699 :             if ( s_max[0] < 0 )
    1036             :             {
    1037        2781 :                 idx = add( idx, j );
    1038             :             }
    1039             : 
    1040        5699 :             if ( s_max[1] < 0 )
    1041             :             {
    1042        3079 :                 idx = add( idx, q );
    1043             :             }
    1044             :         }
    1045             : 
    1046       12913 :         push_indice( hBstr, IND_ALG_CDBK_2T32, idx, bits );
    1047             :     }
    1048             :     ELSE
    1049             :     {
    1050             :         /* compute index of codevector */
    1051       15734 :         set16_fx( ind_stream, -1, i_mult( NPMAXPT, nb_tracks ) );
    1052             : 
    1053       15734 :         bits_track = 4;
    1054       15734 :         move16();
    1055       15734 :         nb_pos = NB_POS_FCB_4T;
    1056       15734 :         move16();
    1057             : 
    1058       15734 :         IF( EQ_16( L_subfr, 2 * L_SUBFR ) )
    1059             :         {
    1060          10 :             bits_track = 5;
    1061          10 :             move16();
    1062          10 :             nb_pos = NB_POS_FCB_4T_128;
    1063          10 :             move16();
    1064             :         }
    1065             : 
    1066       63770 :         FOR( q = 0; q < nb_pulse; q++ )
    1067             :         {
    1068       48036 :             i = i_mult( m_max[q] % NB_TRACK_FCB_4T, NPMAXPT ); /* track number */
    1069       48036 :             if ( ind_stream[i] >= 0 )
    1070             :             {
    1071         954 :                 i = add( i, 1 );
    1072             :             }
    1073       48036 :             ind_stream[i] = shr( m_max[q], 2 ); // / NB_TRACK_FCB_4T; /* pos of pulse */
    1074       48036 :             move16();
    1075             : 
    1076       48036 :             IF( s_max[q] < 0 )
    1077             :             {
    1078       24346 :                 ind_stream[i] = add( ind_stream[i], nb_pos );
    1079       24346 :                 move16();
    1080             :             }
    1081             :         }
    1082             : 
    1083       15734 :         test();
    1084       15734 :         IF( EQ_16( codetrackpos, TRACKPOS_FREE_THREE ) || EQ_16( codetrackpos, TRACKPOS_FREE_ONE ) )
    1085             :         {
    1086        1105 :             push_indice( hBstr, IND_ALG_CDBK_4T64, skip_track_max, 2 );
    1087             :         }
    1088             : 
    1089       15734 :         IF( LT_16( nb_pulse, 5 ) )
    1090             :         {
    1091       73900 :             FOR( q = 0; q < NB_TRACK_FCB_4T; q++ )
    1092             :             {
    1093       59120 :                 j = i_mult( q, NPMAXPT );
    1094       59120 :                 IF( NE_16( ind_stream[j], -1 ) )
    1095             :                 {
    1096       43266 :                     idx = quant_1p_N1_L_subfr_fx( nb_pos, ind_stream[j], bits_track );
    1097       43266 :                     push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( bits_track, 1 ) );
    1098             :                 }
    1099             :             }
    1100             :         }
    1101             :         ELSE
    1102             :         {
    1103        4770 :             FOR( q = 0; q < NB_TRACK_FCB_4T; q++ )
    1104             :             {
    1105        3816 :                 j = i_mult( q, NPMAXPT );
    1106        3816 :                 IF( EQ_16( q, skip_track_max ) )
    1107             :                 {
    1108         954 :                     idx = quant_2p_2N1_fx( ind_stream[j], ind_stream[j + 1], bits_track );
    1109         954 :                     push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( shl( bits_track, 1 ), 1 ) );
    1110             :                 }
    1111             :                 ELSE
    1112             :                 {
    1113        2862 :                     idx = quant_1p_N1_L_subfr_fx( nb_pos, ind_stream[j], bits_track );
    1114        2862 :                     push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( bits_track, 1 ) );
    1115             :                 }
    1116             :             }
    1117             :         }
    1118             :     }
    1119             : 
    1120       28647 :     return;
    1121             : }

Generated by: LCOV version 1.14