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

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : 
       6             : #include <stdint.h>
       7             : #include "options.h"
       8             : #include "basop_util.h"
       9             : #include "vad_basop.h"
      10             : //#include "prot_fx.h"
      11             : #include "rom_enc.h"
      12             : #include "prot_fx.h"     /* Function prototypes                    */
      13             : #include "prot_fx_enc.h" /* Function prototypes                    */
      14             : 
      15             : /*---------------------------------------------------------------------*
      16             :  * Local
      17             :  *---------------------------------------------------------------------*/
      18             : #define RE( A ) A.r
      19             : #define IM( A ) A.i
      20             : 
      21             : typedef struct
      22             : {
      23             :     complex_16 work[32];
      24             :     complex_16 const *tab;
      25             : } cfft_info_16;
      26             : /*-------------------------------------------------------------------*
      27             :  * ComplexMult_16()
      28             :  *
      29             :  *-------------------------------------------------------------------*/
      30      496000 : static void ComplexMult_16(
      31             :     Word16 *y1,
      32             :     Word16 *y2,
      33             :     const Word16 x1,
      34             :     const Word16 x2,
      35             :     const Word16 c1,
      36             :     const Word16 c2 )
      37             : {
      38      496000 :     *y1 = add( mult( x1, c1 ), mult( x2, c2 ) );
      39      496000 :     move16();
      40      496000 :     *y2 = sub( mult( x2, c1 ), mult( x1, c2 ) );
      41      496000 :     move16();
      42      496000 : }
      43             : /*-------------------------------------------------------------------*
      44             :  * ffr_getSfWord32()
      45             :  *
      46             :  *-------------------------------------------------------------------*/
      47       24800 : Word16 ffr_getSfWord32(
      48             :     const Word32 *vector, /*!< Pointer to input vector */
      49             :     const Word16 len      /*!< Length of input vector */
      50             : )
      51             : {
      52             :     Word32 maxVal;
      53             :     Word16 i;
      54             :     Word16 resu;
      55             : 
      56             : 
      57       24800 :     maxVal = 0;
      58       24800 :     move32();
      59      254200 :     FOR( i = 0; i < len; i++ )
      60             :     {
      61      229400 :         maxVal = L_max( maxVal, L_abs( vector[i] ) );
      62             :     }
      63             : 
      64       24800 :     resu = 31;
      65       24800 :     move16();
      66       24800 :     if ( maxVal )
      67             :     {
      68       24707 :         resu = norm_l( maxVal );
      69             :     }
      70             : 
      71       24800 :     return resu;
      72             : }
      73             : /*-------------------------------------------------------------------*
      74             :  * cgetpreSfWord16()
      75             :  *
      76             :  *-------------------------------------------------------------------*/
      77             : 
      78       93000 : static void cgetpreSfWord16(
      79             :     Word16 *vector, /*!< Pointer to input vector */
      80             :     const Word16 len,
      81             :     const Word16 preshr,
      82             :     Word16 *num )
      83             : {
      84             :     Word16 i;
      85             : 
      86             : 
      87       93000 :     *num = sub( *num, preshr );
      88       93000 :     move16();
      89     3069000 :     FOR( i = 0; i < len; i++ )
      90             :     {
      91     2976000 :         vector[i] = shr( vector[i], preshr );
      92     2976000 :         move16();
      93             :     }
      94       93000 : }
      95             : /*-------------------------------------------------------------------*
      96             :  * passf4_1_16()
      97             :  *
      98             :  *-------------------------------------------------------------------*/
      99             : 
     100       31000 : static void passf4_1_16(
     101             :     const cmplx_s *cc,
     102             :     cmplx_s *ch,
     103             :     const cmplx_s *wa1,
     104             :     const cmplx_s *wa2,
     105             :     const cmplx_s *wa3 )
     106             : {
     107             :     UWord16 i;
     108             : 
     109             : 
     110      155000 :     FOR( i = 0; i < 4; i++ )
     111             :     {
     112             :         cmplx_s c2, c3, c4, t1, t2, t3, t4;
     113             : 
     114      124000 :         t2 = C_add( cc[i], cc[i + 8] );
     115      124000 :         t1 = C_sub( cc[i], cc[i + 8] );
     116      124000 :         t3 = C_add( cc[i + 4], cc[i + 12] );
     117      124000 :         t4 = C_sub( cc[i + 4], cc[i + 12] );
     118      124000 :         t4 = C_mul_j( t4 );
     119             : 
     120      124000 :         c2 = C_add( t1, t4 );
     121      124000 :         c4 = C_sub( t1, t4 );
     122      124000 :         ch[i] = C_add( t2, t3 );
     123      124000 :         c3 = C_sub( t2, t3 );
     124             : 
     125      124000 :         ch[i + 4] = C_multr( c2, wa1[i] );
     126      124000 :         ch[i + 8] = C_multr( c3, wa2[i] );
     127      124000 :         ch[i + 12] = C_multr( c4, wa3[i] );
     128             : #ifdef WMOPS
     129             :         multiCounter[currCounter].CL_move += 4;
     130             : #endif
     131             :     }
     132       31000 : }
     133             : /*-------------------------------------------------------------------*
     134             :  * passf4_2_16()
     135             :  *
     136             :  *-------------------------------------------------------------------*/
     137       31000 : static void passf4_2_16(
     138             :     const cmplx_s *cc,
     139             :     cmplx_s *ch )
     140             : {
     141             : 
     142             :     Word16 k;
     143             : 
     144             : 
     145      155000 :     FOR( k = 0; k < 4; k++ )
     146             :     {
     147             :         cmplx_s t1, t2, t3, t4;
     148             : 
     149      124000 :         t2 = C_add( cc[4 * k], cc[4 * k + 2] );
     150      124000 :         t1 = C_sub( cc[4 * k], cc[4 * k + 2] );
     151      124000 :         t3 = C_add( cc[4 * k + 3], cc[4 * k + 1] );
     152      124000 :         t4 = C_sub( cc[4 * k + 1], cc[4 * k + 3] );
     153      124000 :         t4 = C_mul_j( t4 );
     154             : 
     155             : 
     156      124000 :         ch[k] = C_add( t2, t3 );
     157      124000 :         ch[k + 8] = C_sub( t2, t3 );
     158      124000 :         ch[k + 4] = C_add( t1, t4 );
     159      124000 :         ch[k + 12] = C_sub( t1, t4 );
     160             : #ifdef WMOPS
     161             :         multiCounter[currCounter].CL_move += 4;
     162             : #endif
     163             :     }
     164       31000 : }
     165             : 
     166             : /*-------------------------------------------------------------------*
     167             :  * cfftf_16()
     168             :  *
     169             :  *-------------------------------------------------------------------*/
     170       31000 : static void cfftf_16(
     171             :     Word16 *scale,
     172             :     complex_16 *c,
     173             :     complex_16 *ch,
     174             :     const complex_16 *wa )
     175             : {
     176             : 
     177       31000 :     cgetpreSfWord16( (Word16 *) c, 32, 3, scale );
     178       31000 :     passf4_1_16( (const cmplx_s *) c, (cmplx_s *) ch, (const cmplx_s *) &wa[0], (const cmplx_s *) &wa[4], (const cmplx_s *) &wa[8] );
     179       31000 :     cgetpreSfWord16( (Word16 *) ch, 32, 2, scale );
     180       31000 :     passf4_2_16( (const cmplx_s *) ch, (cmplx_s *) c );
     181       31000 : }
     182             : /*-------------------------------------------------------------------*
     183             :  * fft16_fix_4_16()
     184             :  *
     185             :  *-------------------------------------------------------------------*/
     186       15500 : static void fft16_fix_4_16(
     187             :     Word32 **Sr,
     188             :     Word32 **Si,
     189             :     const Word32 Offset,
     190             :     const Word16 i,
     191             :     cfft_info_16 cfft,
     192             :     Word16 in_specamp_Q,
     193             :     const Word16 tmpQ,
     194             :     Word32 *spec_amp )
     195             : {
     196             :     Word32 n;
     197             : 
     198             :     Word32 tmpr, tmpi, ptmpn, ptmp15_n, tmpspec;
     199             :     Word16 specamp_Q, tmpr_16, tmpi_16;
     200             :     Word16 resu, scalefactor1;
     201             :     complex_16 f_int2[16];
     202       15500 :     Word16 *count2 = &resu;
     203             :     Word16 Sr16, Si16;
     204             :     Word32 maxVal;
     205             : 
     206             : 
     207       15500 :     maxVal = L_deposit_l( 0 );
     208      263500 :     FOR( n = 0; n < 16; n++ )
     209             :     {
     210      248000 :         maxVal = L_max( maxVal, L_abs( Sr[Offset + n][i] ) );
     211      248000 :         maxVal = L_max( maxVal, L_abs( Si[Offset + n][i] ) );
     212             :     }
     213             : 
     214       15500 :     resu = 30;
     215       15500 :     move16();
     216       15500 :     IF( maxVal )
     217             :     {
     218       15500 :         resu = sub( norm_l( maxVal ), 1 );
     219             :     }
     220             : 
     221      263500 :     FOR( n = 0; n < 16; n++ )
     222             :     {
     223      248000 :         Sr16 = round_fx( L_shl( Sr[Offset + n][i], resu ) );
     224      248000 :         Si16 = round_fx( L_shl( Si[Offset + n][i], resu ) );
     225      248000 :         ComplexMult_16( &IM( f_int2[n] ), &RE( f_int2[n] ), Si16, Sr16, RE( M_in_fix16[n] ), IM( M_in_fix16[n] ) ); /*q+16*/
     226             :     }
     227             : 
     228       15500 :     cfftf_16( count2, f_int2, cfft.work, (const complex_16 *) cfft.tab );
     229       15500 :     cgetpreSfWord16( (Word16 *) f_int2, 32, 1, count2 );
     230       15500 :     scalefactor1 = add( *count2, DATAFFT_Q );
     231             : 
     232       15500 :     in_specamp_Q = add( in_specamp_Q, shl( scalefactor1, 1 ) );
     233             : 
     234      139500 :     FOR( n = 0; n < 8; n++ )
     235             :     {
     236      124000 :         tmpi = L_mac( L_mult( IM( f_int2[n] ), M_Wr_fix16[n] ), RE( f_int2[n] ), M_Wi_fix16[n] );
     237      124000 :         tmpr = L_msu( L_mult( RE( f_int2[n] ), M_Wr_fix16[n] ), IM( f_int2[n] ), M_Wi_fix16[n] );
     238      124000 :         tmpi_16 = extract_h( tmpi );
     239      124000 :         tmpr_16 = extract_h( tmpr );
     240             : 
     241      124000 :         ptmpn = L_mac0( L_mult0( tmpi_16, tmpi_16 ), tmpr_16, tmpr_16 );
     242             : 
     243      124000 :         tmpi = L_mac( L_mult( IM( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), RE( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
     244      124000 :         tmpr = L_msu( L_mult( RE( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), IM( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
     245      124000 :         tmpi_16 = extract_h( tmpi );
     246      124000 :         tmpr_16 = extract_h( tmpr );
     247             : 
     248      124000 :         ptmp15_n = L_add( ( L_mult0( tmpi_16, tmpi_16 ) ), ( L_mult0( tmpr_16, tmpr_16 ) ) );
     249      124000 :         tmpspec = L_add( ptmpn, ptmp15_n );
     250             : 
     251      124000 :         tmpspec = fft_vad_Sqrt_l( tmpspec, in_specamp_Q, &specamp_Q );
     252      124000 :         spec_amp[i * 8 + n] = L_shr( tmpspec, limitScale32( sub( specamp_Q, tmpQ ) ) );
     253      124000 :         move32();
     254             :     }
     255       15500 : }
     256             : /*-------------------------------------------------------------------*
     257             :  * fft16_fix_5_16()
     258             :  *
     259             :  *-------------------------------------------------------------------*/
     260       15500 : static void fft16_fix_5_16(
     261             :     Word32 **Sr,
     262             :     Word32 **Si,
     263             :     const Word32 Offset,
     264             :     const Word16 i,
     265             :     cfft_info_16 cfft,
     266             :     Word16 in_specamp_Q,
     267             :     const Word16 tmpQ,
     268             :     Word32 *spec_amp )
     269             : {
     270             :     Word32 n;
     271             : 
     272             :     Word32 tmpr, tmpi, ptmpn, ptmp15_n, tmpspec;
     273             :     Word16 specamp_Q, tmpr_16, tmpi_16;
     274             : 
     275             :     Word16 resu, scalefactor1;
     276             :     complex_16 f_int2[16];
     277       15500 :     Word16 *count2 = &resu;
     278             :     Word16 Sr16, Si16;
     279             :     Word32 maxVal;
     280             : 
     281             : 
     282       15500 :     maxVal = L_deposit_l( 0 );
     283      263500 :     FOR( n = 0; n < 16; n++ )
     284             :     {
     285      248000 :         maxVal = L_max( maxVal, L_abs( Sr[Offset + n][i] ) );
     286      248000 :         maxVal = L_max( maxVal, L_abs( Si[Offset + n][i] ) );
     287             :     }
     288             : 
     289       15500 :     resu = 30;
     290       15500 :     move16();
     291       15500 :     IF( maxVal )
     292             :     {
     293       15500 :         resu = sub( norm_l( maxVal ), 1 );
     294             :     }
     295             : 
     296      263500 :     FOR( n = 0; n < 16; n++ )
     297             :     {
     298      248000 :         Sr16 = round_fx( L_shl( Sr[Offset + n][i], resu ) );
     299      248000 :         Si16 = round_fx( L_shl( Si[Offset + n][i], resu ) );
     300      248000 :         ComplexMult_16( &IM( f_int2[n] ), &RE( f_int2[n] ), Si16, Sr16, RE( M_in_fix16[n] ), IM( M_in_fix16[n] ) ); /*q+16*/
     301             :     }
     302             : 
     303       15500 :     cfftf_16( count2, f_int2, cfft.work, (const complex_16 *) cfft.tab );
     304       15500 :     cgetpreSfWord16( (Word16 *) f_int2, 32, 1, count2 );
     305             : 
     306       15500 :     scalefactor1 = add( *count2, DATAFFT_Q );
     307             : 
     308       15500 :     in_specamp_Q = add( in_specamp_Q, shl( scalefactor1, 1 ) );
     309             : 
     310      139500 :     FOR( n = 0; n < 8; n++ )
     311             :     {
     312      124000 :         tmpi = L_mac( L_mult( IM( f_int2[n] ), M_Wr_fix16[n] ), RE( f_int2[n] ), M_Wi_fix16[n] );
     313      124000 :         tmpr = L_msu( L_mult( RE( f_int2[n] ), M_Wr_fix16[n] ), IM( f_int2[n] ), M_Wi_fix16[n] );
     314      124000 :         tmpi_16 = extract_h( tmpi );
     315      124000 :         tmpr_16 = extract_h( tmpr );
     316             : 
     317      124000 :         ptmpn = L_add( ( L_mult0( tmpi_16, tmpi_16 ) ), ( L_mult0( tmpr_16, tmpr_16 ) ) );
     318             : 
     319      124000 :         tmpi = L_mac( L_mult( IM( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), RE( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
     320      124000 :         tmpr = L_msu( L_mult( RE( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), IM( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
     321      124000 :         tmpi_16 = extract_h( tmpi );
     322      124000 :         tmpr_16 = extract_h( tmpr );
     323             : 
     324      124000 :         ptmp15_n = L_mac0( L_mult0( tmpi_16, tmpi_16 ), tmpr_16, tmpr_16 );
     325      124000 :         tmpspec = L_add( ptmpn, ptmp15_n );
     326             : 
     327      124000 :         tmpspec = fft_vad_Sqrt_l( tmpspec, in_specamp_Q, &specamp_Q );
     328      124000 :         spec_amp[i * 8 + 7 - n] = L_shr( tmpspec, limitScale32( sub( specamp_Q, tmpQ ) ) );
     329      124000 :         move32();
     330             :     }
     331       15500 : }
     332             : 
     333        3100 : void subband_FFT_fx(
     334             :     Word32 **Sr,      /*(i) real part of the CLDFB*/
     335             :     Word32 **Si,      /*(i) imag part of the CLDFB*/
     336             :     Word32 *spec_amp, /*(o) spectral amplitude*/
     337             :     Word32 Offset,    /*(i) offset of the CLDFB*/
     338             :     Word16 *fftoQ     /*(o) the Scaling */
     339             : )
     340             : {
     341             :     Word16 i;
     342             :     Word16 tmpQ, in_specamp_Q;
     343             :     cfft_info_16 cfft;
     344             : 
     345             : 
     346        3100 :     cfft.tab = wnk_table_16;
     347        3100 :     in_specamp_Q = shl( sub( *fftoQ, DATAFFT_Q ), 1 );
     348        3100 :     tmpQ = add( *fftoQ, 8 );
     349             : 
     350       18600 :     FOR( i = 0; i < 10; i = i + 2 )
     351             :     {
     352       15500 :         fft16_fix_4_16( Sr, Si, Offset, i, cfft, in_specamp_Q, tmpQ, spec_amp );
     353             :     }
     354             : 
     355       18600 :     FOR( i = 1; i < 10; i = i + 2 )
     356             :     {
     357       15500 :         fft16_fix_5_16( Sr, Si, Offset, i, cfft, in_specamp_Q, tmpQ, spec_amp );
     358             :     }
     359        3100 : }

Generated by: LCOV version 1.14