Commit f42a4d4d authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

[3GPP-Issue #824] Fixes crash in low level signal at 24.4 kbps with dtx enabled

[x] Fix - Qs for calculating scale of stereoDft not handled properly when first_SID_after_TD flag is set. scale is directly multiplied  with sqrt of cngNoiseLevel_hist and stored in cngNoiseLevel_upd.
parent 7c8eaa92
Loading
Loading
Loading
Loading
Loading
+34 −31
Original line number Diff line number Diff line
@@ -683,7 +683,7 @@ static void stereo_dft_generate_comfort_noise_fx(
    Decoder_State *st,                            /* i/o: Core coder decoder state                       */
    Word32 DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers                                    */
    Decoder_State *st1,                           /* i/o: Core coder decoder state secondary channel     */
    const Word16 targetGain,                      /* i  : ICA target gain                            */
    const Word16 targetGain,                      /* i  : ICA target gain                            Q13 */
    const Word16 chan,                            /* i  : channel number                                 */
    const Word16 output_frame,                    /* i  : output frame size                              */
    Word16 q_dft                                  /* i  : Q of DFT                                       */
@@ -710,10 +710,10 @@ static void stereo_dft_generate_comfort_noise_fx(
    Word16 b, q_cngNoiseLevel_upd, q_cngNoiseLevel;
    Word32 *pSideGain;
    Word16 gamma;
    Word16 c;
    Word16 c, c_e;
    Word16 scaleMS;
    Word16 scaleAvg;
    Word16 LR_ratio;
    Word16 scaleAvg, scaleAvg_e;
    Word16 LR_ratio; /* Q15 */
    Word32 factor;
    Word16 alpha;
    Word32 ftmp;
@@ -807,6 +807,8 @@ static void stereo_dft_generate_comfort_noise_fx(
        {
            scaleAvg = 0;
            move16();
            scaleAvg_e = 15;
            move16();
            FOR( b = 0; b < hStereoDft->nbands; b++ )
            {
                IF( LT_16( hStereoCng->cm_fx[b], 0x7333 ) )
@@ -827,36 +829,37 @@ static void stereo_dft_generate_comfort_noise_fx(
                    move16();
                }

                LR_ratio = extract_h( tdm_ratio_tabl_fx[hStereoCng->last_tdm_idx] );
                LR_ratio = extract_h( tdm_ratio_tabl_fx[hStereoCng->last_tdm_idx] ); /* Q15 */
                c = BASOP_Util_Divide3232_Scale(
                    L_add( L_mult( add( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ),
                                   add( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ) ),
                           L_shr( L_mult( gamma, gamma ), 4 ) ),
                    L_add( Mpy_32_32( sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ),
                    L_add( L_mult( sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ),
                                   sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ) ),
                           L_shr( L_mult( gamma, gamma ), 4 ) ),
                    &q_div );
                q_sqrt = q_div;
                    &c_e );
                q_sqrt = c_e;
                move16();
                sqrt_res = Sqrt16( mult( c, hStereoCng->cm_fx[b] ), &q_sqrt );
                // Add 1 to q_sqrt to account for multiplication with 2.0 in float computation.
                q_sqrt = add( q_sqrt, 1 );
                tmp32_1 = L_add( L_add( L_shl( 1, sub( Q15, q_div ) ), c ), L_shr( L_deposit_l( sqrt_res ), sub( q_div, q_sqrt ) ) );
                q_sqrt = q_div;
                tmp32_1 = L_add( L_add( L_shl( 1, sub( Q15, c_e ) ), c ), L_shl( L_deposit_l( sqrt_res ), sub( add( q_sqrt, 1 ), c_e ) ) ); /* Q(15 - c_e) */ /* +1 to account for multiplication with 2 */
                move16();
                // scaleMS = (1 + c + 2 * sqrtf(c * hStereoCng->cm[b])) / (4 * (c * LR_ratio * LR_ratio + (1 - LR_ratio) * (1 - LR_ratio) * targetGain * targetGain + 2 * LR_ratio * (1 - LR_ratio) * targetGain * sqrtf(c * hStereoCng->cm[b])));
                sqrt_res = Sqrt16( mult( c, hStereoCng->cm_fx[b] ), &q_sqrt );
                tmp32_2 = L_shl( L_add( L_shl( L_deposit_l( mult( c, mult( LR_ratio, LR_ratio ) ) ), q_div ),
                                        L_add( mult( mult( sub( MAX_16, LR_ratio ), sub( MAX_16, LR_ratio ) ), mult( targetGain, targetGain ) ),
                                               L_shl( L_deposit_l( mult( mult( LR_ratio, sub( MAX_16, LR_ratio ) ), mult( targetGain, sqrt_res ) ) ), add( 1, q_sqrt ) ) ) ), // add(1, q_sqrt) to account for multiplication with 2 and also to maintain uniform q.
                                 2 );
                scaleMS = BASOP_Util_Divide3232_Scale( tmp32_1, tmp32_2, &q_div );
                q_sqrt = q_div;
                tmp32_2 = L_deposit_l( mult( c, mult( LR_ratio, LR_ratio ) ) ); /* Q(15 - c_e) */
                /* (1 - LR_ratio) * (1 - LR_ratio) * targetGain * targetGain */
                tmp32_2 = L_add( tmp32_2, L_shl( mult( mult( sub( MAX_16, LR_ratio ), sub( MAX_16, LR_ratio ) ), mult( targetGain, targetGain ) ), sub( Q4, c_e ) ) ); /* Q(15 - c_e) */
                /* 2 * LR_ratio * (1 - LR_ratio) * targetGain * sqrtf(c * hStereoCng->cm[b]) */
                tmp32_2 = L_add( tmp32_2, L_shl( L_deposit_l( mult( mult( LR_ratio, sub( MAX_16, LR_ratio ) ), mult( targetGain, sqrt_res ) ) ), sub( add( q_sqrt, 3 ), c_e ) ) ); /* Q(15 - c_e) */ /* +1 to account for multiplication with 2 */
                tmp32_2 = L_shl( tmp32_2, 2 );
                scaleMS = BASOP_Util_Divide3232_Scale( tmp32_1, tmp32_2, &c_e );
                q_sqrt = c_e;
                move16();
                scaleMS = Sqrt16( scaleMS, &q_sqrt );
                scaleAvg = add( scaleAvg, shr( scaleMS, sub( Q15, q_sqrt ) ) );
                scaleAvg_e = BASOP_Util_Add_MantExp( scaleAvg, scaleAvg_e, scaleMS, q_sqrt, &scaleAvg );
            }
            scaleAvg = BASOP_Util_Divide1616_Scale( scaleAvg, hStereoDft->nbands, &q_div );
            hStereoDft->scale_fx = shl_sat( scaleAvg, q_div );
            scaleAvg = BASOP_Util_Divide1616_Scale( scaleAvg, hStereoDft->nbands, &c_e );
            c_e = sub( add( c_e, scaleAvg_e ), 15 );
            hStereoDft->scale_fx = shl_sat( scaleAvg, c_e );
            move16();
        }
    }