한국   대만   중국   일본 
?音多? - ?基百科,自由的百科全? 跳?到?容

?音多?

本页使用了标题或全文手工转换
?基百科,自由的百科全?

?音多?信? (英語: Dual-Tone Multi-Frequency ,簡稱: DTMF ),??系?中 ??机 ? 交?机 之?的一? 信令 ,最常用于撥號時?送被叫?? [1] 。不過雙音多頻的發明,除了縮短撥號時間,也擴展了撥號之外的功能,例如自動 總機 互動式語音應答

在?音多?信?普及之前,??系?中使用一?串的??????送被叫??,?? ???? 。????需要?信局中的操作?手工完成?途接?。由脈衝撥號到雙音複頻這幾年轉換期當中,新設計的電話機?了能相容於兩種系統,大都設計?複頻/脈衝(TONE / PULSE)兩用。

?音多?信?是 ????室 ?明的,其目的是?了自?完成?途呼叫。 因?傳統的 ???? ,只能把信號送到電話接上的這一台 電信交換 機,但長距通話時,往往必須經由多台電信交換機才能完成,雙音多頻信號可以克服這個障?,利用本來就用來傳送聲音的電話線傳送使用者的按鍵信號。

因?雙音多頻的發明,讓自動 總機 互動式語音應答 得以發展,此類設備可以在接聽電話後自動宣讀預錄的語音,再依據發話端的按鍵信號做相對回應。

多?信? [ ?? ]

按? [ ?? ]

DTMF??布局
1209 Hz?697 Hz?合成?“1”的音

?音多?的????是 的矩?,有 個數字鍵和 個字符鍵,每個數字或字符都是由兩個單頻信號的組合來進行傳輸,因此鍵盤上每個按鍵所對應的信號都可以表示? ,其中 分別表示按鍵所在的行和列對應的頻率?。換句話說每一行代表一? ?,每一列代表一? ?。也就是說每按一??就?送一? ?和 ?的正弦信??合,比如'1'相?于697和1209 赫? (Hz)。交?机可以解??些?率?合??定所??的按?。 AT&T貝爾實驗室提出用 DTMF 信號作?音頻電話的撥號信號,因?這種方式可以提供更高的撥號速率,且容易被自動檢測和識別。但反之,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

注意:ABCD四個字母?不使用於撥號鍵盤,但常做?機器對機器的控制信號,例如DTMF格式的來話顯示。

按鍵識別實驗 [ ?? ]

根據撥號音識別號碼的關鍵就在於準確?計出DTMF信號的頻率?。有?多種方法可以?計DTMF信號的頻率?,在此?例兩種實現方法,一種是基於"帶通濾波器"的方法,?一種方法?基於" 格策爾演算法 (Goertzel algorithm)"。

1.帶通濾波器算法:

濾波器算法識別按鍵的關鍵是設計8個帶通濾波器,每個帶通濾波器的中心頻率對應著低/高頻組的各個頻率點。將待識別的撥號音也就是DTMF的信號波型依次通過這8個帶通濾波器。理論上只有頻率成分與濾波器中心頻率一致的信號才會通過,在濾波器輸出端檢測能量最大者?可判斷出低/高頻序號,最後再通過電話機鍵盤的頻率陣列表格的對應關係?可反推出按鍵?。

以下展示使用帶通濾波器算法應用於 MATLAB 程式碼:

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):

理論上DTMF信號只會在兩個固定的頻率點上出現能量,如何準確又高效地?計這兩個頻率?(低/高頻組)是識別撥號音的關鍵。傳統的頻譜?計方法得到的是一個頻率區間內所有頻率點的?計結果,而對於DTMF信號我們只在乎那8個固定頻率點上的功率譜?計?。而Goertzel算法就是?計DTMF信號功率譜最經典又實用的方法,這個算法只?計DTMF信號特定頻率點上的功率譜。

以下展示 MATLAB 利用Goertzel演算法?計DTMF信號的範例:

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
)
 %顯示識別結果

特殊音? [ ?? ]

特別頻率
事件 低頻 高頻 週期(on / off)
忙音 480 Hz 620 Hz 0.5 s / 0.5 s
回?音 (美及英式) 440 Hz 480 Hz 1 s / 4 s
撥號音 (美及英式) 350 Hz 440 Hz 持續長音

?式音?:

事件 低頻 高頻
忙音 (?洲大部) 425 Hz ----
回?音 (英?和???) 400 Hz 450 Hz
回?音 (?洲大部) 425 Hz ----
??音 (英?) 350 Hz 450 Hz
??音 (?洲大部) 425 Hz ----

?見 [ ?? ]

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