1 // Copyright (C) 2008-2011 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU Bayonne.
4 //
5 // GNU Bayonne is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU Bayonne is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with GNU Bayonne. If not, see <http://www.gnu.org/licenses/>.
17
18 #include <config.h>
19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
22
24 using namespace UCOMMON_NAMESPACE;
25
26 DTMFDialer::DTMFDialer(const char *d, level_t l, timeout_t duration, timeout_t timer) :
27 Tonegen(duration)
28 {
29 dtmfframes = (timer / duration);
30 framing = duration;
31 level = l;
32
33 if(timer % duration)
34 ++dtmfframes;
35
36 digits = d;
37 remaining = 0;
38 reset();
39
40 complete = true;
41 if(digits && *digits)
42 complete = false;
43 }
44
45 DTMFDialer::~DTMFDialer()
46 {
47 Tonegen::cleanup();
48 }
49
50 Audio::linear_t DTMFDialer::getFrame(void)
51 {
52 for(;;)
53 {
54 if(remaining) {
55 --remaining;
56 return Tonegen::getFrame();
57 }
58
59 if(!digits || !*digits) {
60 complete = true;
61 return NULL;
62 }
63
64 if(!is_silent()) {
65 remaining = dtmfframes;
66 reset();
67 continue;
68 }
69
70 switch(*(digits++)) {
71 case '!':
72 case 'f':
73 case 'F':
74 return NULL;
75
76 case '1':
77 dual(697, 1209, level, level);
78 remaining = dtmfframes;
79 break;
80
81 case '2':
82 dual(697, 1336, level, level);
83 remaining = dtmfframes;
84 break;
85
86 case '3':
87 dual(697, 1477, level, level);
88 remaining = dtmfframes;
89 break;
90
91 case 'A':
92 case 'a':
93 dual(697, 1633, level, level);
94 remaining = dtmfframes;
95 break;
96
97 case '4':
98 dual(770, 1209, level, level);
99 remaining = dtmfframes;
100 break;
101
102 case '5':
103 dual(770, 1336, level, level);
104 remaining = dtmfframes;
105 break;
106
107 case '6':
108 dual(770, 1477, level, level);
109 remaining = dtmfframes;
110 break;
111
112 case '7':
113 dual(852, 1209, level, level);
114 remaining = dtmfframes;
115 break;
116
117 case '8':
118 dual(852, 1336, level, level);
119 remaining = dtmfframes;
120 break;
121
122 case '9':
123 dual(852, 1477, level, level);
124 remaining = dtmfframes;
125 break;
126
127 case 'C':
128 case 'c':
129 dual(852, 1633, level, level);
130 remaining = dtmfframes;
131 break;
132
133 case '*':
134 dual(941, 1209, level, level);
135 remaining = dtmfframes;
136 break;
137
138 case '0':
139 dual(941, 1336, level, level);
140 remaining = dtmfframes;
141 break;
142
143 case '#':
144 dual(941, 1477, level, level);
145 remaining = dtmfframes;
146 break;
147
148 case 'D':
149 case 'd':
150 dual(941, 1633, level, level);
151 remaining = dtmfframes;
152 break;
153
154 case 's':
155 case 'S':
156 case ',':
157 remaining = 1000 / framing;
158 reset();
159 break;
160 case '.':
161 remaining = dtmfframes * 2;
162 reset();
163 break;
164 }
165 }
166 }
167
168 MFDialer::MFDialer(const char *d, level_t l, timeout_t duration, timeout_t timer) :
169 Tonegen(duration)
170 {
171 mfframes = (timer / duration);
172 framing = duration;
173 level = l;
174 kflag = false;
175
176 if(timer % duration)
177 ++mfframes;
178
179 digits = d;
180 remaining = 0;
181 reset();
182
183 complete = true;
184 if(digits && *digits)
185 complete = false;
186 }
187
188 MFDialer::~MFDialer()
189 {
190 Tonegen::cleanup();
191 }
192
193 Audio::linear_t MFDialer::getFrame(void)
194 {
195 for(;;)
196 {
197 if(remaining) {
198 --remaining;
199 return Tonegen::getFrame();
200 }
201
202 if(!digits || !*digits) {
203 complete = true;
204 return NULL;
205 }
206
207 if(!is_silent()) {
208 if(kflag)
209 remaining = 100 / framing;
210 else
211 remaining = mfframes;
212 kflag = false;
213 reset();
214 continue;
215 }
216
217 switch(*(digits++)) {
218 case '!':
219 case 'f':
220 case 'F':
221 return NULL;
222
223 case '1':
224 dual(700, 900, level, level);
225 remaining = mfframes;
226 break;
227
228 case '2':
229 dual(700, 1100, level, level);
230 remaining = mfframes;
231 break;
232
233 case '3':
234 dual(900, 1100, level, level);
235 remaining = mfframes;
236 break;
237
238 case '4':
239 dual(700, 1300, level, level);
240 remaining = mfframes;
241 break;
242
243 case '5':
244 dual(900, 1300, level, level);
245 remaining = mfframes;
246 break;
247
248 case '6':
249 dual(1100, 1300, level, level);
250 remaining = mfframes;
251 break;
252
253 case '7':
254 dual(700, 1500, level, level);
255 remaining = mfframes;
256 break;
257
258 case '8':
259 dual(900, 1500, level, level);
260 remaining = mfframes;
261 break;
262
263 case '9':
264 dual(1100, 1500, level, level);
265 remaining = mfframes;
266 break;
267
268 case 'K':
269 case 'k':
270 case '#':
271 dual(1100, 1700, level, level);
272 remaining = 100 / framing;
273 kflag = true;
274 break;
275
276 case '0':
277 dual(1300, 1500, level, level);
278 remaining = mfframes;
279 break;
280
281 case 'S':
282 case 's':
283 case '*':
284 dual(1500, 1700, level, level);
285 remaining = mfframes;
286 break;
287
288 case 'B':
289 case 'b':
290 single(2600, level);
291 kflag = true;
292 remaining = 1000 / framing;
293 break;
294
295 case ',':
296 remaining = 1000 / framing;
297 reset();
298 break;
299 case '.':
300 remaining = mfframes * 2;
301 reset();
302 break;
303 }
304 }
305 }
306
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.