This source file includes following definitions.
- TELETONE_API
- TELETONE_API
- TELETONE_API
- TELETONE_API
- ensure_buffer
- TELETONE_API
- TELETONE_API
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 #include <libteletone.h>
37 #include "private/ftdm_core.h"
38
39 #define SMAX 32767
40 #define SMIN -32768
41 #define normalize_to_16bit(n) if (n > SMAX) n = SMAX; else if (n < SMIN) n = SMIN;
42
43 #ifdef _MSC_VER
44 #pragma warning(disable:4706)
45 #endif
46
47 TELETONE_API_DATA int16_t TELETONE_SINES[SINE_TABLE_MAX] = {
48 0x00c9, 0x025b, 0x03ed, 0x057f, 0x0711, 0x08a2, 0x0a33, 0x0bc4,
49 0x0d54, 0x0ee4, 0x1073, 0x1201, 0x138f, 0x151c, 0x16a8, 0x1833,
50 0x19be, 0x1b47, 0x1cd0, 0x1e57, 0x1fdd, 0x2162, 0x22e5, 0x2467,
51 0x25e8, 0x2768, 0x28e5, 0x2a62, 0x2bdc, 0x2d55, 0x2ecc, 0x3042,
52 0x31b5, 0x3327, 0x3497, 0x3604, 0x3770, 0x38d9, 0x3a40, 0x3ba5,
53 0x3d08, 0x3e68, 0x3fc6, 0x4121, 0x427a, 0x43d1, 0x4524, 0x4675,
54 0x47c4, 0x490f, 0x4a58, 0x4b9e, 0x4ce1, 0x4e21, 0x4f5e, 0x5098,
55 0x51cf, 0x5303, 0x5433, 0x5560, 0x568a, 0x57b1, 0x58d4, 0x59f4,
56 0x5b10, 0x5c29, 0x5d3e, 0x5e50, 0x5f5e, 0x6068, 0x616f, 0x6272,
57 0x6371, 0x646c, 0x6564, 0x6657, 0x6747, 0x6832, 0x691a, 0x69fd,
58 0x6add, 0x6bb8, 0x6c8f, 0x6d62, 0x6e31, 0x6efb, 0x6fc2, 0x7083,
59 0x7141, 0x71fa, 0x72af, 0x735f, 0x740b, 0x74b3, 0x7556, 0x75f4,
60 0x768e, 0x7723, 0x77b4, 0x7840, 0x78c8, 0x794a, 0x79c9, 0x7a42,
61 0x7ab7, 0x7b27, 0x7b92, 0x7bf9, 0x7c5a, 0x7cb7, 0x7d0f, 0x7d63,
62 0x7db1, 0x7dfb, 0x7e3f, 0x7e7f, 0x7eba, 0x7ef0, 0x7f22, 0x7f4e,
63 0x7f75, 0x7f98, 0x7fb5, 0x7fce, 0x7fe2, 0x7ff1, 0x7ffa, 0x7fff
64 };
65
66
67 TELETONE_API(int) teletone_set_tone(teletone_generation_session_t *ts, int index, ...)
68 {
69 va_list ap;
70 int i = 0;
71 teletone_process_t x = 0;
72
73 va_start(ap, index);
74 while (i < TELETONE_MAX_TONES && (x = va_arg(ap, teletone_process_t))) {
75 ts->TONES[index].freqs[i++] = x;
76 }
77 va_end(ap);
78
79 return (i > TELETONE_MAX_TONES) ? -1 : 0;
80
81 }
82
83 TELETONE_API(int) teletone_set_map(teletone_tone_map_t *map, ...)
84 {
85 va_list ap;
86 int i = 0;
87 teletone_process_t x = 0;
88
89 va_start(ap, map);
90 while (i < TELETONE_MAX_TONES && (x = va_arg(ap, teletone_process_t))) {
91 map->freqs[i++] = x;
92 }
93 va_end(ap);
94
95 return (i > TELETONE_MAX_TONES) ? -1 : 0;
96
97 }
98
99 TELETONE_API(int) teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data)
100 {
101 memset(ts, 0, sizeof(*ts));
102 ts->rate = 8000;
103 ts->channels = 1;
104 ts->duration = 2000;
105 ts->wait = 500;
106 ts->tmp_duration = -1;
107 ts->tmp_wait = -1;
108 ts->handler = handler;
109 ts->user_data = user_data;
110 ts->volume = -7;
111 ts->decay_step = 0;
112 ts->decay_factor = 1;
113 if (buflen) {
114 if ((ts->buffer = ftdm_calloc(buflen, sizeof(teletone_audio_t))) == 0) {
115 return -1;
116 }
117 ts->datalen = buflen;
118 } else {
119 ts->dynamic = 1024;
120 }
121
122 teletone_set_tone(ts, '1', 697.0, 1209.0, 0.0);
123 teletone_set_tone(ts, '2', 697.0, 1336.0, 0.0);
124 teletone_set_tone(ts, '3', 697.0, 1477.0, 0.0);
125 teletone_set_tone(ts, 'A', 697.0, 1633.0, 0.0);
126 teletone_set_tone(ts, '4', 770.0, 1209.0, 0.0);
127 teletone_set_tone(ts, '5', 770.0, 1336.0, 0.0);
128 teletone_set_tone(ts, '6', 770.0, 1477.0, 0.0);
129 teletone_set_tone(ts, 'B', 770.0, 1633.0, 0.0);
130 teletone_set_tone(ts, '7', 859.0, 1209.0, 0.0);
131 teletone_set_tone(ts, '8', 859.0, 1336.0, 0.0);
132 teletone_set_tone(ts, '9', 859.0, 1477.0, 0.0);
133 teletone_set_tone(ts, 'C', 859.0, 1633.0, 0.0);
134 teletone_set_tone(ts, '*', 941.0, 1209.0, 0.0);
135 teletone_set_tone(ts, '0', 941.0, 1336.0, 0.0);
136 teletone_set_tone(ts, '#', 941.0, 1477.0, 0.0);
137 teletone_set_tone(ts, 'D', 941.0, 1633.0, 0.0);
138
139 return 0;
140 }
141
142 TELETONE_API(int) teletone_destroy_session(teletone_generation_session_t *ts)
143 {
144 if (ts->buffer) {
145 ftdm_safe_free(ts->buffer);
146 ts->buffer = NULL;
147 ts->samples = 0;
148 }
149 return 0;
150 }
151
152 static int ensure_buffer(teletone_generation_session_t *ts, int need)
153 {
154 need += ts->samples;
155 need *= sizeof(teletone_audio_t);
156 need *= ts->channels;
157
158 if (need > ts->datalen) {
159 teletone_audio_t *tmp;
160 ts->datalen = need + ts->dynamic;
161 tmp = realloc(ts->buffer, ts->datalen);
162 if (!tmp) {
163 return -1;
164 }
165 ts->buffer = tmp;
166 }
167
168 return 0;
169 }
170
171 TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map)
172 {
173
174 int i, c;
175 int freqlen = 0;
176 teletone_dds_state_t tones[TELETONE_MAX_TONES+1];
177
178 int duration;
179 int wait = 0;
180 int32_t sample;
181 int32_t dc = 0;
182 float vol = ts->volume;
183 ts->samples = 0;
184 memset(tones, 0, sizeof(tones[0]) * TELETONE_MAX_TONES);
185 duration = (ts->tmp_duration > -1) ? ts->tmp_duration : ts->duration;
186 wait = (ts->tmp_wait > -1) ? ts->tmp_wait : ts->wait;
187
188 if (map->freqs[0] > 0) {
189 for (freqlen = 0; freqlen < TELETONE_MAX_TONES && map->freqs[freqlen]; freqlen++) {
190 teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, 0);
191 teletone_dds_state_set_tx_level(&tones[freqlen], vol);
192 }
193
194 if (ts->channels > 1) {
195 duration *= ts->channels;
196 }
197
198 if (ts->dynamic) {
199 if (ensure_buffer(ts, duration)) {
200 return -1;
201 }
202 }
203
204 for (ts->samples = 0; ts->samples < ts->datalen && ts->samples < duration; ts->samples++) {
205 if (ts->decay_direction && ++dc >= ts->decay_step) {
206 float nvol = vol + ts->decay_direction * ts->decay_factor;
207 int j;
208
209 if (nvol <= TELETONE_VOL_DB_MAX && nvol >= TELETONE_VOL_DB_MIN) {
210 vol = nvol;
211 for (j = 0; j < TELETONE_MAX_TONES && map->freqs[j]; j++) {
212 teletone_dds_state_set_tx_level(&tones[j], vol);
213 }
214 dc = 0;
215 }
216 }
217
218 sample = 128;
219
220 for (i = 0; i < freqlen; i++) {
221 int32_t s = teletone_dds_state_modulate_sample(&tones[i], 0);
222 sample += s;
223 }
224 sample /= freqlen;
225 ts->buffer[ts->samples] = (teletone_audio_t)sample;
226
227 for (c = 1; c < ts->channels; c++) {
228 ts->buffer[ts->samples+1] = ts->buffer[ts->samples];
229 ts->samples++;
230 }
231
232 }
233 }
234 if (ts->dynamic) {
235 if (ensure_buffer(ts, wait)) {
236 return -1;
237 }
238 }
239 for (c = 0; c < ts->channels; c++) {
240 for (i = 0; i < wait && ts->samples < ts->datalen; i++) {
241 ts->buffer[ts->samples++] = 0;
242 }
243 }
244
245 if (ts->debug && ts->debug_stream) {
246 if (map->freqs[0] <= 0) {
247 fprintf(ts->debug_stream, "wait %d (%dms)\n", wait, wait / (ts->rate / 1000));
248 } else {
249 fprintf(ts->debug_stream, "Generate: (");
250
251 for (i = 0; i < TELETONE_MAX_TONES && map->freqs[i]; i++) {
252 fprintf(ts->debug_stream, "%s%0.2f", i == 0 ? "" : "+",map->freqs[i]);
253 }
254
255 fprintf(ts->debug_stream,
256 ") [volume %0.2fdB; samples %d(%dms) x %d channel%s; wait %d(%dms); decay_factor %0.2fdB; decay_step %d(%dms); wrote %d bytes]\n",
257 ts->volume,
258 duration,
259 duration / (ts->rate / 1000),
260 ts->channels,
261 ts->channels == 1 ? "" : "s",
262 wait,
263 wait / (ts->rate / 1000),
264 ts->decay_factor,
265 ts->decay_step,
266 ts->decay_step / (ts->rate / 1000),
267 ts->samples * 2);
268 }
269 }
270 return ts->samples / ts->channels;
271 }
272
273 TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd)
274 {
275 char *data = NULL, *cur = NULL, *end = NULL;
276 int var = 0, LOOPING = 0;
277
278 if (!cmd) {
279 return -1;
280 }
281
282 do {
283 if (!(data = ftdm_strdup(cmd))) {
284 return -1;
285 }
286
287 cur = data;
288
289 while (*cur) {
290 var = 0;
291 if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
292 cur++;
293 continue;
294 }
295
296 if ((end = strchr(cur, ';')) != 0) {
297 *end++ = '\0';
298 }
299
300 if (*(cur + 1) == '=') {
301 var = 1;
302 switch(*cur) {
303 case 'c':
304 ts->channels = atoi(cur + 2);
305 break;
306 case 'r':
307 ts->rate = atoi(cur + 2);
308 break;
309 case 'd':
310 ts->duration = atoi(cur + 2) * (ts->rate / 1000);
311 break;
312 case 'v':
313 {
314 float vol = (float)atof(cur + 2);
315 if (vol <= TELETONE_VOL_DB_MAX && vol >= TELETONE_VOL_DB_MIN) {
316 ts->volume = vol;
317 }
318 }
319 break;
320 case '>':
321 ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
322 ts->decay_direction = -1;
323 break;
324 case '<':
325 ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
326 ts->decay_direction = 1;
327 break;
328 case '+':
329 ts->decay_factor = (float)atof(cur + 2);
330 break;
331 case 'w':
332 ts->wait = atoi(cur + 2) * (ts->rate / 1000);
333 break;
334 case 'l':
335 ts->loops = atoi(cur + 2);
336 break;
337 case 'L':
338 if (!LOOPING) {
339 ts->LOOPS = atoi(cur + 2);
340 }
341 LOOPING++;
342 break;
343 }
344 } else {
345 while (*cur) {
346 char *p = NULL, *e = NULL;
347 teletone_tone_map_t mymap, *mapp = NULL;
348
349 if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
350 cur++;
351 continue;
352 }
353
354 ts->tmp_duration = -1;
355 ts->tmp_wait = -1;
356
357 memset(&mymap, 0, sizeof(mymap));
358
359 if (*(cur + 1) == '(') {
360 p = cur + 2;
361 if (*cur) {
362 char *next;
363 int i = 0;
364 if ((e = strchr(p, ')')) != 0) {
365 *e++ = '\0';
366 }
367 do {
368 if ((next = strchr(p, ',')) != 0) {
369 *next++ = '\0';
370 }
371 if (i == 0) {
372 ts->tmp_duration = atoi(p) * (ts->rate / 1000);
373 i++;
374 } else if (i == 1) {
375 ts->tmp_wait = atoi(p) * (ts->rate / 1000);
376 i++;
377 } else {
378 mymap.freqs[i++ - 2] = atof(p);
379 }
380 p = next;
381
382 } while (next && (i-2) < TELETONE_MAX_TONES);
383 if (i > 2 && *cur == '%') {
384 mapp = &mymap;
385 } else if ((i != 2 || *cur == '%')) {
386 if (ts->debug && ts->debug_stream) {
387 fprintf(ts->debug_stream, "Syntax Error!\n");
388 }
389 goto bottom;
390 }
391 }
392 }
393
394 if (*cur && !mapp) {
395 if (*cur > 0 && *cur < TELETONE_TONE_RANGE) {
396 mapp = &ts->TONES[(int)*cur];
397 } else if (ts->debug && ts->debug_stream) {
398 fprintf(ts->debug_stream, "Map [%c] Out Of Range!\n", *cur);
399 }
400 }
401
402 if (mapp) {
403 if (mapp->freqs[0]) {
404 if (ts->handler) {
405 do {
406 ts->handler(ts, mapp);
407 if (ts->loops > 0) {
408 ts->loops--;
409 }
410 } while (ts->loops);
411 }
412 } else if (ts->debug && ts->debug_stream) {
413 fprintf(ts->debug_stream, "Ignoring Empty Map [%c]!\n", *cur);
414 }
415 }
416
417 if (e) {
418 cur = e;
419 } else {
420 cur++;
421 }
422 }
423 }
424
425 if (end) {
426 cur = end;
427 } else if (*cur){
428 cur++;
429 }
430 }
431 bottom:
432 ftdm_safe_free(data);
433 data = NULL;
434 if (ts->LOOPS > 0) {
435 ts->LOOPS--;
436 }
437
438 } while (ts->LOOPS);
439
440 return 0;
441 }
442
443
444
445
446
447
448
449
450
451
452