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