LCOV - code coverage report
Current view: top level - lib_dec - dec_acelp_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 181 200 90.5 %
Date: 2025-05-03 01:55:50 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include <memory.h>
       7             : #include <assert.h>
       8             : #include "options.h"
       9             : #include "basop_util.h"
      10             : #include "prot_fx.h"
      11             : #include "rom_com.h"
      12             : #include "rom_basop_util.h"
      13             : #define _1_CODE 0x200 /*codebook excitation Q9 */
      14             : 
      15             : /*---------------------------------------------------------------------*
      16             :  * Local function prototypes
      17             :  *---------------------------------------------------------------------*/
      18             : static void D_ACELP_decode_arithtrack_fx( Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen );
      19             : 
      20             : /*---------------------------------------------------------------------*
      21             :  * Function D_ACELP_indexing_fx()
      22             :  *
      23             :  *---------------------------------------------------------------------*/
      24             : 
      25      514781 : void D_ACELP_indexing_fx(
      26             :     Word16 code[], // Q9
      27             :     PulseConfig config,
      28             :     Word16 num_tracks,
      29             :     Word16 index[],
      30             :     Word16 *BER_detect )
      31             : {
      32             :     Word16 track, pulses, k, pulsestrack[NB_TRACK_FCB_4T];
      33             :     Word32 s;
      34             :     Word16 trackpos;
      35             :     UWord16 *idxs;
      36             :     UWord32 idxs32[4], index_n[NB_TRACK_FCB_4T];
      37             :     Word16 restpulses, wordcnt, wordcnt32;
      38             : 
      39      514781 :     assert( EQ_16( num_tracks, NB_TRACK_FCB_4T ) );
      40             : 
      41      514781 :     wordcnt = shr( add( config.bits, 15 ), 4 ); /* ceil(bits/16) */
      42             : 
      43             :     /* check if some tracks have more pulses */
      44      514781 :     restpulses = s_and( (Word16) config.nb_pulse, sub( num_tracks, 1 ) );
      45             : 
      46             :     /* cast to short */
      47      514781 :     idxs = (UWord16 *) idxs32;
      48     2167514 :     FOR( k = 0; k < wordcnt; k++ )
      49             :     {
      50     1652733 :         idxs[k] = (UWord16) index[k];
      51     1652733 :         move16();
      52             :     }
      53      514781 :     idxs[wordcnt] = 0;
      54      514781 :     move16();
      55             : 
      56             :     /*init 32bits wordcnt*/
      57      514781 :     wordcnt32 = shr( add( wordcnt, 1 ), 1 );
      58             : 
      59      514781 :     IF( restpulses )
      60             :     {
      61             :         /* check if we need to code track positions */
      62      369304 :         SWITCH( config.codetrackpos )
      63             :         {
      64       59682 :             case TRACKPOS_FREE_THREE:
      65             :                 /* Find track with less pulses */
      66       59682 :                 trackpos = extract_l( L_and( idxs[0], 3 ) );
      67       59682 :                 longshr( idxs32, 2, wordcnt32 );
      68             : 
      69             :                 /* set number of pulses per track */
      70       59682 :                 set16_fx( pulsestrack, add( shr( (Word16) config.nb_pulse, 2 ), 1 ), 4 );
      71       59682 :                 cast16();
      72       59682 :                 pulsestrack[trackpos] = sub( pulsestrack[trackpos], 1 ); /* this one has less pulses */
      73       59682 :                 move16();
      74       59682 :                 BREAK;
      75       18527 :             case TRACKPOS_FREE_ONE:
      76             :                 /* Find track with more pulses */
      77       18527 :                 trackpos = extract_l( L_and( idxs[0], 3 ) );
      78       18527 :                 longshr( idxs32, 2, wordcnt32 );
      79             : 
      80             :                 /* set number of pulses per track */
      81       18527 :                 set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
      82       18527 :                 cast16();
      83       18527 :                 pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 ); /* this one has less pulses */
      84       18527 :                 move16();
      85       18527 :                 BREAK;
      86           0 :             case TRACKPOS_FIXED_EVEN:
      87             :                 /* Pulses on even tracks */
      88           0 :                 pulsestrack[0] = shr( add( (Word16) config.nb_pulse, 1 ), 1 );
      89           0 :                 cast16();
      90           0 :                 move16();
      91           0 :                 pulsestrack[1] = 0;
      92           0 :                 move16();
      93           0 :                 pulsestrack[2] = shr( (Word16) config.nb_pulse, 1 );
      94           0 :                 cast16();
      95           0 :                 move16();
      96           0 :                 pulsestrack[3] = 0;
      97           0 :                 move16();
      98           0 :                 BREAK;
      99      222921 :             case TRACKPOS_FIXED_FIRST:
     100             :                 /* set number of pulses per track */
     101      222921 :                 set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
     102      222921 :                 cast16();
     103      666584 :                 FOR( k = 0; k < restpulses; k++ )
     104             :                 {
     105      443663 :                     pulsestrack[k] = add( pulsestrack[k], 1 );
     106      443663 :                     move16();
     107             :                 }
     108      222921 :                 BREAK;
     109       68174 :             case TRACKPOS_FIXED_TWO:
     110             :                 /* 1100, 0110, 0011, 1001 */
     111             :                 /* Find track with less pulses */
     112       68174 :                 trackpos = extract_l( L_and( idxs[0], 3 ) );
     113       68174 :                 longshr( idxs32, 2, wordcnt32 );
     114             : 
     115             :                 /* set number of pulses per track */
     116       68174 :                 set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
     117       68174 :                 cast16();
     118       68174 :                 pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
     119       68174 :                 move16();
     120       68174 :                 trackpos = add( trackpos, 1 );
     121       68174 :                 trackpos = s_and( trackpos, 3 );
     122       68174 :                 pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
     123       68174 :                 move16();
     124       68174 :                 BREAK;
     125           0 :             default:
     126           0 :                 assert( 0 );
     127             :                 BREAK;
     128             :         }
     129             :     }
     130             :     ELSE
     131             :     {
     132             :         /* set number of pulses per track */
     133      145477 :         set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
     134      145477 :         cast16();
     135             :     }
     136             : 
     137      514781 :     IF( EQ_16( config.bits, 43 ) )
     138             :     {
     139       32873 :         D_ACELP_decode_43bit_fx( idxs, code, pulsestrack );
     140             :     }
     141             :     ELSE
     142             :     {
     143      481908 :         fcb_pulse_track_joint_decode_fx( idxs, wordcnt, index_n, pulsestrack, num_tracks );
     144     1927632 :         FOR( track = ( num_tracks - 1 ); track >= 1; track-- )
     145             :         {
     146     1445724 :             pulses = pulsestrack[track];
     147     1445724 :             move16();
     148             : 
     149     1445724 :             IF( pulses )
     150             :             {
     151             :                 /* divide by number of possible states: rest is actual state and
     152             :                  * the integer part goes to next track */
     153     1431531 :                 s = index_n[track];
     154     1431531 :                 move32();
     155             :                 /* decode state to actual pulse positions on track */
     156     1431531 :                 D_ACELP_decode_arithtrack_fx( code + track, s, pulses, num_tracks, 16 );
     157             :             }
     158             :             ELSE /* track is empty */
     159             :             {
     160      241281 :                 FOR( k = track; k < ( 16 * num_tracks ); k += num_tracks )
     161             :                 {
     162      227088 :                     code[k] = 0;
     163      227088 :                     move16();
     164             :                 }
     165             :             }
     166             :         }
     167             : 
     168      481908 :         s = L_add( index_n[0], 0 );
     169      481908 :         pulses = pulsestrack[0];
     170      481908 :         move16();
     171             : 
     172             : #ifndef FIX_1378_ACELP_OUT_OF_BOUNDS
     173             :         /* safety check in case of bit errors */
     174             :         IF( GE_64( s, pulsestostates[16][pulses - 1] ) )
     175             :         {
     176             :             set16_fx( code, 0, L_SUBFR );
     177             :             *BER_detect = 1;
     178             :             move16();
     179             :             return;
     180             :         }
     181             : #endif
     182             : 
     183      481908 :         IF( pulses )
     184             :         {
     185             : #ifdef FIX_1378_ACELP_OUT_OF_BOUNDS
     186             :             /* safety check in case of bit errors */
     187      477431 :             IF( GE_64( s, pulsestostates[16][pulses - 1] ) )
     188             :             {
     189           0 :                 set16_fx( code, 0, L_SUBFR );
     190           0 :                 *BER_detect = 1;
     191           0 :                 move16();
     192           0 :                 return;
     193             :             }
     194             : #endif
     195      477431 :             D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 );
     196             :         }
     197             :         ELSE
     198             :         { /* track is empty */
     199       76109 :             FOR( k = 0; k < imult1616( 16, num_tracks ); k += num_tracks )
     200             :             {
     201       71632 :                 code[k] = 0;
     202       71632 :                 move16();
     203             :             }
     204             :         }
     205             :     }
     206             : }
     207             : 
     208     1908962 : static void D_ACELP_decode_arithtrack_fx( Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen )
     209             : {
     210             :     Word16 k, idx;
     211             : 
     212             :     /*initialy s was UWords32 but it seems that s is never greater then 0x80000000*/
     213             :     /*this assumption reduces complexity but if it is not true than exit*/
     214     1908962 :     assert( s >= 0 );
     215             : 
     216    32452354 :     FOR( k = (tracklen) -1; k >= 0; k-- )
     217             :     {
     218    30543392 :         idx = imult1616( k, trackstep );
     219    30543392 :         v[idx] = 0; /* default: there is no pulse here */
     220    30543392 :         move16();
     221             : 
     222    35543010 :         FOR( ; p; p-- ) /* one pulse placed, so one less left */
     223             :         {
     224    25152724 :             IF( LT_32( s, pulsestostates[k][p - 1] ) )
     225             :             {
     226    20153106 :                 BREAK;
     227             :             }
     228             : 
     229     4999618 :             s = L_sub( s, pulsestostates[k][p - 1] );
     230             : 
     231     4999618 :             IF( v[idx] != 0 ) /* there is a pulse here already = sign is known */
     232             :             {
     233      280864 :                 IF( v[idx] > 0 )
     234             :                 {
     235      138653 :                     v[idx] = add( v[idx], _1_CODE ); /* place one more pulse here */
     236      138653 :                     move16();
     237             :                 }
     238      280864 :                 IF( v[idx] <= 0 )
     239             :                 {
     240      142211 :                     v[idx] = sub( v[idx], _1_CODE ); /* place one more pulse here */
     241      142211 :                     move16();
     242             :                 }
     243             :             }
     244             :             ELSE /* this is the first pulse here -> determine sign */
     245             :             {
     246     4718754 :                 v[idx] = _1_CODE; /* place a negative pulse here */
     247     4718754 :                 move16();
     248     4718754 :                 IF( L_and( s, 0x1 ) != 0 )
     249             :                 {
     250     2364713 :                     v[idx] = negate( _1_CODE ); /* place a negative pulse here */
     251     2364713 :                     move16();
     252             :                 }
     253     4718754 :                 s = L_lshr( s, 1 );
     254             :             }
     255             :         }
     256             :     }
     257     1908962 : }
     258             : 
     259      481908 : void fcb_pulse_track_joint_decode_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num )
     260             : {
     261      481908 :     Word16 hi_to_low[10] = { 0, 0, 0, 3, 9, 5, 3, 1, 8, 8 };
     262             : 
     263             :     UWord32 index;
     264             :     Word32 indx_tmp;
     265             :     Word16 indx_flag, indx_flag_1;
     266             :     Word16 track, track_num1, pulse_num0, pulse_num1;
     267             :     Word32 div_tmp;
     268             :     Word16 indx_flag_2;
     269             : 
     270      481908 :     indx_flag = 0;
     271      481908 :     move16();
     272      481908 :     indx_flag_1 = 0;
     273      481908 :     move16();
     274      481908 :     indx_flag_2 = 0;
     275      481908 :     move16();
     276             : 
     277     2409540 :     FOR( track = 0; track < track_num; track++ )
     278             :     {
     279     1927632 :         indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
     280     1927632 :         indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
     281     1927632 :         indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
     282             :     }
     283             : 
     284      481908 :     hi_to_low[4] = 1;
     285      481908 :     move16();
     286      481908 :     if ( GE_16( indx_flag, track_num ) )
     287             :     {
     288       70385 :         hi_to_low[4] = 9;
     289       70385 :         move16();
     290             :     }
     291             : 
     292      481908 :     hi_to_low[7] = 1;
     293      481908 :     move16();
     294      481908 :     if ( GE_16( indx_flag_2, 1 ) )
     295             :     {
     296          25 :         hi_to_low[7] = 9;
     297          25 :         move16();
     298             :     }
     299             : 
     300      481908 :     IF( GE_16( indx_flag_1, track_num ) )
     301             :     {
     302      311872 :         IF( GE_16( indx_flag, track_num ) )
     303             :         {
     304       70385 :             index = 0;
     305       70385 :             move32();
     306       70385 :             IF( GE_16( indx_flag_2, 1 ) )
     307             :             {
     308          25 :                 FOR( track = sub( wordcnt, 1 ); track >= 6; track-- )
     309             :                 {
     310           0 :                     index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
     311             :                 }
     312          25 :                 index_n[3] = L_add( L_lshl( idxs[5], 8 ), L_and( L_lshr( idxs[4], 8 ), 0xFF ) );
     313          25 :                 move32();
     314          25 :                 index_n[2] = L_and( L_add( L_lshl( idxs[4], 16 ), idxs[3] ), 0xFFFFFF );
     315          25 :                 move32();
     316          25 :                 index_n[1] = L_add( L_lshl( idxs[2], 8 ), L_and( L_lshr( idxs[1], 8 ), 0xFF ) );
     317          25 :                 move32();
     318          25 :                 index_n[0] = L_and( L_add( L_lshl( idxs[1], 16 ), idxs[0] ), 0xFFFFFF );
     319          25 :                 move32();
     320             :             }
     321             :             ELSE
     322             :             {
     323      145263 :                 FOR( track = sub( wordcnt, 1 ); track >= track_num; track-- )
     324             :                 {
     325       74903 :                     index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
     326             :                 }
     327      351800 :                 FOR( track = 0; track < track_num; track++ )
     328             :                 {
     329      281440 :                     index_n[track] = (UWord32) idxs[track];
     330      281440 :                     move32();
     331             :                 }
     332             :             }
     333             :         }
     334             :         ELSE
     335             :         {
     336      241487 :             index = 0;
     337      241487 :             move32();
     338      594308 :             FOR( track = ( wordcnt - 1 ); track >= 2; track-- )
     339             :             {
     340      352821 :                 index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
     341             :             }
     342             : 
     343      241487 :             index_n[3] = L_and( (Word32) idxs[1], 0xFF );
     344      241487 :             move32();
     345      241487 :             index_n[2] = L_lshr( (Word32) idxs[1], 8 );
     346      241487 :             move32();
     347      241487 :             index_n[1] = L_and( (Word32) idxs[0], 0xFF );
     348      241487 :             move32();
     349      241487 :             index_n[0] = L_lshr( (Word32) idxs[0], 8 );
     350      241487 :             move32();
     351             :         }
     352             : 
     353      311872 :         track_num1 = sub( track_num, 1 );
     354      311872 :         pulse_num1 = pulse_num[track_num1];
     355      311872 :         move16();
     356      311872 :         index = L_add( L_lshl( index, hi_to_low[pulse_num1] ), L_lshr( index_n[track_num1], low_len[pulse_num1] ) );
     357     1247488 :         FOR( track = ( track_num - 1 ); track > 0; track-- )
     358             :         {
     359      935616 :             track_num1 = sub( track, 1 );
     360      935616 :             pulse_num0 = pulse_num[track_num1];
     361      935616 :             move16();
     362      935616 :             pulse_num1 = pulse_num[track];
     363      935616 :             move16();
     364      935616 :             index = L_add( L_lshl( index, hi_to_low[pulse_num0] ), L_lshr( index_n[track_num1], low_len[pulse_num0] ) );
     365             : 
     366      935616 :             iDiv_and_mod_32( index, indx_fact[pulse_num1], &div_tmp, &indx_tmp, 0 );
     367      935616 :             index_n[track] = L_add( L_and( index_n[track], low_mask[pulse_num1] ), L_lshl( indx_tmp, low_len[pulse_num1] ) );
     368      935616 :             move32();
     369      935616 :             index = L_add( div_tmp, 0 );
     370             :         }
     371      311872 :         pulse_num1 = pulse_num[0];
     372      311872 :         move16();
     373      311872 :         index_n[0] = L_add( L_and( index_n[0], low_mask[pulse_num1] ), L_lshl( index, low_len[pulse_num1] ) );
     374      311872 :         move32();
     375             :     }
     376             :     ELSE
     377             :     {
     378      170036 :         index = 0;
     379      170036 :         move32();
     380      531862 :         FOR( track = ( wordcnt - 1 ); track >= 0; track-- )
     381             :         {
     382      361826 :             index = (UWord32) W_add( UL_lshl( index, 16 ), (UWord32) idxs[track] );
     383             :         }
     384      680144 :         FOR( track = 3; track > 0; track-- )
     385             :         {
     386      510108 :             pulse_num1 = pulse_num[track];
     387      510108 :             move16();
     388      510108 :             index_n[track] = UL_and( index, index_mask_ACELP[pulse_num1] );
     389      510108 :             move32();
     390      510108 :             index = UL_lshr( index, index_len[pulse_num1] );
     391             :         }
     392      170036 :         index_n[0] = index;
     393      170036 :         move32();
     394             :     }
     395             : 
     396      481908 :     return;
     397             : }

Generated by: LCOV version 1.14