I'm using a sliding RMS mechanism to compute RMS of a signal, i.e. with a window size of N, I add the squared value of the new sample $x[n]$ to the running total while deducting the squared value of the $x[n - N]$ sample and then performing a square root to get the RMS value.

This method works fine when a cycle's worth data in the signal under question lines up exactly with the length of the window. For ex,

Let the window length $N = 512$, frequency of the signal $f=100 \ \mathrm{Hz}$ and sampling frequency $f_s= 51200 \ \mathrm{Hz}$.

With the above settings, every set of 512 samples would have a cycle's worth data of the signal and the computation works fine. One full cycle in the RMS window

Now, the issue begins when the frequency of the signal deviates from $100 \ \mathrm{Hz}$ giving more or less number of samples in the same 512 samples window which throws off the accuracy of the sliding RMS algorithm. More than a cycle in the same window due to frequency rise

This happens because the division by 512 to get the RMS, is no longer valid due to the fact that this particular cycle of the signal is getting complete before the end of the 512 samples window. However, the running squared total would already have the contributions from the previous samples which were divided by 512 while the samples of this cycle would require a different window length.

Is there a way to compensate for the addition/lack of samples due to the frequency drifts while using this technique?

  • $\begingroup$ do you have knowledge about the "instantaneous" frequency of your signal or should the algorithm work for any signal form? $\endgroup$ Feb 23, 2017 at 15:27
  • $\begingroup$ The algorithm is strictly for sinusoids & not for any arbitrary signals.If by "instantaneous", you mean frequency at every sample, then no. I get the frequency only every half or full cycle. It's possible for me to 1st get the frequency of a cycle(and subsequently the window length) & then proceed to use the algorithm on all it's samples. The same is repeated for each cycle. $\endgroup$
    – John Smith
    Feb 23, 2017 at 15:40
  • $\begingroup$ you need to make your window width much wider than any anticipated period of your signal. then the sliding r.m.s. won't be much different than the '"perfect" which will be an integer multiple of the signal period. $\endgroup$ Feb 24, 2017 at 3:09
  • $\begingroup$ @robertbristow-johnson Increasing the window width to an extent which is much wider than the period poses an issue wherein if the magnitude of the signal were to change, it would require much more time/ many more samples for the RMS to reflect this change which makes it seem that the change in magnitude is "slow" even if the change happened in just one cycle. $\endgroup$
    – John Smith
    Feb 24, 2017 at 3:44
  • $\begingroup$ sure, it makes the envelope slower. this depends on the discipline one is working in, but in audio and computer music, the envelopes have a bandwidth that is, at least, a couple of octaves less than the fundamental frequency of the waveform. at least after the attack portion of a note. i s'pose what one can do is run contemporaneously a pitch detector on the input and adjust the width of the smoothing window to be have 2 periods of length and have complementary properties (two adjacent windows overlap and add to 1). $\endgroup$ Feb 24, 2017 at 3:55

1 Answer 1


You're right that when you're using this method to calculate the RMS value of a sinusoid, it's sensitive to getting an integer number of periods of that sinusoid in the observation window. I can see a couple ways to tweak your approach:

  • Since it's important to get full periods into your estimate, you could add some tracking of the sinusoid's frequency and phase. In the most complicated implementation, this could be a full-blown phase-locked loop. I've seen embedded RMS measurement systems before where this approach is used. Basically, you create a PLL that is locked to your input signal, then use the locked phase and frequency to ensure you take samples across as close to an integer number of periods as you can.

    A somewhat simpler way of doing this is as follows: consider processing datasets like those you plotted above. If the data should have approximately one period of the signal, then you can get a finer estimate of the period by locating the sinusoid's zero crossings. Once you've estimated the period, then you can use that subset of the data for your RMS calculation. This might be sufficient, depending upon the accuracy that your application requires.

  • Thinking a bit outside the box: is the input signal a very pure sinusoid (with negligible noise), and is it always significantly oversampled? You could dispense with the RMS approach altogether and simply look for peak amplitude, then use this to calculate the sinusoid's RMS level.

  • $\begingroup$ Hi Jason. Thanks for your answer. I am in fact doing the processing in a batch fashion itself wherein I keep acquiring samples until I get a full cycle using zero crossings. Like you pointed, this'd indeed give an accurate RMS but there's a caveat & unfortunately it's a big one. This gives RMS values cycle by cycle & not sample by sample as I need, i.e. whenever a full cycle is acquired, you get 1 RMS but what I need is RMS for each sample in that cycle which is the essence of the sliding RMS mechanism. Unfortunately, I can't use the last method cause the signal can have noise. $\endgroup$
    – John Smith
    Feb 24, 2017 at 14:46
  • $\begingroup$ John, first of all, if you're looking at only a sinusoid, make sure you run this through a DC blocking filter to make sure no DC gets in there. Then, if you want a measure of RMS that is updated sample-by-sample, you can still slide your window by one sample for each output sample of RMS. but you cannot update the length of that window without waiting for the next zero-crossing. $\endgroup$ Feb 24, 2017 at 18:48
  • $\begingroup$ another thing you can do, after the DC-blocking filter, is run the signal through a Hilbert transform (a causal filter of known delay) and delay the original by the same delay, so you have a Hilbert pair (a.k.a. "Analytic Signal"). one will be a sine wave the other a cosine wave and you can square both and add the squares and square-root. that will give you $\sqrt{2}$ times the RMS of your sine. and you can update it sample-by-sample. $\endgroup$ Feb 24, 2017 at 18:52
  • $\begingroup$ Hi Robert. What if I process the samples in batches? I mean, I can keep storing them until one full cycle is obtained & then process all the samples in that batch sample by sample? The way I'd have a new window length every cycle. Would this provide better options? Also, could you maybe point to some resources(or maybe yourself if it isn't a lot of trouble) which explains the way you suggest the Hilbert transform to be used? $\endgroup$
    – John Smith
    Feb 27, 2017 at 3:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.