LCOV - code coverage report
Current view: top level - lib_enc - cod4t64_fast_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 600 613 97.9 %
Date: 2025-06-27 02:59:36 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       46115 : 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       46115 :     mask = extract_l( L_sub( L_shl( 1, N ), 1 ) );
      70             : 
      71       46115 :     index = s_and( pos, mask );
      72             : 
      73       46115 :     IF( s_and( pos, nb_pos ) != 0 )
      74             :     {
      75       23321 :         index = add( index, shl( 1, N ) );
      76             :     }
      77             : 
      78       46115 :     return index;
      79             : }
      80      104921 : 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      104921 :     max_val = EPSILLON_FX;
      93      104921 :     move32();
      94      104921 :     m = track;
      95      104921 :     move16();
      96     2461721 :     FOR( i = track; i < L_subfr; i += nb_tracks )
      97             :     {
      98     2356800 :         temp = imult3216( dn[i], sign[i] );
      99             : 
     100     2356800 :         IF( GE_32( temp, max_val ) )
     101             :         {
     102      345693 :             max_val = temp;
     103      345693 :             move32();
     104      345693 :             m = i;
     105      345693 :             move16();
     106             :         }
     107             :     }
     108             : 
     109      104921 :     *s = sign[m];
     110      104921 :     move16();
     111             : 
     112      104921 :     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       28620 : 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       28620 :     Word32 Gd32 = 0;
     149       28620 :     move32();
     150             :     Word16 y_tmp[L_SUBFR_MAX];
     151             :     Word32 dn[L_SUBFR_MAX];
     152             :     Word32 crit_num, crit_den, crit_num_max, crit_den_max, L_tmp1, L_tmp2;
     153             :     Word16 q_crit_num, q_crit_den, q_crit_num_max, q_crit_den_max;
     154             :     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;
     155             :     Word32 dndn_fx, cncn_fx, cncn_track[NB_TRACK_FCB_4T];
     156             :     Word16 dndn_e, cncn_e, cncn_track_e[NB_TRACK_FCB_4T];
     157             :     Word16 s_coef_fx;
     158             :     Word32 bn_orig_fx[L_SUBFR_MAX];
     159             :     Word32 max_val_fx, temp_fx, max_track[MAX_NUM_INTER];
     160             :     Word16 sign_fx[L_SUBFR_MAX];
     161             :     Word16 beta1_fx, beta2_fx;
     162             :     Word16 exp, exp1, shift, q_H;
     163             :     Word64 s64;
     164       28620 :     Word16 flag = 0;
     165       28620 :     move16();
     166             :     Word32 temp1, temp2, temp3, temp4, temp5, temp6;
     167             :     Word16 q_temp1, q_temp2;
     168             :     Word16 scale_temp1, scale_temp2;
     169             :     /*-----------------------------------------------------------------*
     170             :      * Initialization
     171             :      *-----------------------------------------------------------------*/
     172             : 
     173       28620 :     nb_iter = NB_TRACK_FCB_4T;
     174       28620 :     move16();
     175       28620 :     nb_tracks = NB_TRACK_FCB_4T;
     176       28620 :     move16();
     177       28620 :     nb_pulse = 0; /* to avoid compilation warnings */
     178       28620 :     move16();
     179             : 
     180       28620 :     IF( EQ_16( L_subfr, L_SUBFR ) )
     181             :     {
     182       24470 :         config = PulseConfTable[cdk_index];
     183       24470 :         bits = config.bits;
     184       24470 :         move16();
     185       24470 :         nb_pulse = config.nb_pulse;
     186       24470 :         move16();
     187       24470 :         codetrackpos = config.codetrackpos;
     188       24470 :         move16();
     189             : 
     190       24470 :         IF( EQ_16( cdk_index, 2 ) )
     191             :         {
     192             :             /* 12 bits, 2 pulses, 2 tracks:  11 (used all tracks) */
     193        8752 :             nb_tracks = NB_TRACK_FCB_2T;
     194        8752 :             move16();
     195        8752 :             nb_iter = NB_TRACK_FCB_2T;
     196        8752 :             move16();
     197             :         }
     198       15718 :         ELSE IF( EQ_16( nb_pulse, 2 ) )
     199             :         {
     200             :             /* 10 bits,  2 pulses, 4 tracks:  1010 (used only even tracks) */
     201        1469 :             nb_iter = NB_TRACK_FCB_4T - 2;
     202        1469 :             move16();
     203             :         }
     204       14249 :         ELSE IF( EQ_16( nb_pulse, 3 ) )
     205             :         {
     206       12898 :             IF( EQ_16( codetrackpos, TRACKPOS_FIXED_FIRST ) )
     207             :             {
     208             :                 /* 15 bits,  3 pulses, 4 tracks:  1110 (fixed track to first) */
     209       12205 :                 nb_iter = NB_TRACK_FCB_4T - 1;
     210       12205 :                 move16();
     211             :             }
     212         693 :             ELSE IF( EQ_16( codetrackpos, TRACKPOS_FREE_THREE ) )
     213             :             {
     214             :                 /* 17 bits,  3 pulses, 4 tracks  (used all tracks): 1110, 1101, 1011, 0111 */
     215         693 :                 nb_iter = NB_TRACK_FCB_4T;
     216         693 :                 move16();
     217             :             }
     218             :         }
     219             :     }
     220             :     ELSE /* L_subfr == 2*L_SUBFFR */
     221             :     {
     222        4150 :         bits = cdk_index;
     223        4150 :         move16();
     224        4150 :         codetrackpos = -1; /* to avoid compilation warnings */
     225        4150 :         move16();
     226             : 
     227             : 
     228        4150 :         IF( EQ_16( cdk_index, 14 ) )
     229             :         {
     230             :             /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */
     231        4140 :             nb_pulse = 2;
     232        4140 :             move16();
     233        4140 :             nb_iter = NB_TRACK_FCB_2T;
     234        4140 :             move16();
     235        4140 :             codetrackpos = TRACKPOS_FIXED_TWO;
     236        4140 :             move16();
     237        4140 :             nb_tracks = NB_TRACK_FCB_2T;
     238        4140 :             move16();
     239             :         }
     240          10 :         ELSE IF( EQ_16( cdk_index, 12 ) )
     241             :         {
     242             :             /* 12 bits, 2 pulses, 4 tracks: 1010 (used only even tracks) */
     243           0 :             nb_pulse = 2;
     244           0 :             move16();
     245           0 :             nb_iter = NB_TRACK_FCB_4T - 2;
     246           0 :             move16();
     247           0 :             codetrackpos = TRACKPOS_FIXED_EVEN;
     248           0 :             move16();
     249             :         }
     250          10 :         ELSE IF( EQ_16( cdk_index, 18 ) )
     251             :         {
     252             :             /* 18 bits, 3 pulses, 4 tracks: 1110 (used first three tracks) */
     253           5 :             nb_pulse = 3;
     254           5 :             move16();
     255           5 :             nb_iter = NB_TRACK_FCB_4T - 1;
     256           5 :             move16();
     257           5 :             codetrackpos = TRACKPOS_FIXED_FIRST;
     258           5 :             move16();
     259             :         }
     260           5 :         ELSE IF( EQ_16( cdk_index, 20 ) )
     261             :         {
     262             :             /* 20 bits, 3 pulses, 4 tracks (used all tracks): 1110, 1101, 1011, 0111 */
     263           5 :             nb_pulse = 3;
     264           5 :             move16();
     265           5 :             nb_iter = NB_TRACK_FCB_4T;
     266           5 :             move16();
     267           5 :             codetrackpos = TRACKPOS_FREE_THREE;
     268           5 :             move16();
     269             :         }
     270           0 :         ELSE IF( EQ_16( cdk_index, 24 ) )
     271             :         {
     272             :             /* 24 bits, 4 pulses, 4 tracks: 1111 */
     273           0 :             nb_pulse = 4;
     274           0 :             move16();
     275           0 :             nb_iter = NB_TRACK_FCB_4T;
     276           0 :             move16();
     277           0 :             codetrackpos = TRACKPOS_FIXED_FIRST;
     278           0 :             move16();
     279             :         }
     280             :     }
     281             : 
     282       28620 :     beta1_fx = BETA_BN1_FX; // Q0
     283       28620 :     move16();
     284       28620 :     beta2_fx = BETA_BN2_FX; // Q2
     285       28620 :     move16();
     286             : 
     287       28620 :     IF( LE_16( cdk_index, 2 ) )
     288             :     {
     289       10221 :         beta1_fx = BETA_BN1_FX * 2; // Q0
     290       10221 :         move16();
     291       10221 :         beta2_fx = BETA_BN2_FX * 2; // Q2
     292       10221 :         move16();
     293             :     }
     294             : 
     295             :     /*-----------------------------------------------------------------*
     296             :      * Find signal bn[] and sign pre-selection vector sign[].
     297             :      *-----------------------------------------------------------------*/
     298             : 
     299       28620 :     exp = sub( Q31, shl( Q_dn, 1 ) );
     300             : 
     301       28620 :     s64 = 0;
     302       28620 :     move64();
     303     2125900 :     FOR( i = 0; i < L_subfr; i++ )
     304             :     {
     305     2097280 :         s64 = W_mac_16_16( s64, dn_orig[i], dn_orig[i] ); // 2 * Q_dn + 1
     306             :     }
     307       28620 :     dndn_fx = 21474836 /*0.01f in Q31 */;
     308       28620 :     move32();
     309       28620 :     dndn_e = 0;
     310       28620 :     move16();
     311       28620 :     IF( s64 )
     312             :     {
     313       28514 :         Word16 new_exp1 = W_norm( s64 );
     314       28514 :         dndn_fx = W_extract_h( W_shl( s64, new_exp1 ) ); // 2 * Q_dyn + exp1 - 31
     315       28514 :         dndn_e = sub( 31, sub( add( add( shl( Q_dn, 1 ), 1 ), new_exp1 ), 32 ) );
     316             :     }
     317             : 
     318             : 
     319       28620 :     cncn_fx = 214748365 /* 0.1f in Q31 */;
     320       28620 :     move32();
     321       28620 :     cncn_e = 0;
     322       28620 :     move16();
     323             : 
     324      117316 :     FOR( q = 0; q < nb_tracks; q++ )
     325             :     {
     326       88696 :         s64 = 0;
     327       88696 :         move64();
     328     2185976 :         FOR( i = 0; i < L_subfr; i += nb_tracks )
     329             :         {
     330     2097280 :             s64 = W_mac_16_16( s64, cn[i + q], cn[i + q] ); // 2 * q_cn + 1
     331             :         }
     332             : 
     333       88696 :         cncn_track[q] = 214748365 /* 0.1f in Q31 */;
     334       88696 :         move32();
     335       88696 :         cncn_track_e[q] = 0;
     336       88696 :         move16();
     337       88696 :         IF( s64 )
     338             :         {
     339       88306 :             Word16 new_exp1 = W_norm( s64 );
     340       88306 :             cncn_track[q] = W_extract_h( W_shl( s64, new_exp1 ) ); // 2 * Q_dyn + exp1 - 31
     341       88306 :             cncn_track_e[q] = sub( 31, sub( add( add( shl( q_cn, 1 ), 1 ), new_exp1 ), 32 ) );
     342             :         }
     343       88696 :         cncn_fx = BASOP_Util_Add_Mant32Exp( cncn_fx, cncn_e, cncn_track[q], cncn_track_e[q], &cncn_e ); // Q(cncn_e)
     344             :     }
     345             : 
     346       28620 :     Word16 tmp = 0;
     347       28620 :     move16();
     348       28620 :     s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_fx, &tmp );
     349       28620 :     tmp = add( tmp, sub( dndn_e, cncn_e ) );
     350       28620 :     s_coef_fx = Sqrt16( s_coef_fx, &tmp ); // Q(15 - tmp)
     351             : 
     352       28620 :     q_temp1 = add( add( sub( Q15, tmp ), q_cn ), Q1 );
     353       28620 :     scale_temp1 = sub( q_temp1, Q_dn );
     354     2125900 :     FOR( i = 0; i < L_subfr; i++ )
     355             :     {
     356     2097280 :         temp1 = L_mult( s_coef_fx, cn[i] );     // Q(15 - tmp)+q_cn+1
     357     2097280 :         temp2 = L_mult( beta1_fx, dn_orig[i] ); // 1+Q_dn+1
     358             :         /* bn_orig_fx[i] is being used in Q_dn */
     359     2097280 :         temp2 = L_shr( temp2, 1 );
     360     2097280 :         temp1 = L_shr( temp1, scale_temp1 );
     361     2097280 :         bn_orig_fx[i] = L_add( temp1, temp2 ); // Q_dn
     362     2097280 :         move32();
     363             : 
     364     2097280 :         IF( bn_orig_fx[i] >= 0 )
     365             :         {
     366     1031595 :             sign_fx[i] = 1;
     367             :         }
     368             :         ELSE
     369             :         {
     370     1065685 :             sign_fx[i] = -1;
     371             :         }
     372     2097280 :         move16();
     373             :     }
     374             : 
     375             :     /*-----------------------------------------------------------------*
     376             :      * Compute buffer h_buf[].
     377             :      *-----------------------------------------------------------------*/
     378             : 
     379       28620 :     h = h_buf;
     380       28620 :     h_inv = h_buf + shl( L_subfr, 1 );
     381             : 
     382     2125900 :     FOR( i = 0; i < L_subfr; i++ )
     383             :     {
     384     2097280 :         *h++ = 0;
     385     2097280 :         move16();
     386     2097280 :         *h_inv++ = 0;
     387     2097280 :         move16();
     388             :     }
     389             : 
     390     2125900 :     FOR( i = 0; i < L_subfr; i++ )
     391             :     {
     392     2097280 :         h[i] = H[i];
     393     2097280 :         move16();
     394     2097280 :         h_inv[i] = negate( H[i] );
     395     2097280 :         move16();
     396             :     }
     397             : 
     398             :     /*-----------------------------------------------------------------*
     399             :      * Approximate FI[i][j] by alp[abs(i-j)] and compute buffer alp_buf[].
     400             :      *-----------------------------------------------------------------*/
     401       28620 :     q_H = sub( 14, norm_s( H[0] ) );
     402       28620 :     shift = sub( shl( q_H, 1 ), 6 );
     403             : 
     404       28620 :     alp = alp_buf + L_subfr;
     405             : 
     406     2125900 :     FOR( i = 0; i < L_subfr; i++ )
     407             :     {
     408     2097280 :         s64 = 0;
     409     2097280 :         move64();
     410             : 
     411    87257280 :         FOR( j = i; j < L_subfr; j++ )
     412             :         {
     413    85160000 :             s64 = W_mac0_16_16( s64, H[j], H[j - i] ); /* Q = shift + 6*/
     414             :         }
     415     2097280 :         *alp = extract_l( W_extract_l( W_shr( s64, shift ) ) ); /*Q6*/
     416     2097280 :         move16();
     417     2097280 :         alp_buf[L_subfr - i] = *alp++; /*Q6*/
     418     2097280 :         move16();
     419             :     }
     420             : 
     421       28620 :     alp = alp_buf + L_subfr;
     422             : 
     423      117316 :     FOR( q = 0; q < nb_tracks; q++ )
     424             :     {
     425       88696 :         max_track[q] = 0;
     426       88696 :         move32();
     427             : 
     428     2185976 :         FOR( i = q; i < L_subfr; i += nb_tracks )
     429             :         {
     430     2097280 :             temp_fx = imult3216( bn_orig_fx[i], sign_fx[i] ); // Q_dn
     431             : 
     432     2097280 :             IF( GE_32( temp_fx, max_track[q] ) )
     433             :             {
     434      308524 :                 max_track[q] = temp_fx; // Q_dn
     435      308524 :                 move32();
     436      308524 :                 m0_track[q] = i;
     437      308524 :                 move16();
     438             :             }
     439             :         }
     440             :     }
     441             : 
     442             :     /*-----------------------------------------------------------------*
     443             :      * Track re-order
     444             :      *-----------------------------------------------------------------*/
     445             : 
     446       28620 :     IF( EQ_16( nb_tracks, NB_TRACK_FCB_2T ) )
     447             :     {
     448       12892 :         track_order[0] = 0;
     449       12892 :         move16();
     450       12892 :         track_order[1] = 1;
     451       12892 :         move16();
     452       12892 :         track_order[2] = 1;
     453       12892 :         move16();
     454       12892 :         track_order[3] = 0;
     455       12892 :         move16();
     456             :     }
     457             :     ELSE
     458             :     {
     459       15728 :         test();
     460       15728 :         test();
     461             :         /* skip certain tracks if number of pulses is lower than number of tracks */
     462       15728 :         IF( EQ_16( nb_pulse, 2 ) && EQ_16( nb_tracks, NB_TRACK_FCB_4T ) )
     463             :         {
     464        1469 :             max_track[NB_TRACK_FCB_4T - 3] = L_shl( -1, Q_dn ); // Q_dn
     465        1469 :             move32();
     466        1469 :             max_track[NB_TRACK_FCB_4T - 1] = L_shl( -1, Q_dn ); // Q_dn
     467        1469 :             move32();
     468             :         }
     469       14259 :         ELSE IF( EQ_16( nb_pulse, 3 ) && EQ_16( codetrackpos, TRACKPOS_FIXED_FIRST ) )
     470             :         {
     471       12210 :             max_track[NB_TRACK_FCB_4T - 1] = L_shl( -1, Q_dn ); // Q_dn
     472       12210 :             move32();
     473             :         }
     474             : 
     475       78640 :         FOR( q = 0; q < nb_tracks; q++ )
     476             :         {
     477       62912 :             i = maximum_32_fx( max_track, nb_tracks, &L_tmp1 );
     478       62912 :             track_order[q] = i;
     479       62912 :             move16();
     480       62912 :             max_track[i] = L_shl( -1, Q_dn ); // Q_dn
     481       62912 :             move32();
     482             :         }
     483             : 
     484       15728 :         track_order[4] = track_order[1]; // Q0
     485       15728 :         move16();
     486       15728 :         track_order[5] = track_order[0]; // Q0
     487       15728 :         move16();
     488       15728 :         track_order[6] = track_order[2]; // Q0
     489       15728 :         move16();
     490       15728 :         track_order[7] = track_order[3]; // Q0
     491       15728 :         move16();
     492             : 
     493       15728 :         track_order[8] = track_order[2]; // Q0
     494       15728 :         move16();
     495       15728 :         track_order[9] = track_order[0]; // Q0
     496       15728 :         move16();
     497       15728 :         track_order[10] = track_order[1]; // Q0
     498       15728 :         move16();
     499       15728 :         track_order[11] = track_order[3]; // Q0
     500       15728 :         move16();
     501             : 
     502       15728 :         track_order[12] = track_order[3]; // Q0
     503       15728 :         move16();
     504       15728 :         track_order[13] = track_order[0]; // Q0
     505       15728 :         move16();
     506       15728 :         track_order[14] = track_order[1]; // Q0
     507       15728 :         move16();
     508       15728 :         track_order[15] = track_order[2]; // Q0
     509       15728 :         move16();
     510             : 
     511       15728 :         IF( EQ_16( cdk_index, 3 ) )
     512             :         {
     513       12205 :             track_order[12] = track_order[2]; // Q0
     514       12205 :             move16();
     515       12205 :             track_order[13] = track_order[1]; // Q0
     516       12205 :             move16();
     517       12205 :             track_order[14] = track_order[0]; // Q0
     518       12205 :             move16();
     519             : 
     520       12205 :             track_order[16] = track_order[1]; // Q0
     521       12205 :             move16();
     522       12205 :             track_order[17] = track_order[2]; // Q0
     523       12205 :             move16();
     524       12205 :             track_order[18] = track_order[0]; // Q0
     525       12205 :             move16();
     526       12205 :             nb_iter = 5;
     527       12205 :             move16();
     528             :         }
     529        3523 :         ELSE IF( EQ_16( cdk_index, 4 ) )
     530             :         {
     531         693 :             track_order[16] = track_order[2]; // Q0
     532         693 :             move16();
     533         693 :             track_order[17] = track_order[3]; // Q0
     534         693 :             move16();
     535         693 :             track_order[18] = track_order[1]; // Q0
     536         693 :             move16();
     537         693 :             track_order[19] = track_order[0]; // Q0
     538         693 :             move16();
     539         693 :             nb_iter = 5;
     540         693 :             move16();
     541             :         }
     542             :     }
     543             : 
     544             :     /*-----------------------------------------------------------------*
     545             :      * Main searching loop
     546             :      *-----------------------------------------------------------------*/
     547             : 
     548       28620 :     crit_num_max = MIN_32; // Q31
     549       28620 :     move32();
     550       28620 :     q_crit_num_max = Q31;
     551       28620 :     move16();
     552       28620 :     crit_den_max = MAX_32; // Q31
     553       28620 :     move32();
     554       28620 :     q_crit_den_max = Q31;
     555       28620 :     move16();
     556       28620 :     skip_track_max = -1;
     557       28620 :     move16();
     558             : 
     559      127271 :     FOR( q = 0; q < nb_iter; q++ )
     560             :     {
     561             :         /*-----------------------------------------------------------------*
     562             :          * First pulse search
     563             :          *-----------------------------------------------------------------*/
     564             : 
     565       98651 :         track = track_order[q * nb_tracks]; // Q0
     566       98651 :         move16();
     567       98651 :         m[0] = m0_track[track]; // Q0
     568       98651 :         move16();
     569       98651 :         s[0] = sign_fx[m[0]]; // Q0
     570       98651 :         move16();
     571             : 
     572             :         /*-----------------------------------------------------------------*
     573             :          * Second pulse search
     574             :          *-----------------------------------------------------------------*/
     575             : 
     576       98651 :         IF( EQ_16( nb_tracks, NB_TRACK_FCB_2T ) )
     577             :         {
     578       25784 :             Gn = i_mult( s[0], shr( dn_orig[m[0]], 1 ) ); // Q_dn - 1
     579       25784 :             Gd = alp[0];                                  // Q6
     580       25784 :             move16();
     581       25784 :             G = BASOP_Util_Divide1616_Scale( Gn, Gd, &exp1 ); // Q_dn -1 - 6 + 15 - exp1 = Q_dn - 6 + 14 - exp1
     582       25784 :             G = i_mult( G, s[0] );                            // Q_dn - 6 + 14 - exp1
     583       25784 :             shift = sub( 14, exp1 );
     584             : 
     585       25784 :             track = track_order[q * nb_tracks + 1]; // Q0
     586       25784 :             move16();
     587       25784 :             alp_pos0 = alp - m[0] + track;
     588             : 
     589     1115832 :             FOR( i = track; i < L_subfr; i += NB_TRACK_FCB_2T )
     590             :             {
     591     1090048 :                 dn[i] = L_sub( L_deposit_l( dn_orig[i] ), L_shr( L_mult0( G, *alp_pos0 ), shift ) ); // Q_dn
     592     1090048 :                 move32();
     593     1090048 :                 alp_pos0 = alp_pos0 + NB_TRACK_FCB_2T;
     594             :             }
     595             : 
     596       25784 :             m[1] = find_best_pulse_fx( L_subfr, NB_TRACK_FCB_2T, track, dn, sign_fx, &s[1] ); // Q0
     597       25784 :             move16();
     598             :         }
     599             :         ELSE
     600             :         {
     601       72867 :             Gn = i_mult( s[0], dn_orig[m[0]] ); // Q_dn
     602       72867 :             Gd = alp[0];                        // Q6
     603       72867 :             move16();
     604       72867 :             G = Gn; // Q_dn
     605       72867 :             move16();
     606       72867 :             G = i_mult( G, s[0] ); // Q_dn
     607             : 
     608       72867 :             track = track_order[q * nb_tracks + 1]; // Q0
     609       72867 :             move16();
     610       72867 :             alp_pos0 = alp - m[0] + track; // exp(shift)
     611             : 
     612       72867 :             dndn_fx = 214748365 /* 0.1f in Q31 */;
     613       72867 :             move32();
     614       72867 :             dndn_e = 0;
     615       72867 :             move16();
     616             : 
     617       72867 :             s64 = 0;
     618       72867 :             move64();
     619     1239299 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     620             :             {
     621     1166432 :                 temp1 = L_mult0( Gd, dn_orig[i] );
     622     1166432 :                 temp2 = L_mult0( G, *alp_pos0 );
     623     1166432 :                 temp3 = L_sub( temp1, temp2 );
     624     1166432 :                 dn[i] = L_shr( temp3, 6 );
     625     1166432 :                 move32();
     626     1166432 :                 alp_pos0 += nb_tracks;
     627     1166432 :                 s64 = W_mac_32_32( s64, dn[i], dn[i] ); // 2 * Q_dn + 1
     628             :             }
     629       72867 :             exp1 = W_norm( s64 );
     630       72867 :             dndn_fx = W_extract_h( W_shl( s64, exp1 ) ); // 2 * Q_dyn + exp1 - 31
     631       72867 :             dndn_e = sub( 31, sub( add( add( shl( Q_dn, 1 ), 1 ), exp1 ), 32 ) );
     632             : 
     633       72867 :             IF( dndn_fx == 0 )
     634             :             {
     635         445 :                 dndn_fx = 214748365 /* 0.1f in Q31 */;
     636         445 :                 move32();
     637         445 :                 dndn_e = 0;
     638         445 :                 move16();
     639             :             }
     640       72867 :             exp1 = 0;
     641       72867 :             move16();
     642       72867 :             s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_track[track], &exp1 );
     643       72867 :             exp1 = add( exp1, sub( dndn_e, cncn_track_e[track] ) );
     644       72867 :             s_coef_fx = Sqrt16( s_coef_fx, &exp1 );
     645       72867 :             max_val_fx = EPSILLON_FX;
     646       72867 :             move16();
     647       72867 :             m[1] = track; // Q0
     648       72867 :             move16();
     649       72867 :             q_temp1 = add( add( sub( Q15, exp1 ), q_cn ), 1 );
     650       72867 :             q_temp2 = add( Q_dn, Q2 );
     651       72867 :             scale_temp1 = sub( q_temp1, Q_dn );
     652       72867 :             scale_temp2 = sub( q_temp2, Q_dn );
     653     1239299 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     654             :             {
     655     1166432 :                 temp1 = L_mult( s_coef_fx, cn[i] );   // Q(15 - tmp)+q_cn+1
     656     1166432 :                 temp2 = imult3216( dn[i], beta2_fx ); // Q_dn + 2
     657             : 
     658             :                 /* bn_orig_fx[i] is being used in Q_dn */
     659     1166432 :                 temp2 = L_shr( temp2, scale_temp2 );
     660     1166432 :                 temp1 = L_shr( temp1, scale_temp1 );
     661     1166432 :                 dn[i] = L_add( temp1, temp2 ); // Q_dn
     662     1166432 :                 move32();
     663     1166432 :                 temp_fx = imult3216( dn[i], sign_fx[i] ); // Q_dn
     664             : 
     665     1166432 :                 IF( GE_32( temp_fx, max_val_fx ) )
     666             :                 {
     667      216878 :                     max_val_fx = temp_fx; // Q_dn
     668      216878 :                     move16();
     669      216878 :                     m[1] = i;
     670      216878 :                     move16();
     671             :                 }
     672             :             }
     673             : 
     674       72867 :             s[1] = sign_fx[m[1]];
     675       72867 :             move16();
     676             :         }
     677             : 
     678             :         /*-----------------------------------------------------------------*
     679             :          * Third pulse search
     680             :          *-----------------------------------------------------------------*/
     681             : 
     682       98651 :         IF( GE_16( nb_pulse, 3 ) )
     683             :         {
     684       69929 :             Gn = add( Gn, i_mult( s[1], dn_orig[m[1]] ) ); // Q_dn
     685       69929 :             Gd32 = Gd;
     686       69929 :             move16();
     687       69929 :             Gd32 = L_add( Gd32, L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[1] ), alp[m[0] - m[1]] ) ) ); // Q6
     688       69929 :             G = Gn;                                                                                             // Q_dn
     689       69929 :             move16();
     690       69929 :             G1 = i_mult( G, s[1] ); // Q_dn
     691       69929 :             G = i_mult( G, s[0] );  // Q_dn
     692             : 
     693       69929 :             track = track_order[q * nb_tracks + 2]; // Q0
     694       69929 :             move16();
     695       69929 :             alp_pos0 = alp - m[0] + track;
     696       69929 :             alp_pos1 = alp - m[1] + track;
     697             : 
     698     1189353 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     699             :             {
     700     1119424 :                 temp1 = imult3216( Gd32, dn_orig[i] );
     701     1119424 :                 temp2 = L_mult0( G, *alp_pos0 );
     702     1119424 :                 temp3 = L_mult0( G1, *alp_pos1 );
     703     1119424 :                 temp4 = L_sub( temp1, temp2 );
     704     1119424 :                 temp4 = L_sub( temp4, temp3 );
     705     1119424 :                 dn[i] = L_shr( temp4, 6 );
     706     1119424 :                 move32();
     707     1119424 :                 alp_pos0 += nb_tracks;
     708     1119424 :                 alp_pos1 += nb_tracks;
     709             :             }
     710             : 
     711       69929 :             m[2] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[2] ); // Q0
     712       69929 :             move16();
     713             :         }
     714             : 
     715             :         /*-----------------------------------------------------------------*
     716             :          * Fourth pulse search
     717             :          *-----------------------------------------------------------------*/
     718             : 
     719       98651 :         IF( GE_16( nb_pulse, 4 ) )
     720             :         {
     721        5404 :             Gn = add( Gn, i_mult( s[2], dn_orig[m[2]] ) ); // Q_dn
     722        5404 :             temp1 = alp[0];
     723        5404 :             move32();
     724        5404 :             temp2 = L_mult0( i_mult( shl( s[0], 1 ), s[2] ), alp[m[0] - m[2]] );
     725        5404 :             temp3 = L_mult0( i_mult( shl( s[1], 1 ), s[2] ), alp[m[1] - m[2]] );
     726        5404 :             Gd32 = L_add( Gd32, L_add( L_add( temp1, temp2 ), temp3 ) ); // Q6
     727        5404 :             G = Gn;                                                      // Q_dn
     728        5404 :             move16();
     729        5404 :             G1 = i_mult( G, s[1] ); // Q_dn
     730        5404 :             G2 = i_mult( G, s[2] ); // Q_dn
     731        5404 :             G = i_mult( G, s[0] );  // Q_dn
     732             : 
     733        5404 :             track = track_order[q * nb_tracks + 3];
     734        5404 :             move16();
     735        5404 :             alp_pos0 = alp - m[0] + track;
     736        5404 :             alp_pos1 = alp - m[1] + track;
     737        5404 :             alp_pos2 = alp - m[2] + track;
     738             : 
     739       91868 :             FOR( i = track; i < L_subfr; i += nb_tracks )
     740             :             {
     741             : 
     742       86464 :                 temp1 = imult3216( Gd32, dn_orig[i] );
     743       86464 :                 temp2 = L_mult0( G, *alp_pos0 );
     744       86464 :                 temp3 = L_mult0( G1, *alp_pos1 );
     745       86464 :                 temp4 = L_mult0( G2, *alp_pos2 );
     746       86464 :                 temp5 = L_sub( temp1, temp2 );
     747       86464 :                 temp5 = L_sub( temp5, temp3 );
     748       86464 :                 temp5 = L_sub( temp5, temp4 );
     749       86464 :                 dn[i] = L_shr( temp5, 6 );
     750       86464 :                 move32();
     751       86464 :                 alp_pos0 += nb_tracks;
     752       86464 :                 alp_pos1 += nb_tracks;
     753       86464 :                 alp_pos2 += nb_tracks;
     754             :             }
     755             : 
     756        5404 :             m[3] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[3] );
     757        5404 :             move16();
     758             :         }
     759             :         ELSE
     760             :         {
     761       93247 :             skip_track[q] = track_order[q * nb_tracks + 3];
     762       93247 :             move16();
     763             :         }
     764             : 
     765             :         /*-----------------------------------------------------------------*
     766             :          * Fifth pulse search
     767             :          *-----------------------------------------------------------------*/
     768             : 
     769       98651 :         IF( GE_16( nb_pulse, 5 ) )
     770             :         {
     771        3804 :             Gn = add( Gn, i_mult( s[3], dn_orig[m[3]] ) ); // Q_dn
     772        3804 :             temp1 = alp[0];
     773        3804 :             move32();
     774        3804 :             temp2 = L_mult0( i_mult( shl( s[0], 1 ), s[3] ), alp[m[0] - m[3]] );
     775        3804 :             temp3 = L_mult0( i_mult( shl( s[1], 1 ), s[3] ), alp[m[1] - m[3]] );
     776        3804 :             temp4 = L_mult0( i_mult( shl( s[2], 1 ), s[3] ), alp[m[2] - m[3]] );
     777             : 
     778        3804 :             Gd32 = L_add( Gd32, L_add( L_add( L_add( temp1, temp2 ), temp3 ), temp4 ) ); // Q6
     779        3804 :             G = Gn;
     780        3804 :             move16();               // Q_dn
     781        3804 :             G1 = i_mult( G, s[1] ); // Q_dn
     782        3804 :             G2 = i_mult( G, s[2] ); // Q_dn
     783        3804 :             G3 = i_mult( G, s[3] ); // Q_dn
     784        3804 :             G = i_mult( G, s[0] );  // Q_dn
     785             : 
     786        3804 :             IF( EQ_16( cdk_index, 6 ) )
     787             :             {
     788        2272 :                 track = 0; /* always track 0 */
     789        2272 :                 move16();
     790             : 
     791        2272 :                 alp_pos0 = alp - m[0];
     792        2272 :                 alp_pos1 = alp - m[1];
     793        2272 :                 alp_pos2 = alp - m[2];
     794        2272 :                 alp_pos3 = alp - m[3];
     795             : 
     796       38624 :                 FOR( i = track; i < L_subfr; i += nb_tracks )
     797             :                 {
     798       36352 :                     temp1 = imult3216( Gd32, dn_orig[i] );
     799       36352 :                     temp2 = L_mult0( G, *alp_pos0 );
     800       36352 :                     temp3 = L_mult0( G1, *alp_pos1 );
     801       36352 :                     temp4 = L_mult0( G2, *alp_pos2 );
     802       36352 :                     temp5 = L_mult0( G3, *alp_pos3 );
     803       36352 :                     temp6 = L_sub( temp1, temp2 );
     804       36352 :                     temp6 = L_sub( temp6, temp3 );
     805       36352 :                     temp6 = L_sub( temp6, temp4 );
     806       36352 :                     temp6 = L_sub( temp6, temp5 );
     807       36352 :                     dn[i] = L_shr( temp6, 6 );
     808       36352 :                     move32();
     809       36352 :                     alp_pos0 += nb_tracks;
     810       36352 :                     alp_pos1 += nb_tracks;
     811       36352 :                     alp_pos2 += nb_tracks;
     812       36352 :                     alp_pos3 += nb_tracks;
     813             :                 }
     814             : 
     815        2272 :                 m[4] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[4] );
     816        2272 :                 move16();
     817             :             }
     818             :             ELSE /* cdk_index == 7 (26 bits codebook) */
     819             :             {
     820        1532 :                 alp_pos0 = alp - m[0];
     821        1532 :                 alp_pos1 = alp - m[1];
     822        1532 :                 alp_pos2 = alp - m[2];
     823        1532 :                 alp_pos3 = alp - m[3];
     824             : 
     825       99580 :                 FOR( i = 0; i < L_subfr; i++ )
     826             :                 {
     827       98048 :                     temp1 = imult3216( Gd32, dn_orig[i] );
     828       98048 :                     temp2 = L_mult0( G, *alp_pos0 );
     829       98048 :                     temp3 = L_mult0( G1, *alp_pos1 );
     830       98048 :                     temp4 = L_mult0( G2, *alp_pos2 );
     831       98048 :                     temp5 = L_mult0( G3, *alp_pos3 );
     832       98048 :                     temp6 = L_sub( temp1, temp2 );
     833       98048 :                     temp6 = L_sub( temp6, temp3 );
     834       98048 :                     temp6 = L_sub( temp6, temp4 );
     835       98048 :                     temp6 = L_sub( temp6, temp5 );
     836       98048 :                     dn[i] = L_shr( temp6, 6 );
     837       98048 :                     move16();
     838       98048 :                     alp_pos0++;
     839       98048 :                     alp_pos1++;
     840       98048 :                     alp_pos2++;
     841       98048 :                     alp_pos3++;
     842             :                 }
     843             : 
     844             :                 Word16 k;
     845             :                 Word64 W_tmp, W_tmp1;
     846             :                 Word64 emax;
     847             : 
     848        1532 :                 emax = W_mult0_32_32( dn[0], dn[0] );
     849        1532 :                 i = 0;
     850        1532 :                 move16();
     851             : 
     852       98048 :                 FOR( k = 1; k < L_subfr; k++ )
     853             :                 {
     854       96516 :                     W_tmp = W_mult0_32_32( dn[k], dn[k] );
     855       96516 :                     W_tmp1 = W_sub( W_tmp, emax );
     856       96516 :                     if ( W_tmp1 > 0 )
     857             :                     {
     858        8810 :                         i = k;
     859        8810 :                         move16();
     860             :                     }
     861       96516 :                     if ( LE_64( emax, W_tmp ) )
     862             :                     {
     863        8866 :                         emax = W_tmp;
     864        8866 :                         move64();
     865             :                     }
     866             :                 }
     867             : 
     868        1532 :                 track = i % nb_tracks;
     869        1532 :                 move16();
     870             : 
     871        1532 :                 m[4] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[4] );
     872        1532 :                 move16();
     873             :             }
     874        3804 :             skip_track[q] = track;
     875        3804 :             move16();
     876             :         }
     877             : 
     878             :         /*-----------------------------------------------------------------*
     879             :          * - Build the filtered codeword and criterion computing.
     880             :          * - Memorize the best code positions & signs, and the best filtered codevector.
     881             :          *-----------------------------------------------------------------*/
     882             : 
     883       98651 :         crit_num = 0;
     884       98651 :         move32();
     885       98651 :         set16_fx( y_tmp, 0, L_subfr );
     886             : 
     887      375090 :         FOR( j = 0; j < nb_pulse; j++ )
     888             :         {
     889      276439 :             IF( s[j] > 0 )
     890             :             {
     891      137213 :                 p_hn = h - m[j];
     892             :             }
     893             :             ELSE
     894             :             {
     895      139226 :                 p_hn = h_inv - m[j];
     896             :             }
     897             : 
     898    19035095 :             FOR( i = 0; i < L_subfr; i++ )
     899             :             {
     900    18758656 :                 y_tmp[i] = add_sat( y_tmp[i], *p_hn++ ); // q_H
     901    18758656 :                 move16();
     902             :             }
     903             : 
     904      276439 :             crit_num = L_mac0( crit_num, s[j], dn_orig[m[j]] ); // Q_dn
     905             :         }
     906             : 
     907       98651 :         s64 = W_mult0_32_32( crit_num, crit_num ); // 2*Q_dn
     908       98651 :         exp = W_norm( s64 );
     909       98651 :         crit_num = W_extract_h( W_shl( s64, exp ) ); // 2*Q_dn + exp - 32
     910       98651 :         q_crit_num = add( shl( Q_dn, 1 ), sub( exp, 32 ) );
     911             : 
     912             :         // crit_den = sum2_fx( y_tmp, L_subfr );                          // 2*q_H
     913       98651 :         s64 = 0;
     914       98651 :         move64();
     915     6944475 :         FOR( i = 0; i < L_subfr; i++ )
     916             :         {
     917     6845824 :             s64 = W_mac0_16_16( s64, y_tmp[i], y_tmp[i] );
     918             :         }
     919       98651 :         exp1 = W_norm( s64 );
     920       98651 :         crit_den = W_extract_h( W_shl( s64, exp1 ) ); // 2*q_H + exp1 - 32
     921       98651 :         q_crit_den = add( shl( q_H, 1 ), sub( exp1, 32 ) );
     922             : 
     923       98651 :         L_tmp1 = Mpy_32_32( crit_num, crit_den_max ); // q_crit_num+q_crit_den_max-31
     924       98651 :         exp = sub( add( q_crit_num, q_crit_den_max ), 31 );
     925       98651 :         L_tmp2 = Mpy_32_32( crit_den, crit_num_max ); // q_crit_den+q_crit_num_max-31
     926       98651 :         exp1 = sub( add( q_crit_den, q_crit_num_max ), 31 );
     927             : 
     928       98651 :         IF( GT_16( exp, exp1 ) )
     929             :         {
     930       12844 :             IF( GE_32( L_shr( L_tmp1, sub( exp, exp1 ) ), L_tmp2 ) )
     931             :             {
     932        1609 :                 flag = 1;
     933        1609 :                 move16();
     934             :             }
     935             :             ELSE
     936             :             {
     937       11235 :                 flag = 0;
     938       11235 :                 move16();
     939             :             }
     940             :         }
     941             :         ELSE
     942             :         {
     943       85807 :             IF( GE_32( L_tmp1, L_shr( L_tmp2, sub( exp1, exp ) ) ) )
     944             :             {
     945       57691 :                 flag = 1;
     946       57691 :                 move16();
     947             :             }
     948             :             ELSE
     949             :             {
     950       28116 :                 flag = 0;
     951       28116 :                 move16();
     952             :             }
     953             :         }
     954             : 
     955             : 
     956       98651 :         IF( flag )
     957             :         {
     958       59300 :             crit_num_max = crit_num;
     959       59300 :             move32();
     960       59300 :             q_crit_num_max = q_crit_num;
     961       59300 :             move16();
     962       59300 :             crit_den_max = crit_den;
     963       59300 :             move32();
     964       59300 :             q_crit_den_max = q_crit_den;
     965       59300 :             move16();
     966             : 
     967      220285 :             FOR( j = 0; j < nb_pulse; j++ )
     968             :             {
     969      160985 :                 m_max[j] = m[j];
     970      160985 :                 move16();
     971      160985 :                 s_max[j] = s[j];
     972      160985 :                 move16();
     973             :             }
     974             : 
     975       59300 :             Copy_Scale_sig( y_tmp, y, L_subfr, sub( 9, q_H ) ); // y in Q9
     976       59300 :             skip_track_max = skip_track[q];
     977       59300 :             move16();
     978             :         }
     979             :     }
     980             : 
     981             :     /*-----------------------------------------------------------------*
     982             :      * Reconstruct the best codevector,
     983             :      * compute index of codevector and write it into the bitstream.
     984             :      *-----------------------------------------------------------------*/
     985             : 
     986       28620 :     set16_fx( code, 0, L_subfr );
     987      102421 :     FOR( q = 0; q < nb_pulse; q++ )
     988             :     {
     989       73801 :         code[m_max[q]] = add( code[m_max[q]], shl( s_max[q], Q9 ) ); // Q9
     990       73801 :         move16();
     991             :     }
     992       28620 :     test();
     993       28620 :     IF( EQ_16( bits, 12 ) || EQ_16( bits, 14 ) )
     994             :     {
     995             :         /* 12 bits, 2 pulses, 2 tracks  11 used all tracks */
     996       12892 :         i = 6;
     997       12892 :         move16();
     998       12892 :         j = 0x800;
     999       12892 :         move16();
    1000       12892 :         q = 0x20;
    1001       12892 :         move16();
    1002             : 
    1003       12892 :         IF( EQ_16( L_subfr, 2 * L_SUBFR ) )
    1004             :         {
    1005             :             /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */
    1006        4140 :             i = 7;
    1007        4140 :             move16();
    1008        4140 :             j = 0x2000;
    1009        4140 :             move16();
    1010        4140 :             q = 0x40;
    1011        4140 :             move16();
    1012             :         }
    1013             : 
    1014       12892 :         IF( EQ_16( m_max[0] % NB_TRACK_FCB_2T, 1 ) )
    1015             :         {
    1016        7320 :             idx = add( shl( shr( m_max[1], 1 ), i ), shr( m_max[0], 1 ) );
    1017             : 
    1018        7320 :             if ( s_max[1] < 0 )
    1019             :             {
    1020        3676 :                 idx = add( idx, j );
    1021             :             }
    1022             : 
    1023        7320 :             if ( s_max[0] < 0 )
    1024             :             {
    1025        3658 :                 idx = add( idx, q );
    1026             :             }
    1027             :         }
    1028             :         ELSE
    1029             :         {
    1030        5572 :             idx = add( shl( shr( m_max[0], 1 ), i ), shr( m_max[1], 1 ) );
    1031             : 
    1032        5572 :             if ( s_max[0] < 0 )
    1033             :             {
    1034        2732 :                 idx = add( idx, j );
    1035             :             }
    1036             : 
    1037        5572 :             if ( s_max[1] < 0 )
    1038             :             {
    1039        2772 :                 idx = add( idx, q );
    1040             :             }
    1041             :         }
    1042             : 
    1043       12892 :         push_indice( hBstr, IND_ALG_CDBK_2T32, idx, bits );
    1044             :     }
    1045             :     ELSE
    1046             :     {
    1047             :         /* compute index of codevector */
    1048       15728 :         set16_fx( ind_stream, -1, i_mult( NPMAXPT, nb_tracks ) );
    1049             : 
    1050       15728 :         bits_track = 4;
    1051       15728 :         move16();
    1052       15728 :         nb_pos = NB_POS_FCB_4T;
    1053       15728 :         move16();
    1054             : 
    1055       15728 :         IF( EQ_16( L_subfr, 2 * L_SUBFR ) )
    1056             :         {
    1057          10 :             bits_track = 5;
    1058          10 :             move16();
    1059          10 :             nb_pos = NB_POS_FCB_4T_128;
    1060          10 :             move16();
    1061             :         }
    1062             : 
    1063       63745 :         FOR( q = 0; q < nb_pulse; q++ )
    1064             :         {
    1065       48017 :             i = i_mult( m_max[q] % NB_TRACK_FCB_4T, NPMAXPT ); /* track number */
    1066       48017 :             if ( ind_stream[i] >= 0 )
    1067             :             {
    1068         951 :                 i = add( i, 1 );
    1069             :             }
    1070       48017 :             ind_stream[i] = shr( m_max[q], 2 ); // / NB_TRACK_FCB_4T; /* pos of pulse */
    1071       48017 :             move16();
    1072             : 
    1073       48017 :             IF( s_max[q] < 0 )
    1074             :             {
    1075       24422 :                 ind_stream[i] = add( ind_stream[i], nb_pos );
    1076       24422 :                 move16();
    1077             :             }
    1078             :         }
    1079             : 
    1080       15728 :         test();
    1081       15728 :         IF( EQ_16( codetrackpos, TRACKPOS_FREE_THREE ) || EQ_16( codetrackpos, TRACKPOS_FREE_ONE ) )
    1082             :         {
    1083        1081 :             push_indice( hBstr, IND_ALG_CDBK_4T64, skip_track_max, 2 );
    1084             :         }
    1085             : 
    1086       15728 :         IF( LT_16( nb_pulse, 5 ) )
    1087             :         {
    1088       73885 :             FOR( q = 0; q < NB_TRACK_FCB_4T; q++ )
    1089             :             {
    1090       59108 :                 j = i_mult( q, NPMAXPT );
    1091       59108 :                 IF( NE_16( ind_stream[j], -1 ) )
    1092             :                 {
    1093       43262 :                     idx = quant_1p_N1_L_subfr_fx( nb_pos, ind_stream[j], bits_track );
    1094       43262 :                     push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( bits_track, 1 ) );
    1095             :                 }
    1096             :             }
    1097             :         }
    1098             :         ELSE
    1099             :         {
    1100        4755 :             FOR( q = 0; q < NB_TRACK_FCB_4T; q++ )
    1101             :             {
    1102        3804 :                 j = i_mult( q, NPMAXPT );
    1103        3804 :                 IF( EQ_16( q, skip_track_max ) )
    1104             :                 {
    1105         951 :                     idx = quant_2p_2N1_fx( ind_stream[j], ind_stream[j + 1], bits_track );
    1106         951 :                     push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( shl( bits_track, 1 ), 1 ) );
    1107             :                 }
    1108             :                 ELSE
    1109             :                 {
    1110        2853 :                     idx = quant_1p_N1_L_subfr_fx( nb_pos, ind_stream[j], bits_track );
    1111        2853 :                     push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( bits_track, 1 ) );
    1112             :                 }
    1113             :             }
    1114             :         }
    1115             :     }
    1116             : 
    1117       28620 :     return;
    1118             : }

Generated by: LCOV version 1.14