# 双音多频

## 按键

 DTMF拨号 DTMF拨号音 播放此文件有问题？请参见媒體幫助。

1209 Hz 1336 Hz 1477 Hz 1633 Hz
697 Hz 1 2 3 A
770 Hz 4 5 6 B
852 Hz 7 8 9 C
941 Hz * 0 # D

## 按鍵識別實驗

1.帶通濾波器算法:

clear
clc
fs=8000;
t=(0:800)/fs;
fcolumns1 = 697;fcolumns2 = 770;fcolumns3 = 852;fcolumns4 = 941;
frow1 = 1209;frow2 = 1336;frow3 = 1477;
num0 = sin(2*pi*fcolumns4*t)+sin(2*pi*frow2*t); %數字0
num1 = sin(2*pi*fcolumns1*t)+sin(2*pi*frow1*t); %數字1
num2 = sin(2*pi*fcolumns1*t)+sin(2*pi*frow2*t); %數字2
num3 = sin(2*pi*fcolumns1*t)+sin(2*pi*frow3*t); %數字3
num4 = sin(2*pi*fcolumns2*t)+sin(2*pi*frow1*t); %數字4
num5 = sin(2*pi*fcolumns2*t)+sin(2*pi*frow2*t); %數字5
num6 = sin(2*pi*fcolumns2*t)+sin(2*pi*frow3*t); %數字6
num7 = sin(2*pi*fcolumns3*t)+sin(2*pi*frow1*t); %數字7
num8 = sin(2*pi*fcolumns3*t)+sin(2*pi*frow2*t); %數字8
num9 = sin(2*pi*fcolumns3*t)+sin(2*pi*frow3*t); %數字9
numStar = sin(2*pi*fcolumns4*t)+sin(2*pi*frow1*t); %符號*
numJin = sin(2*pi*fcolumns4*t)+sin(2*pi*frow3*t); %符號#
blank = zeros(size(num1)); %間隔
f = [fcolumns1 fcolumns2 fcolumns3 fcolumns4 frow1 frow2 frow3];
f_Low = [fcolumns1 fcolumns2 fcolumns3 fcolumns4];
f_High = [frow1 frow2 frow3];

%設計帶通濾波器(low frequency)
N = 400;
Bandwidth = 70;
B_Low = zeros(4,N+1); %存放低頻組的濾波器係數
for i = 1:4
Wo = f_Low(i);
wc1 = ( Wo - Bandwidth/2 ) * 2* pi/fs;
wc2 = ( Wo + Bandwidth/2 ) * 2* pi/fs;
B_Low(i, :) = fir2(N,[0,wc1/pi,wc2/pi,1],[0,1,1,0]);
end

%設計帶通濾波器(high frequency)
N = 200;
Bandwidth = 110;
B_High = zeros(3,N+1); %存放高頻組的濾波器係數
for i = 1:3
Wo = f_High(i);
wc1 = ( Wo - Bandwidth/2 ) * 2* pi/fs;
wc2 = ( Wo + Bandwidth/2 ) * 2* pi/fs;
B_High(i, :) = fir2(N,[0,wc1/pi,wc2/pi,1],[0,1,1,0]);
end

DialNum = num1; %DTMF訊號
sound(DialNum);

%計算當前信號與各個頻率點的距離(low frequency)
Diatance_Low = zeros(1,4);
for i = 1:4
Output = filter(B_Low(i, :),1,DialNum);
Diatance_Low(1,i) = max(abs(fft(Output)));
end
[maxnum_low,index_low] = max(Diatance_Low(1, :));

%計算當前信號與各個頻率點的距離(high frequency)
Diatance_High = zeros(1,3);
for i = 1:3
Output = filter(B_High(i, :),1,DialNum);
Diatance_High(1,i) = max(abs(fft(Output)));
end
[maxnum_high,index_high] = max(Diatance_High(1, :));

%判斷按鍵
if index_low == 1 && index_high == 1
keynum = '1';
elseif index_low == 1 && index_high == 2
keynum = '2';
elseif index_low == 1 && index_high == 3
keynum = '3';
elseif index_low == 2 && index_high == 1
keynum = '4';
elseif index_low == 2 && index_high == 2
keynum = '5';
elseif index_low == 2 && index_high == 3
keynum = '6';
elseif index_low == 3 && index_high == 1
keynum = '7';
elseif index_low == 3 && index_high == 2
keynum = '8';
elseif index_low == 3 && index_high == 3
keynum = '9';
elseif index_low == 4 && index_high == 2
keynum = '0';
elseif index_low == 4 && index_high == 1
keynum = '*';
elseif index_low == 4 && index_high == 3
keynum = '#';
end
keynum


2.格策爾演算法(Goertzel algorithm):

clear
clc
fs=8000;
t=(0:2000)/fs;
fcolumns1=697;fcolumns2=770;fcolumns3=852;fcolumns4=941;
frow1=1209;frow2=1336;frow3=1477;
num0=sin(2*pi*fcolumns4*t)+sin(2*pi*frow2*t); %數字0
num1=sin(2*pi*fcolumns1*t)+sin(2*pi*frow1*t); %數字1
num2=sin(2*pi*fcolumns1*t)+sin(2*pi*frow2*t); %數字2
num3=sin(2*pi*fcolumns1*t)+sin(2*pi*frow3*t); %數字3
num4=sin(2*pi*fcolumns2*t)+sin(2*pi*frow1*t); %數字4
num5=sin(2*pi*fcolumns2*t)+sin(2*pi*frow2*t); %數字5
num6=sin(2*pi*fcolumns2*t)+sin(2*pi*frow3*t); %數字6
num7=sin(2*pi*fcolumns3*t)+sin(2*pi*frow1*t); %數字7
num8=sin(2*pi*fcolumns3*t)+sin(2*pi*frow2*t); %數字8
num9=sin(2*pi*fcolumns3*t)+sin(2*pi*frow3*t); %數字9
numStar=sin(2*pi*fcolumns4*t)+sin(2*pi*frow1*t); %符號*
numJin=sin(2*pi*fcolumns4*t)+sin(2*pi*frow3*t); %符號#
blank=zeros(size(num1)); %間隔
f=[fcolumns1 fcolumns2 fcolumns3 fcolumns4 frow1 frow2 frow3];
freq_indices=round(f/fs*length(t))+1;

%DTMF信號%
CellPhoneNum=[num1 blank num3 blank num9 blank num8 blank num0 blank num7 blank num6 blank num6 blank num5 blank num2 blank num4];
CellPhoneNum=0.2*randn(size(CellPhoneNum))+CellPhoneNum;
sound(CellPhoneNum);

for i=1:2:21
DialNumber=CellPhoneNum(((i-1)*length(t)+1):i*length(t));
dft_data=goertzel(DialNumber,freq_indices);
temp = sort(abs(dft_data),'descend'); %找最大的兩個頻率點數值
temp_index1 = find(abs(dft_data) == temp(1));
temp_inedx2 = find(abs(dft_data) == temp(2));
if temp_index1 < temp_inedx2 %保證 temp_index1代表低頻,temp_index2代表高頻
index_low = temp_index1;
index_high = temp_inedx2;
else
index_low = temp_inedx2;
index_high = temp_index1;
end
%判斷按鍵
if index_low == 1 && index_high == 5
keynum = '1';
elseif index_low == 1 && index_high == 6
keynum = '2';
elseif index_low == 1 && index_high == 7
keynum = '3';
elseif index_low == 2 && index_high == 5
keynum = '4';
elseif index_low == 2 && index_high == 6
keynum = '5';
elseif index_low == 2 && index_high == 7
keynum = '6';
elseif index_low == 3 && index_high == 5
keynum = '7';
elseif index_low == 3 && index_high == 6
keynum = '8';
elseif index_low == 3 && index_high == 7
keynum = '9';
elseif index_low == 4 && index_high == 6
keynum = '0';
elseif index_low == 4 && index_high == 5
keynum = '*';
elseif index_low == 4 && index_high == 7
keynum = '#';
end
PhoneCell_Indent(round(i/2)) = keynum;
end
display(PhoneCell_Indent) %顯示識別結果


## 另見

1. ^ Z., Dodd, Annabel. The essential guide to telecommunications 5th. Upper Saddle River, NJ: Prentice Hall. 2012. ISBN 9780137058914. OCLC 779863446.