How to analyse frequency of wave file in a simple way? Without extra modules.
4 Answers
What does it mean "analyse"? It can mean lot of different things, but one of simplest way I know about is to use convolution which you may easily implement for discrete functions (you'll have the points in array or be trying discrete step):
Which can be easily done by:
for i in main_array:
from = i - len(convolution_kernel)/2
// Todo: check boundaries
result[i] = 0
for j in convolution_kernel:
result[i] += convolution_kernel[j] * main_array( from+j)
Or you could use circular convolution (idea taken from eryksuns comment):
result = [sum(f[m]*g[n-m] for m in xrange(len(f))) for n in xrange(len(g))]
Which will give you ability to test whether certain signal is present in another signal (and you'll try frequencies 10,20,50,... and just get the best result).
You may also google determine wave frequency
or study Fourier transformation a bit (it's base for a lot of signal processing algorithms).

- 20,559
- 6
- 64
- 96
-
1Or you could do a circular convolution, assuming zero padding, like the DFT does: `result = [sum(f[m]*g[(n-m)%len(g)] for m in xrange(len(f))) for n in xrange(len(g))]`. – Eryk Sun Nov 14 '12 at 12:05
-
Minor update: since Python wraps negative indices, the modulo operation is redundant. You can just use `g[n-m]`. – Eryk Sun Nov 14 '12 at 12:29
Disclaimer: Signal processing is not my specialty and this answer may be a bit crude and rudimentary; feel free to correct/ me :)
I would look into fourier-analysis. A Fourier transformation transforms your input from the time domain to the frequency domain. Let me explain that a bit more:
When sampling sound for instance, you determine your sampling frequency and your bit-depth. I believe CD's are sampled at 44.1 kHz with a resolution of 16 bits pr. sample. That means the music is sampled 44,100 times a second and converted to a 16bit value. The music is represented as a vector (or array) with a length of 44,100. It is a function of time, thus this is the time domain.
On the other hand, do a Fourier-transform on the data and you'll have the data represented as a function of frequency instead. You will still have a vector 44,100 elements long, but each element will represent the amplitude - how much "signal" you have sampled at each frequency! In other words, how much signal of each given frequency your signal contains IN TOTAL over the whole sampling period.
You should look into discrete fourier analysis and an implementation of the Fast Fourier Transformation (FFT).
This question touches on FFT analysis a bit more: Scipy/Numpy FFT Frequency Analysis
EDIT:
I've shamelessly stolen some graphics online:
FFT formula:
Time vs Frequency domain:

- 1
- 1

- 5,818
- 3
- 43
- 55
If your wave file consists of only one note, you can get the fundamental frequency (not the harmonics) simply by detecting the periodicity of the wave. Do this by looking for 0-crossings.

- 42,952
- 15
- 108
- 157
If you don't want to implement a whole FFT algorithm and don't want any additional modules then I would recomment the Goertzel Algorithm which is effectively a Fourier transform for a specific freqency and gives you the power at that frequency for a sample:
define goertzel(sample, target_frequency, sample_rate):
s_prev = 0
s_prev2 = 0
normalized_frequency = target_frequency / sample_rate
coeff = 2 * cos(2 * PI * normalized_frequency)
for element in sample:
s = element + coeff * s_prev - s_prev2
s_prev2 = s_prev
s_prev = s
end
power = s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev * s_prev2
return power

- 25,354
- 32
- 99
- 167