efficient way to calc RMS of 24bit samples

Hi !

I'm looking for an efficient way to calc the RMS of a series of n-samples(24bit) with my BF537.

if have troubles to calc the sum of x^2 and store it because i need at least 64bit-and more if i have an large buffer of samples.

Is there any efficient method known?

is it better to do it by Xrms^2=mean(x)^2+stdDeviation^2 - cost me to loops?

regards chris

in addition

i have observed that define a var as unsigned long long (for u64) dont produce the wanted code to multiply two 32bit vars

or is the u64-value in debug window(locals) not correctly displayed ??

unsigned long long measureCH2=0;

int currInSample[4];

measureCH2 += currInSample[1]*currInSample[1];   /* get the square value */

produces:
[FFA01504] R2 *= R2 ;
[FFA01506] R5 = R2 >>> 31 ;
[FFA0150A] R3 = [ FP + -140 ] ;
[FFA0150E] R6 = [ FP + -136 ] ;
[FFA01512] R2 = R2 + R3 ( NS ) ;
[FFA01516] CC = AC0 ;
[FFA01518] R3 = CC ;
[FFA0151A] R6 = R5 + R6 ( NS ) ;
[FFA0151E] R3 = R6 + R3 ( NS ) ;
[FFA01522] [ FP + -140 ] = R2 ;
[FFA01526] [ FP + -136 ] = R3 ;

  • If your 24-bit data are fixed point values in 1.23 format, you could implement a rms function as follows (please note the use of explicit fixed point operators as opposed to using integer arithmetic):

    #include <fract_math.h>
    #include <fract2float_conv.h>

    #include <math.h>

     

        int                   currInSample[sample_length];
        fract32               sample;
        unsigned long long    sum;
        float                 rms;

        int k;

     

        for( k = 0; k < sample_length; k++ )
        {
           /* Convert from 1.23 fractional to 1.31 (aligning decimal points) */
           sample = shl_fr1x32( (fract32) currInSample[k], 8 );

     

           /* Compute MAC,
              using fixed point mulitplication with rounding and saturation
           */
           sum += (unsigned long long) multr_fr1x32x32( sample, sample );

        }

     

        /* Compute sum of squares / sample length => will return 32-bit result */
        sum  = sum / (unsigned long long) sample_length;

     

        /* Compute sqrt( sum of squares / sample length ), with 24-bit precision */
        rms[k] = sqrtf( fr32_to_float( (fract32) sum ));

    Using integer arithmetic means you will be accumulating 48-bit data (24.0 * 24.0 Integers) as opposed to 32-bit data (1.31 * 1.31 = 2.62, rounded to 1.31) for the fractional example. Thus your 64-bit sum will fill up faster.

    To perform a 24.0 * 24.0 => 64.0 MAC, you should modify your expression to:

    measureCH2 += (unsigned long long) currInSample[1] * (unsigned long long) currInSample[1];

    This way, the product will be computed using 64-bit arithmetic (which is necessary to fully capture a 24.0 * 24.0 product). Using a 32-bit multiplication is not recommened since the resulting product is likely to exceed the 32-bit return value.

  • This question has been assumed as answered either offline via email or with a multi-part answer. This question has now been closed out. If you have an inquiry related to this topic please post a new question in the applicable product forum.

    Thank you,
    EZ Admin