-
Notifications
You must be signed in to change notification settings - Fork 3
/
DTMF.js
88 lines (83 loc) · 1.77 KB
/
DTMF.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const FREQ_DTMF = { // 14 patterns
"1": [ 697, 1209 ],
"2": [ 697, 1336 ],
"3": [ 697, 1477 ],
"A": [ 697, 1633 ],
"4": [ 770, 1209 ],
"5": [ 770, 1336 ],
"6": [ 770, 1477 ],
"B": [ 770, 1633 ],
"7": [ 852, 1209 ],
"8": [ 852, 1336 ],
"9": [ 852, 1477 ],
"C": [ 852, 1633 ],
"*": [ 941, 1209 ],
"0": [ 941, 1336 ],
"#": [ 941, 1477 ],
"D": [ 941, 1633 ]
};
/*
信号送出時間 50ms以上 (0.05sec)
ミニマムポーズ 隣接する信号間の休止時間の最小値。30ms以上 (0.03sec)
周期 信号送出時間とミニマムポーズの和。120ms以上
*/
let audio;
let gain;
let onodes = [];
const startDTMF = async (dtmf, len = .2) => {
/*
if (audio) {
await audio.close()
}
*/
if (!audio) {
const AudioContext = window.AudioContext || window.webkitAudioContext;
audio = new AudioContext();
gain = audio.createGain();
gain.connect(audio.destination);
gain.gain.value = 0.2;
}
for (const o of onodes) {
o.disconnect();
}
onodes = [];
for (let i = 0; i < dtmf.length; i++) {
const c = dtmf.charAt(i);
const tone = FREQ_DTMF[c];
if (tone) {
const start = audio.currentTime;
for (const t of tone) {
const node = audio.createOscillator();
node.frequency.value = t;
node.connect(gain);
node.start(start + i * len);
node.stop(start + (i + .5) * len);
onodes.push(node);
}
}
}
};
class DTMF {
static play(code, len) {
startDTMF(code, len);
}
static decode(freq1, freq2) {
let diff = 60;
let num = null;
if (freq1 > freq2) {
const tmp = freq1;
freq1 = freq2;
freq2 = tmp;
}
for (const val in FREQ_DTMF) {
const fr = FREQ_DTMF[val];
const n = Math.abs(fr[0] - freq1) + Math.abs(fr[1] - freq2);
if (n < diff) {
diff = n;
num = val;
}
}
return num;
}
}
export { DTMF };