Bug Summary

File:libs/libteletone/src/libteletone_generate.c
Location:line 259, column 11
Description:Division by zero

Annotated Source Code

1/*
2 * libteletone
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is libteletone
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 *
28 *
29 * libteletone.c -- Tone Generator
30 *
31 *
32 *
33 * Exception:
34 * The author hereby grants the use of this source code under the
35 * following license if and only if the source code is distributed
36 * as part of the OpenZAP or FreeTDM library. Any use or distribution of this
37 * source code outside the scope of the OpenZAP or FreeTDM library will nullify the
38 * following license and reinact the MPL 1.1 as stated above.
39 *
40 * Copyright (c) 2007, Anthony Minessale II
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 *
47 * * Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 *
50 * * Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 *
54 * * Neither the name of the original author; nor the names of any contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 *
59 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
60 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
61 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
62 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
63 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
64 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
65 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
66 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
67 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
68 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70 */
71
72#include <libteletone.h>
73
74#define SMAX32767 32767
75#define SMIN-32768 -32768
76#define normalize_to_16bit(n)if (n > 32767) n = 32767; else if (n < -32768) n = -32768
;
if (n > SMAX32767) n = SMAX32767; else if (n < SMIN-32768) n = SMIN-32768;
77
78#ifdef _MSC_VER
79#pragma warning(disable:4706)
80#endif
81
82TELETONE_API_DATA__attribute__((visibility("default"))) int16_t TELETONE_SINES[SINE_TABLE_MAX128] = {
83 0x00c9, 0x025b, 0x03ed, 0x057f, 0x0711, 0x08a2, 0x0a33, 0x0bc4,
84 0x0d54, 0x0ee4, 0x1073, 0x1201, 0x138f, 0x151c, 0x16a8, 0x1833,
85 0x19be, 0x1b47, 0x1cd0, 0x1e57, 0x1fdd, 0x2162, 0x22e5, 0x2467,
86 0x25e8, 0x2768, 0x28e5, 0x2a62, 0x2bdc, 0x2d55, 0x2ecc, 0x3042,
87 0x31b5, 0x3327, 0x3497, 0x3604, 0x3770, 0x38d9, 0x3a40, 0x3ba5,
88 0x3d08, 0x3e68, 0x3fc6, 0x4121, 0x427a, 0x43d1, 0x4524, 0x4675,
89 0x47c4, 0x490f, 0x4a58, 0x4b9e, 0x4ce1, 0x4e21, 0x4f5e, 0x5098,
90 0x51cf, 0x5303, 0x5433, 0x5560, 0x568a, 0x57b1, 0x58d4, 0x59f4,
91 0x5b10, 0x5c29, 0x5d3e, 0x5e50, 0x5f5e, 0x6068, 0x616f, 0x6272,
92 0x6371, 0x646c, 0x6564, 0x6657, 0x6747, 0x6832, 0x691a, 0x69fd,
93 0x6add, 0x6bb8, 0x6c8f, 0x6d62, 0x6e31, 0x6efb, 0x6fc2, 0x7083,
94 0x7141, 0x71fa, 0x72af, 0x735f, 0x740b, 0x74b3, 0x7556, 0x75f4,
95 0x768e, 0x7723, 0x77b4, 0x7840, 0x78c8, 0x794a, 0x79c9, 0x7a42,
96 0x7ab7, 0x7b27, 0x7b92, 0x7bf9, 0x7c5a, 0x7cb7, 0x7d0f, 0x7d63,
97 0x7db1, 0x7dfb, 0x7e3f, 0x7e7f, 0x7eba, 0x7ef0, 0x7f22, 0x7f4e,
98 0x7f75, 0x7f98, 0x7fb5, 0x7fce, 0x7fe2, 0x7ff1, 0x7ffa, 0x7fff
99};
100
101
102TELETONE_API(int)__attribute__((visibility("default"))) int teletone_set_tone(teletone_generation_session_t *ts, int index, ...)
103{
104 va_list ap;
105 int i = 0;
106 teletone_process_t x = 0;
107
108 va_start(ap, index)__builtin_va_start(ap, index);
109 while (i < TELETONE_MAX_TONES18 && (x = va_arg(ap, teletone_process_t)__builtin_va_arg(ap, teletone_process_t))) {
110 ts->TONES[index].freqs[i++] = x;
111 }
112 va_end(ap)__builtin_va_end(ap);
113
114 return (i > TELETONE_MAX_TONES18) ? -1 : 0;
115
116}
117
118TELETONE_API(int)__attribute__((visibility("default"))) int teletone_set_map(teletone_tone_map_t *map, ...)
119{
120 va_list ap;
121 int i = 0;
122 teletone_process_t x = 0;
123
124 va_start(ap, map)__builtin_va_start(ap, map);
125 while (i < TELETONE_MAX_TONES18 && (x = va_arg(ap, teletone_process_t)__builtin_va_arg(ap, teletone_process_t))) {
126 map->freqs[i++] = x;
127 }
128 va_end(ap)__builtin_va_end(ap);
129
130 return (i > TELETONE_MAX_TONES18) ? -1 : 0;
131
132}
133
134TELETONE_API(int)__attribute__((visibility("default"))) int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data)
135{
136 memset(ts, 0, sizeof(*ts));
137 ts->rate = 8000;
138 ts->channels = 1;
139 ts->duration = 2000;
140 ts->wait = 500;
141 ts->tmp_duration = -1;
142 ts->tmp_wait = -1;
143 ts->handler = handler;
144 ts->user_data = user_data;
145 ts->volume = -7;
146 ts->decay_step = 0;
147 ts->decay_factor = 1;
148 if (buflen) {
149 if ((ts->buffer = calloc(buflen, sizeof(teletone_audio_t))) == 0) {
150 return -1;
151 }
152 ts->datalen = buflen;
153 } else {
154 ts->dynamic = 1024;
155 }
156 /* Add Standard DTMF Tones */
157 teletone_set_tone(ts, '1', 697.0, 1209.0, 0.0);
158 teletone_set_tone(ts, '2', 697.0, 1336.0, 0.0);
159 teletone_set_tone(ts, '3', 697.0, 1477.0, 0.0);
160 teletone_set_tone(ts, 'A', 697.0, 1633.0, 0.0);
161 teletone_set_tone(ts, '4', 770.0, 1209.0, 0.0);
162 teletone_set_tone(ts, '5', 770.0, 1336.0, 0.0);
163 teletone_set_tone(ts, '6', 770.0, 1477.0, 0.0);
164 teletone_set_tone(ts, 'B', 770.0, 1633.0, 0.0);
165 teletone_set_tone(ts, '7', 859.0, 1209.0, 0.0);
166 teletone_set_tone(ts, '8', 859.0, 1336.0, 0.0);
167 teletone_set_tone(ts, '9', 859.0, 1477.0, 0.0);
168 teletone_set_tone(ts, 'C', 859.0, 1633.0, 0.0);
169 teletone_set_tone(ts, '*', 941.0, 1209.0, 0.0);
170 teletone_set_tone(ts, '0', 941.0, 1336.0, 0.0);
171 teletone_set_tone(ts, '#', 941.0, 1477.0, 0.0);
172 teletone_set_tone(ts, 'D', 941.0, 1633.0, 0.0);
173
174 return 0;
175}
176
177TELETONE_API(int)__attribute__((visibility("default"))) int teletone_destroy_session(teletone_generation_session_t *ts)
178{
179 if (ts->buffer) {
180 free(ts->buffer);
181 ts->buffer = NULL((void*)0);
182 ts->samples = 0;
183 }
184 return 0;
185}
186
187static int ensure_buffer(teletone_generation_session_t *ts, int need)
188{
189 need += ts->samples;
190 need *= sizeof(teletone_audio_t);
191 need *= ts->channels;
192
193 if (need > ts->datalen) {
194 teletone_audio_t *tmp;
195 ts->datalen = need + ts->dynamic;
196 tmp = realloc(ts->buffer, ts->datalen);
197 if (!tmp) {
198 return -1;
199 }
200 ts->buffer = tmp;
201 }
202
203 return 0;
204}
205
206TELETONE_API(int)__attribute__((visibility("default"))) int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map)
207{
208 /*teletone_process_t period = (1.0 / ts->rate) / ts->channels;*/
209 int i, c;
210 int freqlen = 0;
211 teletone_dds_state_t tones[TELETONE_MAX_TONES18+1];
212 //int decay = 0;
213 int duration;
214 int wait = 0;
215 int32_t sample;
216 int32_t dc = 0;
217 float vol = ts->volume;
218 ts->samples = 0;
219 memset(tones, 0, sizeof(tones[0]) * TELETONE_MAX_TONES18);
220 duration = (ts->tmp_duration > -1) ? ts->tmp_duration : ts->duration;
1
'?' condition is false
221 wait = (ts->tmp_wait > -1) ? ts->tmp_wait : ts->wait;
2
'?' condition is false
222
223 if (map->freqs[0] > 0) {
3
Taking true branch
224 for (freqlen = 0; freqlen < TELETONE_MAX_TONES18 && map->freqs[freqlen]; freqlen++) {
4
The value 0 is assigned to 'freqlen'
5
Loop condition is false. Execution continues on line 229
225 teletone_dds_state_set_tone(&tones[freqlen], map->freqs[freqlen], ts->rate, 0);
226 teletone_dds_state_set_tx_level(&tones[freqlen], vol);
227 }
228
229 if (ts->channels > 1) {
6
Taking false branch
230 duration *= ts->channels;
231 }
232
233 if (ts->dynamic) {
7
Taking false branch
234 if (ensure_buffer(ts, duration)) {
235 return -1;
236 }
237 }
238
239 for (ts->samples = 0; ts->samples < ts->datalen && ts->samples < duration; ts->samples++) {
8
Loop condition is true. Entering loop body
240 if (ts->decay_direction && ++dc >= ts->decay_step) {
241 float nvol = vol + ts->decay_direction * ts->decay_factor;
242 int j;
243
244 if (nvol <= TELETONE_VOL_DB_MAX0 && nvol >= TELETONE_VOL_DB_MIN-63) {
245 vol = nvol;
246 for (j = 0; j < TELETONE_MAX_TONES18 && map->freqs[j]; j++) {
247 teletone_dds_state_set_tx_level(&tones[j], vol);
248 }
249 dc = 0;
250 }
251 }
252
253 sample = 128;
254
255 for (i = 0; i < freqlen; i++) {
9
Loop condition is false. Execution continues on line 259
256 int32_t s = teletone_dds_state_modulate_sample(&tones[i], 0);
257 sample += s;
258 }
259 sample /= freqlen;
10
Division by zero
260 ts->buffer[ts->samples] = (teletone_audio_t)sample;
261
262 for (c = 1; c < ts->channels; c++) {
263 ts->buffer[ts->samples+1] = ts->buffer[ts->samples];
264 ts->samples++;
265 }
266
267 }
268 }
269 if (ts->dynamic) {
270 if (ensure_buffer(ts, wait)) {
271 return -1;
272 }
273 }
274 for (c = 0; c < ts->channels; c++) {
275 for (i = 0; i < wait && ts->samples < ts->datalen; i++) {
276 ts->buffer[ts->samples++] = 0;
277 }
278 }
279
280 if (ts->debug && ts->debug_stream) {
281 if (map->freqs[0] <= 0) {
282 fprintf(ts->debug_stream, "wait %d (%dms)\n", wait, wait / (ts->rate / 1000));
283 } else {
284 fprintf(ts->debug_stream, "Generate: (");
285
286 for (i = 0; i < TELETONE_MAX_TONES18 && map->freqs[i]; i++) {
287 fprintf(ts->debug_stream, "%s%0.2f", i == 0 ? "" : "+",map->freqs[i]);
288 }
289
290 fprintf(ts->debug_stream,
291 ") [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",
292 ts->volume,
293 duration,
294 duration / (ts->rate / 1000),
295 ts->channels,
296 ts->channels == 1 ? "" : "s",
297 wait,
298 wait / (ts->rate / 1000),
299 ts->decay_factor,
300 ts->decay_step,
301 ts->decay_step / (ts->rate / 1000),
302 ts->samples * 2);
303 }
304 }
305 return ts->samples / ts->channels;
306}
307
308/* don't ask */
309static char *my_strdup (const char *s)
310{
311 size_t len = strlen (s) + 1;
312 void *new = malloc (len);
313
314 if (new == NULL((void*)0)) {
315 return NULL((void*)0);
316 }
317
318 return (char *) memcpy (new, s, len);
319}
320
321TELETONE_API(int)__attribute__((visibility("default"))) int teletone_run(teletone_generation_session_t *ts, const char *cmd)
322{
323 char *data = NULL((void*)0), *cur = NULL((void*)0), *end = NULL((void*)0);
324 int LOOPING = 0;
325
326 if (!cmd) {
327 return -1;
328 }
329
330 do {
331 if (!(data = my_strdup(cmd))) {
332 return -1;
333 }
334
335 cur = data;
336
337 while (*cur) {
338 if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
339 cur++;
340 continue;
341 }
342
343 if ((end = strchr(cur, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(cur) && (';') == '\0' ? (char *) __rawmemchr (cur, ';'
) : __builtin_strchr (cur, ';')))
) != 0) {
344 *end++ = '\0';
345 }
346
347 if (*(cur + 1) == '=') {
348 switch(*cur) {
349 case 'c':
350 ts->channels = atoi(cur + 2);
351 break;
352 case 'r':
353 ts->rate = atoi(cur + 2);
354 break;
355 case 'd':
356 ts->duration = atoi(cur + 2) * (ts->rate / 1000);
357 break;
358 case 'v':
359 {
360 float vol = (float)atof(cur + 2);
361 if (vol <= TELETONE_VOL_DB_MAX0 && vol >= TELETONE_VOL_DB_MIN-63) {
362 ts->volume = vol;
363 }
364 }
365 break;
366 case '>':
367 ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
368 ts->decay_direction = -1;
369 break;
370 case '<':
371 ts->decay_step = atoi(cur + 2) * (ts->rate / 1000);
372 ts->decay_direction = 1;
373 break;
374 case '+':
375 ts->decay_factor = (float)atof(cur + 2);
376 break;
377 case 'w':
378 ts->wait = atoi(cur + 2) * (ts->rate / 1000);
379 break;
380 case 'l':
381 ts->loops = atoi(cur + 2);
382 break;
383 case 'L':
384 if (!LOOPING) {
385 int L;
386 if ((L = atoi(cur + 2)) > 0) {
387 ts->LOOPS = L;
388 LOOPING++;
389 }
390 }
391 break;
392 }
393 } else {
394 while (*cur) {
395 char *p = NULL((void*)0), *e = NULL((void*)0);
396 teletone_tone_map_t mymap, *mapp = NULL((void*)0);
397
398 if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
399 cur++;
400 continue;
401 }
402
403 ts->tmp_duration = -1;
404 ts->tmp_wait = -1;
405
406 memset(&mymap, 0, sizeof(mymap));
407
408 if (*(cur + 1) == '(') {
409 p = cur + 2;
410 if (*cur) {
411 char *next;
412 int i = 0;
413 if ((e = strchr(p, ')')(__extension__ (__builtin_constant_p (')') && !__builtin_constant_p
(p) && (')') == '\0' ? (char *) __rawmemchr (p, ')')
: __builtin_strchr (p, ')')))
) != 0) {
414 *e++ = '\0';
415 }
416 do {
417#if (_MSC_VER == 1600)
418 if (!p) {
419 break;
420 }
421#endif
422 if ((next = strchr(p, ',')(__extension__ (__builtin_constant_p (',') && !__builtin_constant_p
(p) && (',') == '\0' ? (char *) __rawmemchr (p, ',')
: __builtin_strchr (p, ',')))
) != 0) {
423 *next++ = '\0';
424 }
425 if (i == 0) {
426 ts->tmp_duration = atoi(p) * (ts->rate / 1000);
427 i++;
428 } else if (i == 1) {
429 ts->tmp_wait = atoi(p) * (ts->rate / 1000);
430 i++;
431 } else {
432 mymap.freqs[i++ - 2] = atof(p);
433 }
434 p = next;
435
436 } while (next && (i-2) < TELETONE_MAX_TONES18);
437 if (i > 2 && *cur == '%') {
438 mapp = &mymap;
439 } else if ((i != 2 || *cur == '%')) {
440 if (ts->debug && ts->debug_stream) {
441 fprintf(ts->debug_stream, "Syntax Error!\n");
442 }
443 goto bottom;
444 }
445 }
446 }
447
448 if (*cur && !mapp) {
449 if (*cur > 0 && *cur < TELETONE_TONE_RANGE127) {
450 mapp = &ts->TONES[(int)*cur];
451 } else if (ts->debug && ts->debug_stream) {
452 fprintf(ts->debug_stream, "Map [%c] Out Of Range!\n", *cur);
453 }
454 }
455
456 if (mapp) {
457 if (mapp->freqs[0]) {
458 if (ts->handler) {
459 do {
460 ts->handler(ts, mapp);
461 if (ts->loops > 0) {
462 ts->loops--;
463 }
464 } while (ts->loops);
465 }
466 } else if (ts->debug && ts->debug_stream) {
467 fprintf(ts->debug_stream, "Ignoring Empty Map [%c]!\n", *cur);
468 }
469 }
470
471 if (e) {
472 cur = e;
473 } else {
474 cur++;
475 }
476 }
477 }
478
479 if (end) {
480 cur = end;
481 } else if (*cur){
482 cur++;
483 }
484 }
485 bottom:
486 free(data);
487 data = NULL((void*)0);
488
489 if (ts->LOOPS > 0) {
490 ts->LOOPS--;
491 }
492
493 } while (ts->LOOPS);
494
495 return 0;
496}
497
498/* For Emacs:
499 * Local Variables:
500 * mode:c
501 * indent-tabs-mode:t
502 * tab-width:4
503 * c-basic-offset:4
504 * End:
505 * For VIM:
506 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
507 */