1 /*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2019, 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 FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
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 * Paul D. Tinsley <pdt at jackhammer.org>
28 * Neal Horman <neal at wanlink dot com>
29 * Matt Klein <mklein@nmedia.net>
30 * Michael Jerris <mike@jerris.com>
31 * Marc Olivier Chouinard <mochouinard@moctel.com>
32 *
33 * switch_ivr_play_say.c -- IVR Library (functions to play or say audio)
34 *
35 */
36
37 #include <switch.h>
38
switch_ivr_phrase_macro_event(switch_core_session_t * session,const char * macro_name,const char * data,switch_event_t * event,const char * lang,switch_input_args_t * args)39 SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang,
40 switch_input_args_t *args)
41 {
42 switch_event_t *hint_data;
43 switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL, macro, input, action;
44 switch_status_t status = SWITCH_STATUS_GENERR;
45 const char *old_sound_prefix = NULL, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL;
46 const char *module_name = NULL, *chan_lang = NULL;
47 switch_channel_t *channel = switch_core_session_get_channel(session);
48 uint8_t done = 0, searched = 0;
49 int matches = 0;
50 const char *pause_val;
51 int pause = 100;
52 const char *group_macro_name = NULL;
53 const char *local_macro_name = macro_name;
54 switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced"));
55 switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE;
56
57
58 if (!macro_name) {
59 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n");
60 return status;
61 }
62
63 arg_recursion_check_start(args);
64
65 if (!lang) {
66 chan_lang = switch_channel_get_variable(channel, "default_language");
67 if (!chan_lang) {
68 chan_lang = "en";
69 }
70 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
71 } else {
72 chan_lang = lang;
73 }
74
75 switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS);
76 switch_assert(hint_data);
77
78 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", macro_name);
79 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
80 if (data) {
81 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "data", data);
82 if (event) {
83 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "data", data);
84 }
85 } else {
86 data = "";
87 }
88 switch_channel_event_set_data(channel, hint_data);
89
90 if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, ¯os, chan_lang) != SWITCH_STATUS_SUCCESS) {
91 goto done;
92 }
93
94 if ((module_name = switch_xml_attr(language, "say-module"))) {
95 } else if ((module_name = switch_xml_attr(language, "module"))) {
96 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute. Use say-module instead\n");
97 } else {
98 module_name = chan_lang;
99 }
100
101 if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
102 if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
103 sound_path = (char *) switch_xml_attr(language, "sound_path");
104 }
105 }
106
107 if (!(tts_engine = (char *) switch_xml_attr(language, "tts-engine"))) {
108 tts_engine = (char *) switch_xml_attr(language, "tts_engine");
109 }
110
111 if (!(tts_voice = (char *) switch_xml_attr(language, "tts-voice"))) {
112 tts_voice = (char *) switch_xml_attr(language, "tts_voice");
113 }
114
115 /* If we use the new structure, check for a group name */
116 if (language != macros) {
117 char *p;
118 char *macro_name_dup = switch_core_session_strdup(session, macro_name);
119 const char *group_sound_path;
120 const char *sound_prefix_enforced_str;
121
122 if ((p = strchr(macro_name_dup, '@'))) {
123 *p++ = '\0';
124 local_macro_name = macro_name_dup;
125 group_macro_name = p;
126
127 if (!(macros = switch_xml_find_child(phrases, "macros", "name", group_macro_name))) {
128 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros group %s.\n", group_macro_name);
129 goto done;
130 }
131 }
132 /* Support override of certain language attribute */
133 if ((group_sound_path = (char *) switch_xml_attr(macros, "sound-prefix")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound-path")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound_path"))) {
134 sound_path = group_sound_path;
135 }
136
137 if (sound_prefix_enforced == SWITCH_FALSE && (sound_prefix_enforced_str = switch_xml_attr(macros, "sound-prefix-enforced"))
138 && (local_sound_prefix_enforced = switch_true(sound_prefix_enforced_str)) == SWITCH_TRUE) {
139 switch_channel_set_variable(channel, "sound_prefix_enforced", sound_prefix_enforced_str);
140 }
141
142 }
143
144 if (!(macro = switch_xml_find_child(macros, "macro", "name", local_macro_name))) {
145 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name);
146 goto done;
147 }
148
149 if (sound_path && sound_prefix_enforced == SWITCH_FALSE) {
150 char *p;
151 old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
152 p = switch_core_session_strdup(session, old_sound_prefix);
153 old_sound_prefix = p;
154 switch_channel_set_variable(channel, "sound_prefix", sound_path);
155 }
156
157 if ((pause_val = switch_xml_attr(macro, "pause"))) {
158 int tmp = atoi(pause_val);
159 if (tmp >= 0) {
160 pause = tmp;
161 }
162 }
163
164 if (!(input = switch_xml_child(macro, "input"))) {
165 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find any input tags.\n");
166 goto done;
167 }
168
169 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
170 status = SWITCH_STATUS_FALSE;
171 goto done;
172 }
173
174 while (input) {
175 char *field = (char *) switch_xml_attr(input, "field");
176 char *pattern = (char *) switch_xml_attr(input, "pattern");
177 const char *do_break = switch_xml_attr_soft(input, "break_on_match");
178 char *field_expanded = NULL;
179 char *field_expanded_alloc = NULL;
180 switch_regex_t *re = NULL;
181 int proceed = 0, ovector[100];
182 switch_xml_t match = NULL;
183
184 searched = 1;
185 if (!field) {
186 field = (char *) data;
187 }
188 if (event) {
189 field_expanded_alloc = switch_event_expand_headers(event, field);
190 } else {
191 field_expanded_alloc = switch_channel_expand_variables(channel, field);
192 }
193
194 if (field_expanded_alloc == field) {
195 field_expanded_alloc = NULL;
196 field_expanded = field;
197 } else {
198 field_expanded = field_expanded_alloc;
199 }
200
201 if (!pattern) {
202 pattern = ".*";
203 }
204
205 status = SWITCH_STATUS_SUCCESS;
206
207 if ((proceed = switch_regex_perform(field_expanded, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
208 match = switch_xml_child(input, "match");
209 } else {
210 match = switch_xml_child(input, "nomatch");
211 }
212
213 if (match) {
214 matches++;
215 for (action = switch_xml_child(match, "action"); action; action = action->next) {
216 char *adata = (char *) switch_xml_attr_soft(action, "data");
217 char *func = (char *) switch_xml_attr_soft(action, "function");
218 char *substituted = NULL;
219 uint32_t len = 0;
220 char *odata = NULL;
221 char *expanded = NULL;
222
223 if (strchr(pattern, '(') && strchr(adata, '$') && proceed > 0) {
224 len = (uint32_t) (strlen(data) + strlen(adata) + 10) * proceed;
225 if (!(substituted = malloc(len))) {
226 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
227 switch_regex_safe_free(re);
228 switch_safe_free(field_expanded_alloc);
229 goto done;
230 }
231 memset(substituted, 0, len);
232 switch_perform_substitution(re, proceed, adata, field_expanded, substituted, len, ovector);
233 odata = substituted;
234 } else {
235 odata = adata;
236 }
237
238 if (event) {
239 expanded = switch_event_expand_headers(event, odata);
240 } else {
241 expanded = switch_channel_expand_variables(channel, odata);
242 }
243
244 if (expanded == odata) {
245 expanded = NULL;
246 } else {
247 odata = expanded;
248 }
249
250 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Handle %s:[%s] (%s:%s)\n", func, odata, chan_lang,
251 module_name);
252
253 if (!strcasecmp(func, "play-file")) {
254 status = switch_ivr_play_file(session, NULL, odata, args);
255 } else if (!strcasecmp(func, "phrase")) {
256 char *name = (char *) switch_xml_attr_soft(action, "phrase");
257 status = switch_ivr_phrase_macro(session, name, odata, chan_lang, args);
258 } else if (!strcasecmp(func, "break")) {
259 done = 1; /* don't break or we leak memory */
260 } else if (!strcasecmp(func, "execute")) {
261 switch_application_interface_t *app;
262 char *cmd, *cmd_args;
263 status = SWITCH_STATUS_FALSE;
264
265 cmd = switch_core_session_strdup(session, odata);
266 cmd_args = switch_separate_paren_args(cmd);
267
268 if (!cmd_args) {
269 cmd_args = "";
270 }
271
272 if ((app = switch_loadable_module_get_application_interface(cmd)) != NULL) {
273 status = switch_core_session_exec(session, app, cmd_args);
274 UNPROTECT_INTERFACE(app);
275 } else {
276 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", cmd);
277 }
278 } else if (!strcasecmp(func, "say")) {
279 switch_say_interface_t *si;
280 if ((si = switch_loadable_module_get_say_interface(module_name))) {
281 char *say_type = (char *) switch_xml_attr_soft(action, "type");
282 char *say_method = (char *) switch_xml_attr_soft(action, "method");
283 char *say_gender = (char *) switch_xml_attr_soft(action, "gender");
284 switch_say_args_t say_args = {0};
285
286 say_args.type = switch_ivr_get_say_type_by_name(say_type);
287 say_args.method = switch_ivr_get_say_method_by_name(say_method);
288 say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
289
290 status = si->say_function(session, odata, &say_args, args);
291 } else {
292 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
293 }
294 } else if (!strcasecmp(func, "speak-text")) {
295 const char *my_tts_engine = switch_xml_attr(action, "tts-engine");
296 const char *my_tts_voice = switch_xml_attr(action, "tts-voice");
297
298 if (!my_tts_engine) {
299 my_tts_engine = tts_engine;
300 }
301
302 if (!my_tts_voice) {
303 my_tts_voice = tts_voice;
304 }
305 if (zstr(tts_engine) || zstr(tts_voice)) {
306 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TTS is not configured\n");
307 } else {
308 status = switch_ivr_speak_text(session, my_tts_engine, my_tts_voice, odata, args);
309 }
310 }
311
312 switch_ivr_sleep(session, pause, SWITCH_FALSE, NULL);
313 switch_safe_free(expanded);
314 switch_safe_free(substituted);
315 if (done || status != SWITCH_STATUS_SUCCESS) break;
316 }
317 }
318
319 switch_regex_safe_free(re);
320 switch_safe_free(field_expanded_alloc);
321
322 if (done || status != SWITCH_STATUS_SUCCESS
323 || (match && do_break && switch_true(do_break))) {
324 break;
325 }
326
327 input = input->next;
328 }
329
330 done:
331
332 arg_recursion_check_stop(args);
333
334 if (hint_data) {
335 switch_event_destroy(&hint_data);
336 }
337
338 if (searched && !matches) {
339 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Macro [%s]: '%s' did not match any patterns\n", macro_name, data);
340 }
341
342 if (old_sound_prefix) {
343 switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
344 }
345 if (local_sound_prefix_enforced == SWITCH_TRUE) {
346 switch_channel_set_variable(channel, "sound_prefix_enforced", NULL);
347 }
348
349 if (xml) {
350 switch_xml_free(xml);
351 }
352
353 return status;
354 }
355
switch_ivr_record_file(switch_core_session_t * session,switch_file_handle_t * fh,const char * file,switch_input_args_t * args,uint32_t limit)356 SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *session,
357 switch_file_handle_t *fh, const char *file, switch_input_args_t *args, uint32_t limit)
358 {
359 switch_channel_t *channel = switch_core_session_get_channel(session);
360 switch_dtmf_t dtmf = { 0 };
361 switch_file_handle_t lfh = { 0 };
362 switch_file_handle_t vfh = { 0 };
363 switch_file_handle_t ind_fh = { 0 };
364 switch_frame_t *read_frame;
365 switch_codec_t codec, write_codec = { 0 };
366 char *codec_name;
367 switch_status_t status = SWITCH_STATUS_SUCCESS;
368 const char *p;
369 const char *vval;
370 time_t start = 0;
371 uint32_t org_silence_hits = 0;
372 int asis = 0;
373 int32_t sample_start = 0;
374 int waste_resources = 1400, fill_cng = 0;
375 switch_codec_implementation_t read_impl = { 0 };
376 switch_frame_t write_frame = { 0 };
377 unsigned char write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
378 switch_event_t *event;
379 int divisor = 0;
380 int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
381 int restart_limit_on_dtmf = 0;
382 const char *prefix, *var, *video_file = NULL;
383 int vid_play_file_flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO;
384 int echo_on = 0;
385 const char *file_trimmed_ms = NULL;
386 const char *file_size = NULL;
387 const char *file_trimmed = NULL;
388
389 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
390 return SWITCH_STATUS_FALSE;
391 }
392
393 if (!file) {
394 return SWITCH_STATUS_FALSE;
395 }
396
397 prefix = switch_channel_get_variable(channel, "sound_prefix");
398
399 if (!prefix) {
400 prefix = SWITCH_GLOBAL_dirs.sounds_dir;
401 }
402
403 if (!switch_channel_media_ready(channel)) {
404 return SWITCH_STATUS_FALSE;
405 }
406
407 switch_core_session_get_read_impl(session, &read_impl);
408
409 if (!(divisor = read_impl.actual_samples_per_second / 8000)) {
410 divisor = 1;
411 }
412
413 arg_recursion_check_start(args);
414
415 if (!fh) {
416 fh = &lfh;
417 }
418
419 fh->channels = read_impl.number_of_channels;
420 fh->native_rate = read_impl.actual_samples_per_second;
421
422 if (fh->samples > 0) {
423 sample_start = fh->samples;
424 fh->samples = 0;
425 }
426
427
428 if ((p = switch_channel_get_variable(channel, "record_sample_rate"))) {
429 int tmp = 0;
430
431 tmp = atoi(p);
432
433 if (switch_is_valid_rate(tmp)) {
434 fh->samplerate = tmp;
435 }
436 }
437
438 if (!strstr(file, SWITCH_URL_SEPARATOR)) {
439 char *ext;
440
441 if (!switch_is_file_path(file)) {
442 char *tfile = NULL;
443 char *e;
444
445 if (*file == '{') {
446 tfile = switch_core_session_strdup(session, file);
447
448 while (*file == '{') {
449 if ((e = switch_find_end_paren(tfile, '{', '}'))) {
450 *e = '\0';
451 file = e + 1;
452 while(*file == ' ') file++;
453 } else {
454 tfile = NULL;
455 break;
456 }
457 }
458 }
459
460 file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "}" : "", prefix, SWITCH_PATH_SEPARATOR, file);
461 }
462 if ((ext = strrchr(file, '.'))) {
463 ext++;
464 } else {
465 ext = read_impl.iananame;
466 file = switch_core_session_sprintf(session, "%s.%s", file, ext);
467 asis = 1;
468 }
469 }
470
471 if (asis && read_impl.encoded_bytes_per_packet == 0) {
472 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel));
473 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
474 arg_recursion_check_stop(args);
475 return SWITCH_STATUS_GENERR;
476 }
477
478
479 vval = switch_channel_get_variable(channel, "enable_file_write_buffering");
480 if (!vval || switch_true(vval)) {
481 fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
482 }
483
484 if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND) || ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p))) {
485 file_flags |= SWITCH_FILE_WRITE_APPEND;
486 }
487
488 if (switch_test_flag(fh, SWITCH_FILE_WRITE_OVER) || ((p = switch_channel_get_variable(channel, "RECORD_WRITE_OVER")) && switch_true(p))) {
489 file_flags |= SWITCH_FILE_WRITE_OVER;
490 }
491
492 if (!fh->prefix) {
493 fh->prefix = prefix;
494 }
495
496 if (switch_channel_test_flag(channel, CF_VIDEO)) {
497 switch_vid_params_t vid_params = { 0 };
498
499 file_flags |= SWITCH_FILE_FLAG_VIDEO;
500 switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ);
501 switch_core_session_request_video_refresh(session);
502 if (switch_core_session_wait_for_video_input_params(session, 10000) != SWITCH_STATUS_SUCCESS) {
503 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to establish inbound video stream\n");
504 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
505 arg_recursion_check_stop(args);
506 file_flags &= ~SWITCH_FILE_FLAG_VIDEO;
507 } else {
508 switch_core_media_get_vid_params(session, &vid_params);
509 fh->mm.vw = vid_params.width;
510 fh->mm.vh = vid_params.height;
511 fh->mm.fps = vid_params.fps;
512 }
513 }
514
515 if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
516 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
517 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
518 arg_recursion_check_stop(args);
519 return SWITCH_STATUS_GENERR;
520 }
521
522
523 if ((p = switch_channel_get_variable(channel, "record_fill_cng")) || (fh->params && (p = switch_event_get_header(fh->params, "record_fill_cng")))) {
524 if (!strcasecmp(p, "true")) {
525 fill_cng = 1400;
526 } else {
527 if ((fill_cng = atoi(p)) < 0) {
528 fill_cng = 0;
529 }
530 }
531 }
532
533 if ((p = switch_channel_get_variable(channel, "record_indication")) || (fh->params && (p = switch_event_get_header(fh->params, "record_indication")))) {
534 int flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT;
535 waste_resources = 1400;
536
537 if (switch_core_file_open(&ind_fh,
538 p,
539 read_impl.number_of_channels,
540 read_impl.actual_samples_per_second, flags, NULL) != SWITCH_STATUS_SUCCESS) {
541 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Indication file invalid\n");
542 }
543 }
544
545 if ((p = switch_channel_get_variable(channel, "record_waste_resources")) ||
546 (fh->params && (p = switch_event_get_header(fh->params, "record_waste_resources")))) {
547
548 if (!strcasecmp(p, "true")) {
549 waste_resources = 1400;
550 } else {
551 if ((waste_resources = atoi(p)) < 0) {
552 waste_resources = 0;
553 }
554 }
555 }
556
557 if (fill_cng || waste_resources) {
558 if (switch_core_codec_init(&write_codec,
559 "L16",
560 NULL,
561 NULL,
562 read_impl.actual_samples_per_second,
563 read_impl.microseconds_per_packet / 1000,
564 read_impl.number_of_channels,
565 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
566 switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
567 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated, ready to waste resources!\n");
568 write_frame.data = write_buf;
569 write_frame.buflen = sizeof(write_buf);
570 write_frame.datalen = read_impl.decoded_bytes_per_packet;
571 write_frame.samples = write_frame.datalen / 2;
572 write_frame.codec = &write_codec;
573 } else {
574 arg_recursion_check_stop(args);
575 return SWITCH_STATUS_FALSE;
576 }
577 }
578
579
580
581 if (switch_core_file_has_video(fh, SWITCH_TRUE)) {
582 switch_core_session_request_video_refresh(session);
583
584 if ((p = switch_channel_get_variable(channel, "record_play_video")) ||
585
586 (fh->params && (p = switch_event_get_header(fh->params, "record_play_video")))) {
587
588 video_file = switch_core_session_strdup(session, p);
589
590 if (switch_core_file_open(&vfh, video_file, fh->channels,
591 read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
592 memset(&vfh, 0, sizeof(vfh));
593 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n");
594 }
595
596 if (switch_core_file_has_video(&vfh, SWITCH_TRUE)) {
597 switch_core_media_set_video_file(session, &vfh, SWITCH_RW_WRITE);
598 switch_core_media_gen_key_frame(session);
599 } else {
600 switch_core_file_close(&vfh);
601 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n");
602 memset(&vfh, 0, sizeof(vfh));
603 }
604 }
605
606 if (!switch_test_flag(&vfh, SWITCH_FILE_OPEN)) {
607 echo_on = 1;
608 switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ);
609 switch_channel_set_flag(channel, CF_VIDEO_ECHO);
610 }
611
612 switch_core_media_set_video_file(session, fh, SWITCH_RW_READ);
613 } else if (switch_channel_test_flag(channel, CF_VIDEO)) {
614 switch_channel_set_flag(channel, CF_VIDEO_BLANK);
615 }
616
617 if (sample_start > 0) {
618 uint32_t pos = 0;
619 switch_core_file_seek(fh, &pos, sample_start, SEEK_SET);
620 switch_clear_flag_locked(fh, SWITCH_FILE_SEEK);
621 fh->samples = 0;
622 }
623
624
625 if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
626 asis = 1;
627 }
628
629 restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf"));
630
631 if ((p = switch_channel_get_variable(channel, "record_title")) || (fh->params && (p = switch_event_get_header(fh->params, "record_title")))) {
632 vval = switch_core_session_strdup(session, p);
633 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval);
634 switch_channel_set_variable(channel, "record_title", NULL);
635 }
636
637 if ((p = switch_channel_get_variable(channel, "record_copyright")) || (fh->params && (p = switch_event_get_header(fh->params, "record_copyright")))) {
638 vval = switch_core_session_strdup(session, p);
639 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval);
640 switch_channel_set_variable(channel, "record_copyright", NULL);
641 }
642
643 if ((p = switch_channel_get_variable(channel, "record_software")) || (fh->params && (p = switch_event_get_header(fh->params, "record_software")))) {
644 vval = switch_core_session_strdup(session, p);
645 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval);
646 switch_channel_set_variable(channel, "record_software", NULL);
647 }
648
649 if ((p = switch_channel_get_variable(channel, "record_artist")) || (fh->params && (p = switch_event_get_header(fh->params, "record_artist")))) {
650 vval = switch_core_session_strdup(session, p);
651 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval);
652 switch_channel_set_variable(channel, "record_artist", NULL);
653 }
654
655 if ((p = switch_channel_get_variable(channel, "record_comment")) || (fh->params && (p = switch_event_get_header(fh->params, "record_comment")))) {
656 vval = switch_core_session_strdup(session, p);
657 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval);
658 switch_channel_set_variable(channel, "record_comment", NULL);
659 }
660
661 if ((p = switch_channel_get_variable(channel, "record_date")) || (fh->params && (p = switch_event_get_header(fh->params, "record_date")))) {
662 vval = switch_core_session_strdup(session, p);
663 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval);
664 switch_channel_set_variable(channel, "record_date", NULL);
665 }
666
667
668 switch_channel_set_variable(channel, "silence_hits_exhausted", "false");
669
670 if (!asis) {
671 codec_name = "L16";
672 if (switch_core_codec_init(&codec,
673 codec_name,
674 NULL,
675 NULL,
676 read_impl.actual_samples_per_second,
677 read_impl.microseconds_per_packet / 1000,
678 read_impl.number_of_channels,
679 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
680 switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
681 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
682 switch_core_session_set_read_codec(session, &codec);
683 } else {
684 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
685 "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
686 fh->channels, read_impl.microseconds_per_packet / 1000);
687 if (switch_core_file_has_video(fh, SWITCH_FALSE)) {
688 if (echo_on) {
689 switch_channel_clear_flag(channel, CF_VIDEO_ECHO);
690 switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
691 }
692 switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
693 switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
694 }
695 switch_channel_clear_flag(channel, CF_VIDEO_BLANK);
696 switch_core_file_close(fh);
697
698 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
699 arg_recursion_check_stop(args);
700 return SWITCH_STATUS_GENERR;
701 }
702 }
703
704 if (limit) {
705 start = switch_epoch_time_now(NULL);
706 }
707
708 if (fh->thresh) {
709 if (asis) {
710 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't detect silence on a native recording.\n");
711 } else {
712 if (fh->silence_hits) {
713 fh->silence_hits = fh->samplerate * fh->silence_hits / read_impl.samples_per_packet;
714 } else {
715 fh->silence_hits = fh->samplerate * 3 / read_impl.samples_per_packet;
716 }
717 org_silence_hits = fh->silence_hits;
718 }
719 }
720
721
722 if (switch_event_create(&event, SWITCH_EVENT_RECORD_START) == SWITCH_STATUS_SUCCESS) {
723 switch_channel_event_set_data(channel, event);
724 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
725 switch_event_fire(&event);
726 }
727
728 for (;;) {
729 switch_size_t len;
730
731 if (!switch_channel_ready(channel)) {
732 status = SWITCH_STATUS_FALSE;
733 break;
734 }
735
736 if (switch_channel_test_flag(channel, CF_BREAK)) {
737 switch_channel_clear_flag(channel, CF_BREAK);
738 status = SWITCH_STATUS_BREAK;
739 break;
740 }
741
742 switch_ivr_parse_all_events(session);
743
744 if (start && (switch_epoch_time_now(NULL) - start) > limit) {
745 break;
746 }
747
748 if (args) {
749 /*
750 dtmf handler function you can hook up to be executed when a digit is dialed during playback
751 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
752 */
753 if (switch_channel_has_dtmf(channel)) {
754
755 if (limit && restart_limit_on_dtmf) {
756 start = switch_epoch_time_now(NULL);
757 }
758
759 if (!args->input_callback && !args->buf && !args->dmachine) {
760 status = SWITCH_STATUS_BREAK;
761 break;
762 }
763 switch_channel_dequeue_dtmf(channel, &dtmf);
764
765 if (args->dmachine) {
766 char ds[2] = {dtmf.digit, '\0'};
767 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
768 break;
769 }
770 }
771
772 if (args->input_callback) {
773 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
774 } else if (args->buf) {
775 *((char *) args->buf) = dtmf.digit;
776 status = SWITCH_STATUS_BREAK;
777 }
778 }
779
780 if (args->input_callback) {
781 switch_event_t *event = NULL;
782 switch_status_t ostatus;
783
784 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
785 if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
786 status = ostatus;
787 }
788
789 switch_event_destroy(&event);
790 }
791 }
792
793 if (status != SWITCH_STATUS_SUCCESS) {
794 break;
795 }
796 }
797
798 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
799 if (!SWITCH_READ_ACCEPTABLE(status)) {
800 break;
801 }
802
803 if (args && args->dmachine) {
804 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
805 break;
806 }
807 }
808
809 if (args && (args->read_frame_callback)) {
810 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
811 break;
812 }
813 }
814
815 if (switch_test_flag(&vfh, SWITCH_FILE_OPEN)) {
816 switch_core_file_command(&vfh, SCFC_FLUSH_AUDIO);
817
818 if (switch_test_flag(&vfh, SWITCH_FILE_FLAG_VIDEO_EOF)) {
819
820 //switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
821
822 switch_core_media_lock_video_file(session, SWITCH_RW_WRITE);
823
824 switch_core_file_close(&vfh);
825 memset(&vfh, 0, sizeof(vfh));
826
827 if (switch_core_file_open(&vfh, video_file, fh->channels,
828 read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
829 memset(&vfh, 0, sizeof(vfh));
830 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n");
831 }
832
833 if (switch_core_file_has_video(&vfh, SWITCH_TRUE)) {
834 //switch_core_media_set_video_file(session, &vfh, SWITCH_RW_WRITE);
835 switch_core_media_gen_key_frame(session);
836 } else {
837 switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
838 switch_core_file_close(&vfh);
839 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n");
840 memset(&vfh, 0, sizeof(vfh));
841 }
842
843 switch_core_media_unlock_video_file(session, SWITCH_RW_WRITE);
844 }
845
846 }
847
848 if (!asis && fh->thresh) {
849 int16_t *fdata = (int16_t *) read_frame->data;
850 uint32_t samples = read_frame->datalen / sizeof(*fdata);
851 uint32_t score, count = 0, j = 0;
852 double energy = 0;
853
854
855 for (count = 0; count < samples * read_impl.number_of_channels; count++) {
856 energy += abs(fdata[j++]);
857 }
858
859 score = (uint32_t) (energy / (samples / divisor));
860
861 if (score < fh->thresh) {
862 if (!--fh->silence_hits) {
863 switch_channel_set_variable(channel, "silence_hits_exhausted", "true");
864 break;
865 }
866 } else {
867 fh->silence_hits = org_silence_hits;
868 }
869 }
870
871 write_frame.datalen = read_impl.decoded_bytes_per_packet;
872 write_frame.samples = write_frame.datalen / 2;
873
874 if (switch_test_flag(&ind_fh, SWITCH_FILE_OPEN)) {
875 switch_size_t olen = write_frame.codec->implementation->samples_per_packet;
876
877 if (switch_core_file_read(&ind_fh, write_frame.data, &olen) == SWITCH_STATUS_SUCCESS) {
878 write_frame.samples = olen;
879 write_frame.datalen = olen * 2 * ind_fh.channels;;
880 } else {
881 switch_core_file_close(&ind_fh);
882 }
883
884 } else if (fill_cng) {
885 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, fill_cng);
886 } else if (waste_resources) {
887 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, waste_resources);
888 }
889
890 if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
891 int16_t *data = read_frame->data;
892 len = (switch_size_t) asis ? read_frame->datalen : read_frame->datalen / 2 / fh->channels;
893
894 if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
895 break;
896 }
897 } else if (switch_test_flag(read_frame, SFF_CNG) && fill_cng) {
898 len = write_frame.datalen / 2 / fh->channels;
899 if (switch_core_file_write(fh, write_frame.data, &len) != SWITCH_STATUS_SUCCESS) {
900 break;
901 }
902 }
903
904
905 if (waste_resources || switch_test_flag(&ind_fh, SWITCH_FILE_OPEN)) {
906 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
907 break;
908 }
909 }
910 }
911
912 if (fill_cng || waste_resources) {
913 switch_core_codec_destroy(&write_codec);
914 }
915
916 if (switch_core_file_has_video(fh, SWITCH_FALSE)) {
917 if (echo_on) {
918 switch_channel_clear_flag(channel, CF_VIDEO_ECHO);
919 switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ);
920 }
921 switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
922 switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
923 }
924 switch_channel_clear_flag(channel, CF_VIDEO_BLANK);
925
926 switch_core_file_pre_close(fh);
927 switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_FILE_SIZE, &file_size);
928 switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_FILE_TRIMMED, &file_trimmed);
929 switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_FILE_TRIMMED_MS, &file_trimmed_ms);
930 if (file_trimmed_ms) switch_channel_set_variable(channel, "record_record_trimmed_ms", file_trimmed_ms);
931 if (file_size) switch_channel_set_variable(channel, "record_record_file_size", file_size);
932 if (file_trimmed) switch_channel_set_variable(channel, "record_record_trimmed", file_trimmed);
933 switch_core_file_close(fh);
934
935
936 if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) {
937 char *cmd = switch_core_session_strdup(session, var);
938 char *data, *expanded = NULL;
939 switch_stream_handle_t stream = { 0 };
940
941 SWITCH_STANDARD_STREAM(stream);
942
943 if ((data = strchr(cmd, ':'))) {
944 *data++ = '\0';
945 expanded = switch_channel_expand_variables(channel, data);
946 }
947
948 switch_api_execute(cmd, expanded, session, &stream);
949
950 if (expanded && expanded != data) {
951 free(expanded);
952 }
953
954 switch_safe_free(stream.data);
955
956 }
957
958 if (read_impl.actual_samples_per_second && fh->native_rate >= 1000) {
959 switch_channel_set_variable_printf(channel, "record_seconds", "%d", fh->samples_out / fh->native_rate);
960 switch_channel_set_variable_printf(channel, "record_ms", "%d", fh->samples_out / (fh->native_rate / 1000));
961
962 }
963
964 switch_channel_set_variable_printf(channel, "record_samples", "%d", fh->samples_out);
965
966 if (switch_event_create(&event, SWITCH_EVENT_RECORD_STOP) == SWITCH_STATUS_SUCCESS) {
967 switch_channel_event_set_data(channel, event);
968 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
969 switch_event_fire(&event);
970 }
971
972 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
973
974 arg_recursion_check_stop(args);
975 return status;
976 }
977
teletone_handler(teletone_generation_session_t * ts,teletone_tone_map_t * map)978 static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
979 {
980 switch_buffer_t *audio_buffer = ts->user_data;
981 int wrote;
982
983 if (!audio_buffer) {
984 return -1;
985 }
986
987 wrote = teletone_mux_tones(ts, map);
988 switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
989
990 return 0;
991 }
992
switch_ivr_gentones(switch_core_session_t * session,const char * script,int32_t loops,switch_input_args_t * args)993 SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *session, const char *script, int32_t loops, switch_input_args_t *args)
994 {
995 teletone_generation_session_t ts;
996 switch_dtmf_t dtmf = { 0 };
997 switch_buffer_t *audio_buffer;
998 switch_frame_t *read_frame = NULL;
999 switch_codec_t write_codec = { 0 };
1000 switch_frame_t write_frame = { 0 };
1001 switch_byte_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
1002 switch_channel_t *channel = switch_core_session_get_channel(session);
1003 switch_codec_implementation_t read_impl = { 0 };
1004 switch_core_session_get_read_impl(session, &read_impl);
1005
1006 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
1007 return SWITCH_STATUS_FALSE;
1008 }
1009
1010 if (switch_core_codec_init(&write_codec,
1011 "L16",
1012 NULL,
1013 NULL,
1014 read_impl.actual_samples_per_second,
1015 read_impl.microseconds_per_packet / 1000,
1016 read_impl.number_of_channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
1017 NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
1018
1019 return SWITCH_STATUS_FALSE;
1020 }
1021
1022 arg_recursion_check_start(args);
1023
1024 memset(&ts, 0, sizeof(ts));
1025 write_frame.codec = &write_codec;
1026 write_frame.data = data;
1027 write_frame.buflen = sizeof(data);
1028
1029 switch_buffer_create_dynamic(&audio_buffer, 512, 1024, 0);
1030 teletone_init_session(&ts, 0, teletone_handler, audio_buffer);
1031 ts.rate = read_impl.actual_samples_per_second;
1032 ts.channels = read_impl.number_of_channels;
1033 teletone_run(&ts, script);
1034
1035 if (loops) {
1036 switch_buffer_set_loops(audio_buffer, loops);
1037 }
1038
1039 for (;;) {
1040 switch_status_t status;
1041
1042 if (!switch_channel_ready(channel)) {
1043 break;
1044 }
1045
1046 if (switch_channel_test_flag(channel, CF_BREAK)) {
1047 switch_channel_clear_flag(channel, CF_BREAK);
1048 break;
1049 }
1050
1051 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1052
1053 if (!SWITCH_READ_ACCEPTABLE(status)) {
1054 break;
1055 }
1056
1057 if (args && args->dmachine) {
1058 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
1059 break;
1060 }
1061 }
1062
1063 if (args && (args->read_frame_callback)) {
1064 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
1065 break;
1066 }
1067 }
1068
1069 switch_ivr_parse_all_events(session);
1070
1071 if (args) {
1072 /*
1073 dtmf handler function you can hook up to be executed when a digit is dialed during gentones
1074 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
1075 */
1076 if (switch_channel_has_dtmf(channel)) {
1077 if (!args->input_callback && !args->buf && !args->dmachine) {
1078 break;
1079 }
1080 switch_channel_dequeue_dtmf(channel, &dtmf);
1081
1082 if (args->dmachine) {
1083 char ds[2] = {dtmf.digit, '\0'};
1084 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
1085 break;
1086 }
1087 }
1088
1089 if (args->input_callback) {
1090 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
1091 } else if (args->buf) {
1092 *((char *) args->buf) = dtmf.digit;
1093 status = SWITCH_STATUS_BREAK;
1094 }
1095 }
1096
1097 if (args->input_callback) {
1098 switch_event_t *event;
1099
1100 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1101 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
1102 if (ostatus != SWITCH_STATUS_SUCCESS) {
1103 status = ostatus;
1104 }
1105 switch_event_destroy(&event);
1106 }
1107 }
1108
1109 if (status != SWITCH_STATUS_SUCCESS) {
1110 break;
1111 }
1112 }
1113
1114 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(audio_buffer, write_frame.data, read_impl.decoded_bytes_per_packet)) <= 0) {
1115 break;
1116 }
1117
1118 write_frame.samples = write_frame.datalen / 2;
1119
1120 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
1121 break;
1122 }
1123 }
1124
1125 switch_core_codec_destroy(&write_codec);
1126 switch_buffer_destroy(&audio_buffer);
1127 teletone_destroy_session(&ts);
1128
1129 arg_recursion_check_stop(args);
1130
1131 return SWITCH_STATUS_SUCCESS;
1132 }
1133
switch_ivr_get_file_handle(switch_core_session_t * session,switch_file_handle_t ** fh)1134 SWITCH_DECLARE(switch_status_t) switch_ivr_get_file_handle(switch_core_session_t *session, switch_file_handle_t **fh)
1135 {
1136 switch_file_handle_t *fhp;
1137 switch_channel_t *channel = switch_core_session_get_channel(session);
1138
1139 *fh = NULL;
1140 switch_core_session_io_read_lock(session);
1141
1142 if ((fhp = switch_channel_get_private(channel, "__fh"))) {
1143 *fh = fhp;
1144 return SWITCH_STATUS_SUCCESS;
1145 }
1146
1147 switch_core_session_io_rwunlock(session);
1148
1149 return SWITCH_STATUS_FALSE;
1150 }
1151
switch_ivr_release_file_handle(switch_core_session_t * session,switch_file_handle_t ** fh)1152 SWITCH_DECLARE(switch_status_t) switch_ivr_release_file_handle(switch_core_session_t *session, switch_file_handle_t **fh)
1153 {
1154 *fh = NULL;
1155 switch_core_session_io_rwunlock(session);
1156
1157 return SWITCH_STATUS_SUCCESS;
1158 }
1159
1160 #define FILE_STARTSAMPLES 1024 * 32
1161 #define FILE_BLOCKSIZE 1024 * 8
1162 #define FILE_BUFSIZE 1024 * 64
1163
switch_ivr_play_file(switch_core_session_t * session,switch_file_handle_t * fh,const char * file,switch_input_args_t * args)1164 SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args)
1165 {
1166 switch_channel_t *channel = switch_core_session_get_channel(session);
1167 int16_t *abuf = NULL;
1168 switch_dtmf_t dtmf = { 0 };
1169 uint32_t interval = 0, samples = 0, framelen, sample_start = 0, channels = 1;
1170 uint32_t ilen = 0;
1171 switch_size_t olen = 0, llen = 0;
1172 switch_frame_t write_frame = { 0 };
1173 switch_timer_t timer = { 0 };
1174 switch_codec_t codec = { 0 };
1175 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
1176 char *codec_name;
1177 switch_status_t status = SWITCH_STATUS_SUCCESS;
1178 switch_file_handle_t lfh;
1179 const char *p;
1180 //char *title = "", *copyright = "", *software = "", *artist = "", *comment = "", *date = "";
1181 char *ext;
1182 char *backup_file = NULL;
1183 const char *backup_ext;
1184 const char *prefix;
1185 const char *timer_name;
1186 const char *prebuf;
1187 const char *alt = NULL;
1188 const char *sleep_val;
1189 const char *play_delimiter_val;
1190 char play_delimiter = 0;
1191 int sleep_val_i = 250;
1192 int eof = 0;
1193 switch_size_t bread = 0;
1194 int l16 = 0;
1195 switch_codec_implementation_t read_impl = { 0 };
1196 char *file_dup;
1197 char *argv[128] = { 0 };
1198 int argc;
1199 int cur;
1200 int done = 0;
1201 int timeout_samples = 0;
1202 switch_bool_t timeout_as_success = SWITCH_FALSE;
1203 const char *var;
1204 int more_data = 0;
1205 switch_event_t *event;
1206 uint32_t test_native = 0, last_native = 0;
1207 uint32_t buflen = 0;
1208 int flags;
1209 int cumulative = 0;
1210 int last_speed = -1;
1211
1212 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
1213 return SWITCH_STATUS_FALSE;
1214 }
1215
1216 switch_core_session_get_read_impl(session, &read_impl);
1217
1218 if ((var = switch_channel_get_variable(channel, "playback_timeout_sec_cumulative"))) {
1219 int tmp = atoi(var);
1220 if (tmp > 1) {
1221 timeout_samples = read_impl.actual_samples_per_second * tmp;
1222 cumulative = 1;
1223 }
1224
1225 } else if ((var = switch_channel_get_variable(channel, "playback_timeout_sec"))) {
1226 int tmp = atoi(var);
1227 if (tmp > 1) {
1228 timeout_samples = read_impl.actual_samples_per_second * tmp;
1229 }
1230 }
1231
1232 if ((var = switch_channel_get_variable(channel, "playback_timeout_as_success"))) {
1233 if (switch_true(var)) {
1234 timeout_as_success = SWITCH_TRUE;
1235 }
1236 }
1237 if ((play_delimiter_val = switch_channel_get_variable(channel, "playback_delimiter"))) {
1238 play_delimiter = *play_delimiter_val;
1239
1240 if ((sleep_val = switch_channel_get_variable(channel, "playback_sleep_val"))) {
1241 int tmp = atoi(sleep_val);
1242 if (tmp >= 0) {
1243 sleep_val_i = tmp;
1244 }
1245 }
1246 }
1247
1248 prefix = switch_channel_get_variable(channel, "sound_prefix");
1249 timer_name = switch_channel_get_variable(channel, "timer_name");
1250
1251 if (zstr(file) || !switch_channel_media_ready(channel)) {
1252 return SWITCH_STATUS_FALSE;
1253 }
1254
1255 arg_recursion_check_start(args);
1256
1257 if (!zstr(read_impl.iananame) && !strcasecmp(read_impl.iananame, "l16")) {
1258 l16++;
1259 }
1260
1261 if (play_delimiter) {
1262 file_dup = switch_core_session_strdup(session, file);
1263 argc = switch_separate_string(file_dup, play_delimiter, argv, (sizeof(argv) / sizeof(argv[0])));
1264 } else {
1265 argc = 1;
1266 argv[0] = (char *) file;
1267 }
1268
1269 if (!fh) {
1270 fh = &lfh;
1271 memset(fh, 0, sizeof(lfh));
1272 }
1273
1274 if (fh->samples > 0) {
1275 sample_start = fh->samples;
1276 fh->samples = 0;
1277 }
1278
1279
1280
1281
1282 for (cur = 0; switch_channel_ready(channel) && !done && cur < argc; cur++) {
1283 file = argv[cur];
1284 eof = 0;
1285
1286 if (cur) {
1287 fh->samples = sample_start = 0;
1288 if (sleep_val_i) {
1289 status = switch_ivr_sleep(session, sleep_val_i, SWITCH_FALSE, args);
1290 if(status != SWITCH_STATUS_SUCCESS) {
1291 break;
1292 }
1293 }
1294 }
1295
1296 status = SWITCH_STATUS_SUCCESS;
1297
1298 if ((alt = strchr(file, ':'))) {
1299 char *dup;
1300
1301 if (!strncasecmp(file, "phrase:", 7)) {
1302 char *arg = NULL;
1303 const char *lang = switch_channel_get_variable(channel, "language");
1304 alt = file + 7;
1305 dup = switch_core_session_strdup(session, alt);
1306
1307 if (dup) {
1308 if ((arg = strchr(dup, ':'))) {
1309 *arg++ = '\0';
1310 }
1311 if ((status = switch_ivr_phrase_macro(session, dup, arg, lang, args)) != SWITCH_STATUS_SUCCESS) {
1312 arg_recursion_check_stop(args);
1313 return status;
1314 }
1315 continue;
1316 } else {
1317 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Args\n");
1318 continue;
1319 }
1320 } else if (!strncasecmp(file, "say:", 4)) {
1321 const char *engine = NULL, *voice = NULL, *text = NULL;
1322
1323 alt = file + 4;
1324 text = alt;
1325 engine = switch_channel_get_variable(channel, "tts_engine");
1326 voice = switch_channel_get_variable(channel, "tts_voice");
1327
1328 if (engine && text) {
1329 if ((status = switch_ivr_speak_text(session, engine, voice, (char *)text, args)) != SWITCH_STATUS_SUCCESS) {
1330 arg_recursion_check_stop(args);
1331 return status;
1332 }
1333 } else {
1334 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Args\n");
1335 }
1336
1337 continue;
1338 }
1339
1340 }
1341
1342 if (!prefix) {
1343 prefix = SWITCH_GLOBAL_dirs.base_dir;
1344 }
1345
1346 if (!strstr(file, SWITCH_URL_SEPARATOR)) {
1347 if (!switch_is_file_path(file)) {
1348 char *tfile = NULL;
1349 char *e;
1350
1351 if (*file == '{') {
1352 tfile = switch_core_session_strdup(session, file);
1353
1354 while (*file == '{') {
1355 if ((e = switch_find_end_paren(tfile, '{', '}'))) {
1356 *e = '\0';
1357 file = e + 1;
1358 while(*file == ' ') file++;
1359 } else {
1360 tfile = NULL;
1361 break;
1362 }
1363 }
1364 }
1365
1366 file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "}" : "", prefix, SWITCH_PATH_SEPARATOR, file);
1367 }
1368 if ((ext = strrchr(file, '.'))) {
1369 ext++;
1370 } else {
1371
1372 if (!(backup_ext = switch_channel_get_variable(channel, "native_backup_extension"))) {
1373 backup_ext = "wav";
1374 }
1375
1376 ext = read_impl.iananame;
1377 backup_file = switch_core_session_sprintf(session, "%s.%s", file, backup_ext);
1378 file = switch_core_session_sprintf(session, "%s.%s", file, ext);
1379 }
1380 }
1381
1382 if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) {
1383 int maybe = atoi(prebuf);
1384 if (maybe > 0) {
1385 fh->prebuf = maybe;
1386 }
1387 }
1388
1389
1390 if (!fh->prefix) {
1391 fh->prefix = prefix;
1392 }
1393
1394 flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT;
1395
1396 if (switch_channel_test_flag(channel, CF_VIDEO)) {
1397 flags |= SWITCH_FILE_FLAG_VIDEO;
1398 //switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ);
1399 }
1400
1401
1402 for(;;) {
1403 if (switch_core_file_open(fh,
1404 file,
1405 read_impl.number_of_channels,
1406 read_impl.actual_samples_per_second, flags, NULL) == SWITCH_STATUS_SUCCESS) {
1407 break;
1408 }
1409
1410 if (backup_file) {
1411 file = backup_file;
1412 backup_file = NULL;
1413 } else {
1414 break;
1415 }
1416 }
1417
1418 if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) {
1419 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1420 status = SWITCH_STATUS_NOTFOUND;
1421 continue;
1422 }
1423
1424 switch_channel_audio_sync(channel);
1425 switch_core_session_io_write_lock(session);
1426 switch_channel_set_private(channel, "__fh", fh);
1427 switch_core_session_io_rwunlock(session);
1428
1429 if (switch_core_file_has_video(fh, SWITCH_TRUE)) {
1430 switch_core_media_set_video_file(session, fh, SWITCH_RW_WRITE);
1431 }
1432
1433 if (!abuf) {
1434 write_frame.buflen = FILE_STARTSAMPLES * sizeof(*abuf) * fh->channels;
1435 switch_zmalloc(abuf, write_frame.buflen);
1436 write_frame.data = abuf;
1437 }
1438
1439 if (sample_start > 0) {
1440 uint32_t pos = 0;
1441 switch_core_file_seek(fh, &pos, 0, SEEK_SET);
1442 switch_core_file_seek(fh, &pos, sample_start, SEEK_CUR);
1443 switch_clear_flag_locked(fh, SWITCH_FILE_SEEK);
1444 }
1445
1446 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_TITLE, &p) == SWITCH_STATUS_SUCCESS) {
1447 //title = switch_core_session_strdup(session, p);
1448 switch_channel_set_variable(channel, "RECORD_TITLE", p);
1449 }
1450
1451 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, &p) == SWITCH_STATUS_SUCCESS) {
1452 //copyright = switch_core_session_strdup(session, p);
1453 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", p);
1454 }
1455
1456 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, &p) == SWITCH_STATUS_SUCCESS) {
1457 //software = switch_core_session_strdup(session, p);
1458 switch_channel_set_variable(channel, "RECORD_SOFTWARE", p);
1459 }
1460
1461 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, &p) == SWITCH_STATUS_SUCCESS) {
1462 //artist = switch_core_session_strdup(session, p);
1463 switch_channel_set_variable(channel, "RECORD_ARTIST", p);
1464 }
1465
1466 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, &p) == SWITCH_STATUS_SUCCESS) {
1467 //comment = switch_core_session_strdup(session, p);
1468 switch_channel_set_variable(channel, "RECORD_COMMENT", p);
1469 }
1470
1471 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_DATE, &p) == SWITCH_STATUS_SUCCESS) {
1472 //date = switch_core_session_strdup(session, p);
1473 switch_channel_set_variable(channel, "RECORD_DATE", p);
1474 }
1475
1476 interval = read_impl.microseconds_per_packet / 1000;
1477
1478 codec_name = "L16";
1479
1480 if (!switch_core_codec_ready((&codec))) {
1481 if (switch_core_codec_init(&codec,
1482 codec_name,
1483 NULL,
1484 NULL,
1485 fh->samplerate,
1486 interval, read_impl.number_of_channels,
1487 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) {
1488 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
1489 SWITCH_LOG_DEBUG, "Codec Activated %s@%uhz %u channels %dms\n",
1490 codec_name, fh->samplerate, read_impl.number_of_channels, interval);
1491
1492
1493 } else {
1494 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
1495 "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name,
1496 fh->samplerate, read_impl.number_of_channels, interval);
1497 switch_core_session_io_write_lock(session);
1498 switch_channel_set_private(channel, "__fh", NULL);
1499 switch_core_session_io_rwunlock(session);
1500
1501 switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
1502
1503 switch_core_file_close(fh);
1504
1505 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1506 status = SWITCH_STATUS_GENERR;
1507 continue;
1508 }
1509 }
1510
1511 test_native = switch_test_flag(fh, SWITCH_FILE_NATIVE);
1512
1513 if (test_native) {
1514 write_frame.codec = switch_core_session_get_read_codec(session);
1515 samples = read_impl.samples_per_packet;
1516 framelen = read_impl.encoded_bytes_per_packet;
1517 channels = read_impl.number_of_channels;
1518 if (framelen == 0) {
1519 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel));
1520
1521 switch_core_session_io_write_lock(session);
1522 switch_channel_set_private(channel, "__fh", NULL);
1523 switch_core_session_io_rwunlock(session);
1524
1525 switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
1526 switch_core_file_close(fh);
1527
1528 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1529 status = SWITCH_STATUS_GENERR;
1530 continue;
1531
1532 }
1533 } else {
1534 write_frame.codec = &codec;
1535 samples = codec.implementation->samples_per_packet;
1536 framelen = codec.implementation->decoded_bytes_per_packet;
1537 channels = codec.implementation->number_of_channels;
1538 }
1539
1540 last_native = test_native;
1541
1542 if (timer_name && !timer.samplecount) {
1543 uint32_t len;
1544
1545 len = samples * 2 * channels;
1546 if (switch_core_timer_init(&timer, timer_name, interval, samples, pool) != SWITCH_STATUS_SUCCESS) {
1547 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Setup timer failed!\n");
1548 switch_core_codec_destroy(&codec);
1549 switch_core_session_io_write_lock(session);
1550 switch_channel_set_private(channel, "__fh", NULL);
1551 switch_core_session_io_rwunlock(session);
1552
1553 switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
1554
1555 switch_core_file_close(fh);
1556 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1557 status = SWITCH_STATUS_GENERR;
1558 continue;
1559 }
1560 switch_core_timer_sync(&timer); // Sync timer
1561 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
1562 "Setup timer success %u bytes per %d ms! %d ch\n", len, interval, codec.implementation->number_of_channels);
1563 }
1564 write_frame.rate = fh->samplerate;
1565 write_frame.channels = fh->channels;
1566 if (timer_name) {
1567 /* start a thread to absorb incoming audio */
1568 switch_core_service_session(session);
1569 }
1570
1571 ilen = samples * channels;
1572
1573 if (switch_event_create(&event, SWITCH_EVENT_PLAYBACK_START) == SWITCH_STATUS_SUCCESS) {
1574 switch_channel_event_set_data(channel, event);
1575 if (!strncasecmp(file, "local_stream:", 13)) {
1576 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "local_stream");
1577 }
1578 if (!strncasecmp(file, "tone_stream:", 12)) {
1579 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "tone_stream");
1580 }
1581 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Path", file);
1582 if (fh->params) {
1583 switch_event_merge(event, fh->params);
1584 }
1585 switch_event_fire(&event);
1586 }
1587
1588 if (!fh->audio_buffer) {
1589 switch_buffer_create_dynamic(&fh->audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0);
1590 switch_assert(fh->audio_buffer);
1591 }
1592
1593 for (;;) {
1594 int do_speed = 1;
1595 int f;
1596
1597 if (!switch_channel_ready(channel)) {
1598 status = SWITCH_STATUS_FALSE;
1599 break;
1600 }
1601
1602 if ((f = switch_channel_test_flag(channel, CF_BREAK))) {
1603 switch_channel_clear_flag(channel, CF_BREAK);
1604 if (f == 2) {
1605 done = 1;
1606 }
1607 status = SWITCH_STATUS_BREAK;
1608 break;
1609 }
1610
1611 switch_ivr_parse_all_events(session);
1612
1613 if (args) {
1614 /*
1615 dtmf handler function you can hook up to be executed when a digit is dialed during playback
1616 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
1617 */
1618 if (switch_channel_has_dtmf(channel)) {
1619 switch_channel_dequeue_dtmf(channel, &dtmf);
1620
1621 if (!args->input_callback && !args->buf && !args->dmachine) {
1622 status = SWITCH_STATUS_BREAK;
1623 done = 1;
1624 break;
1625 }
1626
1627
1628 if (args->dmachine) {
1629 char ds[2] = {dtmf.digit, '\0'};
1630 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
1631 break;
1632 }
1633 }
1634
1635 if (args->input_callback) {
1636 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
1637 } else if (args->buf) {
1638 *((char *) args->buf) = dtmf.digit;
1639 status = SWITCH_STATUS_BREAK;
1640 }
1641 }
1642
1643 if (args->input_callback) {
1644 switch_event_t *event;
1645
1646 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1647 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
1648 if (ostatus != SWITCH_STATUS_SUCCESS) {
1649 status = ostatus;
1650 }
1651
1652 switch_event_destroy(&event);
1653 }
1654 }
1655
1656 if (status != SWITCH_STATUS_SUCCESS) {
1657 done = 1;
1658 break;
1659 }
1660 }
1661
1662 buflen = FILE_STARTSAMPLES * sizeof(*abuf) * (fh->cur_channels > 0 ? fh->cur_channels : fh->channels);
1663
1664 if (buflen > write_frame.buflen) {
1665 abuf = realloc(abuf, buflen);
1666 write_frame.data = abuf;
1667 write_frame.buflen = buflen;
1668 }
1669
1670 if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
1671 if (framelen > FILE_STARTSAMPLES) {
1672 framelen = FILE_STARTSAMPLES;
1673 }
1674 memset(abuf, 255, framelen);
1675 olen = ilen;
1676 do_speed = 0;
1677 } else if (fh->sp_audio_buffer && (eof || (switch_buffer_inuse(fh->sp_audio_buffer) > (switch_size_t) (framelen)))) {
1678 if (!(bread = switch_buffer_read(fh->sp_audio_buffer, abuf, framelen))) {
1679 if (eof) {
1680 break;
1681 } else {
1682 continue;
1683 }
1684 }
1685
1686 if (bread < framelen) {
1687 memset(abuf + bread, 255, framelen - bread);
1688 }
1689
1690 olen = switch_test_flag(fh, SWITCH_FILE_NATIVE) ? framelen : ilen;
1691 do_speed = 0;
1692 } else if (fh->audio_buffer && (eof || (switch_buffer_inuse(fh->audio_buffer) > (switch_size_t) (framelen)))) {
1693 if (!(bread = switch_buffer_read(fh->audio_buffer, abuf, framelen))) {
1694 if (eof) {
1695 break;
1696 } else {
1697 continue;
1698 }
1699 }
1700
1701 fh->offset_pos += (uint32_t)(switch_test_flag(fh, SWITCH_FILE_NATIVE) ? bread : bread / 2);
1702
1703 if (bread < framelen) {
1704 memset(abuf + bread, 255, framelen - bread);
1705 }
1706
1707 olen = switch_test_flag(fh, SWITCH_FILE_NATIVE) ? framelen : ilen;
1708 } else {
1709 switch_status_t rstatus;
1710
1711 if (eof) {
1712 break;
1713 }
1714 olen = FILE_STARTSAMPLES;
1715 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
1716 olen /= 2;
1717 }
1718 switch_set_flag_locked(fh, SWITCH_FILE_BREAK_ON_CHANGE);
1719
1720 if ((rstatus = switch_core_file_read(fh, abuf, &olen)) == SWITCH_STATUS_BREAK) {
1721 continue;
1722 }
1723
1724 if (rstatus != SWITCH_STATUS_SUCCESS) {
1725 eof++;
1726 continue;
1727 }
1728
1729 test_native = switch_test_flag(fh, SWITCH_FILE_NATIVE);
1730
1731 if (test_native != last_native) {
1732 if (test_native) {
1733 write_frame.codec = switch_core_session_get_read_codec(session);
1734 framelen = read_impl.encoded_bytes_per_packet;
1735 if (framelen == 0) {
1736 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel));
1737 eof++;
1738 continue;
1739 }
1740 } else {
1741 write_frame.codec = &codec;
1742 framelen = codec.implementation->decoded_bytes_per_packet;
1743 }
1744 switch_buffer_zero(fh->audio_buffer);
1745 }
1746
1747 last_native = test_native;
1748
1749 switch_buffer_write(fh->audio_buffer, abuf, switch_test_flag(fh, SWITCH_FILE_NATIVE) ? olen : olen * 2 * fh->channels);
1750 olen = switch_buffer_read(fh->audio_buffer, abuf, framelen);
1751 fh->offset_pos += (uint32_t)(olen / 2);
1752
1753 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
1754 olen /= 2;
1755 }
1756
1757 }
1758
1759 if (done || olen <= 0) {
1760 break;
1761 }
1762
1763 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
1764 if (fh->speed > 2) {
1765 fh->speed = 2;
1766 } else if (fh->speed < -2) {
1767 fh->speed = -2;
1768 }
1769 }
1770
1771 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->audio_buffer && last_speed > -1 && last_speed != fh->speed) {
1772 switch_buffer_zero(fh->sp_audio_buffer);
1773 }
1774
1775 if (switch_test_flag(fh, SWITCH_FILE_SEEK)) {
1776 /* file position has changed flush the buffer */
1777 switch_buffer_zero(fh->audio_buffer);
1778 switch_clear_flag_locked(fh, SWITCH_FILE_SEEK);
1779 }
1780
1781
1782 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->speed && do_speed) {
1783 float factor = 0.25f * abs(fh->speed);
1784 switch_size_t newlen, supplement, step;
1785 short *bp = write_frame.data;
1786 switch_size_t wrote = 0;
1787
1788 supplement = (int) (factor * olen);
1789 if (!supplement) {
1790 supplement = 1;
1791 }
1792 newlen = (fh->speed > 0) ? olen - supplement : olen + supplement;
1793
1794 step = (fh->speed > 0) ? (newlen / supplement) : (olen / supplement);
1795
1796 if (!fh->sp_audio_buffer) {
1797 switch_buffer_create_dynamic(&fh->sp_audio_buffer, 1024, 1024, 0);
1798 }
1799
1800 while ((wrote + step) < newlen) {
1801 switch_buffer_write(fh->sp_audio_buffer, bp, step * 2);
1802 wrote += step;
1803 bp += step;
1804 if (fh->speed > 0) {
1805 bp++;
1806 } else {
1807 float f;
1808 short s;
1809 f = (float) (*bp + *(bp + 1) + *(bp - 1));
1810 f /= 3;
1811 s = (short) f;
1812 switch_buffer_write(fh->sp_audio_buffer, &s, 2);
1813 wrote++;
1814 }
1815 }
1816 if (wrote < newlen) {
1817 switch_size_t r = newlen - wrote;
1818 switch_buffer_write(fh->sp_audio_buffer, bp, r * 2);
1819 }
1820 last_speed = fh->speed;
1821 continue;
1822 }
1823
1824 if (olen < llen) {
1825 uint8_t *dp = (uint8_t *) write_frame.data;
1826 memset(dp + (int) olen, 255, (int) (llen - olen));
1827 olen = llen;
1828 }
1829
1830 if (!more_data) {
1831 if (timer_name) {
1832 if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) {
1833 break;
1834 }
1835 } else { /* time off the channel (if you must) */
1836 switch_frame_t *read_frame;
1837 switch_status_t tstatus;
1838
1839 while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
1840 switch_ivr_parse_all_messages(session);
1841 switch_yield(10000);
1842 }
1843
1844 tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_SINGLE_READ, 0);
1845
1846
1847 if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
1848 break;
1849 }
1850
1851 if (args && args->dmachine) {
1852 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
1853 break;
1854 }
1855 }
1856
1857 if (args && (args->read_frame_callback)) {
1858 int ok = 1;
1859 switch_set_flag_locked(fh, SWITCH_FILE_CALLBACK);
1860 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
1861 ok = 0;
1862 }
1863 switch_clear_flag_locked(fh, SWITCH_FILE_CALLBACK);
1864 if (!ok) {
1865 break;
1866 }
1867 }
1868 }
1869 }
1870
1871 more_data = 0;
1872 write_frame.samples = (uint32_t) olen;
1873
1874 if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
1875 write_frame.datalen = (uint32_t) olen;
1876 } else {
1877 write_frame.datalen = write_frame.samples * 2;
1878 }
1879
1880 llen = olen;
1881
1882 if (timer_name) {
1883 write_frame.timestamp = timer.samplecount;
1884 }
1885 #ifndef WIN32
1886 #if SWITCH_BYTE_ORDER == __BIG_ENDIAN
1887 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && l16) {
1888 switch_swap_linear(write_frame.data, (int) write_frame.datalen / 2);
1889 }
1890 #endif
1891 #endif
1892 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->vol) {
1893 switch_change_sln_volume(write_frame.data, write_frame.datalen / 2, fh->vol);
1894 }
1895
1896 /* write silence while dmachine is in reading state */
1897 if (args && args->dmachine && switch_ivr_dmachine_is_parsing(args->dmachine)) {
1898 memset(write_frame.data, 0, write_frame.datalen);
1899 }
1900
1901 status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
1902
1903 if (timeout_samples) {
1904 timeout_samples -= write_frame.samples;
1905 if (timeout_samples <= 0) {
1906 timeout_samples = 0;
1907 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "timeout reached playing file\n");
1908 if (timeout_as_success) {
1909 status = SWITCH_STATUS_SUCCESS;
1910 } else {
1911 status = SWITCH_STATUS_TIMEOUT;
1912 }
1913 done = 1;
1914 break;
1915 }
1916 }
1917
1918
1919 if (status == SWITCH_STATUS_MORE_DATA) {
1920 status = SWITCH_STATUS_SUCCESS;
1921 more_data = 1;
1922 continue;
1923 } else if (status != SWITCH_STATUS_SUCCESS) {
1924 done = 1;
1925 break;
1926 }
1927
1928 if (done) {
1929 break;
1930 }
1931 }
1932
1933 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done playing file %s\n", file);
1934 switch_channel_set_variable_printf(channel, "playback_last_offset_pos", "%d", fh->offset_pos);
1935
1936 if (read_impl.samples_per_second && fh->native_rate >= 1000) {
1937 switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_in / fh->native_rate);
1938 switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_in / (fh->native_rate / 1000));
1939 }
1940
1941 switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_in);
1942
1943 if (switch_event_create(&event, SWITCH_EVENT_PLAYBACK_STOP) == SWITCH_STATUS_SUCCESS) {
1944 switch_channel_event_set_data(channel, event);
1945 if (!strncasecmp(file, "local_stream:", 13)) {
1946 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "local_stream");
1947 }
1948 if (!strncasecmp(file, "tone_stream:", 12)) {
1949 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "tone_stream");
1950 }
1951 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Path", file);
1952 if (status == SWITCH_STATUS_BREAK) {
1953 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-Status", "break");
1954 } else {
1955 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-Status", "done");
1956 }
1957 if (fh->params) {
1958 switch_event_merge(event, fh->params);
1959 }
1960 switch_event_fire(&event);
1961 }
1962
1963 switch_core_session_io_write_lock(session);
1964 switch_channel_set_private(channel, "__fh", NULL);
1965 switch_core_session_io_rwunlock(session);
1966
1967 switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE);
1968 switch_core_file_close(fh);
1969
1970 if (fh->audio_buffer) {
1971 switch_buffer_destroy(&fh->audio_buffer);
1972 }
1973
1974 if (fh->sp_audio_buffer) {
1975 switch_buffer_destroy(&fh->sp_audio_buffer);
1976 }
1977 }
1978
1979 if (switch_core_codec_ready((&codec))) {
1980 switch_core_codec_destroy(&codec);
1981 }
1982
1983 if (timer.samplecount) {
1984 /* End the audio absorbing thread */
1985 switch_core_thread_session_end(session);
1986 switch_core_timer_destroy(&timer);
1987 }
1988
1989 switch_safe_free(abuf);
1990
1991 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE);
1992
1993 arg_recursion_check_stop(args);
1994
1995 if (timeout_samples && cumulative) {
1996 switch_channel_set_variable_printf(channel, "playback_timeout_sec_cumulative", "%d", timeout_samples / read_impl.actual_samples_per_second);
1997 }
1998
1999
2000 return status;
2001 }
2002
switch_ivr_wait_for_silence(switch_core_session_t * session,uint32_t thresh,uint32_t silence_hits,uint32_t listen_hits,uint32_t timeout_ms,const char * file)2003 SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_t *session, uint32_t thresh,
2004 uint32_t silence_hits, uint32_t listen_hits, uint32_t timeout_ms, const char *file)
2005 {
2006 uint32_t score, count = 0, j = 0;
2007 double energy = 0;
2008 switch_channel_t *channel = switch_core_session_get_channel(session);
2009 int divisor = 0;
2010 uint32_t org_silence_hits = silence_hits;
2011 uint32_t channels;
2012 switch_frame_t *read_frame;
2013 switch_status_t status = SWITCH_STATUS_FALSE;
2014 int16_t *data;
2015 uint32_t listening = 0;
2016 int countdown = 0;
2017 switch_codec_t raw_codec = { 0 };
2018 int16_t *abuf = NULL;
2019 switch_frame_t write_frame = { 0 };
2020 switch_file_handle_t fh = { 0 };
2021 int32_t sample_count = 0;
2022 switch_codec_implementation_t read_impl = { 0 };
2023 switch_core_session_get_read_impl(session, &read_impl);
2024
2025
2026 if (timeout_ms) {
2027 sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms;
2028 }
2029
2030 if (file) {
2031 if (switch_core_file_open(&fh,
2032 file,
2033 read_impl.number_of_channels,
2034 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
2035 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening playback file %s.\n", file);
2036 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
2037 return SWITCH_STATUS_NOTFOUND;
2038 }
2039 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
2040 write_frame.data = abuf;
2041 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
2042 }
2043
2044
2045 if (switch_core_codec_init(&raw_codec,
2046 "L16",
2047 NULL,
2048 NULL,
2049 read_impl.actual_samples_per_second,
2050 read_impl.microseconds_per_packet / 1000,
2051 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
2052 NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
2053
2054 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to initialize L16 codec.\n");
2055 status = SWITCH_STATUS_FALSE;
2056 goto end;
2057 }
2058
2059 write_frame.codec = &raw_codec;
2060
2061 divisor = read_impl.actual_samples_per_second / 8000;
2062 channels = read_impl.number_of_channels;
2063
2064 switch_core_session_set_read_codec(session, &raw_codec);
2065
2066 while (switch_channel_ready(channel)) {
2067
2068 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2069
2070 if (!SWITCH_READ_ACCEPTABLE(status)) {
2071 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to read frame.\n");
2072 break;
2073 }
2074
2075 if (sample_count) {
2076 sample_count -= raw_codec.implementation->samples_per_packet;
2077 if (sample_count <= 0) {
2078 switch_channel_set_variable(channel, "wait_for_silence_timeout", "true");
2079 switch_channel_set_variable_printf(channel, "wait_for_silence_listenhits", "%d", listening);
2080 switch_channel_set_variable_printf(channel, "wait_for_silence_silence_hits", "%d", silence_hits);
2081 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
2082 "switch_ivr_wait_for_silence: TIMEOUT after %d ms at %d listen hits, %d silence hits, %d countdown\n",
2083 timeout_ms, listening, (org_silence_hits - silence_hits), countdown);
2084 break;
2085 }
2086 }
2087
2088 if (abuf) {
2089 switch_size_t olen = raw_codec.implementation->samples_per_packet;
2090
2091 if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
2092 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to read file %s.\n", file);
2093 break;
2094 }
2095
2096 write_frame.samples = (uint32_t) olen;
2097 write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels);
2098 if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
2099 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to write frame from file %s.\n", file);
2100 break;
2101 }
2102 }
2103
2104 if (countdown) {
2105 if (!--countdown) {
2106 switch_channel_set_variable(channel, "wait_for_silence_timeout", "false");
2107 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "switch_ivr_wait_for_silence: SILENCE DETECTED\n");
2108 break;
2109 } else {
2110 continue;
2111 }
2112 }
2113
2114 data = (int16_t *) read_frame->data;
2115
2116 for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) {
2117 energy += abs(data[j++]);
2118 j += channels;
2119 }
2120
2121 score = (uint32_t) (energy / (read_frame->samples / divisor));
2122
2123 if (score >= thresh) {
2124 listening++;
2125 }
2126
2127 if (listening > listen_hits && score < thresh) {
2128 if (!--silence_hits) {
2129 countdown = 25;
2130 }
2131 } else {
2132 silence_hits = org_silence_hits;
2133 }
2134 }
2135
2136 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
2137 switch_core_codec_destroy(&raw_codec);
2138
2139 end:
2140
2141 if (abuf) {
2142
2143 switch_core_file_close(&fh);
2144 free(abuf);
2145 }
2146
2147 return status;
2148 }
2149
switch_ivr_detect_audio(switch_core_session_t * session,uint32_t thresh,uint32_t audio_hits,uint32_t timeout_ms,const char * file)2150 SWITCH_DECLARE(switch_status_t) switch_ivr_detect_audio(switch_core_session_t *session, uint32_t thresh,
2151 uint32_t audio_hits, uint32_t timeout_ms, const char *file)
2152 {
2153 uint32_t score, count = 0, j = 0;
2154 double energy = 0;
2155 switch_channel_t *channel = switch_core_session_get_channel(session);
2156 int divisor = 0;
2157 uint32_t channels;
2158 switch_frame_t *read_frame;
2159 switch_status_t status = SWITCH_STATUS_FALSE;
2160 int16_t *data;
2161 uint32_t hits = 0;
2162 switch_codec_t raw_codec = { 0 };
2163 int16_t *abuf = NULL;
2164 switch_frame_t write_frame = { 0 };
2165 switch_file_handle_t fh = { 0 };
2166 int32_t sample_count = 0;
2167 switch_codec_implementation_t read_impl = { 0 };
2168 switch_core_session_get_read_impl(session, &read_impl);
2169
2170 if (timeout_ms) {
2171 sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms;
2172 }
2173
2174 if (file) {
2175 if (switch_core_file_open(&fh,
2176 file,
2177 read_impl.number_of_channels,
2178 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
2179 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening playback file %s.\n", file);
2180 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
2181 return SWITCH_STATUS_NOTFOUND;
2182 }
2183 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
2184 write_frame.data = abuf;
2185 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
2186 }
2187
2188
2189 if (switch_core_codec_init(&raw_codec,
2190 "L16",
2191 NULL,
2192 NULL,
2193 read_impl.actual_samples_per_second,
2194 read_impl.microseconds_per_packet / 1000,
2195 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
2196 NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
2197
2198 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to initialize L16 codec.\n");
2199 status = SWITCH_STATUS_FALSE;
2200 goto end;
2201 }
2202
2203 write_frame.codec = &raw_codec;
2204
2205 divisor = read_impl.actual_samples_per_second / 8000;
2206 channels = read_impl.number_of_channels;
2207
2208 switch_core_session_set_read_codec(session, &raw_codec);
2209
2210 while (switch_channel_ready(channel)) {
2211
2212 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2213
2214 if (!SWITCH_READ_ACCEPTABLE(status)) {
2215 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to read frame.\n");
2216 break;
2217 }
2218
2219 if (sample_count) {
2220 sample_count -= raw_codec.implementation->samples_per_packet;
2221 if (sample_count <= 0) {
2222 switch_channel_set_variable(channel, "detect_audio_timeout", "true");
2223 switch_channel_set_variable_printf(channel, "detect_audio_hits", "%d", hits);
2224 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
2225 "switch_ivr_detect_audio: TIMEOUT after %d ms at %d hits\n",
2226 timeout_ms, hits);
2227 break;
2228 }
2229 }
2230
2231 if (abuf) {
2232 switch_size_t olen = raw_codec.implementation->samples_per_packet;
2233
2234 if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
2235 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to read file %s.\n", file);
2236 break;
2237 }
2238
2239 write_frame.samples = (uint32_t) olen;
2240 write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels);
2241 if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
2242 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to write frame from file %s.\n", file);
2243 break;
2244 }
2245 }
2246
2247 data = (int16_t *) read_frame->data;
2248
2249 for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) {
2250 energy += abs(data[j++]);
2251 j += channels;
2252 }
2253
2254 score = (uint32_t) (energy / (read_frame->samples / divisor));
2255
2256 if (score >= thresh) {
2257 hits++;
2258 } else {
2259 hits=0;
2260 }
2261
2262 if (hits > audio_hits) {
2263 switch_channel_set_variable(channel, "detect_audio_timeout", "false");
2264 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "switch_ivr_detect_audio: AUDIO DETECTED\n");
2265 break;
2266 }
2267 }
2268
2269 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
2270 switch_core_codec_destroy(&raw_codec);
2271
2272 end:
2273
2274 if (abuf) {
2275
2276 switch_core_file_close(&fh);
2277 free(abuf);
2278 }
2279
2280 return status;
2281 }
2282
switch_ivr_detect_silence(switch_core_session_t * session,uint32_t thresh,uint32_t silence_hits,uint32_t timeout_ms,const char * file)2283 SWITCH_DECLARE(switch_status_t) switch_ivr_detect_silence(switch_core_session_t *session, uint32_t thresh,
2284 uint32_t silence_hits, uint32_t timeout_ms, const char *file)
2285 {
2286 uint32_t score, count = 0, j = 0;
2287 double energy = 0;
2288 switch_channel_t *channel = switch_core_session_get_channel(session);
2289 int divisor = 0;
2290 uint32_t channels;
2291 switch_frame_t *read_frame;
2292 switch_status_t status = SWITCH_STATUS_FALSE;
2293 int16_t *data;
2294 uint32_t hits = 0;
2295 switch_codec_t raw_codec = { 0 };
2296 int16_t *abuf = NULL;
2297 switch_frame_t write_frame = { 0 };
2298 switch_file_handle_t fh = { 0 };
2299 int32_t sample_count = 0;
2300 switch_codec_implementation_t read_impl = { 0 };
2301 switch_core_session_get_read_impl(session, &read_impl);
2302
2303
2304 if (timeout_ms) {
2305 sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms;
2306 }
2307
2308 if (file) {
2309 if (switch_core_file_open(&fh,
2310 file,
2311 read_impl.number_of_channels,
2312 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
2313 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening playback file %s.\n", file);
2314 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
2315 return SWITCH_STATUS_NOTFOUND;
2316 }
2317 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
2318 write_frame.data = abuf;
2319 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
2320 }
2321
2322
2323 if (switch_core_codec_init(&raw_codec,
2324 "L16",
2325 NULL,
2326 NULL,
2327 read_impl.actual_samples_per_second,
2328 read_impl.microseconds_per_packet / 1000,
2329 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
2330 NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
2331
2332 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to initialize L16 codec.\n");
2333 status = SWITCH_STATUS_FALSE;
2334 goto end;
2335 }
2336
2337 write_frame.codec = &raw_codec;
2338
2339 divisor = read_impl.actual_samples_per_second / 8000;
2340 channels = read_impl.number_of_channels;
2341
2342 switch_core_session_set_read_codec(session, &raw_codec);
2343
2344 while (switch_channel_ready(channel)) {
2345
2346 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2347
2348 if (!SWITCH_READ_ACCEPTABLE(status)) {
2349 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to read frame.\n");
2350 break;
2351 }
2352
2353 if (sample_count) {
2354 sample_count -= raw_codec.implementation->samples_per_packet;
2355 if (sample_count <= 0) {
2356 switch_channel_set_variable(channel, "detect_silence_timeout", "true");
2357 switch_channel_set_variable_printf(channel, "detect_silence_hits", "%d", hits);
2358 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
2359 "switch_ivr_detect_silence: TIMEOUT after %d ms at %d hits\n",
2360 timeout_ms, hits);
2361 break;
2362 }
2363 }
2364
2365 if (abuf) {
2366 switch_size_t olen = raw_codec.implementation->samples_per_packet;
2367
2368 if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
2369 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to read file %s.\n", file);
2370 break;
2371 }
2372
2373 write_frame.samples = (uint32_t) olen;
2374 write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels);
2375 if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
2376 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failed to write frame from file %s.\n", file);
2377 break;
2378 }
2379 }
2380
2381 data = (int16_t *) read_frame->data;
2382
2383 for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) {
2384 energy += abs(data[j++]);
2385 j += channels;
2386 }
2387
2388 score = (uint32_t) (energy / (read_frame->samples / divisor));
2389
2390 if (score <= thresh) {
2391 hits++;
2392 } else {
2393 hits=0;
2394 }
2395
2396 if (hits > silence_hits) {
2397 switch_channel_set_variable(channel, "detect_silence_timeout", "false");
2398 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "switch_ivr_detect_silence: SILENCE DETECTED\n");
2399 break;
2400 }
2401 }
2402
2403 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
2404 switch_core_codec_destroy(&raw_codec);
2405
2406 end:
2407
2408 if (abuf) {
2409
2410 switch_core_file_close(&fh);
2411 free(abuf);
2412 }
2413
2414 return status;
2415 }
2416
switch_ivr_read(switch_core_session_t * session,uint32_t min_digits,uint32_t max_digits,const char * prompt_audio_file,const char * var_name,char * digit_buffer,switch_size_t digit_buffer_length,uint32_t timeout,const char * valid_terminators,uint32_t digit_timeout)2417 SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
2418 uint32_t min_digits,
2419 uint32_t max_digits,
2420 const char *prompt_audio_file,
2421 const char *var_name,
2422 char *digit_buffer,
2423 switch_size_t digit_buffer_length,
2424 uint32_t timeout,
2425 const char *valid_terminators,
2426 uint32_t digit_timeout)
2427
2428 {
2429 switch_channel_t *channel;
2430 switch_input_args_t args = { 0 };
2431 switch_status_t status = SWITCH_STATUS_SUCCESS;
2432 size_t len = 0;
2433 char tb[2] = "";
2434 int term_required = 0;
2435
2436
2437 if (valid_terminators && *valid_terminators == '=') {
2438 term_required = 1;
2439 }
2440
2441 switch_assert(session);
2442
2443 if (!digit_timeout) {
2444 digit_timeout = timeout;
2445 }
2446
2447 if (max_digits < min_digits) {
2448 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
2449 "Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits);
2450 max_digits = min_digits;
2451 }
2452
2453 channel = switch_core_session_get_channel(session);
2454 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, NULL);
2455
2456 if (var_name) {
2457 switch_channel_set_variable(channel, var_name, NULL);
2458 }
2459
2460 if ((min_digits && digit_buffer_length < min_digits) || digit_buffer_length < max_digits) {
2461 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Buffer too small!\n");
2462 return SWITCH_STATUS_FALSE;
2463 }
2464
2465 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
2466 return SWITCH_STATUS_FALSE;
2467 }
2468
2469 memset(digit_buffer, 0, digit_buffer_length);
2470 args.buf = digit_buffer;
2471 args.buflen = (uint32_t) digit_buffer_length;
2472
2473 if (!zstr(prompt_audio_file) && strcasecmp(prompt_audio_file, "silence")) {
2474 if ((status = switch_ivr_play_file(session, NULL, prompt_audio_file, &args)) == SWITCH_STATUS_BREAK) {
2475 status = SWITCH_STATUS_SUCCESS;
2476 }
2477 }
2478
2479 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
2480 goto end;
2481 }
2482
2483 len = strlen(digit_buffer);
2484
2485 if ((min_digits && len < min_digits) || len < max_digits) {
2486 args.buf = digit_buffer + len;
2487 args.buflen = (uint32_t) (digit_buffer_length - len);
2488 status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0],
2489 len ? digit_timeout : timeout, digit_timeout, 0);
2490 }
2491
2492
2493 if (tb[0]) {
2494 char *p;
2495
2496 switch_channel_set_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE, tb);
2497
2498 if (!zstr(valid_terminators) && (p = strchr(valid_terminators, tb[0]))) {
2499 if (p >= (valid_terminators + 1) && (*(p - 1) == '+' || *(p - 1) == 'x')) {
2500 switch_snprintf(digit_buffer + strlen(digit_buffer), digit_buffer_length - strlen(digit_buffer), "%s", tb);
2501 if (*(p - 1) == 'x') {
2502 status = SWITCH_STATUS_RESTART;
2503 }
2504 }
2505 }
2506 } else if (term_required) {
2507 status = SWITCH_STATUS_TOO_SMALL;
2508 }
2509
2510 len = strlen(digit_buffer);
2511 if ((min_digits && len < min_digits)) {
2512 status = SWITCH_STATUS_TOO_SMALL;
2513 }
2514
2515 switch (status) {
2516 case SWITCH_STATUS_SUCCESS:
2517 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "success");
2518 break;
2519 case SWITCH_STATUS_TIMEOUT:
2520 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "timeout");
2521 break;
2522 default:
2523 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "failure");
2524 break;
2525
2526 }
2527
2528 end:
2529
2530 if (status != SWITCH_STATUS_RESTART && max_digits == 1 && len == 1 && valid_terminators && strchr(valid_terminators, *digit_buffer)) {
2531 *digit_buffer = '\0';
2532 }
2533
2534 if (var_name && !zstr(digit_buffer)) {
2535 switch_channel_set_variable(channel, var_name, digit_buffer);
2536 }
2537
2538 return status;
2539
2540 }
2541
switch_play_and_get_digits(switch_core_session_t * session,uint32_t min_digits,uint32_t max_digits,uint32_t max_tries,uint32_t timeout,const char * valid_terminators,const char * prompt_audio_file,const char * bad_input_audio_file,const char * var_name,char * digit_buffer,uint32_t digit_buffer_length,const char * digits_regex,uint32_t digit_timeout,const char * transfer_on_failure)2542 SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t *session,
2543 uint32_t min_digits,
2544 uint32_t max_digits,
2545 uint32_t max_tries,
2546 uint32_t timeout,
2547 const char *valid_terminators,
2548 const char *prompt_audio_file,
2549 const char *bad_input_audio_file,
2550 const char *var_name,
2551 char *digit_buffer,
2552 uint32_t digit_buffer_length,
2553 const char *digits_regex,
2554 uint32_t digit_timeout,
2555 const char *transfer_on_failure)
2556 {
2557 switch_channel_t *channel = switch_core_session_get_channel(session);
2558 char *var_name_invalid = NULL;
2559
2560 if (!zstr(digits_regex) && !zstr(var_name)) {
2561 var_name_invalid = switch_mprintf("%s_invalid", var_name);
2562 switch_channel_set_variable(channel, var_name_invalid, NULL);
2563 switch_safe_free(var_name_invalid);
2564 }
2565
2566 while (switch_channel_ready(channel) && max_tries) {
2567 switch_status_t status;
2568
2569 memset(digit_buffer, 0, digit_buffer_length);
2570
2571 status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name,
2572 digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout);
2573
2574 if (status == SWITCH_STATUS_RESTART) {
2575 return status;
2576 }
2577
2578 if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) {
2579 status = SWITCH_STATUS_SUCCESS;
2580 }
2581
2582 if ((min_digits == 0) && (strlen(digit_buffer) == 0) && switch_channel_get_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE) != 0)
2583 {
2584 return SWITCH_STATUS_SUCCESS;
2585 }
2586
2587 if (!(status == SWITCH_STATUS_TOO_SMALL && strlen(digit_buffer) == 0)) {
2588 if (status == SWITCH_STATUS_SUCCESS) {
2589 if (!zstr(digit_buffer)) {
2590 if (zstr(digits_regex)) {
2591 return SWITCH_STATUS_SUCCESS;
2592 }
2593 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "Test Regex [%s][%s]\n", digit_buffer, digits_regex);
2594
2595 if (switch_regex_match(digit_buffer, digits_regex) == SWITCH_STATUS_SUCCESS) {
2596 return SWITCH_STATUS_SUCCESS;
2597 } else {
2598 switch_channel_set_variable(channel, var_name, NULL);
2599 if (!zstr(var_name)) {
2600 var_name_invalid = switch_mprintf("%s_invalid", var_name);
2601 switch_channel_set_variable(channel, var_name_invalid, digit_buffer);
2602 switch_safe_free(var_name_invalid);
2603 }
2604 }
2605 }
2606 }
2607 }
2608
2609 if (!switch_channel_ready(channel)) {
2610 break;
2611 }
2612
2613 switch_ivr_play_file(session, NULL, bad_input_audio_file, NULL);
2614 max_tries--;
2615 }
2616
2617 memset(digit_buffer, 0, digit_buffer_length);
2618
2619 /* If we get here then check for transfer-on-failure ext/dp/context */
2620 /* split this arg on spaces to get ext, dp, and context */
2621
2622 if (!zstr(transfer_on_failure)) {
2623 const char *failure_ext = NULL;
2624 const char *failure_dialplan = NULL;
2625 const char *failure_context = NULL;
2626 char *target[4];
2627 char *mydata = switch_core_session_strdup(session, transfer_on_failure);
2628 int argc;
2629
2630 argc = switch_separate_string(mydata, ' ', target, (sizeof(target) / sizeof(target[0])));
2631
2632 if ( argc < 1 ) {
2633 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Bad target for PAGD failure: [%s]\n", transfer_on_failure);
2634 return SWITCH_STATUS_FALSE;
2635 }
2636
2637 if ( argc > 0 ) {
2638 failure_ext = target[0];
2639 }
2640
2641 if ( argc > 1 ) {
2642 failure_dialplan = target[1];
2643 }
2644
2645 if ( argc > 2 ) {
2646 failure_context = target[2];
2647 }
2648
2649 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
2650 "PAGD failure! Transfer to: %s / %s / %s\n", failure_ext, failure_dialplan, failure_context);
2651
2652 switch_ivr_session_transfer(session,failure_ext, failure_dialplan, failure_context);
2653 return SWITCH_STATUS_FALSE;
2654 }
2655
2656 return SWITCH_STATUS_FALSE;
2657 }
2658
switch_ivr_speak_text_handle(switch_core_session_t * session,switch_speech_handle_t * sh,switch_codec_t * codec,switch_timer_t * timer,const char * text,switch_input_args_t * args)2659 SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session_t *session,
2660 switch_speech_handle_t *sh,
2661 switch_codec_t *codec, switch_timer_t *timer, const char *text, switch_input_args_t *args)
2662 {
2663 switch_channel_t *channel = switch_core_session_get_channel(session);
2664 short abuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
2665 switch_dtmf_t dtmf = { 0 };
2666 uint32_t len = 0;
2667 switch_size_t ilen = 0;
2668 switch_frame_t write_frame = { 0 };
2669 switch_status_t status = SWITCH_STATUS_SUCCESS;
2670 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
2671 switch_size_t extra = 0;
2672 char *tmp = NULL;
2673 const char *star, *pound, *p;
2674 switch_size_t starlen, poundlen;
2675
2676 if (!sh) {
2677 return SWITCH_STATUS_FALSE;
2678 }
2679
2680 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
2681 return SWITCH_STATUS_FALSE;
2682 }
2683
2684 if (!switch_core_codec_ready(codec)) {
2685 return SWITCH_STATUS_FALSE;
2686 }
2687
2688 arg_recursion_check_start(args);
2689
2690 write_frame.data = abuf;
2691 write_frame.buflen = sizeof(abuf);
2692
2693 len = sh->samples * 2 * sh->channels;
2694
2695 flags = 0;
2696
2697 if (!(star = switch_channel_get_variable(channel, "star_replace"))) {
2698 star = "star";
2699 }
2700 if (!(pound = switch_channel_get_variable(channel, "pound_replace"))) {
2701 pound = "pound";
2702 }
2703 starlen = strlen(star);
2704 poundlen = strlen(pound);
2705
2706
2707 for (p = text; p && *p; p++) {
2708 if (*p == '*') {
2709 extra += starlen;
2710 } else if (*p == '#') {
2711 extra += poundlen;
2712 }
2713 }
2714
2715 if (extra) {
2716 char *tp;
2717 switch_size_t mylen = strlen(text) + extra + 1;
2718 tmp = malloc(mylen);
2719 if (!tmp) {
2720 arg_recursion_check_stop(args);
2721 return SWITCH_STATUS_MEMERR;
2722 }
2723 memset(tmp, 0, mylen);
2724 tp = tmp;
2725 for (p = text; p && *p; p++) {
2726 if (*p == '*' ) {
2727 snprintf(tp + strlen(tp), sizeof(tp) - strlen(tp), "%s", star);
2728 tp += starlen;
2729 } else if (*p == '#') {
2730 snprintf(tp + strlen(tp), sizeof(tp) - strlen(tp), "%s", pound);
2731 tp += poundlen;
2732 } else {
2733 *tp++ = *p;
2734 }
2735 }
2736
2737 text = tmp;
2738 }
2739
2740 switch_core_speech_feed_tts(sh, text, &flags);
2741 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Speaking text: %s\n", text);
2742 switch_safe_free(tmp);
2743 text = NULL;
2744
2745 write_frame.rate = sh->rate;
2746 memset(write_frame.data, 0, len);
2747 write_frame.datalen = len;
2748 write_frame.samples = len / 2;
2749 write_frame.codec = codec;
2750
2751 switch_assert(codec->implementation != NULL);
2752
2753 switch_channel_audio_sync(channel);
2754
2755
2756 for (;;) {
2757 switch_event_t *event;
2758
2759 ilen = len;
2760
2761 if (!switch_channel_ready(channel)) {
2762 status = SWITCH_STATUS_FALSE;
2763 break;
2764 }
2765
2766 if (switch_channel_test_flag(channel, CF_BREAK)) {
2767 switch_channel_clear_flag(channel, CF_BREAK);
2768 status = SWITCH_STATUS_BREAK;
2769 break;
2770 }
2771
2772 switch_ivr_parse_all_events(session);
2773
2774 if (args) {
2775 /* dtmf handler function you can hook up to be executed when a digit is dialed during playback
2776 * if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
2777 */
2778 if (switch_channel_has_dtmf(channel)) {
2779 if (!args->input_callback && !args->buf && !args->dmachine) {
2780 status = SWITCH_STATUS_BREAK;
2781 break;
2782 }
2783 if (args->buf && !strcasecmp(args->buf, "_break_")) {
2784 status = SWITCH_STATUS_BREAK;
2785 } else {
2786 switch_channel_dequeue_dtmf(channel, &dtmf);
2787
2788 if (args->dmachine) {
2789 char ds[2] = {dtmf.digit, '\0'};
2790 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
2791 break;
2792 }
2793 }
2794
2795 if (args->input_callback) {
2796 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
2797 } else if (args->buf) {
2798 *((char *) args->buf) = dtmf.digit;
2799 status = SWITCH_STATUS_BREAK;
2800 }
2801 }
2802 }
2803
2804 if (args->input_callback) {
2805 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
2806 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
2807 if (ostatus != SWITCH_STATUS_SUCCESS) {
2808 status = ostatus;
2809 }
2810 switch_event_destroy(&event);
2811 }
2812 }
2813
2814 if (status != SWITCH_STATUS_SUCCESS) {
2815 break;
2816 }
2817 }
2818
2819 if (switch_test_flag(sh, SWITCH_SPEECH_FLAG_PAUSE)) {
2820 if (timer) {
2821 if (switch_core_timer_next(timer) != SWITCH_STATUS_SUCCESS) {
2822 break;
2823 }
2824 } else {
2825 switch_frame_t *read_frame;
2826 switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2827
2828 while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
2829 switch_ivr_parse_all_messages(session);
2830 switch_yield(10000);
2831 }
2832
2833 if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
2834 break;
2835 }
2836
2837 if (args && args->dmachine) {
2838 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
2839 goto done;
2840 }
2841 }
2842
2843 if (args && (args->read_frame_callback)) {
2844 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
2845 goto done;
2846 }
2847 }
2848 }
2849 continue;
2850 }
2851
2852
2853 flags = SWITCH_SPEECH_FLAG_BLOCKING;
2854 status = switch_core_speech_read_tts(sh, abuf, &ilen, &flags);
2855
2856 if (status != SWITCH_STATUS_SUCCESS) {
2857 if (status == SWITCH_STATUS_BREAK) {
2858 status = SWITCH_STATUS_SUCCESS;
2859 }
2860 break;
2861 }
2862
2863 write_frame.datalen = (uint32_t) ilen;
2864 write_frame.samples = (uint32_t) (ilen / 2 / sh->channels);
2865 if (timer) {
2866 write_frame.timestamp = timer->samplecount;
2867 }
2868 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
2869 break;
2870 }
2871
2872 if (timer) {
2873 if (switch_core_timer_next(timer) != SWITCH_STATUS_SUCCESS) {
2874 break;
2875 }
2876 } else { /* time off the channel (if you must) */
2877 switch_frame_t *read_frame;
2878 switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2879
2880 while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
2881 switch_ivr_parse_all_messages(session);
2882 switch_yield(10000);
2883 }
2884
2885 if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
2886 break;
2887 }
2888
2889 if (args && args->dmachine) {
2890 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
2891 goto done;
2892 }
2893 }
2894
2895 if (args && (args->read_frame_callback)) {
2896 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
2897 goto done;
2898 }
2899 }
2900 }
2901 }
2902
2903 done:
2904
2905 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done speaking text\n");
2906 flags = 0;
2907 switch_core_speech_flush_tts(sh);
2908
2909 arg_recursion_check_stop(args);
2910 return status;
2911 }
2912
2913 struct cached_speech_handle {
2914 char tts_name[80];
2915 char voice_name[80];
2916 switch_speech_handle_t sh;
2917 switch_codec_t codec;
2918 switch_timer_t timer;
2919 };
2920
2921 typedef struct cached_speech_handle cached_speech_handle_t;
2922
switch_ivr_clear_speech_cache(switch_core_session_t * session)2923 SWITCH_DECLARE(void) switch_ivr_clear_speech_cache(switch_core_session_t *session)
2924 {
2925 cached_speech_handle_t *cache_obj = NULL;
2926 switch_channel_t *channel = switch_core_session_get_channel(session);
2927
2928 if ((cache_obj = switch_channel_get_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME))) {
2929 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
2930 if (cache_obj->timer.interval) {
2931 switch_core_timer_destroy(&cache_obj->timer);
2932 }
2933 if (cache_obj->sh.speech_interface) {
2934 switch_core_speech_close(&cache_obj->sh, &flags);
2935 }
2936 switch_core_codec_destroy(&cache_obj->codec);
2937 switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, NULL);
2938 }
2939 }
2940
switch_ivr_speak_text(switch_core_session_t * session,const char * tts_name,const char * voice_name,const char * text,switch_input_args_t * args)2941 SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *session,
2942 const char *tts_name, const char *voice_name, const char *text, switch_input_args_t *args)
2943 {
2944 switch_channel_t *channel = switch_core_session_get_channel(session);
2945 uint32_t rate = 0;
2946 int interval = 0;
2947 uint32_t channels;
2948 switch_frame_t write_frame = { 0 };
2949 switch_timer_t ltimer, *timer;
2950 switch_codec_t lcodec, *codec;
2951 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
2952 char *codec_name;
2953 switch_status_t status = SWITCH_STATUS_SUCCESS;
2954 switch_speech_handle_t lsh, *sh;
2955 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
2956 const char *timer_name, *var;
2957 cached_speech_handle_t *cache_obj = NULL;
2958 int need_create = 1, need_alloc = 1;
2959 switch_codec_implementation_t read_impl = { 0 };
2960 switch_core_session_get_read_impl(session, &read_impl);
2961
2962 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
2963 return SWITCH_STATUS_FALSE;
2964 }
2965
2966 arg_recursion_check_start(args);
2967
2968 sh = ↰
2969 codec = &lcodec;
2970 timer = <imer;
2971
2972 if ((var = switch_channel_get_variable(channel, SWITCH_CACHE_SPEECH_HANDLES_VARIABLE)) && switch_true(var)) {
2973 if ((cache_obj = (cached_speech_handle_t *) switch_channel_get_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME))) {
2974 need_create = 0;
2975 if (!strcasecmp(cache_obj->tts_name, tts_name)) {
2976 need_alloc = 0;
2977 } else {
2978 switch_ivr_clear_speech_cache(session);
2979 }
2980 }
2981
2982 if (!cache_obj) {
2983 cache_obj = (cached_speech_handle_t *) switch_core_session_alloc(session, sizeof(*cache_obj));
2984 }
2985 if (need_alloc) {
2986 switch_copy_string(cache_obj->tts_name, tts_name, sizeof(cache_obj->tts_name));
2987 switch_copy_string(cache_obj->voice_name, voice_name, sizeof(cache_obj->voice_name));
2988 switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, cache_obj);
2989 }
2990 sh = &cache_obj->sh;
2991 codec = &cache_obj->codec;
2992 timer = &cache_obj->timer;
2993 }
2994
2995 timer_name = switch_channel_get_variable(channel, "timer_name");
2996
2997 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE);
2998
2999 rate = read_impl.actual_samples_per_second;
3000 interval = read_impl.microseconds_per_packet / 1000;
3001 channels = read_impl.number_of_channels;
3002
3003 if (need_create) {
3004 memset(sh, 0, sizeof(*sh));
3005 if ((status = switch_core_speech_open(sh, tts_name, voice_name, (uint32_t) rate, interval, read_impl.number_of_channels, &flags, NULL)) != SWITCH_STATUS_SUCCESS) {
3006 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid TTS module %s[%s]!\n", tts_name, voice_name);
3007 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
3008 switch_ivr_clear_speech_cache(session);
3009 arg_recursion_check_stop(args);
3010 return status;
3011 }
3012 } else if (cache_obj && strcasecmp(cache_obj->voice_name, voice_name)) {
3013 switch_copy_string(cache_obj->voice_name, voice_name, sizeof(cache_obj->voice_name));
3014 switch_core_speech_text_param_tts(sh, "voice", voice_name);
3015 }
3016
3017 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
3018 flags = 0;
3019 switch_core_speech_close(sh, &flags);
3020 arg_recursion_check_stop(args);
3021 return SWITCH_STATUS_FALSE;
3022 }
3023 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "OPEN TTS %s\n", tts_name);
3024
3025 codec_name = "L16";
3026
3027 if (need_create) {
3028 if (switch_core_codec_init(codec,
3029 codec_name,
3030 NULL,
3031 NULL, (int) rate, interval, channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
3032 pool) == SWITCH_STATUS_SUCCESS) {
3033 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
3034 } else {
3035 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed %s@%uhz 1 channel %dms\n", codec_name,
3036 rate, interval);
3037 flags = 0;
3038 switch_core_speech_close(sh, &flags);
3039 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
3040 switch_ivr_clear_speech_cache(session);
3041 arg_recursion_check_stop(args);
3042 return SWITCH_STATUS_GENERR;
3043 }
3044 }
3045
3046 write_frame.codec = codec;
3047
3048 if (timer_name) {
3049 if (need_create) {
3050 if (switch_core_timer_init(timer, timer_name, interval, (int) sh->samples, pool) != SWITCH_STATUS_SUCCESS) {
3051 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Setup timer failed!\n");
3052 switch_core_codec_destroy(write_frame.codec);
3053 flags = 0;
3054 switch_core_speech_close(sh, &flags);
3055 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
3056 switch_ivr_clear_speech_cache(session);
3057 arg_recursion_check_stop(args);
3058 return SWITCH_STATUS_GENERR;
3059 }
3060 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", sh->samples * 2,
3061 interval);
3062 }
3063 switch_core_timer_sync(timer); // Sync timer
3064
3065 /* start a thread to absorb incoming audio */
3066 switch_core_service_session(session);
3067
3068 }
3069
3070 status = switch_ivr_speak_text_handle(session, sh, write_frame.codec, timer_name ? timer : NULL, text, args);
3071 flags = 0;
3072
3073 if (!cache_obj) {
3074 switch_core_speech_close(sh, &flags);
3075 switch_core_codec_destroy(codec);
3076 }
3077
3078 if (timer_name) {
3079 /* End the audio absorbing thread */
3080 switch_core_thread_session_end(session);
3081 if (!cache_obj) {
3082 switch_core_timer_destroy(timer);
3083 }
3084 }
3085
3086 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
3087 arg_recursion_check_stop(args);
3088
3089 return status;
3090 }
3091
3092
hold_on_dtmf(switch_core_session_t * session,void * input,switch_input_type_t itype,void * buf,unsigned int buflen)3093 static switch_status_t hold_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
3094 {
3095 char *stop_key = (char *) buf;
3096
3097 switch (itype) {
3098 case SWITCH_INPUT_TYPE_DTMF:
3099 {
3100 switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
3101 if (dtmf->digit == *stop_key) {
3102 return SWITCH_STATUS_BREAK;
3103 }
3104 }
3105 break;
3106 default:
3107 break;
3108 }
3109
3110 return SWITCH_STATUS_SUCCESS;
3111 }
3112
switch_ivr_soft_hold(switch_core_session_t * session,const char * unhold_key,const char * moh_a,const char * moh_b)3113 SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *session, const char *unhold_key, const char *moh_a, const char *moh_b)
3114 {
3115 switch_channel_t *channel, *other_channel;
3116 switch_core_session_t *other_session;
3117 const char *other_uuid, *moh = NULL;
3118 int moh_br = 0;
3119 switch_input_args_t args = { 0 };
3120 args.input_callback = hold_on_dtmf;
3121 args.buf = (void *) unhold_key;
3122 args.buflen = (uint32_t) strlen(unhold_key);
3123
3124 switch_assert(session != NULL);
3125 channel = switch_core_session_get_channel(session);
3126 switch_assert(channel != NULL);
3127
3128 if ((other_uuid = switch_channel_get_partner_uuid(channel))) {
3129 if ((other_session = switch_core_session_locate(other_uuid))) {
3130 other_channel = switch_core_session_get_channel(other_session);
3131
3132 if (moh_b) {
3133 moh = moh_b;
3134 } else {
3135 moh = switch_channel_get_hold_music(other_channel);
3136 }
3137
3138 if (!zstr(moh) && strcasecmp(moh, "silence") && !switch_channel_test_flag(other_channel, CF_BROADCAST)) {
3139 switch_ivr_broadcast(other_uuid, moh, SMF_ECHO_ALEG | SMF_LOOP);
3140 moh_br++;
3141 }
3142
3143 if (moh_a) {
3144 moh = moh_a;
3145 } else {
3146 moh = switch_channel_get_hold_music(channel);
3147 }
3148
3149 if (!zstr(moh) && strcasecmp(moh, "silence")) {
3150 switch_ivr_play_file(session, NULL, moh, &args);
3151 } else {
3152 switch_ivr_collect_digits_callback(session, &args, 0, 0);
3153 }
3154
3155 if (moh_br) {
3156 switch_channel_stop_broadcast(other_channel);
3157 }
3158
3159 switch_core_session_rwunlock(other_session);
3160
3161
3162 return SWITCH_STATUS_SUCCESS;
3163 }
3164
3165 }
3166
3167 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel %s is not in a bridge\n", switch_channel_get_name(channel));
3168 return SWITCH_STATUS_FALSE;
3169
3170 }
3171
3172
3173
3174 typedef enum {
3175 /** playing initial prompt - allow barge in */
3176 SWITCH_COLLECT_INPUT_PROMPT = (1 << 0),
3177 /** looking for speech input */
3178 SWITCH_COLLECT_INPUT_SPEECH = (1 << 1),
3179 /** finished looking for speech input */
3180 SWITCH_COLLECT_INPUT_SPEECH_DONE = (1 << 2),
3181 /** looking for digits */
3182 SWITCH_COLLECT_INPUT_DIGITS = (1 << 3),
3183 /** finished looking for digits */
3184 SWITCH_COLLECT_INPUT_DIGITS_DONE = (1 << 4)
3185 } switch_collect_input_flags_t;
3186
3187 typedef struct {
3188 int flags;
3189 cJSON *recognition_result;
3190 char *digits;
3191 int min_digits;
3192 int max_digits;
3193 const char *terminators;
3194 char terminator;
3195 switch_time_t last_digit_time;
3196 } switch_collect_input_state_t;
3197
switch_collect_input_callback(switch_core_session_t * session,void * input,switch_input_type_t input_type,void * data,unsigned int len)3198 static switch_status_t switch_collect_input_callback(switch_core_session_t *session, void *input, switch_input_type_t input_type, void *data, unsigned int len)
3199 {
3200 switch_collect_input_state_t *state = (switch_collect_input_state_t *)data;
3201 switch_channel_t *channel = switch_core_session_get_channel(session);
3202
3203 if (switch_test_flag(state, SWITCH_COLLECT_INPUT_SPEECH) && input_type == SWITCH_INPUT_TYPE_EVENT) {
3204 const char *speech_type = NULL;
3205 switch_event_t *event = (switch_event_t *)input;
3206
3207 if (event->event_id != SWITCH_EVENT_DETECTED_SPEECH) return SWITCH_STATUS_SUCCESS;
3208
3209 speech_type = switch_event_get_header(event, "Speech-Type");
3210
3211 if (zstr(speech_type)) return SWITCH_STATUS_SUCCESS;
3212
3213 if (!strcasecmp(speech_type, "detected-speech")) {
3214 const char *result = switch_event_get_body(event);
3215
3216 /* stop waiting for speech */
3217 switch_set_flag(state, SWITCH_COLLECT_INPUT_SPEECH_DONE);
3218
3219 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) DETECTED SPEECH\n", switch_channel_get_name(channel));
3220
3221 if (!zstr(result)) {
3222 state->recognition_result = cJSON_Parse(result);
3223
3224 if (state->recognition_result) {
3225 const char *text = cJSON_GetObjectCstr(state->recognition_result, "text");
3226
3227 if (!zstr(text)) {
3228 /* stop waiting for digits */
3229 switch_set_flag(state, SWITCH_COLLECT_INPUT_DIGITS_DONE);
3230 }
3231 }
3232 }
3233 return SWITCH_STATUS_BREAK;
3234 }
3235
3236 if (!strcasecmp("closed", speech_type)) {
3237 /* stop waiting for speech */
3238 switch_set_flag(state, SWITCH_COLLECT_INPUT_SPEECH_DONE);
3239 return SWITCH_STATUS_BREAK;
3240 }
3241
3242 if (!strcasecmp(speech_type, "begin-speaking")) {
3243 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) START OF SPEECH\n", switch_channel_get_name(channel));
3244
3245 if (switch_test_flag(state, SWITCH_COLLECT_INPUT_PROMPT)) {
3246 /* barge in on prompt */
3247 return SWITCH_STATUS_BREAK;
3248 }
3249 }
3250
3251 }
3252
3253 if (switch_test_flag(state, SWITCH_COLLECT_INPUT_DIGITS) && input_type == SWITCH_INPUT_TYPE_DTMF) {
3254 switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
3255 state->last_digit_time = switch_micro_time_now();
3256
3257 if (!zstr(state->terminators) && strchr(state->terminators, dtmf->digit)) {
3258 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) ACCEPT TERMINATOR %c\n",
3259 switch_channel_get_name(channel), dtmf->digit);
3260
3261 state->terminator = dtmf->digit;
3262
3263 /* stop waiting for digits */
3264 switch_set_flag(state, SWITCH_COLLECT_INPUT_DIGITS_DONE);
3265
3266 if (switch_test_flag(state, SWITCH_COLLECT_INPUT_DIGITS) && !zstr(state->digits)) {
3267 /* stop waiting for speech */
3268 switch_set_flag(state, SWITCH_COLLECT_INPUT_SPEECH_DONE);
3269 }
3270
3271 /* barge-in and break playback on terminator */
3272 return SWITCH_STATUS_BREAK;
3273 }
3274
3275 if (!switch_test_flag(state, SWITCH_COLLECT_INPUT_DIGITS_DONE)) {
3276 int digits_collected = strlen(state->digits);
3277
3278 if (digits_collected < state->max_digits) {
3279 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) ACCEPT DIGIT %c\n",
3280 switch_channel_get_name(channel), dtmf->digit);
3281 state->digits[digits_collected] = dtmf->digit;
3282 }
3283
3284 if (digits_collected + 1 >= state->max_digits) {
3285 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) MAX DIGITS COLLECTED\n", switch_channel_get_name(channel));
3286 switch_set_flag(state, SWITCH_COLLECT_INPUT_DIGITS_DONE); // stop waiting for digits
3287 switch_set_flag(state, SWITCH_COLLECT_INPUT_SPEECH_DONE); // stop waiting for speech, too
3288 }
3289 }
3290 return SWITCH_STATUS_BREAK; // got a digit- break for inter-digit timeout / checking results / barge-in
3291 }
3292
3293 return SWITCH_STATUS_SUCCESS;
3294 }
3295
3296
3297
3298 /*!\brief Play prompt and collect input
3299 *
3300 * Returns collect status
3301 *
3302 * \param[in] session the current session
3303 *
3304 * \return Returns status
3305 * SWITCH_STATUS_SUCCESS when success
3306 * SWITCH_STATUS_FALSE when error
3307 * SWITCH_STATUS_GENERR when error
3308 */
switch_ivr_play_and_collect_input(switch_core_session_t * session,const char * prompt,const char * recognizer_mod_name,const char * recognizer_grammar,int min_digits,int max_digits,const char * terminators,uint32_t digit_timeout,cJSON ** recognition_result,char ** digits_collected,char * terminator_collected,switch_input_args_t * args)3309 SWITCH_DECLARE(switch_status_t) switch_ivr_play_and_collect_input(switch_core_session_t *session,
3310 const char *prompt,
3311 const char *recognizer_mod_name,
3312 const char *recognizer_grammar,
3313 int min_digits,
3314 int max_digits,
3315 const char *terminators,
3316 uint32_t digit_timeout,
3317 cJSON **recognition_result,
3318 char **digits_collected,
3319 char *terminator_collected,
3320 switch_input_args_t *args)
3321 {
3322 switch_status_t status = SWITCH_STATUS_FALSE;
3323 switch_input_args_t myargs = { 0 };
3324 switch_collect_input_state_t state = { 0 };
3325 switch_channel_t *channel = switch_core_session_get_channel(session);
3326
3327 arg_recursion_check_start(args);
3328
3329 /* configure digit collection */
3330 if (digit_timeout <= 0) digit_timeout = 5000;
3331 if (min_digits < 0) {
3332 min_digits = 0;
3333 }
3334
3335 /* check if digit collection is enabled */
3336 if (min_digits > 0) {
3337 if (max_digits < min_digits) {
3338 max_digits = min_digits;
3339 }
3340 if (max_digits > 100) {
3341 max_digits = 100;
3342 }
3343 state.digits = switch_core_session_alloc(session, sizeof(char) * (max_digits + 1));
3344 switch_set_flag(&state, SWITCH_COLLECT_INPUT_DIGITS);
3345 } else {
3346 switch_set_flag(&state, SWITCH_COLLECT_INPUT_DIGITS_DONE);
3347 }
3348
3349 state.min_digits = min_digits;
3350 state.max_digits = max_digits;
3351 if (!zstr(terminators)) {
3352 if (!strcasecmp(terminators, "any")) {
3353 state.terminators = "1234567890*#";
3354 } else if (!strcasecmp(terminators, "none")) {
3355 state.terminators = NULL;
3356 } else {
3357 state.terminators = terminators;
3358 }
3359 }
3360
3361 if (!args) {
3362 args = &myargs;
3363 }
3364
3365 /* start speech recognition, if enabled */
3366 if (recognizer_grammar && recognizer_mod_name) {
3367 if ((status = switch_ivr_detect_speech(session, recognizer_mod_name, recognizer_grammar, "", NULL, NULL)) != SWITCH_STATUS_SUCCESS) {
3368 /* map SWITCH_STATUS_FALSE to SWITCH_STATUS_GENERR to indicate grammar load failed
3369 SWITCH_STATUS_NOT_INITALIZED will be passed back to indicate ASR resource problem */
3370 if (status == SWITCH_STATUS_FALSE) {
3371 status = SWITCH_STATUS_GENERR;
3372 }
3373 goto done;
3374 }
3375 switch_set_flag(&state, SWITCH_COLLECT_INPUT_SPEECH);
3376 } else {
3377 switch_set_flag(&state, SWITCH_COLLECT_INPUT_SPEECH_DONE);
3378 }
3379
3380 /* play the prompt, looking for input result */
3381 args->input_callback = switch_collect_input_callback;
3382 args->buf = &state;
3383 args->buflen = sizeof(state);
3384 switch_set_flag(&state, SWITCH_COLLECT_INPUT_PROMPT);
3385 status = switch_ivr_play_file(session, NULL, prompt, args);
3386 switch_clear_flag(&state, SWITCH_COLLECT_INPUT_PROMPT);
3387
3388 if (args->dmachine && switch_ivr_dmachine_last_ping(args->dmachine) != SWITCH_STATUS_SUCCESS) {
3389 switch_set_flag(&state, SWITCH_COLLECT_INPUT_DIGITS_DONE);
3390 switch_set_flag(&state, SWITCH_COLLECT_INPUT_SPEECH_DONE);
3391 status = SWITCH_STATUS_SUCCESS;
3392 }
3393
3394 if (status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_SUCCESS) {
3395 status = SWITCH_STATUS_FALSE;
3396 goto done;
3397 }
3398
3399 // wait for final result if not done
3400 if (!switch_test_flag(&state, SWITCH_COLLECT_INPUT_DIGITS_DONE) || !switch_test_flag(&state, SWITCH_COLLECT_INPUT_SPEECH_DONE)) {
3401 int sleep_time = digit_timeout;
3402
3403 if (switch_test_flag(&state, SWITCH_COLLECT_INPUT_SPEECH)) {
3404 switch_ivr_detect_speech_start_input_timers(session);
3405 }
3406 state.last_digit_time = switch_micro_time_now();
3407
3408 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) WAITING FOR RESULT\n", switch_channel_get_name(channel));
3409
3410 while ((!switch_test_flag(&state, SWITCH_COLLECT_INPUT_DIGITS_DONE) || !switch_test_flag(&state, SWITCH_COLLECT_INPUT_SPEECH_DONE))
3411 && switch_channel_ready(channel)) {
3412
3413 status = switch_ivr_sleep(session, sleep_time, SWITCH_FALSE, args);
3414
3415 if (args->dmachine && switch_ivr_dmachine_last_ping(args->dmachine) != SWITCH_STATUS_SUCCESS) {
3416 // dmachine done
3417 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) DMACHINE DONE\n", switch_channel_get_name(channel));
3418 switch_set_flag(&state, SWITCH_COLLECT_INPUT_DIGITS_DONE);
3419 switch_set_flag(&state, SWITCH_COLLECT_INPUT_SPEECH_DONE);
3420 status = SWITCH_STATUS_SUCCESS;
3421 goto done;
3422 }
3423
3424 if (state.terminator != 0) {
3425 switch_set_flag(&state, SWITCH_COLLECT_INPUT_SPEECH_DONE);
3426 status = SWITCH_STATUS_SUCCESS;
3427 sleep_time = digit_timeout;
3428 continue;
3429 }
3430
3431 sleep_time = (switch_micro_time_now() - state.last_digit_time) / 1000;
3432 if (sleep_time >= digit_timeout) {
3433 // too much time since last digit
3434 if (!switch_test_flag(&state, SWITCH_COLLECT_INPUT_DIGITS_DONE)) {
3435 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) INTER-DIGIT TIMEOUT\n", switch_channel_get_name(channel));
3436 switch_set_flag(&state, SWITCH_COLLECT_INPUT_DIGITS_DONE);
3437 }
3438 status = SWITCH_STATUS_SUCCESS;
3439 sleep_time = digit_timeout;
3440 } else {
3441 // woke up early, sleep for remaining digit timeout
3442 sleep_time = digit_timeout - sleep_time;
3443 }
3444
3445 if (status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_SUCCESS) {
3446 // error of some sort
3447 status = SWITCH_STATUS_FALSE;
3448 goto done;
3449 }
3450
3451 }
3452 }
3453
3454 done:
3455
3456 if (status == SWITCH_STATUS_BREAK) {
3457 status = SWITCH_STATUS_SUCCESS;
3458 }
3459
3460 if (switch_test_flag(&state, SWITCH_COLLECT_INPUT_SPEECH)) {
3461 switch_ivr_pause_detect_speech(session);
3462 }
3463
3464 if (!zstr(state.digits) && strlen(state.digits) >= state.min_digits) {
3465 /* got DTMF result */
3466 if (digits_collected) {
3467 *digits_collected = state.digits;
3468 }
3469
3470 if (state.recognition_result) {
3471 cJSON_Delete(state.recognition_result);
3472 }
3473 } else if (state.recognition_result) {
3474 /* have some kind of recognition result or error */
3475 if (recognition_result) {
3476 *recognition_result = state.recognition_result;
3477 } else {
3478 cJSON_Delete(state.recognition_result);
3479 }
3480 }
3481
3482 if (terminator_collected && state.terminator != 0) {
3483 *terminator_collected = state.terminator;
3484 }
3485
3486 arg_recursion_check_stop(args);
3487
3488 return status;
3489 }
3490
3491
3492
3493 /* For Emacs:
3494 * Local Variables:
3495 * mode:c
3496 * indent-tabs-mode:t
3497 * tab-width:4
3498 * c-basic-offset:4
3499 * End:
3500 * For VIM:
3501 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
3502 */
3503