How can i do detection in DTMF ? i want to enter a tone and get the numbers of it

41 views (last 30 days)
i want to enter a tone and get the numbers that consist it ....
  8 Comments

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 18 Dec 2015
Success!
Sort of.
I had to kludge it a bit because there are problems getting good time separation as well as good frequency separation, but — other than producing duplicate results — this works and gives reasonable answers. You will likely want to experiment with it. It is quite likely not robust, and may only work with the file you sent. (I left the spectrogram plot in but commented it out. Un-comment it if you want to see what it does.) The ‘TL’ and ‘TH’ vectors seem to make no sense in the context of the length of the signal and the sampling frequency, since your entire signal is only about 3.63 seconds in length.
The code:
dtmf_tones = load('Eng Abeer dtmf.mat');
xr = dtmf_tones.R;
fs = dtmf_tones.fs;
x = xr - mean(xr); % Remove d-c Component
[S,F,T] = spectrogram(x, 1536, 64, 512, fs, 'yaxis');
% Fm = repmat(F, 1, length(T));
% Tm = repmat(T, length(F), 1);
% figure(2)
% surf(Fm, Tm, abs(S))
% xlabel('Frequency')
% ylabel('Time')
% axis([0 2000 ylim zlim])
% grid on
Sa = abs(S);
[r, c] = find(Sa >= 20);
Fr = F(r);
Tc = T(c)';
FT = [Tc Fr];
[C, ia, ic] = unique(FT(:,1)); % Find Unique Times
for k1 = 1:size(C,1) % Create Cell Array By Time
FrqTime{k1} = FT(FT(:,1) == C(k1),:); % Time & Frequency Cell
if size(FrqTime{k1},1) > 2
FrqTime{k1} = [FrqTime{k1}(1,:); mean(FrqTime{k1}(2:end,:))]; % If MoreThan 2 Rows, Second Row Is Mean Of Last 2 Rows
end
end
FrqTime{1:10}
original_f = [697 770 852 941 1209 1336 1477]; % DTMF Frequencies
dtmf_dcd = [1 5; 1 6; 1 7; 2 5; 2 6; 2 7; 3 5; 3 6; 3 7; 4 5; 4 6; 4 7]; % Combination Codes w.r.t. ‘original_f’
nbr_map = ['1' '2' '3' '4' '5' '6' '7' '8' '9' '*' '0' '#']; % Number Key Map
for k1 = 1:size(C,1)
freq_dist = abs(bsxfun(@minus, FrqTime{k1}(:,2), original_f)); % Distance Of ‘FrqTime’ Frequencies From ‘original_f’ Frequencies
[~,freq_pos(:,k1)] = min(freq_dist,[],2); % Frequency Positions Of ‘FrqTime’ In ‘original_f’
num_pad(k1) = nbr_map(ismember(dtmf_dcd, freq_pos(:,k1)', 'rows')); % Map To Number Key Pad
end
The only other way to approach this would be to create bandpass filters for each DTMF frequency, then program the logic to decode each one of those frequency pairs. The spectrogram approach has the virtue of being easier.

More Answers (1)

M.Manu Prakash
M.Manu Prakash on 23 Oct 2020
dtmf_tones = load('Eng Abeer dtmf.mat');
xr = dtmf_tones.R;
fs = dtmf_tones.fs;
x = xr - mean(xr); % Remove d-c Component
[S,F,T] = spectrogram(x, 1536, 64, 512, fs, 'yaxis');
% Fm = repmat(F, 1, length(T));
% Tm = repmat(T, length(F), 1);
% figure(2)
% surf(Fm, Tm, abs(S))
% xlabel('Frequency')
% ylabel('Time')
% axis([0 2000 ylim zlim])
% grid on
Sa = abs(S);
[r, c] = find(Sa >= 20);
Fr = F(r);
Tc = T(c)';
FT = [Tc Fr];
[C, ia, ic] = unique(FT(:,1)); % Find Unique Times
for k1 = 1:size(C,1) % Create Cell Array By Time
FrqTime{k1} = FT(FT(:,1) == C(k1),:); % Time & Frequency Cell
if size(FrqTime{k1},1) > 2
FrqTime{k1} = [FrqTime{k1}(1,:); mean(FrqTime{k1}(2:end,:))]; % If MoreThan 2 Rows, Second Row Is Mean Of Last 2 Rows
end
end
FrqTime{1:10}
original_f = [697 770 852 941 1209 1336 1477]; % DTMF Frequencies
dtmf_dcd = [1 5; 1 6; 1 7; 2 5; 2 6; 2 7; 3 5; 3 6; 3 7; 4 5; 4 6; 4 7]; % Combination Codes w.r.t. ‘original_f’
nbr_map = ['1' '2' '3' '4' '5' '6' '7' '8' '9' '*' '0' '#']; % Number Key Map
for k1 = 1:size(C,1)
freq_dist = abs(bsxfun(@minus, FrqTime{k1}(:,2), original_f)); % Distance Of ‘FrqTime’ Frequencies From ‘original_f’ Frequencies
[~,freq_pos(:,k1)] = min(freq_dist,[],2); % Frequency Positions Of ‘FrqTime’ In ‘original_f’
num_pad(k1) = nbr_map(ismember(dtmf_dcd, freq_pos(:,k1)', 'rows')); % Map To Number Key Pad
end

Tags

Community Treasure Hunt

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

Start Hunting!