webrtc的Sqrt()快速计算

本文介绍了一个用于WebRTC项目的快速平方根计算方法,采用六项泰勒级数展开来估算平方根,适用于固定点运算环境。该算法通过一系列位移和乘法操作实现高效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

webrtc的Sqrt()快速计算

/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


/*
 * This file contains the function WebRtcSpl_Sqrt().
 * The description header can be found in signal_processing_library.h
 *
 */

#include "signal_processing_library.h"

WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in);

WebRtc_Word32 WebRtcSpl_SqrtLocal(WebRtc_Word32 in)
{

    WebRtc_Word16 x_half, t16;
    WebRtc_Word32 A, B, x2;

    /* The following block performs:
     y=in/2
     x=y-2^30
     x_half=x/2^31
     t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4)
         + 0.875*((x_half)^5)
     */

    B = in;

    B = WEBRTC_SPL_RSHIFT_W32(B, 1); // B = in/2
    B = B - ((WebRtc_Word32)0x40000000); // B = in/2 - 1/2
    x_half = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(B, 16);// x_half = x/2 = (in-1)/2
    B = B + ((WebRtc_Word32)0x40000000); // B = 1 + x/2
    B = B + ((WebRtc_Word32)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31)

    x2 = ((WebRtc_Word32)x_half) * ((WebRtc_Word32)x_half) * 2; // A = (x/2)^2
    A = -x2; // A = -(x/2)^2
    B = B + (A >> 1); // B = 1 + x/2 - 0.5*(x/2)^2

    A = WEBRTC_SPL_RSHIFT_W32(A, 16);
    A = A * A * 2; // A = (x/2)^4
    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16);
    B = B + WEBRTC_SPL_MUL_16_16(-20480, t16) * 2; // B = B - 0.625*A
    // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4

    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16);
    A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = (x/2)^5
    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16);
    B = B + WEBRTC_SPL_MUL_16_16(28672, t16) * 2; // B = B + 0.875*A
    // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + 0.875*(x/2)^5

    t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(x2, 16);
    A = WEBRTC_SPL_MUL_16_16(x_half, t16) * 2; // A = x/2^3

    B = B + (A >> 1); // B = B + 0.5*A
    // After this, B = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 + 0.875*(x/2)^5

    B = B + ((WebRtc_Word32)32768); // Round off bit

    return B;
}

WebRtc_Word32 WebRtcSpl_Sqrt(WebRtc_Word32 value)
{
    /*
     Algorithm:

     Six term Taylor Series is used here to compute the square root of a number
     y^0.5 = (1+x)^0.5 where x = y-1
     = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5)
     0.5 <= x < 1

     Example of how the algorithm works, with ut=sqrt(in), and
     with in=73632 and ut=271 (even shift value case):

     in=73632
     y= in/131072
     x=y-1
     t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5)
     ut=t*(1/sqrt(2))*512

     or:

     in=73632
     in2=73632*2^14
     y= in2/2^31
     x=y-1
     t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5)
     ut=t*(1/sqrt(2))
     ut2=ut*2^9

     which gives:

     in  = 73632
     in2 = 1206386688
     y   = 0.56176757812500
     x   = -0.43823242187500
     t   = 0.74973506527313
     ut  = 0.53014274874797
     ut2 = 2.714330873589594e+002

     or:

     in=73632
     in2=73632*2^14
     y=in2/2
     x=y-2^30
     x_half=x/2^31
     t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4)
         + 0.875*((x_half)^5)
     ut=t*(1/sqrt(2))
     ut2=ut*2^9

     which gives:

     in  = 73632
     in2 = 1206386688
     y   = 603193344
     x   = -470548480
     x_half =  -0.21911621093750
     t   = 0.74973506527313
     ut  = 0.53014274874797
     ut2 = 2.714330873589594e+002

     */

    WebRtc_Word16 x_norm, nshift, t16, sh;
    WebRtc_Word32 A;

    WebRtc_Word16 k_sqrt_2 = 23170; // 1/sqrt2 (==5a82)

    A = value;

    if (A == 0)
        return (WebRtc_Word32)0; // sqrt(0) = 0

    sh = WebRtcSpl_NormW32(A); // # shifts to normalize A
    A = WEBRTC_SPL_LSHIFT_W32(A, sh); // Normalize A
    if (A < (WEBRTC_SPL_WORD32_MAX - 32767))
    {
        A = A + ((WebRtc_Word32)32768); // Round off bit
    } else
    {
        A = WEBRTC_SPL_WORD32_MAX;
    }

    x_norm = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // x_norm = AH

    nshift = WEBRTC_SPL_RSHIFT_W16(sh, 1); // nshift = sh>>1
    nshift = -nshift; // Negate the power for later de-normalization

    A = (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)x_norm, 16);
    A = WEBRTC_SPL_ABS_W32(A); // A = abs(x_norm<<16)
    A = WebRtcSpl_SqrtLocal(A); // A = sqrt(A)

    if ((-2 * nshift) == sh)
    { // Even shift value case

        t16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(A, 16); // t16 = AH

        A = WEBRTC_SPL_MUL_16_16(k_sqrt_2, t16) * 2; // A = 1/sqrt(2)*t16
        A = A + ((WebRtc_Word32)32768); // Round off
        A = A & ((WebRtc_Word32)0x7fff0000); // Round off

        A = WEBRTC_SPL_RSHIFT_W32(A, 15); // A = A>>16

    } else
    {
        A = WEBRTC_SPL_RSHIFT_W32(A, 16); // A = A>>16
    }

    A = A & ((WebRtc_Word32)0x0000ffff);
    A = (WebRtc_Word32)WEBRTC_SPL_SHIFT_W32(A, nshift); // De-normalize the result

    return A;
}
### 自适应音量控制算法概述 自适应音量控制算法的核心目标是对音频信号进行动态调整,使其在各种复杂的环境中保持一致的听觉体验。这种技术广泛应用于电话通讯、视频会议、语音识别等领域。其中,自动增益控制(AGC, Automatic Gain Control)是一种常见的实现方式。 #### AGC 的基本原理 AGC 是一种通过实时监测输入信号的能量水平并对其进行放大或衰减的操作来维持输出信号在一个稳定范围内的技术[^1]。它能够有效应对由于距离变化、环境噪音或其他因素引起的音频响度波动问题。具体而言: - **能量检测**:通过对输入信号计算短时均方根值(RMS),评估当前帧的强度。 - **增益估计**:依据预设的目标响度与实际测量得到的结果差距决定合适的增益因子。 - **平滑滤波器**:为了避免快速变动造成的声音失真现象引入低通滤波器对最终增益曲线加以修整[^2]。 #### 改进型 AGC —— 结合 NLMS 算法 为了进一步提升性能表现,在基础版之上还可以融入最小均方误差准则指导下的归一化梯度下降机制——即 Normalized Least Mean Squares (NLMS)[^1]。此方法利用历史数据不断优化权重系数直至收敛至最优解附近位置处停止迭代过程为止。如此这般既保留了原有结构简单易懂的优点同时也增强了抗干扰能力从而更好地服务于实际应用场景需求之中去。 以下是基于 MATLAB 平台的一个简易版本代码展示如何构建这样一个系统框架出来供参考学习之用: ```matlab function y = agc(x, target_level, attack_time, release_time) % x: 输入音频信号 % target_level: 目标响度级别(dBFS) % attack_time & release_time: 响应时间常数(秒) fs = 8000; % 假定采样率为8kHz frame_size = round(fs * min(attack_time,release_time)/2); if frame_size < 16 error('Frame size too small'); end overlap_ratio = .75; hop_size = floor((1-overlap_ratio)*frame_size); num_frames = ceil(length(x)/hop_size); y=zeros(size(x)); gain_vector=ones(num_frames ,1 )*10^(target_level/20); for i=1:num_frames, start_idx=(i-1)*hop_size +1 ; stop_idx=min(start_idx+frame_size -1,length(x)); current_frame=x(start_idx :stop_idx ); rms_value=sqrt(mean(current_frame.^2)); if rms_value ~=0 , gain_factor=1/rms_value*sqrt(10^(gain_vector(i)/20)); smoothed_gain=gain_factor.*current_frame; y(start_idx :stop_idx )=smoothed_gain(:)'; end end ``` ### 复杂环境下更先进的解决方案-AliAGC 针对更加多样化且不可预测性强的真实世界状况,则需要更为智能化全面考虑多种变量相互作用关系的设计思路。阿里巴巴团队开发出来的 AliAGC 就是一个典型例子[^3]。相比于传统的 WebRTC AGC 它具有以下几个显著特点: - 能够根据不同类型的声源特征灵活切换处理模式; - 提高对于非平稳背景噪声条件下的鲁棒性; - 减少因过度压缩而导致的人声自然质感损失等问题发生概率; 这些改进使得即使是在极端恶劣条件下也能提供较为满意的用户体验效果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值