Commit 4595b00c authored by vasilache's avatar vasilache
Browse files

FIX 2492 decode_indexes

parent fdf639fa
Loading
Loading
Loading
Loading
Loading
+224 −7
Original line number Diff line number Diff line

/******************************************************************************************************

   (C) 2022-2026 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
@@ -53,11 +54,17 @@ static void put_value_fx( Word16 *cv, Word16 *p, Word16 val, Word16 dim, Word16
static void decode_leaders_fx( Word16 index, Word16 idx_lead, Word16 *cv );
static void idx2c_fx( Word16 n, Word16 *p, Word16 k, Word16 val );
static void divide_64_32_fx( Word16 *xs, Word32 y, Word32 *result, Word32 *rem );
#ifdef FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES
Word16 decode_indexes_fx( Word16 *index, Word16 no_bits, const Word16 *p_scales, Word16 *p_no_scales, Word32 *p_offset_scale1, Word32 *p_offset_scale2, Word16 *x_lvq, Word16 mode_glb, Word16 *scales_mslvq, Word16 use_ivas_mode, Word16 prediction_flag );
#else
static Word16 decode_indexes_fx( Word16 *index, Word16 no_bits, const Word16 *p_scales, Word16 *p_no_scales, Word32 *p_offset_scale1, Word32 *p_offset_scale2, Word16 *x_lvq, Word16 mode_glb, Word16 *scales );
static Word16 decode_indexes_ivas_fx( Word16 *index, const Word16 no_bits, const Word16 *p_scales, const Word16 prediction_flag, Word16 *x_lvq, const Word16 mode_glb, Word16 *scales_mslvq );
#endif
static Word32 divide_32_32_fx( Word32 y, Word32 x, Word32 *rem );
static Word16 divide_16_16_fx( Word16 y, Word16 x, Word16 *rem );
#ifndef FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES
static Word16 decode_indexes_ivas_fx( Word16 *index, const Word16 no_bits, const Word16 *p_scales, const Word16 prediction_flag, Word16 *x_lvq, const Word16 mode_glb, Word16 *scales_mslvq );
#endif

/* used in CNG-LP coding */
void permute_fx(
@@ -264,6 +271,193 @@ void init_offset_fx(
    return;
}

/* Unified decode_indexes function under compilation switch */
#ifdef FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES 
Word16 decode_indexes_fx(
    Word16 *index,
    Word16 no_bits,
    const Word16 *p_scales,
    Word16 *p_no_scales, /* NULL for IVAS mode */
    Word32 *p_offset_scale1, /* NULL for IVAS mode */
    Word32 *p_offset_scale2, /* NULL for IVAS mode */
    Word16 *x_lvq,
    Word16 mode_glb,
    Word16 *scales_mslvq,
    Word16 use_ivas_mode, /* 0: EVS, 1: IVAS */
    Word16 prediction_flag /* only used in IVAS mode */
)
{
    Word32 index1 = 0, index2 = 0;
    Word16 i, im1 = 0, idx_scale = 0;
    Word16 len_scales = shl(MAX_NO_SCALES, 1);
    Word16 no_modes = add(MAX_NO_SCALES, 1);
    Word32 offset_scale1[MAX_NO_SCALES + 1], offset_scale2[MAX_NO_SCALES + 1];
    Word16 max_scale_index;
    move32();
    move32();
    move16();
    move16();

    /* Setup local offset arrays for both modes */
    IF (use_ivas_mode) 
    {
        create_offset((UWord32*)offset_scale1, (UWord32*)offset_scale2, mode_glb, prediction_flag);
        max_scale_index = MAX_NO_SCALES;
        move16();
    }
    ELSE
    {
        Word16 tmp = i_mult2(mode_glb, no_modes);
        move16();
        /* Extract relevant row from 2D offset arrays into local arrays */
        FOR (i = 0; i <= MAX_NO_SCALES; i++)
        {
            offset_scale1[i] = p_offset_scale1[add(tmp, i)];
            move32();
            offset_scale2[i] = p_offset_scale2[add(tmp, i)];
            move32();
        }
        max_scale_index = p_no_scales[shl(mode_glb, 1)];
        move16();
    }

    /* Handle index[2] and index[1] zeroing for both modes */
    IF (LE_16(no_bits, shl(LEN_INDICE, 1))) 
    {
       index[2] = 0;
        move16();
        IF (LE_16(no_bits, LEN_INDICE)) 
        {
            index[1] = 0;
            move16();
        }
    }
    

    /* Safety check for bit errors (common) */
    FOR (i = 0; i < 3; i++) {
        IF (index[i] < 0 ) {
            set16_fx(x_lvq, 0, shl(LATTICE_DIM,1));
            scales_mslvq[0] = 0;
            move16();
            scales_mslvq[1] = 0;
            move16();
            index[i] = 0;
            move16();
            return 1;
        }
    }

    /* First subvector: unified logic using local offset arrays */
    IF (offset_scale2[max_scale_index] > 0) 
    {
        divide_64_32_fx(index, offset_scale2[max_scale_index], &index1, &index2);
    } 
    ELSE 
    {
        index1 = L_deposit_l(index[0]);
        move32();
        index2 = L_deposit_l(0);
        move32();
    }

    /* Common: handle index1 == 0 */
    IF (index1 == 0) 
    {
        FOR (i = 0; i < LATTICE_DIM; i++) 
        {
            x_lvq[i] = 0;
            move16();
        } 
        scales_mslvq[0] = 0;
        move16(); 
    } 
    ELSE 
    {
        /* safety check in case of bit errors */
        IF (GE_32(index1, offset_scale1[max_scale_index])) 
        {
            set16_fx(x_lvq, 0, shl(LATTICE_DIM,1));
            scales_mslvq[0] = 0;
            move16();
            scales_mslvq[1] = 0;
            move16();
            return 1;
        }

        /* Find idx_scale */
        i = 1;
        move16();
        WHILE (LE_16(i, max_scale_index) && GE_32(index1, offset_scale1[i])) 
        {
            i = add(i, 1);
        }
        idx_scale = sub(i, 1);
        move16();
        index1 = L_sub(index1, offset_scale1[idx_scale]);
        move32();

        /* Find idx_leader (common) */
        i = 1;
        move16();

        WHILE (GE_32(index1, table_no_cv_fx[i])) 
        {
            i = add(i, 1);
        }
        im1 = sub(i, 1);
        decode_comb_fx(L_sub(index1, table_no_cv_fx[im1]), x_lvq, im1);
        
        scales_mslvq[0] = p_scales[add(i_mult2(mode_glb, len_scales), idx_scale)];
        move16();
    }

    /* Second subvector (common structure, offset logic differs) */
    IF (index2 == 0) {
        FOR (i = LATTICE_DIM; i < shl(LATTICE_DIM,1); i++) 
        {
            x_lvq[i] = 0;
            move16();
        }
        scales_mslvq[1] = 0;
        move16();
    } 
    ELSE 
    {
        /* find the index for the scale/truncation */
        i = 1;
        move16();
        WHILE (GE_32(index2, offset_scale2[i])) 
        {
            i = add(i, 1);
        }
        idx_scale = sub(i, 1);
        move16();
        index2 = L_sub(index2, offset_scale2[idx_scale]);
        move32();
        /* Find leader (common) */
        i = 1;
        move16();
        IF (use_ivas_mode) {
            WHILE (GE_32(index2, (Word32)table_no_cv[i])) {
                i++;
            }
            decode_comb_fx((Word32)(index2 - table_no_cv[i - 1]), &x_lvq[LATTICE_DIM], i - 1);
            scales_mslvq[1] = p_scales[mode_glb * len_scales + MAX_NO_SCALES + idx_scale];
        } ELSE {
            WHILE (GE_32(index2, table_no_cv_fx[i])) {
                i = add(i, 1);
            }
            im1 = sub(i, 1);
            decode_comb_fx(index2 - table_no_cv_fx[im1], &x_lvq[LATTICE_DIM], im1);
            scales_mslvq[1] = p_scales[add(i_mult2(mode_glb, len_scales), add(MAX_NO_SCALES, idx_scale))];
        }
        move16();
    }

    return 0;
}
#else

static Word16 decode_indexes_fx(
    Word16 *index,           /* i  : LSF vector index, written as array of Word16 because it generally uses more than 16 bits */
@@ -567,6 +761,7 @@ static Word16 decode_indexes_ivas_fx(

    return 0;
}
 #endif

Word16 deindex_lvq_fx(
    Word16 *index,           /* i  : index to be decoded, as an array of 3 Word16             */
@@ -601,10 +796,17 @@ Word16 deindex_lvq_fx(
    }

    /* decode the lattice index into the lattice codevectors for the two subvectors */
#ifdef FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES
    ber_flag = decode_indexes_fx(index, no_bits, p_scales, p_no_scales, 
                                 p_offset_scale1, p_offset_scale2, 
                                 x_lvq, mode_glb, scales_mslvq,
                                 0, 0); /* use_ivas_mode=0, prediction_flag=0 */
                                 /* x_lvq is here Q1 */
#else
    ber_flag =
        decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1,
                           p_offset_scale2, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */

#endif

    IF( EQ_16( sf_flag, 1 ) )
    {
@@ -707,11 +909,14 @@ Word16 deindex_lvq_ivas_fx(
    create_offset( offset_scale1, offset_scale2, mode_glb, 1 - sf_flag );

    /* decode the lattice index into the lattice codevectors for the two subvectors */
    // ber_flag =
    //     decode_indexes_fx(index, no_bits, p_scales, p_no_scales, offset_scale1,
    //         offset_scale2, x_lvq, mode_glb, scales_mslvq); /* x_lvq is here Q1 */
#ifdef FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES
    ber_flag = decode_indexes_fx(index, no_bits, p_scales, NULL, 
                                 NULL, NULL, 
                                 x_lvq, mode_glb, scales_mslvq,
                                 1, 1 - sf_flag); /* use_ivas_mode=1 */ /* x_lvq is here Q1 */
#else
    ber_flag = decode_indexes_ivas_fx( index, no_bits, p_scales, 1 - sf_flag, x_lvq, mode_glb, scales_mslvq ); /* x_lvq is here Q1 */

#endif

    IF( EQ_16( sf_flag, 1 ) )
    {
@@ -799,8 +1004,15 @@ Word16 deindex_lvq_cng_fx(

    p_scales = &scales_fx[0][0];
    move16();
#ifdef FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES
    ber_flag = decode_indexes_fx(index, no_bits, p_scales, p_no_scales, 
                                 p_offset_scale1, p_offset_scale2, 
                                 x_lvq, mode_glb, scales_mslvq,
                                 0, 0); /* use_ivas_mode=0, prediction_flag=0 */
#else
    ber_flag =
        decode_indexes_fx( index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq );
#endif

    FOR( i = 0; i < LATTICE_DIM; i++ )
    {
@@ -857,10 +1069,15 @@ Word16 deindex_lvq_cng_ivas_fx(

    p_scales = &scales_ivas_fx[0][0];
    move16();
    // ber_flag =
    //     decode_indexes_fx(index, no_bits, p_scales, p_no_scales, p_offset_scale1, p_offset_scale2, x_lvq, mode_glb, scales_mslvq);
#ifdef FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES
    ber_flag = decode_indexes_fx(index, no_bits, p_scales, NULL, 
                                 NULL, NULL, 
                                 x_lvq, mode_glb, scales_mslvq,
                                 1, 0); /* use_ivas_mode=1, prediction_flag=0 */
#else
    ber_flag =
        decode_indexes_ivas_fx( index, no_bits, p_scales, 0, x_lvq, mode_glb, scales_mslvq );
#endif

    FOR( i = 0; i < LATTICE_DIM; i++ )
    {
+1 −2
Original line number Diff line number Diff line
@@ -89,8 +89,7 @@
#define FIX_2455_HARMONIZE_generate_comfort_noise_enc   /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */
#define FIX_2455_HARMONIZE_configureFdCngEnc            /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */
#define FIX_2463_EVS_BWE_LSF                            /* VA: basop issue 2463: harmonize calling of Quant_BWE_LSF_fx() */


#define FIX_2492_REMOVE_DUPLICATES_FOR_DECODE_INDEXES   /* Nokia: basop issue 2492: remove duplicates for decode_indexes() */
/* #################### End BE switches ################################## */

/* #################### Start NON-BE switches ############################ */