Here is the context of the problem: I have a DTMF signal in wav format, I have to identify the number sequence it has encoded. I must do so using fast fourier transform in Matlab, implying that I read the wav file using wavread
and to identify each number that is seperated by 40ms silence or more.
Here is my code so far:
[signal, fs] = wavread( 'C:\Temp\file.wav' ); % here, fs = 8000Hz
N = 512;
T = 1/fs;
L = length( signal )
samples = fs / 1000 * 40
windows = floor(L / samples)
t = (1:L)/fs;
figure(1), plot(t, signal);
Here is what the figure 1
looks like, that is the signal read from the wav:
How can I effectively split the signal into pieces so that I can then do an FFT on each of the 10 pieces seperately to decode the corresponding numbers?
I would recommend the following approach:
- Find the envelope of the signal in the time domain (see Hilbert transform).
- Smooth the envelope a bit.
- Take the diff and find peaks to get the onsets of the tones.
- Use the onsets to pick frames and find the spectrum using fft.
- Find the index of the max in each of the spectrums and convert them to a frequency.
The tricky part in this is to get a robust onset detector in point 3. The peaks in the difference you pick, has to be of a certain size in order to qualify as on onset. If your tones are of varying strength this might pose a problem, but from your image of the time signal it doesn't seem like a problem.
Regards
This worked for me:
windowSize = 256;
nbWindows = floor(L / windowSize);
for i=1:nbWindows
coeffs = fft(signal((i-1)*windowSize+1:i*windowSize));
plot(abs(coeffs(1:N)));
waitforbuttonpress
end;
This way it is possible to shift the window until the end of the input signal