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