Commit 6eef831c authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch 'ivas_filters_fxd_conv' into 'main'

Few functions in ivas_filters.c file converted to fixed point.

See merge request !59
parents 230afc5d d0ec34f4
Loading
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1463,6 +1463,8 @@ typedef enum
#define IVAS_LFE_ABS_SUM_FLT_THR                (0.000001f)
#define IVAS_ZERO_PAD_LEN_MULT_FAC              (0.5f)

#define IVAS_ZERO_PAD_LEN_MULT_FAC_fx             16384       //0.5*Q15

/* LFE PLC */
#define LFE_PLC_BUFLEN                          240
#define LFE_PLC_FS                              1600
+202 −2
Original line number Diff line number Diff line
@@ -36,7 +36,9 @@
#include "ivas_cnst.h"
#include "ivas_stat_com.h"
#include "wmc_auto.h"

#ifdef IVAS_FLOAT_FIXED
#include "ivas_rom_com.h"
#endif

/*------------------------------------------------------------------------------------------*
 * Local functions declaration
@@ -44,6 +46,7 @@

static void ivas_iir_2_filter( ivas_filters_process_state_t *filter_state, float *pIn_Out, const int16_t length, const int16_t stage );

static void ivas_iir_2_filter_fx(ivas_filters_process_state_t *filter_state, Word32 *pIn_Out_fx, const Word16 length, const Word16 stage, Word16 q_fcator);

/*-----------------------------------------------------------------------------------------*
 * Function ivas_filters_init()
@@ -96,6 +99,74 @@ void ivas_filters_init(
    return;
}

#ifdef IVAS_FLOAT_FIXED
void ivas_filters_init_fx(
    ivas_filters_process_state_t *filter_state, /* i/o: filter state handle     */
    const Word32 *filt_coeff_fx,                    /* i  : filter coefficients     */
    const Word16 order)                       /* i  : filter order            */
{
    Word16 i;
    filter_state->order = order;

    IF(EQ_16(order, IVAS_FILTER_ORDER_2) || EQ_16(order, IVAS_FILTER_ORDER_1))
    {
        filter_state->filt_len = add(order, 1);

        FOR(i = 0; i < IVAS_BIQUAD_FILT_LEN; i++)
        {
            filter_state->num_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[i];
            filter_state->den_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[add(i, IVAS_BIQUAD_FILT_LEN)];

            filter_state->num[IVAS_FILTER_STAGE_0][i] = WORD322FL_SCALE(filter_state->num_fx[IVAS_FILTER_STAGE_0][i], 1);
            filter_state->den[IVAS_FILTER_STAGE_0][i] = WORD322FL_SCALE(filter_state->den_fx[IVAS_FILTER_STAGE_0][i], 1);
        }

        filter_state->state_fx[0][0] = 0;
        filter_state->state_fx[0][1] = 0;
        filter_state->state_fx[0][2] = 0;

        filter_state->state[0][0] = WORD322FL_SCALE(filter_state->state_fx[0][0], 1);
        filter_state->state[0][1] = WORD322FL_SCALE(filter_state->state_fx[0][1], 1);
        filter_state->state[0][2] = WORD322FL_SCALE(filter_state->state_fx[0][2], 1);
    }
    ELSE
    {
        filter_state->filt_len = IVAS_BIQUAD_FILT_LEN;

        FOR(i = 0; i < IVAS_BIQUAD_FILT_LEN; i++)
        {

            filter_state->num_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[i];
            filter_state->den_fx[IVAS_FILTER_STAGE_0][i] = filt_coeff_fx[add(i, IVAS_BIQUAD_FILT_LEN)];
            filter_state->num_fx[IVAS_FILTER_STAGE_1][i] = filt_coeff_fx[add(i, i_mult(IVAS_BIQUAD_FILT_LEN,2))];
            filter_state->den_fx[IVAS_FILTER_STAGE_1][i] = filt_coeff_fx[add(i, i_mult(IVAS_BIQUAD_FILT_LEN, 3))];

            filter_state->num[IVAS_FILTER_STAGE_0][i] = WORD322FL_SCALE(filter_state->num_fx[IVAS_FILTER_STAGE_0][i], 1);
            filter_state->den[IVAS_FILTER_STAGE_0][i] = WORD322FL_SCALE(filter_state->den_fx[IVAS_FILTER_STAGE_0][i], 1);
            filter_state->num[IVAS_FILTER_STAGE_1][i] = WORD322FL_SCALE(filter_state->num_fx[IVAS_FILTER_STAGE_1][i], 1);
            filter_state->den[IVAS_FILTER_STAGE_1][i] = WORD322FL_SCALE(filter_state->den_fx[IVAS_FILTER_STAGE_1][i], 1);
        }

        filter_state->state_fx[0][0] = 0;
        filter_state->state_fx[0][1] = 0;
        filter_state->state_fx[0][2] = 0;
        filter_state->state_fx[1][0] = 0;
        filter_state->state_fx[1][1] = 0;
        filter_state->state_fx[1][2] = 0;

        filter_state->state[0][0] = WORD322FL_SCALE(filter_state->state_fx[0][0], 1);
        filter_state->state[0][1] = WORD322FL_SCALE(filter_state->state_fx[0][1], 1);
        filter_state->state[0][2] = WORD322FL_SCALE(filter_state->state_fx[0][2], 1);
        filter_state->state[1][0] = WORD322FL_SCALE(filter_state->state_fx[1][0], 1);
        filter_state->state[1][1] = WORD322FL_SCALE(filter_state->state_fx[1][1], 1);
        filter_state->state[1][2] = WORD322FL_SCALE(filter_state->state_fx[1][2], 1);
    }

    return;
}
#endif



/*-----------------------------------------------------------------------------------------*
 * Function ivas_filter_process()
@@ -129,6 +200,35 @@ void ivas_filter_process(
    return;
}

#ifdef IVAS_FLOAT_FIXED
void ivas_filter_process_fx(
    ivas_filters_process_state_t *filter_state, /* i/o: filter state handle             */
    Word32 *pIn_Out_fx,                             /* i/o: signal subject to filtering     */
    const Word16 length,                        /* i  : filter order                    */
    Word16 q_factor
)
{
    SWITCH(filter_state->order)
    {
        case IVAS_FILTER_ORDER_1:
        case IVAS_FILTER_ORDER_2:
            ivas_iir_2_filter_fx(filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q_factor);
            BREAK;
        case IVAS_FILTER_ORDER_4:
            /* biquad-1 */
            ivas_iir_2_filter_fx(filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q_factor);
            /* biquad-2 */
            ivas_iir_2_filter_fx(filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_1, q_factor);
            BREAK;
        default:
            BREAK;
    }

    return;
}
#endif



/*-----------------------------------------------------------------------------------------*
 * Function ivas_iir_2_filter()
@@ -158,6 +258,106 @@ static void ivas_iir_2_filter(
                                                filter_state->den[stage][j] * pOut[i];
        }
    }

    return;
}

#ifdef IVAS_FLOAT_FIXED
static void ivas_iir_2_filter_fx(
    ivas_filters_process_state_t *filter_state,
    Word32 *pIn_Out_fx,
    const Word16 length,
    const Word16 stage,
    Word16 q_factor)
{
    Word16 i, j;

    Word32 *pIn_fx = pIn_Out_fx;
    Word32 *pOut_fx = pIn_Out_fx;
    Word32 tmp_pIn_buf_i_fx;

    Word32  L_tmp, L_tmp_1;
    Word64 L_tmp_2;
    Word16 L_tmp_q_factor, L_tmp_2_q_factor, L_tmp_3_q_factor, L_tmp_4_q_factor, L_tmp_5_q_factor, L_tmp_6_q_factor;

    Word16 q_factor_diff;

    Word16 q_factor_filter_num = 30;
    Word16 q_factor_filter_den = 30;

    FOR(i = 0; i < length; i++)
    {
        tmp_pIn_buf_i_fx = pIn_fx[i];

        /*L_tmp = Mpy_32_32(pIn_fx[i], filter_state->num_fx[stage][0]);*/

        L_tmp_q_factor = sub(add(q_factor, q_factor_filter_num), 31);

        IF(GE_16(L_tmp_q_factor, q_factor)) {
            q_factor_diff = sub(L_tmp_q_factor, q_factor);
            pOut_fx[i] = L_add((filter_state->state_fx[stage][0]), L_shr(Mpy_32_32(filter_state->num_fx[stage][0], pIn_fx[i]), q_factor_diff));
            L_tmp_2_q_factor = q_factor;
        }
        ELSE{
            q_factor_diff = sub(q_factor, L_tmp_q_factor);
            pOut_fx[i] = L_add(L_shr(filter_state->state_fx[stage][0], q_factor_diff), (Mpy_32_32(filter_state->num_fx[stage][0], pIn_fx[i])));
            pOut_fx[i] = L_shl(pOut_fx[i], q_factor_diff);
            L_tmp_2_q_factor = q_factor;

        }


        FOR(j = 1; j < filter_state->filt_len; j++)
        {
            /*L_tmp_1 = filter_state->num_fx[stage][j] * tmp_pIn_buf_i_fx;*/

            L_tmp_3_q_factor = sub(add(q_factor_filter_num, q_factor), 31);

            IF(GE_16(L_tmp_3_q_factor, q_factor)) {
                q_factor_diff = sub(L_tmp_3_q_factor, q_factor);
                L_tmp = L_add((filter_state->state_fx[stage][j]), L_shr(Mpy_32_32(filter_state->num_fx[stage][j], tmp_pIn_buf_i_fx), q_factor_diff));
                L_tmp_4_q_factor = q_factor;
            }
            ELSE{
                q_factor_diff = sub(q_factor, L_tmp_3_q_factor);
            L_tmp = L_add(L_shr(filter_state->state_fx[stage][j], q_factor_diff), (Mpy_32_32(filter_state->num_fx[stage][j], tmp_pIn_buf_i_fx)));
                L_tmp_4_q_factor = L_tmp_3_q_factor;

            }

            /*L_tmp_3 = filter_state->den_fx[stage][j] * pOut_fx[i];*/

            L_tmp_5_q_factor = sub(add(q_factor_filter_den, L_tmp_2_q_factor), 31);


            IF(GE_16(L_tmp_5_q_factor, L_tmp_4_q_factor)) {
                q_factor_diff = sub(L_tmp_5_q_factor, L_tmp_4_q_factor);
                L_tmp_1 = L_sub(L_tmp, L_shr(Mpy_32_32(filter_state->den_fx[stage][j], pOut_fx[i]), q_factor_diff));
                L_tmp_6_q_factor = L_tmp_4_q_factor;

            }
            ELSE{
                q_factor_diff = sub(L_tmp_4_q_factor, L_tmp_5_q_factor);
                L_tmp_1 = L_sub(L_shr(L_tmp, q_factor_diff), Mpy_32_32(filter_state->den_fx[stage][j], pOut_fx[i]));
                L_tmp_6_q_factor = L_tmp_5_q_factor;
            }

            IF(GE_16(L_tmp_6_q_factor, q_factor)) {
                q_factor_diff = sub(L_tmp_6_q_factor, q_factor);
                L_tmp_2 = W_shr((Word64)L_tmp_1, q_factor_diff);
            }
            ELSE{
                q_factor_diff = sub(q_factor, L_tmp_6_q_factor);
                L_tmp_2 = W_shl((Word64)L_tmp_1, q_factor_diff);
            }


            filter_state->state_fx[stage][j - 1] = W_extract_l(L_tmp_2);

            filter_state->state[stage][j - 1] = WORD322FL_SCALE(filter_state->state_fx[stage][j - 1], sub(31, q_factor));
        }

    }

}
#endif
+79 −9
Original line number Diff line number Diff line
@@ -96,6 +96,56 @@ void ivas_lfe_lpf_select_filt_coeff(
    return;
}

#ifdef IVAS_FLOAT_FIXED
void ivas_lfe_lpf_select_filt_coeff_fx(
    const Word32 sampling_rate, /* i  : sampling rate          */
    const Word16 order,         /* i  : filter order           */
    const Word32 **ppFilt_coeff_fx   /* o  : filter coefficients    */
)
{
    SWITCH(order)
    {
        case IVAS_FILTER_ORDER_2:
            SWITCH(sampling_rate)
            {
                case 16000:
                    *ppFilt_coeff_fx = ivas_lpf_2_butter_16k_fx;
                    BREAK;
                case 32000:
                    *ppFilt_coeff_fx = ivas_lpf_2_butter_32k_fx;
                    BREAK;
                case 48000:
                    *ppFilt_coeff_fx = ivas_lpf_2_butter_48k_fx;
                    BREAK;
                default:
                    BREAK;
            }
            BREAK;
        case IVAS_FILTER_ORDER_4:
            SWITCH(sampling_rate)
            {
                case 16000:
                    *ppFilt_coeff_fx = ivas_lpf_4_butter_16k_sos_fx;
                    BREAK;
                case 32000:
                    *ppFilt_coeff_fx = ivas_lpf_4_butter_32k_sos_fx;
                    BREAK;
                case 48000:
                    *ppFilt_coeff_fx = ivas_lpf_4_butter_48k_sos_fx;
                    BREAK;
                default:
                    BREAK;
            }
            BREAK;
        default:
            assert(!"Unsupported LFE Filter order");
    }

    return;
}
#endif



/*-----------------------------------------------------------------------------------------*
 * Function ivas_lfe_window_init()
@@ -105,35 +155,55 @@ void ivas_lfe_lpf_select_filt_coeff(

void ivas_lfe_window_init(
    LFE_WINDOW_HANDLE hLFEWindow, /* i/o: LFE window handle           */
    const int32_t sampling_rate,  /* i  : sampling rate               */
    const int16_t frame_len       /* i  : frame length in samples     */
    const Word32 sampling_rate,  /* i  : sampling rate               */
    const Word16 frame_len       /* i  : frame length in samples     */
)
{
    /* Set window coefficients */
    if ( sampling_rate == 48000 )
    IF ( EQ_32(sampling_rate, 48000 ))
    {
        hLFEWindow->pWindow_coeffs = ivas_lfe_window_coeff_48k;
#ifdef IVAS_FLOAT_FIXED
        hLFEWindow->pWindow_coeffs_fx = ivas_lfe_window_coeff_48k_fx;
#endif

    }
    else if ( sampling_rate == 32000 )
    ELSE IF ( EQ_32(sampling_rate, 32000) )
    {
        hLFEWindow->pWindow_coeffs = ivas_lfe_window_coeff_32k;
#ifdef IVAS_FLOAT_FIXED
        hLFEWindow->pWindow_coeffs_fx = ivas_lfe_window_coeff_32k_fx;
#endif

    }
    else if ( sampling_rate == 16000 )
    ELSE IF ( EQ_32(sampling_rate, 16000) )
    {
        hLFEWindow->pWindow_coeffs = ivas_lfe_window_coeff_16k;
#ifdef IVAS_FLOAT_FIXED
        hLFEWindow->pWindow_coeffs_fx = ivas_lfe_window_coeff_16k_fx;
#endif

    }
    else
    ELSE
    {
        assert( !"8kHz LFE Window not supported" );
    }

    /* 10ms stride, MDCT will be done in two iterations */
    hLFEWindow->dct_len = frame_len >> 1;
    hLFEWindow->dct_len = shr(frame_len, 1);

    /* 8ms of latency */
    hLFEWindow->fade_len = NS2SA(sampling_rate, IVAS_LFE_FADE_NS);

#ifdef IVAS_FLOAT_FIXED
    /* 8ms of latency */
    hLFEWindow->zero_pad_len = (mult(IVAS_ZERO_PAD_LEN_MULT_FAC_fx, sub(hLFEWindow->dct_len, hLFEWindow->fade_len)));
    hLFEWindow->full_len = add(add(hLFEWindow->zero_pad_len, hLFEWindow->fade_len), hLFEWindow->dct_len);
#else
    hLFEWindow->zero_pad_len = (int16_t)(IVAS_ZERO_PAD_LEN_MULT_FAC * (hLFEWindow->dct_len - hLFEWindow->fade_len));
    hLFEWindow->full_len = hLFEWindow->zero_pad_len + hLFEWindow->fade_len + hLFEWindow->dct_len;
#endif



    return;
}
+28 −2
Original line number Diff line number Diff line
@@ -5718,8 +5718,8 @@ void ivas_lfe_tdplc(

void ivas_lfe_window_init(
    LFE_WINDOW_HANDLE hLFEWindow,                               /* i/o: LFE window handle                       */
    const int32_t sampling_rate,                                /* i  : sampling rate                           */
    const int16_t frame_len                                     /* i  : frame length in samples                 */
    const Word32 sampling_rate,                                /* i  : sampling rate                           */
    const Word16 frame_len                                     /* i  : frame length in samples                 */
);

void ivas_lfe_lpf_select_filt_coeff(
@@ -5728,18 +5728,44 @@ void ivas_lfe_lpf_select_filt_coeff(
    const float **ppFilt_coeff                                  /* o  : filter coefficients                     */
);

#ifdef IVAS_FLOAT_FIXED
void ivas_lfe_lpf_select_filt_coeff_fx(
    const Word32 sampling_rate,                                /* i  : sampling rate                           */
    const Word16 order,                                        /* i  : filter order                            */
    const Word32 **ppFilt_coeff_fx                             /* o  : filter coefficients                     */
);
#endif


void ivas_filters_init( 
    ivas_filters_process_state_t *filter_state,                 /* i/o: filter state handle                     */
    const float *filt_coeff,                                    /* i  : filter coefficients                     */
    const int16_t order                                         /* i  : filter order                            */
);

#ifdef IVAS_FLOAT_FIXED
void ivas_filters_init_fx(
    ivas_filters_process_state_t *filter_state,                 /* i/o: filter state handle                     */
    const Word32 *filt_coeff,                                   /* i  : filter coefficients                     */
    const Word16 order                                          /* i  : filter order                            */
);
#endif


void ivas_filter_process( 
    ivas_filters_process_state_t *filter_state,                 /* i/o: filter state handle                     */
    float *pIn_Out,                                             /* i  : signal subject to filtering             */
    const int16_t length                                        /* i  : filter order                            */
);

#ifdef IVAS_FLOAT_FIXED
void ivas_filter_process_fx(
    ivas_filters_process_state_t *filter_state,                 /* i/o: filter state handle                     */
    Word32 *pIn_Out_fx,                                         /* i  : signal subject to filtering             */
    const Word16 length,                                        /* i  : filter order                            */
    Word16 q_factor
);
#endif

/*----------------------------------------------------------------------------------*
 * OSBA prototypes
+69 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading