Audioop.rms () - why is it different from regular RMS?

I am writing a python function to return the volume of a WAV file. RMS is apparently the best indicator for this, Detect and record sound using python . audioop.rms()does the trick, but I would like to avoid audioop as a dependency, and I'm already importing numpy. but I do not get the same RMS values ​​and I will be grateful for an understanding of what is happening.

On the RMS Signal Smoothing page

I do not see where I am wrong, but something is not working. Any help is greatly appreciated.


EDITED / UPDATE:

In case this is useful, here is the code I got into. It's not as fast as audioop, but still fast enough, good enough for my purpose. It should be noted that using np.mean () makes it much faster (~ 100x) than my version using python sum ().

def np_audioop_rms(data, width):
    """audioop.rms() using numpy; avoids another dependency for app"""
    #_checkParameters(data, width)
    if len(data) == 0: return None
    fromType = (np.int8, np.int16, np.int32)[width//2]
    d = np.frombuffer(data, fromType).astype(np.float)
    rms = np.sqrt( np.mean(d**2) )
    return int( rms )
+5
source share
2 answers

Perform the calculations using double, as in audioop.rms()code :

d = np.frombuffer(data, np.int16).astype(np.float)

Example

>>> import audioop, numpy as np
>>> data = 'abcdefgh'
>>> audioop.rms(data, 2)
25962
>>> d = np.frombuffer(data, np.int16)
>>> np.sqrt((d*d).sum()/(1.*len(d)))
80.131142510262507
>>> d = np.frombuffer(data, np.int16).astype(np.float)
>>> np.sqrt((d*d).sum()/len(d))
25962.360851817772
+6
source

From matplotlib.mlab:

def rms_flat(a):
    """
    Return the root mean square of all the elements of *a*, flattened out.
    """
    return np.sqrt(np.mean(np.absolute(a)**2))
0
source

All Articles