| File: | libs/libteletone/src/libteletone_generate.c |
| Location: | line 259, column 11 |
| Description: | Division by zero |
| 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 | ||||
| 82 | TELETONE_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 | ||||
| 102 | TELETONE_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 | ||||
| 118 | TELETONE_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 | ||||
| 134 | TELETONE_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 | ||||
| 177 | TELETONE_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 | ||||
| 187 | static 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 | ||||
| 206 | TELETONE_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; | |||
| ||||
| 221 | wait = (ts->tmp_wait > -1) ? ts->tmp_wait : ts->wait; | |||
| 222 | ||||
| 223 | if (map->freqs[0] > 0) { | |||
| 224 | for (freqlen = 0; freqlen < TELETONE_MAX_TONES18 && map->freqs[freqlen]; freqlen++) { | |||
| 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) { | |||
| 230 | duration *= ts->channels; | |||
| 231 | } | |||
| 232 | ||||
| 233 | if (ts->dynamic) { | |||
| 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++) { | |||
| 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++) { | |||
| 256 | int32_t s = teletone_dds_state_modulate_sample(&tones[i], 0); | |||
| 257 | sample += s; | |||
| 258 | } | |||
| 259 | sample /= freqlen; | |||
| ||||
| 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 */ | |||
| 309 | static 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 | ||||
| 321 | TELETONE_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 | */ |