Search code examples
pythonarraysnumpyscipywav

spectral centroid of numpy array


I have a .wav file (in this example it is called "piano2.wav").

i want to find the spectral centroid of in python.

using the code from another post on here i have this function :

import numpy as np
from scipy.io.wavfile import read

def spectral_centroid(x, samplerate=44100):
    magnitudes = np.abs(np.fft.rfft(x))
    length = len(x)
    freqs = np.abs(np.fft.fftfreq(length, 1.0/samplerate)[:length//2+1])
    return np.sum(magnitudes*freqs) / np.sum(magnitudes) 

I read the wav file using scipy.io.wavfile.read into a numpy array, and then try to feed it into the above function

a=read("piano2.wav")
print("Spectral centroid is " + spectral_centroid(a[1]))

This is the error that I get

  File "test.py", line 20, in <module>
    print("Spectral centroid is " + spectral_centroid(a[1]))
  File "test.py", line 8, in spectral_centroid
    return np.sum(magnitudes*freqs) / np.sum(magnitudes) 
ValueError: operands could not be broadcast together with shapes (302712,2) (151357,)

Solution

  • You are trying to multiply arrays of different shapes (magnitudes and freqs):

    a = np.arange(10)
    b = np.arange(5)
    print(a*b)
    

    ValueError: operands could not be broadcast together with shapes (10,) (5,)

    This could help:

    def spectral_centroid(x, samplerate=44100):
        magnitudes = np.abs(np.fft.rfft(x))
        length = len(x)
        freqs = np.abs(np.fft.fftfreq(length, 1.0/samplerate)[:length//2+1])
        magnitudes = magnitudes[:length//2+1]
        return np.sum(magnitudes*freqs) / np.sum(magnitudes)