2

Context :

I am discovering the vast field of DSP. Yes I'm a beginner.

My goal :

Apply fft on an audio array given by audiolab to get the different frequencies of the signal.

Question :

One question : I just cannot get what to do with a numpy array which contains audio datas, thanks to audiolab. :

import numpy as np
from scikits.audiolab import Sndfile


f = Sndfile('first.ogg', 'r')

# Sndfile instances can be queried for the audio file meta-data
fs = f.samplerate
nc = f.channels
enc = f.encoding

print(fs,nc,enc)
# Reading is straightfoward
data = f.read_frames(10)
print(data)
print(np.fft.fft(data))

Now I have got my datas.

Readings

I read those two nice articles here :

Analyze audio using Fast Fourier Transform (the accepted answser is wonderful)

and

http://www.onlamp.com/pub/a/python/2001/01/31/numerically.html?page=2

Now there are two technics : apparently one suggests square (first link) whereas the other a log, especially : 10ln10(abs(1.10**-20 + value))

Which one is the best ?

SUM UP :

I would like to get the fourier analysis of my array but any of those two answers seems to only emphasis the signal and not isolating the components.

I may be wrong, I am a still a noob.

What should I really do then ?

Thanks,

UPDATE:

I ask this question : DSP - get the amplitude of all the frequencies which is related to this one.

Community
  • 1
  • 1
Larry
  • 1,735
  • 1
  • 18
  • 46

2 Answers2

2

Your question seems pretty confused, but you've obviously tried something, which is great. Let me take a step back and suggest an overall route for you:

  • Start by breaking your audio into chunks of some size, say N.
  • Perform the FFT on each chunk of N samples.
  • THEN worry about displaying the data as RMS (the square approach) or dB (the ln-based approach).

Really, you can think of those values as scaling factors for display.

If you need help with the FFT itself, my blog post on pitch detection with the FFT may help: http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html

Bjorn Roche
  • 11,279
  • 6
  • 36
  • 58
  • "The frequency will then be the bin number times the bin size, which we computed earlier. Note that we don't actually need to compute the square root to find the maximum magnitude, so our actual code skips that step". So my concern isn't one actually ? – Larry Nov 19 '13 at 08:07
  • Yes, that tutorial is describing finding a one frequency, and you want to look at them all, so instead of picking one, you would be taking the magnitude of all of them. – Bjorn Roche Nov 19 '13 at 16:51
  • This is really a different question, though -- maybe you should create a new question and link it here. – Bjorn Roche Nov 19 '13 at 16:52
  • I updated my initial question with the link to the related question. Thanks – Larry Nov 19 '13 at 18:08
0

Adding to the answer given by @Bjorn Roche.

Here is a simple code for plotting frequency spectrum, using dB scale. It uses matplotlib for plotting.

import numpy as np
import pylab

# for a real signal
def plotfftspectrum(signal, dt):  # where dt is the sample rate
    n = signal.size
    spectrum = np.abs(np.fft.fft(signal))
    spectrum = 20*np.log(spectrum/spectrum.max()) # dB scale
    frequencies = np.fft.fftfreq(n, dt)
    pylab.plot(frequencies[:n//2], spectrum[:n//2]) 
    # plot n//2 due real function symmetry   
    pylab.show()

You can use it, after reading at least some samples of your data, e.g like 1024.

data = f.read_frames(1024)
plotfftspectrum(data, 1./f.samplerate)

Where I believe your sample rate is in frequency.

imbr
  • 6,226
  • 4
  • 53
  • 65