Loading lib_enc/tcx_utils_enc_fx.c +62 −131 Original line number Diff line number Diff line Loading @@ -2399,6 +2399,7 @@ void tcx_noise_factor_fx( *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); } void tcx_noise_factor_ivas_fx( Word32 *x_orig, /* i: unquantized mdct coefficients */ Word16 x_orig_e, /* i: exponent */ Loading @@ -2415,8 +2416,9 @@ void tcx_noise_factor_ivas_fx( Word16 element_mode /* i: element mode */ ) { Word16 i, k = 0, maxK, segmentOffset; Word16 i, k, win, segmentOffset; Word32 sqErrorNrg, n; Word64 sqErrorNrg64; Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1; Word32 accu1, accu2, tmp32; Word16 tmp1, tmp2, s; Loading @@ -2427,7 +2429,6 @@ void tcx_noise_factor_ivas_fx( Flag Overflow = 0; move32(); #endif move16(); assert( nTransWidth <= 16 ); Loading @@ -2436,8 +2437,10 @@ void tcx_noise_factor_ivas_fx( nTransWidth_1 = sub( nTransWidth, 1 ); /*Adjust noise filling level*/ sqErrorNrg = L_deposit_l( 0 ); n = L_deposit_l( 0 ); sqErrorNrg64 = 0; move64(); n = 0; move32(); /* get inverse frame length */ tmp1 = getInvFrameLen( L_frame ); Loading @@ -2463,15 +2466,13 @@ void tcx_noise_factor_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */ { segmentOffset = i; maxK = 1; move16(); move16(); } ELSE { /* find last nonzero line below iFirstLine, use it as start offset */ tmp1 = shr( iFirstLine, 1 ); FOR( i = iFirstLine; i > tmp1; i-- ) FOR( ; i > tmp1; i-- ) { IF( sqQ[i] != 0 ) { Loading @@ -2484,16 +2485,6 @@ void tcx_noise_factor_ivas_fx( inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); } /* initialize left (k) and right (maxK) non-zero neighbor pointers */ k = 0; move16(); FOR( maxK = 1; maxK < nTransWidth; maxK++ ) { IF( sqQ[i + maxK] != 0 ) { BREAK; } } i = add( i, 1 ); segmentOffset = i; move16(); Loading @@ -2501,17 +2492,20 @@ void tcx_noise_factor_ivas_fx( IF( LE_16( nTransWidth, 3 ) ) { accu1 = L_deposit_l( 0 ); accu2 = L_deposit_l( 0 ); xMax = L_deposit_l( 0 ); accu1 = 0; move32(); accu2 = 0; move32(); xMax = 0; move32(); FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k++ ) FOR( k = i & 0xFFFE; k < lowpassLine; k++ ) { xMax = L_max( xMax, L_abs( x_orig[k] ) ); } s = sub( norm_l( xMax ), 4 ); FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k += 2 ) FOR( k = i & 0xFFFE; k < lowpassLine; k += 2 ) { /* even-index bins, left sub-win */ tmp1 = round_fx( L_shl( x_orig[k], s ) ); Loading @@ -2524,13 +2518,15 @@ void tcx_noise_factor_ivas_fx( k = 0; move16(); IF( accu1 == 0 ) if ( accu1 == 0 ) { accu1 = L_deposit_l( 1 ); accu1 = 1; move32(); } IF( accu2 == 0 ) if ( accu2 == 0 ) { accu2 = L_deposit_l( 1 ); accu2 = 1; move32(); } att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s ); Loading @@ -2545,19 +2541,19 @@ void tcx_noise_factor_ivas_fx( move16(); } accu1 = L_deposit_l( 0 ); win = 0; move16(); tmp1 = sub( lowpassLine, nTransWidth ); FOR( ; i <= tmp1; i++ ) FOR( ; i < lowpassLine; i++ ) { inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ IF( sqQ[i] != 0 ) /* current line is not zero, so reset pointers */ { IF( win > 0 ) { k = sub( i, segmentOffset ); IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ { IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); Loading Loading @@ -2590,58 +2586,35 @@ void tcx_noise_factor_ivas_fx( n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } } sqErrorNrg = L_add( sqErrorNrg, accu1 ); accu1 = L_deposit_l( 0 ); /* segment ended here, so reset segment sum */ k = 0; move16(); } FOR( ; maxK < nTransWidth; maxK++ ) FOR( k = segmentOffset; k < i - win; k++ ) { IF( sqQ[i + maxK] != 0 ) sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); sqQ[k] = 0; move32(); } FOR( ; win > 0; win-- ) { BREAK; sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); sqQ[k++] = 0; move32(); } } segmentOffset = add( i, 1 ); /* new segment might start at next line */ } ELSE /* current line is zero, so update pointers & segment sum */ { IF( LT_16( k, nTransWidth ) ) IF( LT_16( win, nTransWidth ) ) { k = add( k, 1 ); win = add( win, 1 ); } tmp2 = sub( maxK, nTransWidth ); test(); IF( tmp2 < 0 && NE_16( element_mode, IVAS_CPE_MDCT ) ) { maxK = sub( maxK, 1 ); } test(); IF( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) ) { maxK = sub( nTransWidth, 1 ); } /* update segment sum: magnitudes scaled by smoothing function */ /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); sqQ[i] = L_shl( Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ), inv_gain2_e ); move32(); } } FOR( ; i < lowpassLine; i++ ) { inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */ { k = sub( i, segmentOffset ); IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ { IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); Loading Loading @@ -2674,71 +2647,27 @@ void tcx_noise_factor_ivas_fx( n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } } sqErrorNrg = L_add( sqErrorNrg, accu1 ); } segmentOffset = add( i, 1 ); /* no new segments since maxK remains 1 */ } ELSE /* current line is zero, so update pointers & energy sum */ { IF( LT_16( k, nTransWidth ) ) FOR( k = segmentOffset; k < i - win; k++ ) { k = add( k, 1 ); } IF( LT_16( maxK, nTransWidth ) ) { maxK = sub( maxK, 1 ); } /* update segment sum: magnitudes scaled by smoothing function */ /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); } } k = sub( i, segmentOffset ); IF( k > 0 ) /* add last segment sum to sum of segment magnitudes */ { IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); IF( tmp2 > 0 ) { n = L_msu( n, k, (Word16) 0x8000 ); } IF( tmp2 > 0 ) { n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); } IF( tmp2 <= 0 ) { n = L_mac( n, int_sqr[k], c2 ); } } ELSE { tmp2 = sub( k, 12 ); IF( tmp2 > 0 ) { n = L_msu( n, k, (Word16) 0x8000 ); sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); sqQ[k] = 0; move32(); } IF( tmp2 > 0 ) FOR( ; win > 0; win-- ) { n = L_sub( n, 0x70000 ); } IF( tmp2 <= 0 ) { n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); sqQ[k++] = 0; move32(); } sqErrorNrg = L_add( sqErrorNrg, accu1 ); } /* noise level factor: average of segment magnitudes of noise bins */ IF( n > 0 ) { tmp2 = W_norm( sqErrorNrg64 ); sqErrorNrg = W_extract_l( W_shr( sqErrorNrg64, sub( 32, tmp2 ) ) ); // 31 - (x_orig_e - 1) - 32 + tmp2 tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); s = add( add( add( s, x_orig_e ), inv_gain2_e ), 7 - 15 ); s = add( add( add( x_orig_e, sub( 31, tmp2 ) ), -15 ), s ); BASOP_SATURATE_WARNING_OFF_EVS; tmp1 = shl_o( tmp1, s, &Overflow ); BASOP_SATURATE_WARNING_ON_EVS; Loading @@ -2762,8 +2691,10 @@ void tcx_noise_factor_ivas_fx( move16(); *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); move16(); } void tcx_encoder_memory_update_fx( Word16 *wsig, /* i : target weighted signal */ Word16 *xn_buf, /* i/o: mdct output buffer/time domain weigthed synthesis */ Loading Loading
lib_enc/tcx_utils_enc_fx.c +62 −131 Original line number Diff line number Diff line Loading @@ -2399,6 +2399,7 @@ void tcx_noise_factor_fx( *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); } void tcx_noise_factor_ivas_fx( Word32 *x_orig, /* i: unquantized mdct coefficients */ Word16 x_orig_e, /* i: exponent */ Loading @@ -2415,8 +2416,9 @@ void tcx_noise_factor_ivas_fx( Word16 element_mode /* i: element mode */ ) { Word16 i, k = 0, maxK, segmentOffset; Word16 i, k, win, segmentOffset; Word32 sqErrorNrg, n; Word64 sqErrorNrg64; Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1; Word32 accu1, accu2, tmp32; Word16 tmp1, tmp2, s; Loading @@ -2427,7 +2429,6 @@ void tcx_noise_factor_ivas_fx( Flag Overflow = 0; move32(); #endif move16(); assert( nTransWidth <= 16 ); Loading @@ -2436,8 +2437,10 @@ void tcx_noise_factor_ivas_fx( nTransWidth_1 = sub( nTransWidth, 1 ); /*Adjust noise filling level*/ sqErrorNrg = L_deposit_l( 0 ); n = L_deposit_l( 0 ); sqErrorNrg64 = 0; move64(); n = 0; move32(); /* get inverse frame length */ tmp1 = getInvFrameLen( L_frame ); Loading @@ -2463,15 +2466,13 @@ void tcx_noise_factor_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */ { segmentOffset = i; maxK = 1; move16(); move16(); } ELSE { /* find last nonzero line below iFirstLine, use it as start offset */ tmp1 = shr( iFirstLine, 1 ); FOR( i = iFirstLine; i > tmp1; i-- ) FOR( ; i > tmp1; i-- ) { IF( sqQ[i] != 0 ) { Loading @@ -2484,16 +2485,6 @@ void tcx_noise_factor_ivas_fx( inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); } /* initialize left (k) and right (maxK) non-zero neighbor pointers */ k = 0; move16(); FOR( maxK = 1; maxK < nTransWidth; maxK++ ) { IF( sqQ[i + maxK] != 0 ) { BREAK; } } i = add( i, 1 ); segmentOffset = i; move16(); Loading @@ -2501,17 +2492,20 @@ void tcx_noise_factor_ivas_fx( IF( LE_16( nTransWidth, 3 ) ) { accu1 = L_deposit_l( 0 ); accu2 = L_deposit_l( 0 ); xMax = L_deposit_l( 0 ); accu1 = 0; move32(); accu2 = 0; move32(); xMax = 0; move32(); FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k++ ) FOR( k = i & 0xFFFE; k < lowpassLine; k++ ) { xMax = L_max( xMax, L_abs( x_orig[k] ) ); } s = sub( norm_l( xMax ), 4 ); FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k += 2 ) FOR( k = i & 0xFFFE; k < lowpassLine; k += 2 ) { /* even-index bins, left sub-win */ tmp1 = round_fx( L_shl( x_orig[k], s ) ); Loading @@ -2524,13 +2518,15 @@ void tcx_noise_factor_ivas_fx( k = 0; move16(); IF( accu1 == 0 ) if ( accu1 == 0 ) { accu1 = L_deposit_l( 1 ); accu1 = 1; move32(); } IF( accu2 == 0 ) if ( accu2 == 0 ) { accu2 = L_deposit_l( 1 ); accu2 = 1; move32(); } att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s ); Loading @@ -2545,19 +2541,19 @@ void tcx_noise_factor_ivas_fx( move16(); } accu1 = L_deposit_l( 0 ); win = 0; move16(); tmp1 = sub( lowpassLine, nTransWidth ); FOR( ; i <= tmp1; i++ ) FOR( ; i < lowpassLine; i++ ) { inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ IF( sqQ[i] != 0 ) /* current line is not zero, so reset pointers */ { IF( win > 0 ) { k = sub( i, segmentOffset ); IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ { IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); Loading Loading @@ -2590,58 +2586,35 @@ void tcx_noise_factor_ivas_fx( n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } } sqErrorNrg = L_add( sqErrorNrg, accu1 ); accu1 = L_deposit_l( 0 ); /* segment ended here, so reset segment sum */ k = 0; move16(); } FOR( ; maxK < nTransWidth; maxK++ ) FOR( k = segmentOffset; k < i - win; k++ ) { IF( sqQ[i + maxK] != 0 ) sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); sqQ[k] = 0; move32(); } FOR( ; win > 0; win-- ) { BREAK; sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); sqQ[k++] = 0; move32(); } } segmentOffset = add( i, 1 ); /* new segment might start at next line */ } ELSE /* current line is zero, so update pointers & segment sum */ { IF( LT_16( k, nTransWidth ) ) IF( LT_16( win, nTransWidth ) ) { k = add( k, 1 ); win = add( win, 1 ); } tmp2 = sub( maxK, nTransWidth ); test(); IF( tmp2 < 0 && NE_16( element_mode, IVAS_CPE_MDCT ) ) { maxK = sub( maxK, 1 ); } test(); IF( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) ) { maxK = sub( nTransWidth, 1 ); } /* update segment sum: magnitudes scaled by smoothing function */ /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); sqQ[i] = L_shl( Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ), inv_gain2_e ); move32(); } } FOR( ; i < lowpassLine; i++ ) { inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */ { k = sub( i, segmentOffset ); IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ { IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); Loading Loading @@ -2674,71 +2647,27 @@ void tcx_noise_factor_ivas_fx( n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } } sqErrorNrg = L_add( sqErrorNrg, accu1 ); } segmentOffset = add( i, 1 ); /* no new segments since maxK remains 1 */ } ELSE /* current line is zero, so update pointers & energy sum */ { IF( LT_16( k, nTransWidth ) ) FOR( k = segmentOffset; k < i - win; k++ ) { k = add( k, 1 ); } IF( LT_16( maxK, nTransWidth ) ) { maxK = sub( maxK, 1 ); } /* update segment sum: magnitudes scaled by smoothing function */ /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); } } k = sub( i, segmentOffset ); IF( k > 0 ) /* add last segment sum to sum of segment magnitudes */ { IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); IF( tmp2 > 0 ) { n = L_msu( n, k, (Word16) 0x8000 ); } IF( tmp2 > 0 ) { n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); } IF( tmp2 <= 0 ) { n = L_mac( n, int_sqr[k], c2 ); } } ELSE { tmp2 = sub( k, 12 ); IF( tmp2 > 0 ) { n = L_msu( n, k, (Word16) 0x8000 ); sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], nTransWidth ) ); sqQ[k] = 0; move32(); } IF( tmp2 > 0 ) FOR( ; win > 0; win-- ) { n = L_sub( n, 0x70000 ); } IF( tmp2 <= 0 ) { n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); } sqErrorNrg64 = W_add( sqErrorNrg64, W_mult_32_16( sqQ[k], win ) ); sqQ[k++] = 0; move32(); } sqErrorNrg = L_add( sqErrorNrg, accu1 ); } /* noise level factor: average of segment magnitudes of noise bins */ IF( n > 0 ) { tmp2 = W_norm( sqErrorNrg64 ); sqErrorNrg = W_extract_l( W_shr( sqErrorNrg64, sub( 32, tmp2 ) ) ); // 31 - (x_orig_e - 1) - 32 + tmp2 tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); s = add( add( add( s, x_orig_e ), inv_gain2_e ), 7 - 15 ); s = add( add( add( x_orig_e, sub( 31, tmp2 ) ), -15 ), s ); BASOP_SATURATE_WARNING_OFF_EVS; tmp1 = shl_o( tmp1, s, &Overflow ); BASOP_SATURATE_WARNING_ON_EVS; Loading @@ -2762,8 +2691,10 @@ void tcx_noise_factor_ivas_fx( move16(); *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); move16(); } void tcx_encoder_memory_update_fx( Word16 *wsig, /* i : target weighted signal */ Word16 *xn_buf, /* i/o: mdct output buffer/time domain weigthed synthesis */ Loading