0

这是我正在参考的参考文章:C 中任何更快的 RMS 值计算?

#define INITIAL 512  /* Initial value of the filter memory. */
#define SAMPLES 512

uint16_t rms_filter(uint16_t sample)
{
    static uint16_t rms = INITIAL;
    static uint32_t sum_squares = 1UL * SAMPLES * INITIAL * INITIAL;

    sum_squares -= sum_squares / SAMPLES;
    sum_squares += (uint32_t) sample * sample;
    if (rms == 0) rms = 1;    /* do not divide by zero */
    rms = (rms + sum_squares / SAMPLES / rms) / 2;
    return rms;
}
  1. 参数是否sample已经是定点值并且已经按 S 缩放?

  2. 是否sum_squares正在更改为以下行中的定点值?

static uint32_t sum_squares = 1UL * SAMPLES * INITIAL * INITIAL;

  1. 下面的线是为了抵消sample上面的平方吗?此外,这是整数除法,这意味着小数部分将被截断。这个可以吗?我们不会失去精度吗?

sum_squares / SAMPLES

  1. 如果sum_squares是定点值,倒数第二行的 2 不也应该改为定点值吗?
4

1 回答 1

0
  1. 参数样本是否已经是一个定点值并且已经被 S 缩放了?

除了普通整数的普通定点格式之外,显示的代码中没有明显的定点表示。

  1. sum_squares 是否在以下行中更改为定点值?

static uint32_t sum_squares = 1UL * SAMPLES * INITIAL * INITIAL;

不。过滤器被初始化,就好像先前的样本都具有值一样INITIAL。在这种情况下,一个样本的平方为 ,样本INITIAL*INITIAL的平方和为。存在以确保在乘法继续之前将操作数转换为至少一个宽度,以避免一些溢出。SAMPLESSAMPLES * INITIAL * INITIAL1ULunsigned long

这给了我们一个线索,这里没有定点表示。定点表示本质上表示具有某个缩放值sx的某个值x,其中s是为特定定点格式选择的固定比例。(通常s是 2 或 10 的幂,但可以使用任何数字。)在定点格式中,如果我们使用整数运算将x的代表sx乘以y的代表sy,我们会得到s 2 xy。但是我们要的是xy的代表,也就是sxy. 因此,我们必须除以s。所以,如果这里有定点算术,我们会期望看到类似INITIAL * INITIAL / SCALE. 由于没有除以比例(或乘以比例倒数),因此没有定点算术。

  1. 下面的行是为了抵消上面样本的平方吗?

sum_squares / SAMPLES.

不,这条线不会抵消平方。它计算平方的平均值,作为平方平均值平方根计算的一部分。由于sum_squares有 平方和并且它们的数量是SAMPLESsum_squares / SAMPLES是平均值。

此外,这是整数除法,这意味着小数部分将被截断。这个可以吗?我们不会失去精度吗?

失去了一些准确性。是否可以,取决于应用程序。如果可以得到近似的结果,并且这种截断导致的错误对于应用程序来说不是太大,那么就可以了。(总的来说,信号处理人员似乎很好,但会失去很多准确性。)

  1. 如果 sum_squares 是定点值,倒数第二行的 2 不也应该改为定点值吗?

不,2用于取较早的均方根估计值和新的均方根估计值的平均值。

这里的想法是rms包含先前样本的均方根,或接近它的东西。然后,因为sum_squares / SAMPLES是最近样本的平方的平均值,将新平均值除以旧平均值的平方根 ( rms) 得出的结果大约是新的均方根。将其添加到旧平均值中,然后除以 2 取平均值。他们在这里玩弄数学,但这是信号处理人员所做的。对这种近似跟踪真实均方根的效果的一些分析可能很有趣,但我不会在这里讨论它。

于 2021-09-23T16:37:56.247 回答