Commit cce54cc5 authored by Dominik Weckbecker's avatar Dominik Weckbecker 💬
Browse files

rewrite DirAC gain calculation with variable Q

parent 33aefa01
Loading
Loading
Loading
Loading
+80 −10
Original line number Diff line number Diff line
@@ -2578,11 +2578,35 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx(
            {
                g1 = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 );                                                                                        // Q31, (Q31, Q31) -> Q31
                g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_dir ) );                                                                                                                // (Q31, p_gains_dir_q) -> p_gains_dir_q
                g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ) );                                                                                                    // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
#ifdef FIX_867                                                                                                                                                                              // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
                g2 = L_max( g2, Mpy_32_32( 1825361101 /* 0.85f in Q31 */, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev[ch_idx * num_freq_bands + l] ) ) );           // p_gains_dir_q
                g2 = L_min( g2, Mpy_32_32( 1234803098 /* 1.15f in Q30 */, L_shl( 1, add( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev[ch_idx * num_freq_bands + l], 1 ) ) ) ); // p_gains_dir_q
				//g2 = L_add_sat(g2, Mpy_32_32(g1, (*(p_cy_cross_dir_smooth++))));  // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
				
				Word32 tmp1 = L_shr(g2, 1);
				Word16 tmp1_q = sub(h_dirac_output_synthesis_state.gains_dir_prev_q[ch_idx*num_freq_bands + l], 1);

				Word32 tmp2 = L_shr(Mpy_32_32(g1, (*(p_cy_cross_dir_smooth++))), 1);
				Word16 tmp2_q = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth[ch_idx*num_freq_bands + l], 1);

				IF(LT_16(tmp1_q, tmp2_q))
				{
					tmp2 = L_shr(tmp2, sub(tmp2_q, tmp1_q));
					tmp2_q = tmp1_q;
				}
				ELSE
				{
					tmp1 = L_shr(tmp1, sub(tmp1_q, tmp2_q));
					tmp1_q = tmp2_q;
				}

				g2 = L_add(tmp1, tmp2);
				
				g2 = L_max( g2, L_shr( 1825361101 /* 0.85f in Q31 */, sub(Q31, tmp1_q) ) );          // tmp_q1
                g2 = L_min( g2, L_shr( 1234803098 /* 1.15f in Q30 */, sub(Q30, tmp1_q) ) );          // tmp_q1

				g2 = L_shl( g2, sub(h_dirac_output_synthesis_state.gains_dir_prev_q[ch_idx*num_freq_bands + l], tmp1_q));

#else
				g2 = L_add_sat(g2, Mpy_32_32(g1, (*(p_cy_cross_dir_smooth++))));                                                                                            // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
                g2 = L_max( g2, Mpy_32_32( 1825361101 /* 0.85f in Q31 */, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ) );                        // p_gains_dir_q
                g2 = L_min( g2, Mpy_32_32( 1234803098 /* 1.15f in Q30 */, L_shl( 1, add( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 1 ) ) ) );              // p_gains_dir_q
#endif
@@ -2599,11 +2623,33 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx(
        {
            g1 = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31
            g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_dir ) );                         // (Q31, p_gains_dir_q) -> p_gains_dir_q
            g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ) );             // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
#ifdef FIX_867
            g2 = L_max( g2, W_extract_h( W_shl( W_mult_32_32( -DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev[ch_idx * num_freq_bands + l] ) ), Q5 ) ) ); // p_gains_dir_q
            g2 = L_min( g2, W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev[ch_idx * num_freq_bands + l] ) ), Q5 ) ) );  // p_gains_dir_q
			Word32 tmp1 = L_shr(g2, 1);
			Word16 tmp1_q = sub(h_dirac_output_synthesis_state.gains_dir_prev_q[ch_idx*num_freq_bands + l], 1);

			Word32 tmp2 = L_shr(Mpy_32_32(g1, (*(p_cy_cross_dir_smooth++))), 1);
			Word16 tmp2_q = sub(h_dirac_output_synthesis_state.q_cy_cross_dir_smooth[ch_idx*num_freq_bands + l], 1);

			IF(LT_16(tmp1_q, tmp2_q))
			{
				tmp2 = L_shr(tmp2, sub(tmp2_q, tmp1_q));
				tmp2_q = tmp1_q;
			}
			ELSE
			{
				tmp1 = L_shr(tmp1, sub(tmp1_q, tmp2_q));
				tmp1_q = tmp2_q;
			}

			g2 = L_add(tmp1, tmp2); //tmp1_q

			Word32 limit1 = L_shl(DIRAC_GAIN_LIMIT_Q26, sub(tmp1_q, Q26) ); // tmp1_q
            g2 = L_max( g2, L_negate(limit1) );
            g2 = L_min( g2, limit1 );

			g2 = L_shl(g2, sub(h_dirac_output_synthesis_state.gains_dir_prev_q[ch_idx*num_freq_bands + l], tmp1_q)); // p_gains_dir_q
#else
			g2 = L_add_sat(g2, Mpy_32_32(g1, (*(p_cy_cross_dir_smooth++))));             // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
            g2 = L_max( g2, W_extract_h( W_shl( W_mult_32_32( -DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ), Q5 ) ) );     // p_gains_dir_q
            g2 = L_min( g2, W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ), Q5 ) ) );      // p_gains_dir_q
#endif
@@ -2658,11 +2704,35 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx(
            g1 = POINT_1175_Q31; // Q31
            move32();
            g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_diff ) );                                                                                                                           // (Q31, p_gains_dir_q) -> p_gains_dir_q
            g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth++ ) ) ) );                                                                                                                // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
            g2 = L_max( g2, 0 );                                                                                                                                                                    // p_gains_diff_q
#ifdef FIX_867                                                                                                                                                                                      // p_gains_diff_q
            g2 = L_min( g2, W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev[ch_idx * num_freq_bands + l] ) ), Q5 ) ) ); // p_gains_diff_q
                                                                                                                                                                 // p_gains_diff_q
#ifdef FIX_867
			Word32 tmp1 = L_shr(g2, 1);
			Word16 tmp1_q = sub(h_dirac_output_synthesis_state.gains_diff_prev_q[ch_idx*num_freq_bands + l], 1);

			Word32 tmp2 = L_shr(Mpy_32_32(g1, (*(p_cy_auto_diff_smooth++))), 1);
			Word16 tmp2_q = sub(h_dirac_output_synthesis_state.q_cy_auto_diff_smooth[ch_idx*num_freq_bands + l], 1);

			IF(LT_16(tmp1_q, tmp2_q))
			{
				tmp2 = L_shr(tmp2, sub(tmp2_q, tmp1_q));
				tmp2_q = tmp1_q;
			}
			ELSE
			{
				tmp1 = L_shr(tmp1, sub(tmp1_q, tmp2_q));
				tmp1_q = tmp2_q;
			}

			g2 = L_add(tmp1, tmp2); //tmp1_q

			Word32 limit1 = L_shl(DIRAC_GAIN_LIMIT_Q26, sub(tmp1_q, Q26)); // tmp1_q
			g2 = L_max(g2, 0);
			g2 = L_min(g2, limit1);

			g2 = L_shl(g2, sub(h_dirac_output_synthesis_state.gains_diff_prev_q[ch_idx*num_freq_bands + l], tmp1_q)); // p_gains_dir_q
#else
			g2 = L_add_sat(g2, Mpy_32_32(g1, (*(p_cy_auto_diff_smooth++))));                                                                                                                // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
			g2 = L_max(g2, 0);
            g2 = L_min( g2, W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev ) ), Q5 ) ) );      // p_gains_diff_q
#endif
            *( p_gains_diff++ ) = g2; // p_gains_diff_q