NetEq(三) 算法处理(Normal)

如果经过前面介绍的决策判定,该帧需要正常播放,那么正常播放又分为以下几种情况:

上一包是PLC (expand,丢包)

需要计算平滑系数,使上一包和当前包"过渡自然".

平滑系数计算:

D为解码后的数据,即input中的数据,BNG为背景噪声(用默认的初始值)。muteFactor为expand中的muteFactor,64即为8ms数据。

const int fs_mult = fs_hz_ / 8000;

 size_t energy_length =
          std::min(static_cast<size_t>(fs_mult * 64), length_per_channel);

 // energy为平均功率
int local_mute_factor = 16384;  // 1.0 in Q14.
if ((energy != 0) && (energy > background_noise_.Energy(channel_ix))) {
    // Normalize new frame energy to 15 bits.
    scaling = WebRtcSpl_NormW32(energy) - 16;
    // We want background_noise_.energy() / energy in Q14.
    int32_t bgn_energy = WEBRTC_SPL_SHIFT_W32(
        background_noise_.Energy(channel_ix), scaling + 14);
    int16_t energy_scaled =
        static_cast<int16_t>(WEBRTC_SPL_SHIFT_W32(energy, scaling));
    int32_t ratio = WebRtcSpl_DivW32W16(bgn_energy, energy_scaled);
    local_mute_factor =
        std::min(local_mute_factor, WebRtcSpl_SqrtFloor(ratio << 14));
}
mute_factor = std::max<int16_t>(mute_factor, local_mute_factor);

根据平滑因子平滑decoder_buffer中的数据

// If muted increase by 0.64 for every 20 ms (NB/WB 0.0040/0.0020 in Q14),
// or as fast as it takes to come back to full gain within the frame
// length.
const int back_to_fullscale_inc =
    static_cast<int>((16384 - mute_factor) / length_per_channel);
const int increment = std::max(64 / fs_mult, back_to_fullscale_inc);
for (size_t i = 0; i < length_per_channel; i++) {
    // Scale with mute factor.
    RTC_DCHECK_LT(channel_ix, output->Channels());
    RTC_DCHECK_LT(i, output->Size());
    int32_t scaled_signal = (*output)[channel_ix][i] * mute_factor;
    // Shift 14 with proper rounding.
    (*output)[channel_ix][i] =
        static_cast<int16_t>((scaled_signal + 8192) >> 14);
    // Increase mute_factor towards 16384.
    mute_factor =
        static_cast<int16_t>(std::min(mute_factor + increment, 16384));
}

再对上一包和本包前后1ms的数据进行平滑

计算公式为:

E 为上一包expand的数据。

上述公式还需要再加上0.5和下述代码对应。

size_t win_length = samples_per_ms_; // 1 ms数据量
      int16_t win_slope_Q14 = default_win_slope_Q14_;// default_win_slope_Q14 1个sample增长率 1ms从0增加到1
      RTC_DCHECK_LT(channel_ix, output->Channels());
      if (win_length > output->Size()) {
        win_length = output->Size();
        win_slope_Q14 = (1 << 14) / static_cast<int16_t>(win_length);
      }
      int16_t win_up_Q14 = 0;
      for (size_t i = 0; i < win_length; i++) {
        win_up_Q14 += win_slope_Q14;
        // 依据公式
        // expanded为噪声数据
        (*output)[channel_ix][i] =
            (win_up_Q14 * (*output)[channel_ix][i] +
             ((1 << 14) - win_up_Q14) * expanded[channel_ix][i] + (1 << 13)) >>   // 补偿数据,数据写入都算法缓冲区
            14;
      }

上一包是CNG

和上一包是expand情况类似,先生成CNG,然后在这一包数据前面用背景噪音做平滑。

float win_up = 0;
for (size_t i = 0; i < win_length; i++) {
    //win_up_Q14 += win_slope_Q14;
    win_up += win_slope;
    (*output)[0].set_array_index_float(i, win_up * (*output)[0].get_array_index_float(i)+
                                       (1.0 - win_up) * cng_output[i]);
}

其它情况

直接把decoder_buffer中的数据写入algorithm_buffer中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neil_baby

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值