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

205 views (last 30 days)
Eng Abeer on 18 Dec 2015
Answered: M.Manu Prakash on 23 Oct 2020
i want to enter a tone and get the numbers that consist it ....

Star Strider on 18 Dec 2015
I cannot read that file. (I get an error that it is not a binary .mat file. Using the '-ascii' option also fails.)
save('dtmf.mat', 'R', 'fs');
Eng Abeer on 18 Dec 2015
i do like this exactly ...
Eng Abeer on 18 Dec 2015
if it isnt open .. replace it with any (.wav) tone . include numbers on it ...

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:
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’
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.

Eng Abeer on 18 Dec 2015
thanks a lot ....
Star Strider on 18 Dec 2015
My pleasure!

M.Manu Prakash on 23 Oct 2020
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’
end