Commit c5d00498 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Functions in ivas_stereo_icbwe_dec.c converted to fixed point.

This commit includes stereo_icBWE_dec and functions
converted to support 32 bit data types which includes
GenSHBSynth, ScaleShapedSHB, Decimate_allpass_steep,
interpolate_3_over_2_allpass, Interpolate_allpass_steep,
deemph_32
parent c773dbbe
Loading
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -71,6 +71,31 @@ void deemph(
    return;
}

void deemph_fx_32(
    Word16 shift,    /*scaled output*/
    Word32 *signal,  /* i/o: signal            Qx*/
    const Word16 mu, /* i  : deemphasis factor Q15*/
    const int16_t L, /* i  : vector size         */
    Word32 *mem      /* i/o: memory (y[-1])    Qx*/
)
{
    int16_t i;

    signal[0] = L_add(signal[0] , Mpy_32_16_1( ( *mem ), mu ));
    FOR ( i = 1; i < L; i++ )
    {
        signal[i] = L_add(signal[i] , Mpy_32_16_1( signal[i - 1], mu ));
		signal[i] = L_shl(signal[i], shift);
    }

    *mem = signal[L - 1];
	move32();

    return;
}



/*========================================================================*/
/* FUNCTION : deemph_fx()												  */
/*------------------------------------------------------------------------*/
+11 −0
Original line number Diff line number Diff line
@@ -1143,4 +1143,15 @@ void TonalMdctConceal_whiten_noise_shape_ivas_fx(
    Decoder_State *st,
    const Word16 L_frame,
    const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode );

void stereo_icBWE_dec_fx(
  CPE_DEC_HANDLE hCPE,        /* i/o: CPE decoder structure                           */
  Word32 *synthRef_fx,            /* i/o: Reference channel HB synthesis at output Fs     */
  Word32 *synth_fx,               /* o  : Non reference channel HB synthesis at output Fs */
  const Word32 *fb_synth_ref,  /* i  : ref. high-band synthesis 16-20 kHz              */
  const Word32 *voice_factors, /* i  : voicing factors                                 */
  const Word16 output_frame,  /* i  : frame length                                    */
  Word16 *Q_syn
  );

#endif
+29 −0
Original line number Diff line number Diff line
@@ -585,6 +585,13 @@ const float icbwe_gsMapping_tbl[16] =
    -0.1690688f, -0.0987095f, -0.0700000f, -0.0500000f, -0.0200000f,  0.0000000f,  0.0400000f,  0.0800000f
};
const Word16 pow_10_icbwe_gsMapping_tbl_fx[16] = //Q14
{
	164 ,733 ,1793 ,3195 ,4524 ,5875 ,7438 ,9155 ,11101 ,13053 ,13945 ,14602 ,15647 ,16384 ,
    17965 ,19698
};
const float icbwe_gsMappingDFT_tbl[128] =
{
    -5.0000000f,    -4.5000000f,    -4.0000000f,    -3.5000000f,    -3.0000000f,    -2.5000000f,    -1.9000000f,    -1.5474502f,
@@ -605,6 +612,20 @@ const float icbwe_gsMappingDFT_tbl[128] =
     0.0155180f,     0.0224511f,     0.0298570f,     0.0375954f,     0.0457853f,     0.0549424f,     0.0659733f,     0.0785186f
};
const Word16 pow_10_icbwe_gsMappingDFT_tbl_fx[128] = //Q14
{
    0 ,1 ,2 ,5 ,16 ,52 ,206 ,464 ,518 ,585 ,667 ,688 ,803 ,899 ,
    1324 ,1349 ,1513 ,1534 ,1578 ,1625 ,1711 ,1756 ,1808 ,1879 ,1926 ,2001 ,2050 ,2130 ,
    2191 ,2280 ,2366 ,2394 ,2456 ,2574 ,2643 ,2726 ,2796 ,2850 ,2869 ,2908 ,2962 ,2991 ,
    3023 ,3051 ,3091 ,3130 ,3202 ,3233 ,3268 ,3342 ,3388 ,3429 ,3483 ,3519 ,3553 ,3595 ,
    3651 ,3706 ,3738 ,3795 ,3844 ,3890 ,3946 ,3990 ,4028 ,4075 ,4119 ,4166 ,4214 ,4259 ,
    4303 ,4350 ,4389 ,4441 ,4481 ,4540 ,4605 ,4684 ,4764 ,4854 ,4950 ,5068 ,5198 ,5348 ,
    5519 ,5692 ,5881 ,6073 ,6273 ,6473 ,6676 ,6883 ,7124 ,7364 ,7616 ,7852 ,8097 ,8370 ,
    8630 ,8916 ,9200 ,9496 ,9866 ,10252 ,10652 ,11052 ,11436 ,11813 ,12247 ,12697 ,13153 ,13611 ,
    14072 ,14503 ,14936 ,15336 ,15702 ,16032 ,16384 ,16664 ,16980 ,17253 ,17550 ,17866 ,18206 ,18594 ,
    19072 ,19631 
};
/*----------------------------------------------------------------------------------*
 * TD Stereo ROM tables
@@ -617,6 +638,14 @@ const float tdm_ratio_tabl[TDM_NQ+1] =
    0.5523f,    0.6040f,    0.6545f,    0.7034f,    0.7500f,    0.7939f,    0.8346f,    0.8716f,
    0.9045f,    0.9330f,    0.9568f,    0.9755f,    0.9891f,    1.0000f,    1.0000f,    1.0000f
};
const Word16 tdm_ratio_tabl_fx[TDM_NQ+1] /*Q15*/= 
{
	0 ,0 ,357 ,803 ,1416 ,2195 ,3129 ,4207 ,5420 ,6753 ,8192 ,9719 ,11321 ,12976 ,
    14670 ,16384 ,18097 ,19791 ,21446 ,23048 ,24575 ,26014 ,27347 ,28560 ,29638 ,30572 ,31351 ,31964 ,
    32410 ,32767 ,32767 ,32767 ,
};
const float tdm_den_ratio_tabl[TDM_NQ+1] = /*  1.0f/(2*LR_ratio*LR_ratio-2*LR_ratio+1) */
{
    1.0000f,    1.0000f,    1.0221f,    1.0501f,    1.0902f,    1.1429f,    1.2088f,    1.2884f,
+3 −0
Original line number Diff line number Diff line
@@ -95,13 +95,16 @@ extern const float ica_sincInterp6[];
 *----------------------------------------------------------------------------------*/

extern const float icbwe_gsMapping_tbl[];
extern const Word16 pow_10_icbwe_gsMapping_tbl_fx[];
extern const float icbwe_gsMappingDFT_tbl[];
extern const Word16 pow_10_icbwe_gsMappingDFT_tbl_fx[];

/*----------------------------------------------------------------------------------*
 * TD Stereo ROM tables
 *----------------------------------------------------------------------------------*/

extern const float tdm_ratio_tabl[];
extern const Word16 tdm_ratio_tabl_fx[];
extern const float tdm_den_ratio_tabl[];
extern const int16_t tdm_bit_allc_tbl[5][6];

+199 −0
Original line number Diff line number Diff line
@@ -525,7 +525,54 @@ void Interpolate_allpass_steep(

    return;
}
#ifdef IVAS_FLOAT_FIXED
void Interpolate_allpass_steep_32(
    const Word32 *in_fx, /* i  : input array of size N        Qx */
    Word32 *mem_fx,      /* i/o: memory                       Qx */
    const int16_t N,     /* i  : number of input samples     */
    Word32 *out_fx       /* o  : output array of size 2*N     Qx */
)
{
    int16_t n, k;
    Word32 temp_fx[ALLPASSSECTIONS_STEEP - 1];

    /* upper allpass filter chain */
    FOR( k = 0; k < N; k++ )
    {
        temp_fx[0] = L_add(mem_fx[0] , Mpy_32_16_1( in_fx[k], AP2_STEEP_FX[0] ));
        mem_fx[0] = L_sub(in_fx[k] , Mpy_32_16_1( temp_fx[0], AP2_STEEP_FX[0] ));

        /* for better performance, unroll this loop */
        FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
        {
            temp_fx[n] = L_add(mem_fx[n] , Mpy_32_16_1( temp_fx[n - 1], AP2_STEEP_FX[n] ));
            mem_fx[n] = L_sub(temp_fx[n - 1] , Mpy_32_16_1( temp_fx[n], AP2_STEEP_FX[n] ));
        }

        out_fx[2 * k + 1] = L_add(mem_fx[ALLPASSSECTIONS_STEEP - 1] , Mpy_32_16_1( temp_fx[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ));
        mem_fx[ALLPASSSECTIONS_STEEP - 1] = L_sub(temp_fx[ALLPASSSECTIONS_STEEP - 2] , Mpy_32_16_1( out_fx[2 * k + 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ));
    }

    /* lower allpass filter chain */
    FOR( k = 0; k < N; k++ )
    {
        temp_fx[0] = L_add(mem_fx[ALLPASSSECTIONS_STEEP] , Mpy_32_16_1( in_fx[k], AP1_STEEP_FX[0] ));
        mem_fx[ALLPASSSECTIONS_STEEP] = L_sub(in_fx[k] , Mpy_32_16_1( temp_fx[0], AP1_STEEP_FX[0] ));

        /* for better performance, unroll this loop */
        FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
        {
            temp_fx[n] = L_add(mem_fx[ALLPASSSECTIONS_STEEP + n] , Mpy_32_16_1( temp_fx[n - 1], AP1_STEEP_FX[n] ));
            mem_fx[ALLPASSSECTIONS_STEEP + n] = L_sub(temp_fx[n - 1] , Mpy_32_16_1( temp_fx[n], AP1_STEEP_FX[n] ));
        }

        out_fx[2 * k] = L_add(mem_fx[2 * ALLPASSSECTIONS_STEEP - 1] , Mpy_32_16_1( temp_fx[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ));
        mem_fx[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub(temp_fx[ALLPASSSECTIONS_STEEP - 2] , Mpy_32_16_1( out_fx[2 * k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ));
    }

    return;
}
#endif
/*-------------------------------------------------------------------*
 * Decimate_allpass_steep()
 *
@@ -613,7 +660,78 @@ void Decimate_allpass_steep(

    return;
}
#ifdef IVAS_FLOAT_FIXED
void Decimate_allpass_steep_fx32(
    const Word32 *in, /* i  : input array of size N                  Qx */
    Word32 *mem,      /* i/o: memory                                  Qx*/
    const Word16 N,   /* i  : number of input samples                 */
    Word32 *out       /* o  : output array of size N/2                Qx*/
)
{
    Word16 n, k;
    Word32 temp[ALLPASSSECTIONS_STEEP];

    /* upper allpass filter chain */
    FOR( k = 0; k < N / 2; k++ )
    {
        temp[0] = L_add( mem[0], Mpy_32_16_1( in[2 * k], AP1_STEEP_FX[0] ) );
        mem[0] = L_sub( in[2 * k], Mpy_32_16_1( temp[0], AP1_STEEP_FX[0] ) );

        temp[1] = L_add( mem[1], Mpy_32_16_1( temp[0], AP1_STEEP_FX[1] ) );
        mem[1] = L_sub( temp[0], Mpy_32_16_1( temp[1], AP1_STEEP_FX[1] ) );

        out[k] = L_add( mem[ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) );
        mem[ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) );
    }

    /* lower allpass filter chain */
    temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ) );
    mem[ALLPASSSECTIONS_STEEP] = L_sub( mem[2 * ALLPASSSECTIONS_STEEP], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) );

    /* for better performance, unroll this loop */
    FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
    {
        temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) );
        /*if ( fabs( temp[n] ) < 1e-12 )
        {
            temp[n] = sign( temp[n] ) * 1e-12f;
        }*/
        mem[ALLPASSSECTIONS_STEEP + 1] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) );
    }

    temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) );

    mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) );
    out[0] = L_add( out[0], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) );

    FOR( k = 1; k < N / 2; k++ )
    {
        temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( in[2 * k - 1], AP2_STEEP_FX[0] ) );
        mem[ALLPASSSECTIONS_STEEP] = L_sub( in[2 * k - 1], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) );

        /* for better performance, unroll this loop */
        FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
        {
            temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) );
            /*if ( fabs( temp[n] ) < 1e-12 )
            {
                temp[n] = sign( temp[n] ) * 1e-12f;
            }*/
            mem[ALLPASSSECTIONS_STEEP + n] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n - 1] ) );
        }

        temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) );
        mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) );
        out[k] = L_add( out[k], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) );
    }

    /* z^(-1) */
    mem[2 * ALLPASSSECTIONS_STEEP] = in[N - 1];
    move32();

    return;
}
#endif
/*-------------------------------------------------------------------*
 * interpolate_3_over_2_allpass()
 *
@@ -684,7 +802,88 @@ void interpolate_3_over_2_allpass(

    return;
}
#ifdef IVAS_FLOAT_FIXED
void interpolate_3_over_2_allpass_32(
    const Word32 *input, /* i  : input signal            Qx*/
    const int16_t len,   /* i  : number of input samples   */
    Word32 *out,         /* o  : output signal           Qx*/
    Word32 *mem          /* i/o: memory                  Qx*/
)
{
    int16_t i, loop_len;
    Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */
    Word32 out1_buff[L_FRAME32k * 3];
    Word32 *out1;
    Word32 mem_temp;
    const Word16 *filt_coeff = allpass_poles_3_ov_2;

    out1 = out1_buff;

    FOR( i = 0; i < len; i++ )
    {
        /* Upper branch */
        Vu[0] = L_add( mem[0], Mpy_32_16_1( ( input[i] - mem[1] ), filt_coeff[0] ) );
        Vu[1] = L_add( mem[1], Mpy_32_16_1( ( Vu[0] - mem[2] ), filt_coeff[1] ) );
        mem[3] = L_add( mem[2], Mpy_32_16_1( ( Vu[1] - mem[3] ), filt_coeff[2] ) );

        mem[1] = Vu[0];
        move32();
        mem[2] = Vu[1];
        move32();
        *out1++ = mem[3];
        move32();

        /* Middle branch */
        Vm[0] = L_add( mem[0], Mpy_32_16_1( ( input[i] - mem[4] ), filt_coeff[3] ) );
        Vm[1] = L_add( mem[4], Mpy_32_16_1( ( Vm[0] - mem[5] ), filt_coeff[4] ) );
        mem[6] = L_add( mem[5], Mpy_32_16_1( ( Vm[1] - mem[6] ), filt_coeff[5] ) );

        mem[4] = Vm[0];
        move32();
        mem[5] = Vm[1];
        move32();
        *out1++ = mem[6];
        move32();

        /* Lower branch */
        Vl[0] = L_add( mem[0], Mpy_32_16_1( ( input[i] - mem[7] ), filt_coeff[6] ) );
        Vl[1] = L_add( mem[7], Mpy_32_16_1( ( Vl[0] - mem[8] ), filt_coeff[7] ) );
        mem[9] = L_add( mem[8], Mpy_32_16_1( ( Vl[1] - mem[9] ), filt_coeff[8] ) );

        mem[0] = input[i];
        move32();
        mem[7] = Vl[0];
        move32();
        mem[8] = Vl[1];
        move32();
        *out1++ = mem[9];
        move32();
    }

    loop_len = shr( i_mult( len, 3 ), 1 );

    /*decimate by 2 and LPF*/
    FOR( i = 0; i < loop_len; i++ )
    {
        mem_temp = out1_buff[2 * i];
        move32();
        out[i] = L_add( Mpy_32_16_1( ( mem_temp + mem[10] ), 1550 ), Mpy_32_16_1( ( mem[11] + mem[14] ), -4965 ) );
        out[i] = L_add( out[i], Mpy_32_16_1( ( mem[12] + mem[13] ), 20125 ) );
        mem[10] = mem[11];
        move32();
        mem[11] = mem[12];
        move32();
        mem[12] = mem[13];
        move32();
        mem[13] = mem[14];
        move32();
        mem[14] = mem_temp;
        move32();
    }

    return;
}
#endif
/*-------------------------------------------------------------------*
 * decimate_2_over_3_allpass()
 *
Loading