0
$\begingroup$

I'm trying to visualise and understand the output of constant q transform. Based on my experience with FFT and the articles I've read so far, I would expect that each output bin would represent one frequency band (logarithmically spaced). Which means a naive way o finding the fundamental frequency would be to find the bin with highest energy in the spectrum.

The constant q algorithm I'm using has complex output, and I assume that the real part is the magnitude and the imaginary part is the phase. So, I compute the spectrum, but odd enough, the result looks exactly the same for every note or chord I play on the piano:

enter image description here

Which pretty much debunks my initial idea of finding the highest energy bin (it's always the last one).

What am I doing wrong? Is this really how the output should look?

EDIT:

Here is the code I use:

chromaSize = 24
frameSize = 8192 * 4 * (chromaSize / 12)

fft = es.FFT(size = frameSize)
cq = es.ConstantQ(binsPerOctave = chromaSize)
ip = es.InstantPower()

audio = pyaudio.PyAudio()
stream = audio.open(format=pyaudio.paFloat32, channels=1,
                rate=44100, input=True,
                frames_per_buffer=frameSize)

plt.ion()
plt.show(block = False)

while True:
    frame = np.fromstring(stream.read(frameSize, False), dtype=np.float32)

    if len(frame) >= 0 and ip(frame) > 0.0001:
        f = fft(frame)[1:]
        r = np.abs(cq(f))

        plt.clf()
        ind = np.arange(len(r))
        plt.bar(ind, r, color='blue', alpha=0.5)
        plt.draw()
        plt.pause(0.0001)

I'm using essentia's implementation. Ultimately, my goal would be to extract the fundamental and it's harmonics, which will then get compared using markov chains with a given data set.

$\endgroup$
4
  • 1
    $\begingroup$ Try using abs() for magnitude and angle() for phase. Real part for magnitude seems incorrect. $\endgroup$
    – Juancho
    Feb 4, 2017 at 15:37
  • $\begingroup$ Does that mean that, if i'm only interested in the bin with the max value, I can simply discard the imaginary part and use abs() on the real part? $\endgroup$
    – Rad'Val
    Feb 4, 2017 at 16:30
  • $\begingroup$ abs() gets the magnitude of the complex value. Can you edit your question to provide more context on your algorithm and what exactly you have tried so far? $\endgroup$
    – Juancho
    Feb 4, 2017 at 16:48
  • $\begingroup$ @Juancho. Thank you for your comment. If you mean abs as in np.abs, I'm already using that. I've edited my question with the code I use to plot that graph. I'll try to do the same thing using librosa this time. $\endgroup$
    – Rad'Val
    Feb 4, 2017 at 17:12

0

Your Answer

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

Browse other questions tagged or ask your own question.