diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index f422d5e50cc1a32f46d2241f54b5cb91d2e0769d..9b78b44d8ef9a157268317d6be2cd1813540fb9e 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9969,6 +9969,12 @@ Word16 usdequant_fx( /* Qx*/ const Word16 delta /* i: quantization step Qy*/ ); +Word32 usdequant32_fx( /* Qx*/ + const Word16 idx, /* i: quantizer index Q0*/ + const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/ + const Word32 delta /* i: quantization step Qy*/ +); + Word16 usquant_fx( /* o: index of the winning codeword */ const Word16 x, /* i: scalar value to quantize Qx*/ Word16 *xq, /* o: quantized value Qx*/ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 44a86b0ebd8e63ff6a8194689245f95b35378d4f..14a97a0340bcaf409b68e0d053a1bf66c0efabe2 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -284,6 +284,30 @@ Word16 usdequant_fx( /* Qx*/ return ( g ); } +Word32 usdequant32_fx( /* Qx*/ + const Word16 idx, /* i: quantizer index Q0*/ + const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/ + const Word32 delta /* i: quantization step Qx-1*/ +) +{ + Word32 g; + Word64 L_tmp; + + /*g = idx * delta + qlow;*/ + L_tmp = W_deposit32_l( qlow ); /*Qx */ + L_tmp = W_mac_32_16( L_tmp, delta, idx ); + IF( GE_64( L_tmp, MAX_32 ) ) + { + g = MAX_32; + move32(); + } + ELSE + { + g = W_extract_l( L_tmp ); /*Qx */ + } + return ( g ); +} + /*-------------------------------------------------------------------* * usquant() * diff --git a/lib_dec/ivas_masa_dec_fx.c b/lib_dec/ivas_masa_dec_fx.c index dec4d3465771077ed36773e1f56a2085d6eddbf3..36900867e47fe247992d9177597001a1312e22e8 100644 --- a/lib_dec/ivas_masa_dec_fx.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -2572,13 +2572,9 @@ static void create_masa_ext_out_meta_fx( { FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) { - IF( EQ_32( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], ONE_IN_Q30 ) ) - { - hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf]--; - } - UWord8 tmp = (UWord8) L_shr( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8 ); // Q8 + UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); // Q0 move16(); - extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q8 + extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q0 move16(); } } @@ -2637,12 +2633,8 @@ static void create_masa_ext_out_meta_fx( move16(); FOR( dir = 0; dir < numDirections; dir++ ) { - /* todo: not optimal, but less invasive */ - IF( EQ_32( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], ONE_IN_Q30 ) ) - { - hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf]--; - } - UWord8 tmp = (UWord8) L_shr( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8 ); // Q8 + + UWord8 tmp = (UWord8) W_extract_h( W_mult_32_16( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], UINT8_MAX << 1 ) ); // Q0 move16(); extOutMeta->diffuseToTotalRatio[sf][b_new] = (UWord8) sub( extOutMeta->diffuseToTotalRatio[sf][b_new], tmp ); // Q8 move16(); diff --git a/lib_dec/ivas_qmetadata_dec_fx.c b/lib_dec/ivas_qmetadata_dec_fx.c index 6e36c77657fd6e14953745bd19391bf7781d71c4..c1be6caf82100f929c75342db0b7101db89fc2b4 100644 --- a/lib_dec/ivas_qmetadata_dec_fx.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -72,8 +72,7 @@ static Word16 read_coherence_data_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVA static Word16 ivas_qmetadata_raw_decode_dir_512_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const Word16 nbands, const Word16 start_band, const SPHERICAL_GRID_DATA *sph_grid16 ); static Word16 read_surround_coherence( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData ); static ivas_error read_huf( Word16 *num_bits_read, const UWord16 *bitstream, UWord16 *out, const Word16 start_pos, const Word16 len, const Word16 *huff_code, const Word16 max_len ); -const Word16 inv_dfRatio_qsteps[9] = { 0, 0, ONE_IN_Q14, 0, 5461, 0, 0, 0, 2341 }; // Q14 - +const Word32 inv_dfRatio_qsteps[9] = { 0, 0, ONE_IN_Q30, 0, 357913941, 0, 0, 0, 153391689 }; // Q30 /*-----------------------------------------------------------------------* * Global function definitions @@ -223,7 +222,7 @@ Word16 ivas_qmetadata_dec_decode( IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) ) { Word32 diffRatio_fx, dir1ratio_fx, dir2ratio_fx; - Word16 dfRatio_fx; + Word32 dfRatio_fx; Word16 dfRatio_qsteps; diffRatio_fx = diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; // Q30 @@ -233,17 +232,25 @@ Word16 ivas_qmetadata_dec_decode( /* already encoded as total and ratios in HO-DirAC */ IF( hodirac_flag ) { - - dfRatio_fx = usdequant_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0 /* Q15 */, inv_dfRatio_qsteps[dfRatio_qsteps] ); // Q15 + dfRatio_fx = usdequant32_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0 /* Q15 */, inv_dfRatio_qsteps[dfRatio_qsteps] ); // Q31 dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx ); - dir2ratio_fx = L_shl( (Word32) dfRatio_fx, Q15 ); /*Q30*/ + dir2ratio_fx = L_shr( dfRatio_fx, 1 ); /*Q30*/ } ELSE { - dfRatio_fx = usdequant_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], shr( MAX_16, 1 ), shr( inv_dfRatio_qsteps[dfRatio_qsteps], 1 ) ); // Q15 + IF( EQ_16( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], sub( dfRatio_qsteps, 1 ) ) ) + { + dfRatio_fx = MAX_32; // Q31 + move16(); + dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx ); // Q30 + } + ELSE + { + dfRatio_fx = usdequant32_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], L_shr( MAX_32, 1 ), L_shr( inv_dfRatio_qsteps[dfRatio_qsteps], 1 ) ); // Q31 + dir1ratio_fx = Mpy_32_32( L_sub( ONE_IN_Q30, diffRatio_fx ), dfRatio_fx ); // Q30 + } - dir1ratio_fx = Mpy_32_16_1( L_sub( ONE_IN_Q30, diffRatio_fx ), dfRatio_fx ); // Q30 - dir2ratio_fx = L_sub( L_sub( ONE_IN_Q30, diffRatio_fx ), dir1ratio_fx ); // Q30 + dir2ratio_fx = L_sub( L_sub( ONE_IN_Q30, diffRatio_fx ), dir1ratio_fx ); // Q30 } /* Requantize the 1 - dirRatio separately for each direction to obtain inverted dirRatio index. These are used in further decoding. */