Loading lib_com/mslvq_com_fx.c +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, Loading Loading @@ -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( Loading Loading @@ -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 */ Loading Loading @@ -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 */ Loading Loading @@ -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 ) ) { Loading Loading @@ -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 ) ) { Loading Loading @@ -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++ ) { Loading Loading @@ -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++ ) { Loading lib_com/options.h +1 −2 Original line number Diff line number Diff line Loading @@ -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 ############################ */ Loading Loading
lib_com/mslvq_com_fx.c +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, Loading Loading @@ -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( Loading Loading @@ -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 */ Loading Loading @@ -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 */ Loading Loading @@ -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 ) ) { Loading Loading @@ -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 ) ) { Loading Loading @@ -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++ ) { Loading Loading @@ -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++ ) { Loading
lib_com/options.h +1 −2 Original line number Diff line number Diff line Loading @@ -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 ############################ */ Loading