Improve DTMF decoding algorithm

3 views (last 30 days)
Hasan Ghorbani
Hasan Ghorbani on 18 Oct 2015
Edited: Hasan Ghorbani on 19 Oct 2015
Being new to signal processing era, I have written a Matlab code (using fft) to decode digits from a given noisy DTMF audio file (wav format). Considering the input signal to be in the form of x(n)+αv(n) where x(n) is the noise-free signal, v(n) is white Gaussian noise and α is a constant controlling how much noise is added. My algorithms is working fairly well in my eyes but I am still looking for improvements. Below is a report of how my code is coping with a noisy tone (containing 13 digits for this particular instance):
@alpha= 0.00 --> SNR is Inf dB --> (100% recovery )
@alpha= 0.10 --> SNR is 15.90 dB --> ( 92% recovery )
@alpha= 0.29 --> SNR is -2.60 dB --> ( 84% recovery )
@alpha= 0.31 --> SNR is -3.76 dB --> ( 76% recovery )
@alpha= 0.37 --> SNR is -6.83 dB --> ( 69% recovery )
@alpha= 0.39 --> SNR is -7.74 dB --> ( 61% recovery )
@alpha= 0.41 --> SNR is -8.61 dB --> ( 53% recovery )
@alpha= 0.44 --> SNR is -9.84 dB --> ( 38% recovery )
@alpha= 0.45 --> SNR is -10.23 dB --> ( 30% recovery )
@alpha= 0.48 --> SNR is -11.35 dB --> ( 30% recovery )
@alpha= 0.49 --> SNR is -11.71 dB --> ( 23% recovery )
@alpha= 0.62 --> SNR is -15.80 dB --> ( 15% recovery )
@alpha= 0.71 --> SNR is -18.15 dB --> ( 7% recovery )
@alpha= 0.79 --> SNR is -20.01 dB --> ( 0% recovery )
My question is whether I can still improve the performance my algorithm or not? For instance, looking at the second line of the generated report above, indicates that my algorithm is not capable of recovering all digits successfully when SNR is still greater than zero. Can I address that?

Answers (1)

Walter Roberson
Walter Roberson on 18 Oct 2015
abs(LF - LF1) < Freq_Tolerance and like expressions only need to be calculated once. You can assign the result into temporary variables and then use the result in the following tests.
  3 Comments
Walter Roberson
Walter Roberson on 19 Oct 2015
Move the constants out of the "for" loop to before the loop. LF1 never changes, there is no reason to initialize it multiple times.
In your code, if abs(LF - LF1) < Freq_Tolerance then it is not possible for abs(LF - LF2) < Freq_Tolerance and likewise for LF3 . Therefore you can restructure as
if abs(LF - LF1) < Freq_Tolerance
if abs(HF - HF1) < Freq_Tolerance
decodedValue = strcat( decodedValue , '1');
elseif abs(HF - HF2) < Freq_Tolerance
decodedValue = strcat( decodedValue , '2');
elseif abs(HF - HF3) < Freq_Tolerance
decodedValue = strcat( decodedValue , '3');
else
decodedValue = strcat( decodedValue , 'E');
end
elseif abs(LF - LF2) < Freq_Tolerance
....
else
decodedValue = strcat( decodedValue , 'E');
end
I have to question why anything unidentifiable should be 'E', but that's what your current code says.
These tweaks do make a performance difference.
As for the basic method you are using: I have no opinion on that, as I do not work with audio analysis. I do recall seeing some people doing the analysis in quite different ways, including hilbert transform, but it would take me research to find out the advantages and disadvantages of each method.
Hasan Ghorbani
Hasan Ghorbani on 19 Oct 2015
I appreciate your help Walter.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!