Bug Summary

File:src/switch_ivr_play_say.c
Location:line 1635, column 5
Description:Value stored to 'last_speed' is never read

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is 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
39SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) 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((void*)0), language = NULL((void*)0), macros = NULL((void*)0), phrases = NULL((void*)0), macro, input, action;
44 switch_status_t status = SWITCH_STATUS_GENERR;
45 const char *old_sound_prefix = NULL((void*)0), *sound_path = NULL((void*)0), *tts_engine = NULL((void*)0), *tts_voice = NULL((void*)0);
46 const char *module_name = NULL((void*)0), *chan_lang = NULL((void*)0);
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((void*)0);
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")switch_channel_get_variable_dup(channel, "sound_prefix_enforced"
, SWITCH_TRUE, -1)
);
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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 59, (const char*)(session)
, SWITCH_LOG_ERROR, "No phrase macro specified.\n");
60 return status;
61 }
62
63 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_play_say.c", (const char
*)__func__, 63, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
64
65 if (!lang) {
66 chan_lang = switch_channel_get_variable(channel, "default_language")switch_channel_get_variable_dup(channel, "default_language", SWITCH_TRUE
, -1)
;
67 if (!chan_lang) {
68 chan_lang = "en";
69 }
70 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 70, (const char*)(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)switch_event_create_subclass_detailed("src/switch_ivr_play_say.c"
, (const char * )(const char *)__func__, 75, &hint_data, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
76 switch_assert(hint_data)((hint_data) ? (void) (0) : __assert_fail ("hint_data", "src/switch_ivr_play_say.c"
, 76, __PRETTY_FUNCTION__))
;
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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 96, (const char*)(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)switch_core_perform_session_strdup(session, macro_name, "src/switch_ivr_play_say.c"
, (const char *)__func__, 118)
;
119 const char *group_sound_path;
120 const char *sound_prefix_enforced_str;
121
122 if ((p = strchr(macro_name_dup, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(macro_name_dup) && ('@') == '\0' ? (char *) __rawmemchr
(macro_name_dup, '@') : __builtin_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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 128, (const char*)(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)switch_channel_set_variable_var_check(channel, "sound_prefix_enforced"
, sound_prefix_enforced_str, SWITCH_TRUE)
;
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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 145, (const char*)(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"))(switch_channel_get_variable_dup(channel, "sound_prefix", SWITCH_TRUE
, -1) ? switch_channel_get_variable_dup(channel, "sound_prefix"
, SWITCH_TRUE, -1) : "")
;
152 p = switch_core_session_strdup(session, old_sound_prefix)switch_core_perform_session_strdup(session, old_sound_prefix,
"src/switch_ivr_play_say.c", (const char *)__func__, 152)
;
153 old_sound_prefix = p;
154 switch_channel_set_variable(channel, "sound_prefix", sound_path)switch_channel_set_variable_var_check(channel, "sound_prefix"
, sound_path, SWITCH_TRUE)
;
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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 165, (const char*)(session)
, SWITCH_LOG_ERROR, "Can't find any input tags.\n");
166 goto done;
167 }
168
169 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 169)
!= 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((void*)0);
179 char *field_expanded_alloc = NULL((void*)0);
180 switch_regex_t *re = NULL((void*)0);
181 int proceed = 0, ovector[100];
182 switch_xml_t match = NULL((void*)0);
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)switch_event_expand_headers_check(event, field, ((void*)0), (
(void*)0), 0)
;
190 } else {
191 field_expanded_alloc = switch_channel_expand_variables(channel, field)switch_channel_expand_variables_check(channel, field, ((void*
)0), ((void*)0), 0)
;
192 }
193
194 if (field_expanded_alloc == field) {
195 field_expanded_alloc = NULL((void*)0);
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((void*)0);
219 uint32_t len = 0;
220 char *odata = NULL((void*)0);
221 char *expanded = NULL((void*)0);
222
223 if (strchr(pattern, '(')(__extension__ (__builtin_constant_p ('(') && !__builtin_constant_p
(pattern) && ('(') == '\0' ? (char *) __rawmemchr (pattern
, '(') : __builtin_strchr (pattern, '(')))
&& strchr(adata, '$')(__extension__ (__builtin_constant_p ('$') && !__builtin_constant_p
(adata) && ('$') == '\0' ? (char *) __rawmemchr (adata
, '$') : __builtin_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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 226, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
227 switch_regex_safe_free(re)if (re) { switch_regex_free(re); re = ((void*)0); };
228 switch_safe_free(field_expanded_alloc)if (field_expanded_alloc) {free(field_expanded_alloc);field_expanded_alloc
=((void*)0);}
;
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)switch_event_expand_headers_check(event, odata, ((void*)0), (
(void*)0), 0)
;
240 } else {
241 expanded = switch_channel_expand_variables(channel, odata)switch_channel_expand_variables_check(channel, odata, ((void*
)0), ((void*)0), 0)
;
242 }
243
244 if (expanded == odata) {
245 expanded = NULL((void*)0);
246 } else {
247 odata = expanded;
248 }
249
250 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 250, (const char*)(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((void*)0), 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)switch_ivr_phrase_macro_event(session, name, odata, ((void*)0
), 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)switch_core_perform_session_strdup(session, odata, "src/switch_ivr_play_say.c"
, (const char *)__func__, 265)
;
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((void*)0)) {
273 status = switch_core_session_exec(session, app, cmd_args);
274 UNPROTECT_INTERFACE(app)if (app) {switch_mutex_lock(app->reflock); switch_thread_rwlock_unlock
(app->rwlock); switch_thread_rwlock_unlock(app->parent->
rwlock); app->refs--; app->parent->refs--; switch_mutex_unlock
(app->reflock);}
;
275 } else {
276 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 276, (const char*)(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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 292, (const char*)(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_engine) || zstr(tts_voice)_zstr(tts_voice)) {
306 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 306, (const char*)(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((void*)0));
313 switch_safe_free(expanded)if (expanded) {free(expanded);expanded=((void*)0);};
314 switch_safe_free(substituted)if (substituted) {free(substituted);substituted=((void*)0);};
315 if (done || status != SWITCH_STATUS_SUCCESS) break;
316 }
317 }
318
319 switch_regex_safe_free(re)if (re) { switch_regex_free(re); re = ((void*)0); };
320 switch_safe_free(field_expanded_alloc)if (field_expanded_alloc) {free(field_expanded_alloc);field_expanded_alloc
=((void*)0);}
;
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)if (args) args->loops--;
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_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 339, (const char*)(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)switch_channel_set_variable_var_check(channel, "sound_prefix"
, old_sound_prefix, SWITCH_TRUE)
;
344 }
345 if (local_sound_prefix_enforced == SWITCH_TRUE) {
346 switch_channel_set_variable(channel, "sound_prefix_enforced", NULL)switch_channel_set_variable_var_check(channel, "sound_prefix_enforced"
, ((void*)0), SWITCH_TRUE)
;
347 }
348
349 if (xml) {
350 switch_xml_free(xml);
351 }
352
353 return status;
354}
355
356SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) 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_frame_t *read_frame;
363 switch_codec_t codec, write_codec = { 0 };
364 char *codec_name;
365 switch_status_t status = SWITCH_STATUS_SUCCESS;
366 const char *p;
367 const char *vval;
368 time_t start = 0;
369 uint32_t org_silence_hits = 0;
370 int asis = 0;
371 int32_t sample_start = 0;
372 int waste_resources = 0, fill_cng = 0;
373 switch_codec_implementation_t read_impl = { 0 };
374 switch_frame_t write_frame = { 0 };
375 unsigned char write_buf[SWITCH_RECOMMENDED_BUFFER_SIZE8192] = { 0 };
376 switch_event_t *event;
377 int divisor = 0;
378 int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT;
379 int restart_limit_on_dtmf = 0;
380 const char *prefix, *var;
381
382
383 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 383)
!= SWITCH_STATUS_SUCCESS) {
384 return SWITCH_STATUS_FALSE;
385 }
386
387 prefix = switch_channel_get_variable(channel, "sound_prefix")switch_channel_get_variable_dup(channel, "sound_prefix", SWITCH_TRUE
, -1)
;
388
389 if (!prefix) {
390 prefix = SWITCH_GLOBAL_dirs.sounds_dir;
391 }
392
393 if (!switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
394 return SWITCH_STATUS_FALSE;
395 }
396
397 switch_core_session_get_read_impl(session, &read_impl);
398
399 if (!(divisor = read_impl.actual_samples_per_second / 8000)) {
400 divisor = 1;
401 }
402
403 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_play_say.c", (const char
*)__func__, 403, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
404
405 if (!fh) {
406 fh = &lfh;
407 }
408
409 fh->channels = read_impl.number_of_channels;
410 fh->native_rate = read_impl.actual_samples_per_second;
411
412 if (fh->samples > 0) {
413 sample_start = fh->samples;
414 fh->samples = 0;
415 }
416
417 if ((vval = switch_channel_get_variable(channel, "record_sample_rate")switch_channel_get_variable_dup(channel, "record_sample_rate"
, SWITCH_TRUE, -1)
)) {
418 int tmp = 0;
419
420 tmp = atoi(vval);
421
422 if (switch_is_valid_rate(tmp)(tmp == 8000 || tmp == 12000 || tmp == 16000 || tmp == 24000 ||
tmp == 32000 || tmp == 11025 || tmp == 22050 || tmp == 44100
|| tmp == 48000)
) {
423 fh->samplerate = tmp;
424 }
425 }
426
427
428 if ((vval = switch_channel_get_variable(channel, "record_fill_cng")switch_channel_get_variable_dup(channel, "record_fill_cng", SWITCH_TRUE
, -1)
)) {
429
430 if (!strcasecmp(vval, "true")) {
431 fill_cng = 1400;
432 } else {
433 if ((fill_cng = atoi(vval)) < 0) {
434 fill_cng = 0;
435 }
436 }
437 }
438
439
440 if ((vval = switch_channel_get_variable(channel, "record_waste_resources")switch_channel_get_variable_dup(channel, "record_waste_resources"
, SWITCH_TRUE, -1)
)) {
441
442 if (!strcasecmp(vval, "true")) {
443 waste_resources = 1400;
444 } else {
445 if ((waste_resources = atoi(vval)) < 0) {
446 waste_resources = 0;
447 }
448 }
449 }
450
451
452 if (fill_cng || waste_resources) {
453 if (switch_core_codec_init(&write_codec,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
454 "L16",switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
455 NULL,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
456 read_impl.actual_samples_per_second,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
457 read_impl.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
458 read_impl.number_of_channels,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
459 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
460 switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
== SWITCH_STATUS_SUCCESS) {
461 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 461, (const char*)(session)
, SWITCH_LOG_DEBUG, "Raw Codec Activated, ready to waste resources!\n");
462 write_frame.data = write_buf;
463 write_frame.buflen = sizeof(write_buf);
464 write_frame.datalen = read_impl.decoded_bytes_per_packet;
465 write_frame.samples = write_frame.datalen / 2;
466 write_frame.codec = &write_codec;
467 } else {
468 arg_recursion_check_stop(args)if (args) args->loops--;
469 return SWITCH_STATUS_FALSE;
470 }
471 }
472
473 if (!strstr(file, SWITCH_URL_SEPARATOR"://")) {
474 char *ext;
475
476 if (!switch_is_file_path(file)) {
477 char *tfile = NULL((void*)0);
478 char *e;
479
480 if (*file == '[') {
481 tfile = switch_core_session_strdup(session, file)switch_core_perform_session_strdup(session, file, "src/switch_ivr_play_say.c"
, (const char *)__func__, 481)
;
482 if ((e = switch_find_end_paren(tfile, '[', ']'))) {
483 *e = '\0';
484 file = e + 1;
485 } else {
486 tfile = NULL((void*)0);
487 }
488 }
489
490 file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile)(tfile ? tfile : ""), tfile ? "]" : "", prefix, SWITCH_PATH_SEPARATOR"/", file);
491 }
492 if ((ext = strrchr(file, '.'))) {
493 ext++;
494 } else {
495 ext = read_impl.iananame;
496 file = switch_core_session_sprintf(session, "%s.%s", file, ext);
497 asis = 1;
498 }
499 }
500
501 if (asis && read_impl.encoded_bytes_per_packet == 0) {
502 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 502, (const char*)(session)
, SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel));
503 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
504 arg_recursion_check_stop(args)if (args) args->loops--;
505 return SWITCH_STATUS_GENERR;
506 }
507
508
509 vval = switch_channel_get_variable(channel, "enable_file_write_buffering")switch_channel_get_variable_dup(channel, "enable_file_write_buffering"
, SWITCH_TRUE, -1)
;
510 if (!vval || switch_true(vval)) {
511 fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN65536;
512 }
513
514 if (switch_test_flag(fh, SWITCH_FILE_WRITE_APPEND)((fh)->flags & SWITCH_FILE_WRITE_APPEND) || ((p = switch_channel_get_variable(channel, "RECORD_APPEND")switch_channel_get_variable_dup(channel, "RECORD_APPEND", SWITCH_TRUE
, -1)
) && switch_true(p))) {
515 file_flags |= SWITCH_FILE_WRITE_APPEND;
516 }
517
518 if (switch_test_flag(fh, SWITCH_FILE_WRITE_OVER)((fh)->flags & SWITCH_FILE_WRITE_OVER) || ((p = switch_channel_get_variable(channel, "RECORD_WRITE_OVER")switch_channel_get_variable_dup(channel, "RECORD_WRITE_OVER",
SWITCH_TRUE, -1)
) && switch_true(p))) {
519 file_flags |= SWITCH_FILE_WRITE_OVER;
520 }
521
522 if (!fh->prefix) {
523 fh->prefix = prefix;
524 }
525
526 if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL)switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 526, fh, file, fh->channels, read_impl.actual_samples_per_second
, file_flags, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
527 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER)switch_channel_perform_hangup(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 527, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER
)
;
528 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
529 arg_recursion_check_stop(args)if (args) args->loops--;
530 return SWITCH_STATUS_GENERR;
531 }
532
533 if (sample_start > 0) {
534 uint32_t pos = 0;
535 switch_core_file_seek(fh, &pos, sample_start, SEEK_SET0);
536 switch_clear_flag(fh, SWITCH_FILE_SEEK)(fh)->flags &= ~(SWITCH_FILE_SEEK);
537 fh->samples = 0;
538 }
539
540
541 if (switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE)) {
542 asis = 1;
543 }
544
545 restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf")switch_channel_get_variable_dup(channel, "record_restart_limit_on_dtmf"
, SWITCH_TRUE, -1)
);
546
547 if ((p = switch_channel_get_variable(channel, "RECORD_TITLE")switch_channel_get_variable_dup(channel, "RECORD_TITLE", SWITCH_TRUE
, -1)
)) {
548 vval = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr_play_say.c"
, (const char *)__func__, 548)
;
549 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval);
550 switch_channel_set_variable(channel, "RECORD_TITLE", NULL)switch_channel_set_variable_var_check(channel, "RECORD_TITLE"
, ((void*)0), SWITCH_TRUE)
;
551 }
552
553 if ((p = switch_channel_get_variable(channel, "RECORD_COPYRIGHT")switch_channel_get_variable_dup(channel, "RECORD_COPYRIGHT", SWITCH_TRUE
, -1)
)) {
554 vval = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr_play_say.c"
, (const char *)__func__, 554)
;
555 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval);
556 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", NULL)switch_channel_set_variable_var_check(channel, "RECORD_COPYRIGHT"
, ((void*)0), SWITCH_TRUE)
;
557 }
558
559 if ((p = switch_channel_get_variable(channel, "RECORD_SOFTWARE")switch_channel_get_variable_dup(channel, "RECORD_SOFTWARE", SWITCH_TRUE
, -1)
)) {
560 vval = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr_play_say.c"
, (const char *)__func__, 560)
;
561 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval);
562 switch_channel_set_variable(channel, "RECORD_SOFTWARE", NULL)switch_channel_set_variable_var_check(channel, "RECORD_SOFTWARE"
, ((void*)0), SWITCH_TRUE)
;
563 }
564
565 if ((p = switch_channel_get_variable(channel, "RECORD_ARTIST")switch_channel_get_variable_dup(channel, "RECORD_ARTIST", SWITCH_TRUE
, -1)
)) {
566 vval = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr_play_say.c"
, (const char *)__func__, 566)
;
567 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval);
568 switch_channel_set_variable(channel, "RECORD_ARTIST", NULL)switch_channel_set_variable_var_check(channel, "RECORD_ARTIST"
, ((void*)0), SWITCH_TRUE)
;
569 }
570
571 if ((p = switch_channel_get_variable(channel, "RECORD_COMMENT")switch_channel_get_variable_dup(channel, "RECORD_COMMENT", SWITCH_TRUE
, -1)
)) {
572 vval = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr_play_say.c"
, (const char *)__func__, 572)
;
573 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval);
574 switch_channel_set_variable(channel, "RECORD_COMMENT", NULL)switch_channel_set_variable_var_check(channel, "RECORD_COMMENT"
, ((void*)0), SWITCH_TRUE)
;
575 }
576
577 if ((p = switch_channel_get_variable(channel, "RECORD_DATE")switch_channel_get_variable_dup(channel, "RECORD_DATE", SWITCH_TRUE
, -1)
)) {
578 vval = switch_core_session_strdup(session, p)switch_core_perform_session_strdup(session, p, "src/switch_ivr_play_say.c"
, (const char *)__func__, 578)
;
579 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval);
580 switch_channel_set_variable(channel, "RECORD_DATE", NULL)switch_channel_set_variable_var_check(channel, "RECORD_DATE",
((void*)0), SWITCH_TRUE)
;
581 }
582
583 if (!asis) {
584 codec_name = "L16";
585 if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
586 codec_name,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
587 NULL,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
588 read_impl.actual_samples_per_second,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
589 read_impl.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
590 read_impl.number_of_channels,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
591 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
592 switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, read_impl.number_of_channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), switch_core_session_get_pool
(session))
== SWITCH_STATUS_SUCCESS) {
593 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 593, (const char*)(session)
, SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
594 switch_core_session_set_read_codec(session, &codec);
595 } else {
596 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 596, (const char*)(session)
, SWITCH_LOG_ERROR,
597 "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
598 fh->channels, read_impl.microseconds_per_packet / 1000);
599 switch_core_file_close(fh);
600 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
601 arg_recursion_check_stop(args)if (args) args->loops--;
602 return SWITCH_STATUS_GENERR;
603 }
604 }
605
606 if (limit) {
607 start = switch_epoch_time_now(NULL((void*)0));
608 }
609
610 if (fh->thresh) {
611 if (asis) {
612 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 612, (const char*)(session)
, SWITCH_LOG_WARNING, "Can't detect silence on a native recording.\n");
613 } else {
614 if (fh->silence_hits) {
615 fh->silence_hits = fh->samplerate * fh->silence_hits / read_impl.samples_per_packet;
616 } else {
617 fh->silence_hits = fh->samplerate * 3 / read_impl.samples_per_packet;
618 }
619 org_silence_hits = fh->silence_hits;
620 }
621 }
622
623
624 if (switch_event_create(&event, SWITCH_EVENT_RECORD_START)switch_event_create_subclass_detailed("src/switch_ivr_play_say.c"
, (const char * )(const char *)__func__, 624, &event, SWITCH_EVENT_RECORD_START
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
625 switch_channel_event_set_data(channel, event);
626 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
627 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_play_say.c", (const
char * )(const char *)__func__, 627, &event, ((void*)0))
;
628 }
629
630 for (;;) {
631 switch_size_t len;
632
633 if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
634 status = SWITCH_STATUS_FALSE;
635 break;
636 }
637
638 if (switch_channel_test_flag(channel, CF_BREAK)) {
639 switch_channel_clear_flag(channel, CF_BREAK);
640 status = SWITCH_STATUS_BREAK;
641 break;
642 }
643
644 switch_ivr_parse_all_events(session);
645
646 if (start && (switch_epoch_time_now(NULL((void*)0)) - start) > limit) {
647 break;
648 }
649
650 if (args) {
651 /*
652 dtmf handler function you can hook up to be executed when a digit is dialed during playback
653 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
654 */
655 if (switch_channel_has_dtmf(channel)) {
656
657 if (limit && restart_limit_on_dtmf) {
658 start = switch_epoch_time_now(NULL((void*)0));
659 }
660
661 if (!args->input_callback && !args->buf && !args->dmachine) {
662 status = SWITCH_STATUS_BREAK;
663 break;
664 }
665 switch_channel_dequeue_dtmf(channel, &dtmf);
666
667 if (args->dmachine) {
668 char ds[2] = {dtmf.digit, '\0'};
669 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
670 break;
671 }
672 }
673
674 if (args->input_callback) {
675 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
676 } else if (args->buf) {
677 *((char *) args->buf) = dtmf.digit;
678 status = SWITCH_STATUS_BREAK;
679 }
680 }
681
682 if (args->input_callback) {
683 switch_event_t *event = NULL((void*)0);
684 switch_status_t ostatus;
685
686 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
687 if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) {
688 status = ostatus;
689 }
690
691 switch_event_destroy(&event);
692 }
693 }
694
695 if (status != SWITCH_STATUS_SUCCESS) {
696 break;
697 }
698 }
699
700 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
701 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
702 break;
703 }
704
705 if (args && args->dmachine) {
706 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
707 break;
708 }
709 }
710
711 if (args && (args->read_frame_callback)) {
712 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
713 break;
714 }
715 }
716
717 if (!asis && fh->thresh) {
718 int16_t *fdata = (int16_t *) read_frame->data;
719 uint32_t samples = read_frame->datalen / sizeof(*fdata);
720 uint32_t score, count = 0, j = 0;
721 double energy = 0;
722
723
724 for (count = 0; count < samples * read_impl.number_of_channels; count++) {
725 energy += abs(fdata[j++]);
726 }
727
728 score = (uint32_t) (energy / (samples / divisor));
729
730 if (score < fh->thresh) {
731 if (!--fh->silence_hits) {
732 break;
733 }
734 } else {
735 fh->silence_hits = org_silence_hits;
736 }
737 }
738
739 if (fill_cng) {
740 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, fill_cng);
741 } else if (waste_resources) {
742 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, read_impl.number_of_channels, waste_resources);
743 }
744
745 if (!switch_test_flag(fh, SWITCH_FILE_PAUSE)((fh)->flags & SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG)) {
746 int16_t *data = read_frame->data;
747 len = (switch_size_t) asis ? read_frame->datalen : read_frame->datalen / 2 / fh->channels;
748
749 if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
750 break;
751 }
752 } else if (switch_test_flag(read_frame, SFF_CNG)((read_frame)->flags & SFF_CNG) && fill_cng) {
753 len = write_frame.datalen / 2 / fh->channels;
754 if (switch_core_file_write(fh, write_frame.data, &len) != SWITCH_STATUS_SUCCESS) {
755 break;
756 }
757 }
758
759 if (waste_resources) {
760 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
761 break;
762 }
763 }
764
765 }
766
767 if (fill_cng || waste_resources) {
768 switch_core_codec_destroy(&write_codec);
769 }
770
771 switch_core_file_close(fh);
772
773
774 if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api")switch_channel_get_variable_dup(channel, "record_post_process_exec_api"
, SWITCH_TRUE, -1)
)) {
775 char *cmd = switch_core_session_strdup(session, var)switch_core_perform_session_strdup(session, var, "src/switch_ivr_play_say.c"
, (const char *)__func__, 775)
;
776 char *data, *expanded = NULL((void*)0);
777 switch_stream_handle_t stream = { 0 };
778
779 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "src/switch_ivr_play_say.c", 779, __PRETTY_FUNCTION__)); memset
(stream.data, 0, 1024); stream.end = stream.data; stream.data_size
= 1024; stream.write_function = switch_console_stream_write;
stream.raw_write_function = switch_console_stream_raw_write;
stream.alloc_len = 1024; stream.alloc_chunk = 1024
;
780
781 if ((data = strchr(cmd, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(cmd) && (':') == '\0' ? (char *) __rawmemchr (cmd, ':'
) : __builtin_strchr (cmd, ':')))
)) {
782 *data++ = '\0';
783 expanded = switch_channel_expand_variables(channel, data)switch_channel_expand_variables_check(channel, data, ((void*)
0), ((void*)0), 0)
;
784 }
785
786 switch_api_execute(cmd, expanded, session, &stream);
787
788 if (expanded && expanded != data) {
789 free(expanded);
790 }
791
792 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
793
794 }
795
796 if (read_impl.actual_samples_per_second) {
797 switch_channel_set_variable_printf(channel, "record_seconds", "%d", fh->samples_out / fh->native_rate);
798 switch_channel_set_variable_printf(channel, "record_ms", "%d", fh->samples_out / (fh->native_rate/ 1000));
799
800 }
801
802 switch_channel_set_variable_printf(channel, "record_samples", "%d", fh->samples_out);
803
804 if (switch_event_create(&event, SWITCH_EVENT_RECORD_STOP)switch_event_create_subclass_detailed("src/switch_ivr_play_say.c"
, (const char * )(const char *)__func__, 804, &event, SWITCH_EVENT_RECORD_STOP
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
805 switch_channel_event_set_data(channel, event);
806 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", file);
807 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_play_say.c", (const
char * )(const char *)__func__, 807, &event, ((void*)0))
;
808 }
809
810 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
811
812 arg_recursion_check_stop(args)if (args) args->loops--;
813 return status;
814}
815
816static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
817{
818 switch_buffer_t *audio_buffer = ts->user_data;
819 int wrote;
820
821 if (!audio_buffer) {
822 return -1;
823 }
824
825 wrote = teletone_mux_tones(ts, map);
826 switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
827
828 return 0;
829}
830
831SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_gentones(switch_core_session_t *session, const char *script, int32_t loops, switch_input_args_t *args)
832{
833 teletone_generation_session_t ts;
834 switch_dtmf_t dtmf = { 0 };
835 switch_buffer_t *audio_buffer;
836 switch_frame_t *read_frame = NULL((void*)0);
837 switch_codec_t write_codec = { 0 };
838 switch_frame_t write_frame = { 0 };
839 switch_byte_t data[SWITCH_RECOMMENDED_BUFFER_SIZE8192];
840 switch_channel_t *channel = switch_core_session_get_channel(session);
841 switch_codec_implementation_t read_impl = { 0 };
842 switch_core_session_get_read_impl(session, &read_impl);
843
844 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 844)
!= SWITCH_STATUS_SUCCESS) {
845 return SWITCH_STATUS_FALSE;
846 }
847
848 if (switch_core_codec_init(&write_codec,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
849 "L16",switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
850 NULL,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
851 read_impl.actual_samples_per_second,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
852 read_impl.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
853 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
854 NULL, switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&write_codec, "L16", (
(void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
!= SWITCH_STATUS_SUCCESS) {
855
856 return SWITCH_STATUS_FALSE;
857 }
858
859 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_play_say.c", (const char
*)__func__, 859, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
860
861 memset(&ts, 0, sizeof(ts));
862 write_frame.codec = &write_codec;
863 write_frame.data = data;
864 write_frame.buflen = sizeof(data);
865
866 switch_buffer_create_dynamic(&audio_buffer, 512, 1024, 0);
867 teletone_init_session(&ts, 0, teletone_handler, audio_buffer);
868 ts.rate = read_impl.actual_samples_per_second;
869 ts.channels = 1;
870 teletone_run(&ts, script);
871
872 if (loops) {
873 switch_buffer_set_loops(audio_buffer, loops);
874 }
875
876 for (;;) {
877 switch_status_t status;
878
879 if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
880 status = SWITCH_STATUS_FALSE;
881 break;
882 }
883
884 if (switch_channel_test_flag(channel, CF_BREAK)) {
885 switch_channel_clear_flag(channel, CF_BREAK);
886 status = SWITCH_STATUS_BREAK;
887 break;
888 }
889
890 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
891
892 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
893 break;
894 }
895
896 if (args && args->dmachine) {
897 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
898 break;
899 }
900 }
901
902 if (args && (args->read_frame_callback)) {
903 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
904 break;
905 }
906 }
907
908 switch_ivr_parse_all_events(session);
909
910 if (args) {
911 /*
912 dtmf handler function you can hook up to be executed when a digit is dialed during gentones
913 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
914 */
915 if (switch_channel_has_dtmf(channel)) {
916 if (!args->input_callback && !args->buf && !args->dmachine) {
917 status = SWITCH_STATUS_BREAK;
918 break;
919 }
920 switch_channel_dequeue_dtmf(channel, &dtmf);
921
922 if (args->dmachine) {
923 char ds[2] = {dtmf.digit, '\0'};
924 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
925 break;
926 }
927 }
928
929 if (args->input_callback) {
930 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
931 } else if (args->buf) {
932 *((char *) args->buf) = dtmf.digit;
933 status = SWITCH_STATUS_BREAK;
934 }
935 }
936
937 if (args->input_callback) {
938 switch_event_t *event;
939
940 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
941 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
942 if (ostatus != SWITCH_STATUS_SUCCESS) {
943 status = ostatus;
944 }
945 switch_event_destroy(&event);
946 }
947 }
948
949 if (status != SWITCH_STATUS_SUCCESS) {
950 break;
951 }
952 }
953
954 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(audio_buffer, write_frame.data, read_impl.decoded_bytes_per_packet)) <= 0) {
955 break;
956 }
957
958 write_frame.samples = write_frame.datalen / 2;
959
960 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
961 break;
962 }
963 }
964
965 switch_core_codec_destroy(&write_codec);
966 switch_buffer_destroy(&audio_buffer);
967 teletone_destroy_session(&ts);
968
969 arg_recursion_check_stop(args)if (args) args->loops--;
970
971 return SWITCH_STATUS_SUCCESS;
972}
973
974SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_get_file_handle(switch_core_session_t *session, switch_file_handle_t **fh)
975{
976 switch_file_handle_t *fhp;
977 switch_channel_t *channel = switch_core_session_get_channel(session);
978
979 *fh = NULL((void*)0);
980 switch_core_session_io_read_lock(session);
981
982 if ((fhp = switch_channel_get_private(channel, "__fh"))) {
983 *fh = fhp;
984 return SWITCH_STATUS_SUCCESS;
985 }
986
987 switch_core_session_io_rwunlock(session);
988
989 return SWITCH_STATUS_FALSE;
990}
991
992SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_release_file_handle(switch_core_session_t *session, switch_file_handle_t **fh)
993{
994 *fh = NULL((void*)0);
995 switch_core_session_io_rwunlock(session);
996
997 return SWITCH_STATUS_SUCCESS;
998}
999
1000#define FILE_STARTSAMPLES1024 * 32 1024 * 32
1001#define FILE_BLOCKSIZE1024 * 8 1024 * 8
1002#define FILE_BUFSIZE1024 * 64 1024 * 64
1003
1004SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) 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)
1005{
1006 switch_channel_t *channel = switch_core_session_get_channel(session);
1007 int16_t *abuf = NULL((void*)0);
1008 switch_dtmf_t dtmf = { 0 };
1009 uint32_t interval = 0, samples = 0, framelen, sample_start = 0;
1010 uint32_t ilen = 0;
1011 switch_size_t olen = 0, llen = 0;
1012 switch_frame_t write_frame = { 0 };
1013 switch_timer_t timer = { 0 };
1014 switch_codec_t codec = { 0 };
1015 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
1016 char *codec_name;
1017 switch_status_t status = SWITCH_STATUS_SUCCESS;
1018 switch_file_handle_t lfh;
1019 const char *p;
1020 //char *title = "", *copyright = "", *software = "", *artist = "", *comment = "", *date = "";
1021 char *ext;
1022 const char *prefix;
1023 const char *timer_name;
1024 const char *prebuf;
1025 const char *alt = NULL((void*)0);
1026 const char *sleep_val;
1027 const char *play_delimiter_val;
1028 char play_delimiter = 0;
1029 int sleep_val_i = 250;
1030 int eof = 0;
1031 switch_size_t bread = 0;
1032 int l16 = 0;
1033 switch_codec_implementation_t read_impl = { 0 };
1034 char *file_dup;
1035 char *argv[128] = { 0 };
1036 int argc;
1037 int cur;
1038 int done = 0;
1039 int timeout_samples = 0;
1040 switch_bool_t timeout_as_success = SWITCH_FALSE;
1041 const char *var;
1042 int more_data = 0;
1043 switch_event_t *event;
1044 uint32_t test_native = 0, last_native = 0;
1045 uint32_t buflen = 0;
1046
1047 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1047)
!= SWITCH_STATUS_SUCCESS) {
1048 return SWITCH_STATUS_FALSE;
1049 }
1050
1051 switch_core_session_get_read_impl(session, &read_impl);
1052
1053 if ((var = switch_channel_get_variable(channel, "playback_timeout_sec")switch_channel_get_variable_dup(channel, "playback_timeout_sec"
, SWITCH_TRUE, -1)
)) {
1054 int tmp = atoi(var);
1055 if (tmp > 1) {
1056 timeout_samples = read_impl.actual_samples_per_second * tmp;
1057 }
1058 }
1059
1060 if ((var = switch_channel_get_variable(channel, "playback_timeout_as_success")switch_channel_get_variable_dup(channel, "playback_timeout_as_success"
, SWITCH_TRUE, -1)
)) {
1061 if (switch_true(var)) {
1062 timeout_as_success = SWITCH_TRUE;
1063 }
1064 }
1065 if ((play_delimiter_val = switch_channel_get_variable(channel, "playback_delimiter")switch_channel_get_variable_dup(channel, "playback_delimiter"
, SWITCH_TRUE, -1)
)) {
1066 play_delimiter = *play_delimiter_val;
1067
1068 if ((sleep_val = switch_channel_get_variable(channel, "playback_sleep_val")switch_channel_get_variable_dup(channel, "playback_sleep_val"
, SWITCH_TRUE, -1)
)) {
1069 int tmp = atoi(sleep_val);
1070 if (tmp >= 0) {
1071 sleep_val_i = tmp;
1072 }
1073 }
1074 }
1075
1076 prefix = switch_channel_get_variable(channel, "sound_prefix")switch_channel_get_variable_dup(channel, "sound_prefix", SWITCH_TRUE
, -1)
;
1077 timer_name = switch_channel_get_variable(channel, "timer_name")switch_channel_get_variable_dup(channel, "timer_name", SWITCH_TRUE
, -1)
;
1078
1079 if (zstr(file)_zstr(file) || !switch_channel_media_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_TRUE)) {
1080 return SWITCH_STATUS_FALSE;
1081 }
1082
1083 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_play_say.c", (const char
*)__func__, 1083, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
1084
1085 if (!zstr(read_impl.iananame)_zstr(read_impl.iananame) && !strcasecmp(read_impl.iananame, "l16")) {
1086 l16++;
1087 }
1088
1089 if (play_delimiter) {
1090 file_dup = switch_core_session_strdup(session, file)switch_core_perform_session_strdup(session, file, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1090)
;
1091 argc = switch_separate_string(file_dup, play_delimiter, argv, (sizeof(argv) / sizeof(argv[0])));
1092 } else {
1093 argc = 1;
1094 argv[0] = (char *) file;
1095 }
1096
1097 if (!fh) {
1098 fh = &lfh;
1099 memset(fh, 0, sizeof(lfh));
1100 }
1101
1102 if (fh->samples > 0) {
1103 sample_start = fh->samples;
1104 fh->samples = 0;
1105 }
1106
1107
1108
1109
1110 for (cur = 0; switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && !done && cur < argc; cur++) {
1111 file = argv[cur];
1112 eof = 0;
1113
1114 if (cur) {
1115 fh->samples = sample_start = 0;
1116 if (sleep_val_i) {
1117 status = switch_ivr_sleep(session, sleep_val_i, SWITCH_FALSE, args);
1118 if(status != SWITCH_STATUS_SUCCESS) {
1119 break;
1120 }
1121 }
1122 }
1123
1124 status = SWITCH_STATUS_SUCCESS;
1125
1126 if ((alt = strchr(file, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(file) && (':') == '\0' ? (char *) __rawmemchr (file
, ':') : __builtin_strchr (file, ':')))
)) {
1127 char *dup;
1128
1129 if (!strncasecmp(file, "phrase:", 7)) {
1130 char *arg = NULL((void*)0);
1131 const char *lang = switch_channel_get_variable(channel, "language")switch_channel_get_variable_dup(channel, "language", SWITCH_TRUE
, -1)
;
1132 alt = file + 7;
1133 dup = switch_core_session_strdup(session, alt)switch_core_perform_session_strdup(session, alt, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1133)
;
1134
1135 if (dup) {
1136 if ((arg = strchr(dup, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(dup) && (':') == '\0' ? (char *) __rawmemchr (dup, ':'
) : __builtin_strchr (dup, ':')))
)) {
1137 *arg++ = '\0';
1138 }
1139 if ((status = switch_ivr_phrase_macro(session, dup, arg, lang, args)switch_ivr_phrase_macro_event(session, dup, arg, ((void*)0), lang
, args)
) != SWITCH_STATUS_SUCCESS) {
1140 arg_recursion_check_stop(args)if (args) args->loops--;
1141 return status;
1142 }
1143 continue;
1144 } else {
1145 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1145, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Args\n");
1146 continue;
1147 }
1148 } else if (!strncasecmp(file, "say:", 4)) {
1149 char *engine = NULL((void*)0), *voice = NULL((void*)0), *text = NULL((void*)0);
1150 alt = file + 4;
1151 dup = switch_core_session_strdup(session, alt)switch_core_perform_session_strdup(session, alt, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1151)
;
1152 engine = dup;
1153
1154 if (!zstr(engine)_zstr(engine)) {
1155 if ((voice = strchr(engine, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(engine) && (':') == '\0' ? (char *) __rawmemchr (engine
, ':') : __builtin_strchr (engine, ':')))
)) {
1156 *voice++ = '\0';
1157 if (!zstr(voice)_zstr(voice) && (text = strchr(voice, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(voice) && (':') == '\0' ? (char *) __rawmemchr (voice
, ':') : __builtin_strchr (voice, ':')))
)) {
1158 *text++ = '\0';
1159 }
1160 }
1161 }
1162
1163 if (!zstr(engine)_zstr(engine) && !zstr(voice)_zstr(voice) && !zstr(text)_zstr(text)) {
1164 if ((status = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) {
1165 arg_recursion_check_stop(args)if (args) args->loops--;
1166 return status;
1167 }
1168 } else {
1169 text = engine;
1170 engine = (char *) switch_channel_get_variable(channel, "tts_engine")switch_channel_get_variable_dup(channel, "tts_engine", SWITCH_TRUE
, -1)
;
1171 voice = (char *) switch_channel_get_variable(channel, "tts_voice")switch_channel_get_variable_dup(channel, "tts_voice", SWITCH_TRUE
, -1)
;
1172 if (engine && text) {
1173 if ((status = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) {
1174 arg_recursion_check_stop(args)if (args) args->loops--;
1175 return status;
1176 }
1177 } else {
1178 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1178, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid Args\n");
1179 }
1180 }
1181 continue;
1182 }
1183
1184 }
1185
1186 if (!prefix) {
1187 prefix = SWITCH_GLOBAL_dirs.base_dir;
1188 }
1189
1190 if (!strstr(file, SWITCH_URL_SEPARATOR"://")) {
1191 if (!switch_is_file_path(file)) {
1192 char *tfile = NULL((void*)0), *tfile2 = NULL((void*)0);
1193 char *e;
1194 int x;
1195
1196 for (x = 0; x < 2; x++) {
1197 if (*file == '[') {
1198 tfile = switch_core_session_strdup(session, file)switch_core_perform_session_strdup(session, file, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1198)
;
1199 if ((e = switch_find_end_paren(tfile, '[', ']'))) {
1200 *e = '\0';
1201 file = e + 1;
1202 } else {
1203 tfile = NULL((void*)0);
1204 }
1205 } else if (*file == '{') {
1206 tfile2 = switch_core_session_strdup(session, file)switch_core_perform_session_strdup(session, file, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1206)
;
1207 if ((e = switch_find_end_paren(tfile2, '{', '}'))) {
1208 *e = '\0';
1209 file = e + 1;
1210 } else {
1211 tfile2 = NULL((void*)0);
1212 }
1213 } else {
1214 break;
1215 }
1216 }
1217
1218 file = switch_core_session_sprintf(session, "%s%s%s%s%s%s%s", switch_str_nil(tfile)(tfile ? tfile : ""), tfile ? "]" : "", switch_str_nil(tfile2)(tfile2 ? tfile2 : ""), tfile2 ? "}" : "", prefix, SWITCH_PATH_SEPARATOR"/", file);
1219 }
1220 if ((ext = strrchr(file, '.'))) {
1221 ext++;
1222 } else {
1223 ext = read_impl.iananame;
1224 file = switch_core_session_sprintf(session, "%s.%s", file, ext);
1225 }
1226 }
1227
1228 if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer")switch_channel_get_variable_dup(channel, "stream_prebuffer", SWITCH_TRUE
, -1)
)) {
1229 int maybe = atoi(prebuf);
1230 if (maybe > 0) {
1231 fh->prebuf = maybe;
1232 }
1233 }
1234
1235
1236 if (!fh->prefix) {
1237 fh->prefix = prefix;
1238 }
1239
1240 if (switch_core_file_open(fh,switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1243, fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
1241 file,switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1243, fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
1242 read_impl.number_of_channels,switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1243, fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
1243 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1243, fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
1244 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1245 status = SWITCH_STATUS_NOTFOUND;
1246 continue;
1247 }
1248
1249 switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1249)
;
1250 switch_core_session_io_write_lock(session);
1251 switch_channel_set_private(channel, "__fh", fh);
1252 switch_core_session_io_rwunlock(session);
1253
1254
1255 if (!abuf) {
1256 buflen = write_frame.buflen = FILE_STARTSAMPLES1024 * 32 * sizeof(*abuf) * fh->channels;
1257 switch_zmalloc(abuf, write_frame.buflen)(void)((((abuf = calloc(1, (write_frame.buflen)))) ? (void) (
0) : __assert_fail ("(abuf = calloc(1, (write_frame.buflen)))"
, "src/switch_ivr_play_say.c", 1257, __PRETTY_FUNCTION__)),abuf
)
;
1258 write_frame.data = abuf;
1259 }
1260
1261 if (sample_start > 0) {
1262 uint32_t pos = 0;
1263 switch_core_file_seek(fh, &pos, 0, SEEK_SET0);
1264 switch_core_file_seek(fh, &pos, sample_start, SEEK_CUR1);
1265 switch_clear_flag(fh, SWITCH_FILE_SEEK)(fh)->flags &= ~(SWITCH_FILE_SEEK);
1266 }
1267
1268 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_TITLE, &p) == SWITCH_STATUS_SUCCESS) {
1269 //title = switch_core_session_strdup(session, p);
1270 switch_channel_set_variable(channel, "RECORD_TITLE", p)switch_channel_set_variable_var_check(channel, "RECORD_TITLE"
, p, SWITCH_TRUE)
;
1271 }
1272
1273 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, &p) == SWITCH_STATUS_SUCCESS) {
1274 //copyright = switch_core_session_strdup(session, p);
1275 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", p)switch_channel_set_variable_var_check(channel, "RECORD_COPYRIGHT"
, p, SWITCH_TRUE)
;
1276 }
1277
1278 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, &p) == SWITCH_STATUS_SUCCESS) {
1279 //software = switch_core_session_strdup(session, p);
1280 switch_channel_set_variable(channel, "RECORD_SOFTWARE", p)switch_channel_set_variable_var_check(channel, "RECORD_SOFTWARE"
, p, SWITCH_TRUE)
;
1281 }
1282
1283 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, &p) == SWITCH_STATUS_SUCCESS) {
1284 //artist = switch_core_session_strdup(session, p);
1285 switch_channel_set_variable(channel, "RECORD_ARTIST", p)switch_channel_set_variable_var_check(channel, "RECORD_ARTIST"
, p, SWITCH_TRUE)
;
1286 }
1287
1288 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, &p) == SWITCH_STATUS_SUCCESS) {
1289 //comment = switch_core_session_strdup(session, p);
1290 switch_channel_set_variable(channel, "RECORD_COMMENT", p)switch_channel_set_variable_var_check(channel, "RECORD_COMMENT"
, p, SWITCH_TRUE)
;
1291 }
1292
1293 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_DATE, &p) == SWITCH_STATUS_SUCCESS) {
1294 //date = switch_core_session_strdup(session, p);
1295 switch_channel_set_variable(channel, "RECORD_DATE", p)switch_channel_set_variable_var_check(channel, "RECORD_DATE",
p, SWITCH_TRUE)
;
1296 }
1297
1298 interval = read_impl.microseconds_per_packet / 1000;
1299
1300 if (!fh->audio_buffer) {
1301 switch_buffer_create_dynamic(&fh->audio_buffer, FILE_BLOCKSIZE1024 * 8, FILE_BUFSIZE1024 * 64, 0);
1302 switch_assert(fh->audio_buffer)((fh->audio_buffer) ? (void) (0) : __assert_fail ("fh->audio_buffer"
, "src/switch_ivr_play_say.c", 1302, __PRETTY_FUNCTION__))
;
1303 }
1304
1305 codec_name = "L16";
1306
1307 if (!switch_core_codec_ready((&codec))) {
1308 if (switch_core_codec_init(&codec,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), fh->samplerate, interval, read_impl.number_of_channels
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), pool)
1309 codec_name,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), fh->samplerate, interval, read_impl.number_of_channels
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), pool)
1310 NULL,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), fh->samplerate, interval, read_impl.number_of_channels
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), pool)
1311 fh->samplerate,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), fh->samplerate, interval, read_impl.number_of_channels
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), pool)
1312 interval, read_impl.number_of_channels,switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), fh->samplerate, interval, read_impl.number_of_channels
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), pool)
1313 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool)switch_core_codec_init_with_bitrate(&codec, codec_name, (
(void*)0), fh->samplerate, interval, read_impl.number_of_channels
, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, ((void
*)0), pool)
== SWITCH_STATUS_SUCCESS) {
1314 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1314, (const char*)(session)
,
1315 SWITCH_LOG_DEBUG, "Codec Activated %s@%uhz %u channels %dms\n",
1316 codec_name, fh->samplerate, read_impl.number_of_channels, interval);
1317
1318
1319 } else {
1320 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1320, (const char*)(session)
, SWITCH_LOG_DEBUG,
1321 "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name,
1322 fh->samplerate, read_impl.number_of_channels, interval);
1323 switch_core_session_io_write_lock(session);
1324 switch_channel_set_private(channel, "__fh", NULL((void*)0));
1325 switch_core_session_io_rwunlock(session);
1326
1327 switch_core_file_close(fh);
1328
1329 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1330 status = SWITCH_STATUS_GENERR;
1331 continue;
1332 }
1333 }
1334
1335 test_native = switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE);
1336
1337 if (test_native) {
1338 write_frame.codec = switch_core_session_get_read_codec(session);
1339 samples = read_impl.samples_per_packet;
1340 framelen = read_impl.encoded_bytes_per_packet;
1341 if (framelen == 0) {
1342 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1342, (const char*)(session)
, SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel));
1343
1344 switch_core_session_io_write_lock(session);
1345 switch_channel_set_private(channel, "__fh", NULL((void*)0));
1346 switch_core_session_io_rwunlock(session);
1347
1348 switch_core_file_close(fh);
1349
1350 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1351 status = SWITCH_STATUS_GENERR;
1352 continue;
1353
1354 }
1355 } else {
1356 write_frame.codec = &codec;
1357 samples = codec.implementation->samples_per_packet;
1358 framelen = codec.implementation->decoded_bytes_per_packet;
1359 }
1360
1361 last_native = test_native;
1362
1363 if (timer_name && !timer.samplecount) {
1364 uint32_t len;
1365
1366 len = samples * 2;
1367 if (switch_core_timer_init(&timer, timer_name, interval, samples / codec.implementation->number_of_channels, pool) != SWITCH_STATUS_SUCCESS) {
1368 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1368, (const char*)(session)
, SWITCH_LOG_ERROR, "Setup timer failed!\n");
1369 switch_core_codec_destroy(&codec);
1370 switch_core_session_io_write_lock(session);
1371 switch_channel_set_private(channel, "__fh", NULL((void*)0));
1372 switch_core_session_io_rwunlock(session);
1373 switch_core_file_close(fh);
1374 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1375 status = SWITCH_STATUS_GENERR;
1376 continue;
1377 }
1378 switch_core_timer_sync(&timer); // Sync timer
1379 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1379, (const char*)(session)
, SWITCH_LOG_DEBUG,
1380 "Setup timer success %u bytes per %d ms! %d ch\n", len, interval, codec.implementation->number_of_channels);
1381 }
1382 write_frame.rate = fh->samplerate;
1383
1384 if (timer_name) {
1385 /* start a thread to absorb incoming audio */
1386 switch_core_service_session(session)switch_core_service_session_av(session, SWITCH_TRUE, SWITCH_FALSE
)
;
1387 }
1388
1389 ilen = samples;
1390
1391 if (switch_event_create(&event, SWITCH_EVENT_PLAYBACK_START)switch_event_create_subclass_detailed("src/switch_ivr_play_say.c"
, (const char * )(const char *)__func__, 1391, &event, SWITCH_EVENT_PLAYBACK_START
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1392 switch_channel_event_set_data(channel, event);
1393 if (!strncasecmp(file, "local_stream:", 13)) {
1394 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "local_stream");
1395 }
1396 if (!strncasecmp(file, "tone_stream:", 12)) {
1397 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "tone_stream");
1398 }
1399 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Path", file);
1400 if (fh->params) {
1401 switch_event_merge(event, fh->params);
1402 }
1403 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_play_say.c", (const
char * )(const char *)__func__, 1403, &event, ((void*)0)
)
;
1404 }
1405
1406 for (;;) {
1407 int do_speed = 1;
1408 int last_speed = -1;
1409 int f;
1410
1411 if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
1412 status = SWITCH_STATUS_FALSE;
1413 break;
1414 }
1415
1416 if ((f = switch_channel_test_flag(channel, CF_BREAK))) {
1417 switch_channel_clear_flag(channel, CF_BREAK);
1418 if (f == 2) {
1419 done = 1;
1420 }
1421 status = SWITCH_STATUS_BREAK;
1422 break;
1423 }
1424
1425 switch_ivr_parse_all_events(session);
1426
1427 if (args) {
1428 /*
1429 dtmf handler function you can hook up to be executed when a digit is dialed during playback
1430 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
1431 */
1432 if (switch_channel_has_dtmf(channel)) {
1433 if (!args->input_callback && !args->buf && !args->dmachine) {
1434 status = SWITCH_STATUS_BREAK;
1435 done = 1;
1436 break;
1437 }
1438 switch_channel_dequeue_dtmf(channel, &dtmf);
1439
1440 if (args->dmachine) {
1441 char ds[2] = {dtmf.digit, '\0'};
1442 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
1443 break;
1444 }
1445 }
1446
1447 if (args->input_callback) {
1448 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
1449 } else if (args->buf) {
1450 *((char *) args->buf) = dtmf.digit;
1451 status = SWITCH_STATUS_BREAK;
1452 }
1453 }
1454
1455 if (args->input_callback) {
1456 switch_event_t *event;
1457
1458 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1459 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
1460 if (ostatus != SWITCH_STATUS_SUCCESS) {
1461 status = ostatus;
1462 }
1463
1464 switch_event_destroy(&event);
1465 }
1466 }
1467
1468 if (status != SWITCH_STATUS_SUCCESS) {
1469 done = 1;
1470 break;
1471 }
1472 }
1473
1474 buflen = FILE_STARTSAMPLES1024 * 32 * sizeof(*abuf) * fh->cur_channels ? fh->cur_channels : fh->channels;
1475
1476 if (buflen > write_frame.buflen) {
1477 abuf = realloc(abuf, buflen);
1478 write_frame.data = abuf;
1479 write_frame.buflen = buflen;
1480 }
1481
1482 if (switch_test_flag(fh, SWITCH_FILE_PAUSE)((fh)->flags & SWITCH_FILE_PAUSE)) {
1483 if (framelen > FILE_STARTSAMPLES1024 * 32) {
1484 framelen = FILE_STARTSAMPLES1024 * 32;
1485 }
1486 memset(abuf, 255, framelen);
1487 olen = ilen;
1488 do_speed = 0;
1489 } else if (fh->sp_audio_buffer && (eof || (switch_buffer_inuse(fh->sp_audio_buffer) > (switch_size_t) (framelen)))) {
1490 if (!(bread = switch_buffer_read(fh->sp_audio_buffer, abuf, framelen))) {
1491 if (eof) {
1492 continue;
1493 } else {
1494 break;
1495 }
1496 }
1497
1498 if (bread < framelen) {
1499 memset(abuf + bread, 255, framelen - bread);
1500 }
1501
1502 olen = switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) ? framelen : ilen;
1503 do_speed = 0;
1504 } else if (fh->audio_buffer && (eof || (switch_buffer_inuse(fh->audio_buffer) > (switch_size_t) (framelen)))) {
1505 if (!(bread = switch_buffer_read(fh->audio_buffer, abuf, framelen))) {
1506 if (eof) {
1507 break;
1508 } else {
1509 continue;
1510 }
1511 }
1512
1513 fh->offset_pos += (uint32_t)(switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) ? bread : bread / 2);
1514
1515 if (bread < framelen) {
1516 memset(abuf + bread, 255, framelen - bread);
1517 }
1518
1519 olen = switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) ? framelen : ilen;
1520 } else {
1521 switch_status_t rstatus;
1522
1523 if (eof) {
1524 break;
1525 }
1526 olen = FILE_STARTSAMPLES1024 * 32;
1527 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE)) {
1528 olen /= 2;
1529 }
1530 switch_set_flag(fh, SWITCH_FILE_BREAK_ON_CHANGE)(fh)->flags |= (SWITCH_FILE_BREAK_ON_CHANGE);
1531
1532 if ((rstatus = switch_core_file_read(fh, abuf, &olen)) == SWITCH_STATUS_BREAK) {
1533 continue;
1534 }
1535
1536 if (rstatus != SWITCH_STATUS_SUCCESS) {
1537 eof++;
1538 continue;
1539 }
1540
1541 test_native = switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE);
1542
1543 if (test_native != last_native) {
1544 if (test_native) {
1545 write_frame.codec = switch_core_session_get_read_codec(session);
1546 samples = read_impl.samples_per_packet;
1547 framelen = read_impl.encoded_bytes_per_packet;
1548 if (framelen == 0) {
1549 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1549, (const char*)(session)
, SWITCH_LOG_ERROR, "%s cannot play or record native files with variable length data\n", switch_channel_get_name(channel));
1550 eof++;
1551 continue;
1552 }
1553 } else {
1554 write_frame.codec = &codec;
1555 samples = codec.implementation->samples_per_packet;
1556 framelen = codec.implementation->decoded_bytes_per_packet;
1557 }
1558 switch_buffer_zero(fh->audio_buffer);
1559 }
1560
1561 last_native = test_native;
1562
1563 switch_buffer_write(fh->audio_buffer, abuf, switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) ? olen : olen * 2 * fh->channels);
1564 olen = switch_buffer_read(fh->audio_buffer, abuf, framelen);
1565 fh->offset_pos += (uint32_t)(olen / 2);
1566
1567 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE)) {
1568 olen /= 2;
1569 }
1570
1571 }
1572
1573 if (done || olen <= 0) {
1574 break;
1575 }
1576
1577 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE)) {
1578 if (fh->speed > 2) {
1579 fh->speed = 2;
1580 } else if (fh->speed < -2) {
1581 fh->speed = -2;
1582 }
1583 }
1584
1585 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) && fh->audio_buffer && last_speed > -1 && last_speed != fh->speed) {
1586 switch_buffer_zero(fh->sp_audio_buffer);
1587 }
1588
1589 if (switch_test_flag(fh, SWITCH_FILE_SEEK)((fh)->flags & SWITCH_FILE_SEEK)) {
1590 /* file position has changed flush the buffer */
1591 switch_buffer_zero(fh->audio_buffer);
1592 switch_clear_flag(fh, SWITCH_FILE_SEEK)(fh)->flags &= ~(SWITCH_FILE_SEEK);
1593 }
1594
1595
1596 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) && fh->speed && do_speed) {
1597 float factor = 0.25f * abs(fh->speed);
1598 switch_size_t newlen, supplement, step;
1599 short *bp = write_frame.data;
1600 switch_size_t wrote = 0;
1601
1602 supplement = (int) (factor * olen);
1603 if (!supplement) {
1604 supplement = 1;
1605 }
1606 newlen = (fh->speed > 0) ? olen - supplement : olen + supplement;
1607
1608 step = (fh->speed > 0) ? (newlen / supplement) : (olen / supplement);
1609
1610 if (!fh->sp_audio_buffer) {
1611 switch_buffer_create_dynamic(&fh->sp_audio_buffer, 1024, 1024, 0);
1612 }
1613
1614 while ((wrote + step) < newlen) {
1615 switch_buffer_write(fh->sp_audio_buffer, bp, step * 2);
1616 wrote += step;
1617 bp += step;
1618 if (fh->speed > 0) {
1619 bp++;
1620 } else {
1621 float f;
1622 short s;
1623 f = (float) (*bp + *(bp + 1) + *(bp - 1));
1624 f /= 3;
1625 s = (short) f;
1626 switch_buffer_write(fh->sp_audio_buffer, &s, 2);
1627 wrote++;
1628 }
1629 }
1630 if (wrote < newlen) {
1631 switch_size_t r = newlen - wrote;
1632 switch_buffer_write(fh->sp_audio_buffer, bp, r * 2);
1633 wrote += r;
1634 }
1635 last_speed = fh->speed;
Value stored to 'last_speed' is never read
1636 continue;
1637 }
1638
1639 if (olen < llen) {
1640 uint8_t *dp = (uint8_t *) write_frame.data;
1641 memset(dp + (int) olen, 255, (int) (llen - olen));
1642 olen = llen;
1643 }
1644
1645 if (!more_data) {
1646 if (timer_name) {
1647 if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) {
1648 break;
1649 }
1650 } else { /* time off the channel (if you must) */
1651 switch_frame_t *read_frame;
1652 switch_status_t tstatus;
1653
1654 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_flag(channel, CF_HOLD)) {
1655 switch_ivr_parse_all_messages(session);
1656 switch_yield(10000)switch_sleep(10000);;
1657 }
1658
1659 tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_SINGLE_READ, 0);
1660
1661
1662 if (!SWITCH_READ_ACCEPTABLE(tstatus)(tstatus == SWITCH_STATUS_SUCCESS || tstatus == SWITCH_STATUS_BREAK
|| tstatus == SWITCH_STATUS_INUSE)
) {
1663 break;
1664 }
1665
1666 if (args && args->dmachine) {
1667 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
1668 break;
1669 }
1670 }
1671
1672 if (args && (args->read_frame_callback)) {
1673 int ok = 1;
1674 switch_set_flag(fh, SWITCH_FILE_CALLBACK)(fh)->flags |= (SWITCH_FILE_CALLBACK);
1675 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
1676 ok = 0;
1677 }
1678 switch_clear_flag(fh, SWITCH_FILE_CALLBACK)(fh)->flags &= ~(SWITCH_FILE_CALLBACK);
1679 if (!ok) {
1680 break;
1681 }
1682 }
1683 }
1684 }
1685
1686 more_data = 0;
1687 write_frame.samples = (uint32_t) olen;
1688
1689 if (switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE)) {
1690 write_frame.datalen = (uint32_t) olen;
1691 } else {
1692 write_frame.datalen = write_frame.samples * 2;
1693 }
1694
1695 llen = olen;
1696
1697 if (timer_name) {
1698 write_frame.timestamp = timer.samplecount;
1699 }
1700#ifndef WIN32
1701#if SWITCH_BYTE_ORDER == __BIG_ENDIAN4321
1702 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) && l16) {
1703 switch_swap_linear(write_frame.data, (int) write_frame.datalen / 2);
1704 }
1705#endif
1706#endif
1707 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)((fh)->flags & SWITCH_FILE_NATIVE) && fh->vol) {
1708 switch_change_sln_volume(write_frame.data, write_frame.datalen / 2, fh->vol);
1709 }
1710
1711 /* write silence while dmachine is in reading state */
1712 if (args && args->dmachine && switch_ivr_dmachine_is_parsing(args->dmachine)) {
1713 memset(write_frame.data, 0, write_frame.datalen);
1714 }
1715
1716 status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
1717
1718 if (timeout_samples) {
1719 timeout_samples -= write_frame.samples;
1720 if (timeout_samples <= 0) {
1721 timeout_samples = 0;
1722 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1722, (const char*)(session)
, SWITCH_LOG_DEBUG, "timeout reached playing file\n");
1723 if (timeout_as_success) {
1724 status = SWITCH_STATUS_SUCCESS;
1725 } else {
1726 status = SWITCH_STATUS_TIMEOUT;
1727 }
1728 break;
1729 }
1730 }
1731
1732
1733 if (status == SWITCH_STATUS_MORE_DATA) {
1734 status = SWITCH_STATUS_SUCCESS;
1735 more_data = 1;
1736 continue;
1737 } else if (status != SWITCH_STATUS_SUCCESS) {
1738 done = 1;
1739 break;
1740 }
1741
1742 if (done) {
1743 break;
1744 }
1745 }
1746
1747 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1747, (const char*)(session)
, SWITCH_LOG_DEBUG, "done playing file %s\n", file);
1748 switch_channel_set_variable_printf(channel, "playback_last_offset_pos", "%d", fh->offset_pos);
1749
1750 if (read_impl.samples_per_second) {
1751 switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_in / fh->native_rate);
1752 switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_in / (fh->native_rate / 1000));
1753 }
1754 switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_in);
1755
1756 if (switch_event_create(&event, SWITCH_EVENT_PLAYBACK_STOP)switch_event_create_subclass_detailed("src/switch_ivr_play_say.c"
, (const char * )(const char *)__func__, 1756, &event, SWITCH_EVENT_PLAYBACK_STOP
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1757 switch_channel_event_set_data(channel, event);
1758 if (!strncasecmp(file, "local_stream:", 13)) {
1759 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "local_stream");
1760 }
1761 if (!strncasecmp(file, "tone_stream:", 12)) {
1762 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Type", "tone_stream");
1763 }
1764 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Path", file);
1765 if (status == SWITCH_STATUS_BREAK) {
1766 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-Status", "break");
1767 } else {
1768 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-Status", "done");
1769 }
1770 if (fh->params) {
1771 switch_event_merge(event, fh->params);
1772 }
1773 switch_event_fire(&event)switch_event_fire_detailed("src/switch_ivr_play_say.c", (const
char * )(const char *)__func__, 1773, &event, ((void*)0)
)
;
1774 }
1775
1776 switch_core_session_io_write_lock(session);
1777 switch_channel_set_private(channel, "__fh", NULL((void*)0));
1778 switch_core_session_io_rwunlock(session);
1779
1780 switch_core_file_close(fh);
1781
1782 if (fh->audio_buffer) {
1783 switch_buffer_destroy(&fh->audio_buffer);
1784 }
1785
1786 if (fh->sp_audio_buffer) {
1787 switch_buffer_destroy(&fh->sp_audio_buffer);
1788 }
1789 }
1790
1791 if (switch_core_codec_ready((&codec))) {
1792 switch_core_codec_destroy(&codec);
1793 }
1794
1795 if (timer.samplecount) {
1796 /* End the audio absorbing thread */
1797 switch_core_thread_session_end(session);
1798 switch_core_timer_destroy(&timer);
1799 }
1800
1801 switch_safe_free(abuf)if (abuf) {free(abuf);abuf=((void*)0);};
1802
1803 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE);
1804
1805 arg_recursion_check_stop(args)if (args) args->loops--;
1806
1807 return status;
1808}
1809
1810SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_wait_for_silence(switch_core_session_t *session, uint32_t thresh,
1811 uint32_t silence_hits, uint32_t listen_hits, uint32_t timeout_ms, const char *file)
1812{
1813 uint32_t score, count = 0, j = 0;
1814 double energy = 0;
1815 switch_channel_t *channel = switch_core_session_get_channel(session);
1816 int divisor = 0;
1817 uint32_t org_silence_hits = silence_hits;
1818 uint32_t channels;
1819 switch_frame_t *read_frame;
1820 switch_status_t status = SWITCH_STATUS_FALSE;
1821 int16_t *data;
1822 uint32_t listening = 0;
1823 int countdown = 0;
1824 switch_codec_t raw_codec = { 0 };
1825 int16_t *abuf = NULL((void*)0);
1826 switch_frame_t write_frame = { 0 };
1827 switch_file_handle_t fh = { 0 };
1828 int32_t sample_count = 0;
1829 switch_codec_implementation_t read_impl = { 0 };
1830 switch_core_session_get_read_impl(session, &read_impl);
1831
1832
1833 if (timeout_ms) {
1834 sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms;
1835 }
1836
1837 if (file) {
1838 if (switch_core_file_open(&fh,switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1841, &fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
1839 file,switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1841, &fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
1840 read_impl.number_of_channels,switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1841, &fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
1841 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)switch_core_perform_file_open("src/switch_ivr_play_say.c", (const
char *)__func__, 1841, &fh, file, read_impl.number_of_channels
, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ |
SWITCH_FILE_DATA_SHORT, ((void*)0))
!= SWITCH_STATUS_SUCCESS) {
1842 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
1843 return SWITCH_STATUS_NOTFOUND;
1844 }
1845 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE)(void)((((abuf = calloc(1, (8192)))) ? (void) (0) : __assert_fail
("(abuf = calloc(1, (8192)))", "src/switch_ivr_play_say.c", 1845
, __PRETTY_FUNCTION__)),abuf)
;
1846 write_frame.data = abuf;
1847 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE8192;
1848 }
1849
1850
1851 if (switch_core_codec_init(&raw_codec,switch_core_codec_init_with_bitrate(&raw_codec, "L16", ((
void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1852 "L16",switch_core_codec_init_with_bitrate(&raw_codec, "L16", ((
void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1853 NULL,switch_core_codec_init_with_bitrate(&raw_codec, "L16", ((
void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1854 read_impl.actual_samples_per_second,switch_core_codec_init_with_bitrate(&raw_codec, "L16", ((
void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1855 read_impl.microseconds_per_packet / 1000,switch_core_codec_init_with_bitrate(&raw_codec, "L16", ((
void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1856 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,switch_core_codec_init_with_bitrate(&raw_codec, "L16", ((
void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
1857 NULL, switch_core_session_get_pool(session))switch_core_codec_init_with_bitrate(&raw_codec, "L16", ((
void*)0), read_impl.actual_samples_per_second, read_impl.microseconds_per_packet
/ 1000, 1, 0, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE
, ((void*)0), switch_core_session_get_pool(session))
!= SWITCH_STATUS_SUCCESS) {
1858
1859 status = SWITCH_STATUS_FALSE;
1860 goto end;
1861 }
1862
1863 write_frame.codec = &raw_codec;
1864
1865 divisor = read_impl.actual_samples_per_second / 8000;
1866 channels = read_impl.number_of_channels;
1867
1868 switch_core_session_set_read_codec(session, &raw_codec);
1869
1870 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
1871
1872 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1873
1874 if (!SWITCH_READ_ACCEPTABLE(status)(status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK
|| status == SWITCH_STATUS_INUSE)
) {
1875 break;
1876 }
1877
1878 if (sample_count) {
1879 sample_count -= raw_codec.implementation->samples_per_packet;
1880 if (sample_count <= 0) {
1881 switch_channel_set_variable(channel, "wait_for_silence_timeout", "true")switch_channel_set_variable_var_check(channel, "wait_for_silence_timeout"
, "true", SWITCH_TRUE)
;
1882 switch_channel_set_variable_printf(channel, "wait_for_silence_listenhits", "%d", listening);
1883 switch_channel_set_variable_printf(channel, "wait_for_silence_silence_hits", "%d", silence_hits);
1884 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1884, (const char*)(session)
, SWITCH_LOG_ERROR, "switch_ivr_wait_for_silence: TIMEOUT %d\n", countdown);
1885 break;
1886 }
1887 }
1888
1889 if (abuf) {
1890 switch_size_t olen = raw_codec.implementation->samples_per_packet;
1891
1892 if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
1893 break;
1894 }
1895
1896 write_frame.samples = (uint32_t) olen;
1897 write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels);
1898 if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
1899 break;
1900 }
1901 }
1902
1903 if (countdown) {
1904 if (!--countdown) {
1905 switch_channel_set_variable(channel, "wait_for_silence_timeout", "false")switch_channel_set_variable_var_check(channel, "wait_for_silence_timeout"
, "false", SWITCH_TRUE)
;
1906 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1906, (const char*)(session)
, SWITCH_LOG_ERROR, "switch_ivr_wait_for_silence: SILENCE DETECTED\n");
1907 break;
1908 } else {
1909 continue;
1910 }
1911 }
1912
1913 data = (int16_t *) read_frame->data;
1914
1915 for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) {
1916 energy += abs(data[j++]);
1917 j += channels;
1918 }
1919
1920 score = (uint32_t) (energy / (read_frame->samples / divisor));
1921
1922 if (score >= thresh) {
1923 listening++;
1924 }
1925
1926 if (listening > listen_hits && score < thresh) {
1927 if (!--silence_hits) {
1928 countdown = 25;
1929 }
1930 } else {
1931 silence_hits = org_silence_hits;
1932 }
1933 }
1934
1935 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
1936 switch_core_codec_destroy(&raw_codec);
1937
1938 end:
1939
1940 if (abuf) {
1941 switch_core_file_close(&fh);
1942 free(abuf);
1943 }
1944
1945 return status;
1946}
1947
1948SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_read(switch_core_session_t *session,
1949 uint32_t min_digits,
1950 uint32_t max_digits,
1951 const char *prompt_audio_file,
1952 const char *var_name,
1953 char *digit_buffer,
1954 switch_size_t digit_buffer_length,
1955 uint32_t timeout,
1956 const char *valid_terminators,
1957 uint32_t digit_timeout)
1958
1959{
1960 switch_channel_t *channel;
1961 switch_input_args_t args = { 0 };
1962 switch_status_t status = SWITCH_STATUS_SUCCESS;
1963 size_t len = 0;
1964 char tb[2] = "";
1965 int term_required = 0;
1966
1967
1968 if (valid_terminators && *valid_terminators == '=') {
1969 term_required = 1;
1970 }
1971
1972 switch_assert(session)((session) ? (void) (0) : __assert_fail ("session", "src/switch_ivr_play_say.c"
, 1972, __PRETTY_FUNCTION__))
;
1973
1974 if (!digit_timeout) {
1975 digit_timeout = timeout;
1976 }
1977
1978 if (max_digits < min_digits) {
1979 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1979, (const char*)(session)
, SWITCH_LOG_WARNING,
1980 "Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits);
1981 max_digits = min_digits;
1982 }
1983
1984 channel = switch_core_session_get_channel(session);
1985 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, NULL)switch_channel_set_variable_var_check(channel, "read_result",
((void*)0), SWITCH_TRUE)
;
1986
1987 if (var_name) {
1988 switch_channel_set_variable(channel, var_name, NULL)switch_channel_set_variable_var_check(channel, var_name, ((void
*)0), SWITCH_TRUE)
;
1989 }
1990
1991 if ((min_digits && digit_buffer_length < min_digits) || digit_buffer_length < max_digits) {
1992 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 1992, (const char*)(session)
, SWITCH_LOG_ERROR, "Buffer too small!\n");
1993 return SWITCH_STATUS_FALSE;
1994 }
1995
1996 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 1996)
!= SWITCH_STATUS_SUCCESS) {
1997 return SWITCH_STATUS_FALSE;
1998 }
1999
2000 memset(digit_buffer, 0, digit_buffer_length);
2001 args.buf = digit_buffer;
2002 args.buflen = (uint32_t) digit_buffer_length;
2003
2004 if (!zstr(prompt_audio_file)_zstr(prompt_audio_file) && strcasecmp(prompt_audio_file, "silence")) {
2005 if ((status = switch_ivr_play_file(session, NULL((void*)0), prompt_audio_file, &args)) == SWITCH_STATUS_BREAK) {
2006 status = SWITCH_STATUS_SUCCESS;
2007 }
2008 }
2009
2010 if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
2011 goto end;
2012 }
2013
2014 len = strlen(digit_buffer);
2015
2016 if ((min_digits && len < min_digits) || len < max_digits) {
2017 args.buf = digit_buffer + len;
2018 args.buflen = (uint32_t) (digit_buffer_length - len);
2019 status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0],
2020 len ? digit_timeout : timeout, digit_timeout, 0);
2021 }
2022
2023
2024 if (tb[0]) {
2025 char *p;
2026
2027 switch_channel_set_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE, tb)switch_channel_set_variable_var_check(channel, "read_terminator_used"
, tb, SWITCH_TRUE)
;
2028
2029 if (!zstr(valid_terminators)_zstr(valid_terminators) && (p = strchr(valid_terminators, tb[0])(__extension__ (__builtin_constant_p (tb[0]) && !__builtin_constant_p
(valid_terminators) && (tb[0]) == '\0' ? (char *) __rawmemchr
(valid_terminators, tb[0]) : __builtin_strchr (valid_terminators
, tb[0])))
)) {
2030 if (p >= (valid_terminators + 1) && (*(p - 1) == '+' || *(p - 1) == 'x')) {
2031 switch_snprintf(digit_buffer + strlen(digit_buffer), digit_buffer_length - strlen(digit_buffer), "%s", tb);
2032 if (*(p - 1) == 'x') {
2033 status = SWITCH_STATUS_RESTART;
2034 }
2035 }
2036 }
2037 } else if (term_required) {
2038 status = SWITCH_STATUS_TOO_SMALL;
2039 }
2040
2041 len = strlen(digit_buffer);
2042 if ((min_digits && len < min_digits)) {
2043 status = SWITCH_STATUS_TOO_SMALL;
2044 }
2045
2046 switch (status) {
2047 case SWITCH_STATUS_SUCCESS:
2048 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "success")switch_channel_set_variable_var_check(channel, "read_result",
"success", SWITCH_TRUE)
;
2049 break;
2050 case SWITCH_STATUS_TIMEOUT:
2051 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "timeout")switch_channel_set_variable_var_check(channel, "read_result",
"timeout", SWITCH_TRUE)
;
2052 break;
2053 default:
2054 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "failure")switch_channel_set_variable_var_check(channel, "read_result",
"failure", SWITCH_TRUE)
;
2055 break;
2056
2057 }
2058
2059 end:
2060
2061 if (status != SWITCH_STATUS_RESTART && max_digits == 1 && len == 1 && valid_terminators && strchr(valid_terminators, *digit_buffer)(__extension__ (__builtin_constant_p (*digit_buffer) &&
!__builtin_constant_p (valid_terminators) && (*digit_buffer
) == '\0' ? (char *) __rawmemchr (valid_terminators, *digit_buffer
) : __builtin_strchr (valid_terminators, *digit_buffer)))
) {
2062 *digit_buffer = '\0';
2063 }
2064
2065 if (var_name && !zstr(digit_buffer)_zstr(digit_buffer)) {
2066 switch_channel_set_variable(channel, var_name, digit_buffer)switch_channel_set_variable_var_check(channel, var_name, digit_buffer
, SWITCH_TRUE)
;
2067 }
2068
2069 return status;
2070
2071}
2072
2073SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_play_and_get_digits(switch_core_session_t *session,
2074 uint32_t min_digits,
2075 uint32_t max_digits,
2076 uint32_t max_tries,
2077 uint32_t timeout,
2078 const char *valid_terminators,
2079 const char *prompt_audio_file,
2080 const char *bad_input_audio_file,
2081 const char *var_name,
2082 char *digit_buffer,
2083 uint32_t digit_buffer_length,
2084 const char *digits_regex,
2085 uint32_t digit_timeout,
2086 const char *transfer_on_failure)
2087{
2088 switch_channel_t *channel = switch_core_session_get_channel(session);
2089
2090 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && max_tries) {
2091 switch_status_t status;
2092
2093 memset(digit_buffer, 0, digit_buffer_length);
2094
2095 status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name,
2096 digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout);
2097
2098 if (status == SWITCH_STATUS_RESTART) {
2099 return status;
2100 }
2101
2102 if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) {
2103 status = SWITCH_STATUS_SUCCESS;
2104 }
2105
2106 if ((min_digits == 0) && (strlen(digit_buffer) == 0) && switch_channel_get_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE)switch_channel_get_variable_dup(channel, "read_terminator_used"
, SWITCH_TRUE, -1)
!= 0)
2107 {
2108 return SWITCH_STATUS_SUCCESS;
2109 }
2110
2111 if (!(status == SWITCH_STATUS_TOO_SMALL && strlen(digit_buffer) == 0)) {
2112 if (status == SWITCH_STATUS_SUCCESS) {
2113 if (!zstr(digit_buffer)_zstr(digit_buffer)) {
2114 if (zstr(digits_regex)_zstr(digits_regex)) {
2115 return SWITCH_STATUS_SUCCESS;
2116 }
2117 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2117, (const char*)(session)
, SWITCH_LOG_DEBUG1, "Test Regex [%s][%s]\n", digit_buffer, digits_regex);
2118 if (switch_regex_match(digit_buffer, digits_regex) == SWITCH_STATUS_SUCCESS) {
2119 return SWITCH_STATUS_SUCCESS;
2120 } else {
2121 switch_channel_set_variable(channel, var_name, NULL)switch_channel_set_variable_var_check(channel, var_name, ((void
*)0), SWITCH_TRUE)
;
2122 }
2123 }
2124 }
2125 }
2126
2127 if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
2128 break;
2129 }
2130
2131 switch_ivr_play_file(session, NULL((void*)0), bad_input_audio_file, NULL((void*)0));
2132 max_tries--;
2133 }
2134
2135 memset(digit_buffer, 0, digit_buffer_length);
2136
2137 /* If we get here then check for transfer-on-failure ext/dp/context */
2138 /* split this arg on spaces to get ext, dp, and context */
2139
2140 if (!zstr(transfer_on_failure)_zstr(transfer_on_failure)) {
2141 const char *failure_ext = NULL((void*)0);
2142 const char *failure_dialplan = NULL((void*)0);
2143 const char *failure_context = NULL((void*)0);
2144 char *target[4];
2145 char *mydata = switch_core_session_strdup(session, transfer_on_failure)switch_core_perform_session_strdup(session, transfer_on_failure
, "src/switch_ivr_play_say.c", (const char *)__func__, 2145)
;
2146 int argc;
2147
2148 argc = switch_separate_string(mydata, ' ', target, (sizeof(target) / sizeof(target[0])));
2149
2150 if ( argc < 1 ) {
2151 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2151, (const char*)(session)
, SWITCH_LOG_ERROR,"Bad target for PAGD failure: [%s]\n", transfer_on_failure);
2152 return SWITCH_STATUS_FALSE;
2153 }
2154
2155 if ( argc > 0 ) {
2156 failure_ext = target[0];
2157 }
2158
2159 if ( argc > 1 ) {
2160 failure_dialplan = target[1];
2161 }
2162
2163 if ( argc > 2 ) {
2164 failure_context = target[2];
2165 }
2166
2167 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2167, (const char*)(session)
, SWITCH_LOG_WARNING,
2168 "PAGD failure! Transfer to: %s / %s / %s\n", failure_ext, failure_dialplan, failure_context);
2169
2170 switch_ivr_session_transfer(session,failure_ext, failure_dialplan, failure_context);
2171 return SWITCH_STATUS_FALSE;
2172 }
2173
2174 return SWITCH_STATUS_FALSE;
2175}
2176
2177SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_speak_text_handle(switch_core_session_t *session,
2178 switch_speech_handle_t *sh,
2179 switch_codec_t *codec, switch_timer_t *timer, char *text, switch_input_args_t *args)
2180{
2181 switch_channel_t *channel = switch_core_session_get_channel(session);
2182 short abuf[SWITCH_RECOMMENDED_BUFFER_SIZE8192];
2183 switch_dtmf_t dtmf = { 0 };
2184 uint32_t len = 0;
2185 switch_size_t ilen = 0;
2186 switch_frame_t write_frame = { 0 };
2187 int done = 0;
2188 switch_status_t status = SWITCH_STATUS_SUCCESS;
2189 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
2190 switch_size_t extra = 0;
2191 char *p, *tmp = NULL((void*)0);
2192 const char *star, *pound;
2193 switch_size_t starlen, poundlen;
2194
2195 if (!sh) {
2196 return SWITCH_STATUS_FALSE;
2197 }
2198
2199 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 2199)
!= SWITCH_STATUS_SUCCESS) {
2200 return SWITCH_STATUS_FALSE;
2201 }
2202
2203 if (!switch_core_codec_ready(codec)) {
2204 return SWITCH_STATUS_FALSE;
2205 }
2206
2207 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_play_say.c", (const char
*)__func__, 2207, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
2208
2209 write_frame.data = abuf;
2210 write_frame.buflen = sizeof(abuf);
2211
2212 len = sh->samples * 2 * sh->channels;
2213
2214 flags = 0;
2215
2216 if (!(star = switch_channel_get_variable(channel, "star_replace")switch_channel_get_variable_dup(channel, "star_replace", SWITCH_TRUE
, -1)
)) {
2217 star = "star";
2218 }
2219 if (!(pound = switch_channel_get_variable(channel, "pound_replace")switch_channel_get_variable_dup(channel, "pound_replace", SWITCH_TRUE
, -1)
)) {
2220 pound = "pound";
2221 }
2222 starlen = strlen(star);
2223 poundlen = strlen(pound);
2224
2225
2226 for (p = text; p && *p; p++) {
2227 if (*p == '*') {
2228 extra += starlen;
2229 } else if (*p == '#') {
2230 extra += poundlen;
2231 }
2232 }
2233
2234 if (extra) {
2235 char *tp;
2236 switch_size_t mylen = strlen(text) + extra + 1;
2237 tmp = malloc(mylen);
2238 if (!tmp) {
2239 arg_recursion_check_stop(args)if (args) args->loops--;
2240 return SWITCH_STATUS_MEMERR;
2241 }
2242 memset(tmp, 0, mylen);
2243 tp = tmp;
2244 for (p = text; p && *p; p++) {
2245 if (*p == '*') {
2246 strncat(tp, star, starlen)__builtin_strncat (tp, star, starlen);
2247 tp += starlen;
2248 } else if (*p == '#') {
2249 strncat(tp, pound, poundlen)__builtin_strncat (tp, pound, poundlen);
2250 tp += poundlen;
2251 } else {
2252 *tp++ = *p;
2253 }
2254 }
2255
2256 text = tmp;
2257 }
2258
2259 switch_core_speech_feed_tts(sh, text, &flags);
2260 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2260, (const char*)(session)
, SWITCH_LOG_DEBUG, "Speaking text: %s\n", text);
2261 switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);};
2262 text = NULL((void*)0);
2263
2264 write_frame.rate = sh->rate;
2265 memset(write_frame.data, 0, len);
2266 write_frame.datalen = len;
2267 write_frame.samples = len / 2;
2268 write_frame.codec = codec;
2269
2270 switch_assert(codec->implementation != NULL)((codec->implementation != ((void*)0)) ? (void) (0) : __assert_fail
("codec->implementation != ((void*)0)", "src/switch_ivr_play_say.c"
, 2270, __PRETTY_FUNCTION__))
;
2271
2272 switch_channel_audio_sync(channel)switch_channel_perform_audio_sync(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 2272)
;
2273
2274
2275 for (;;) {
2276 switch_event_t *event;
2277
2278 ilen = len;
2279
2280 if (!switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE)) {
2281 status = SWITCH_STATUS_FALSE;
2282 break;
2283 }
2284
2285 if (switch_channel_test_flag(channel, CF_BREAK)) {
2286 switch_channel_clear_flag(channel, CF_BREAK);
2287 status = SWITCH_STATUS_BREAK;
2288 break;
2289 }
2290
2291 if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) {
2292 switch_ivr_parse_event(session, event);
2293 switch_event_destroy(&event);
2294 }
2295
2296 if (args) {
2297 /* dtmf handler function you can hook up to be executed when a digit is dialed during playback
2298 * if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
2299 */
2300 if (switch_channel_has_dtmf(channel)) {
2301 if (!args->input_callback && !args->buf && !args->dmachine) {
2302 status = SWITCH_STATUS_BREAK;
2303 done = 1;
2304 break;
2305 }
2306 if (args->buf && !strcasecmp(args->buf, "_break_")) {
2307 status = SWITCH_STATUS_BREAK;
2308 } else {
2309 switch_channel_dequeue_dtmf(channel, &dtmf);
2310
2311 if (args->dmachine) {
2312 char ds[2] = {dtmf.digit, '\0'};
2313 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
2314 break;
2315 }
2316 }
2317
2318 if (args->input_callback) {
2319 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
2320 } else if (args->buf) {
2321 *((char *) args->buf) = dtmf.digit;
2322 status = SWITCH_STATUS_BREAK;
2323 }
2324 }
2325 }
2326
2327 if (args->input_callback) {
2328 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
2329 switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
2330 if (ostatus != SWITCH_STATUS_SUCCESS) {
2331 status = ostatus;
2332 }
2333 switch_event_destroy(&event);
2334 }
2335 }
2336
2337 if (status != SWITCH_STATUS_SUCCESS) {
2338 done = 1;
2339 break;
2340 }
2341 }
2342
2343 if (switch_test_flag(sh, SWITCH_SPEECH_FLAG_PAUSE)((sh)->flags & SWITCH_SPEECH_FLAG_PAUSE)) {
2344 if (timer) {
2345 if (switch_core_timer_next(timer) != SWITCH_STATUS_SUCCESS) {
2346 break;
2347 }
2348 } else {
2349 switch_frame_t *read_frame;
2350 switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2351
2352 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_flag(channel, CF_HOLD)) {
2353 switch_ivr_parse_all_messages(session);
2354 switch_yield(10000)switch_sleep(10000);;
2355 }
2356
2357 if (!SWITCH_READ_ACCEPTABLE(tstatus)(tstatus == SWITCH_STATUS_SUCCESS || tstatus == SWITCH_STATUS_BREAK
|| tstatus == SWITCH_STATUS_INUSE)
) {
2358 break;
2359 }
2360
2361 if (args && args->dmachine) {
2362 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
2363 goto done;
2364 }
2365 }
2366
2367 if (args && (args->read_frame_callback)) {
2368 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
2369 goto done;
2370 }
2371 }
2372 }
2373 continue;
2374 }
2375
2376
2377 flags = SWITCH_SPEECH_FLAG_BLOCKING;
2378 status = switch_core_speech_read_tts(sh, abuf, &ilen, &flags);
2379
2380 if (status != SWITCH_STATUS_SUCCESS) {
2381 if (status == SWITCH_STATUS_BREAK) {
2382 status = SWITCH_STATUS_SUCCESS;
2383 }
2384 done = 1;
2385 }
2386
2387 if (done) {
2388 break;
2389 }
2390
2391 write_frame.datalen = (uint32_t) ilen;
2392 write_frame.samples = (uint32_t) (ilen / 2 / sh->channels);
2393 if (timer) {
2394 write_frame.timestamp = timer->samplecount;
2395 }
2396 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
2397 done = 1;
2398 break;
2399 }
2400
2401 if (done) {
2402 break;
2403 }
2404
2405 if (timer) {
2406 if (switch_core_timer_next(timer) != SWITCH_STATUS_SUCCESS) {
2407 break;
2408 }
2409 } else { /* time off the channel (if you must) */
2410 switch_frame_t *read_frame;
2411 switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2412
2413 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && switch_channel_test_flag(channel, CF_HOLD)) {
2414 switch_ivr_parse_all_messages(session);
2415 switch_yield(10000)switch_sleep(10000);;
2416 }
2417
2418 if (!SWITCH_READ_ACCEPTABLE(tstatus)(tstatus == SWITCH_STATUS_SUCCESS || tstatus == SWITCH_STATUS_BREAK
|| tstatus == SWITCH_STATUS_INUSE)
) {
2419 break;
2420 }
2421
2422 if (args && args->dmachine) {
2423 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
2424 goto done;
2425 }
2426 }
2427
2428 if (args && (args->read_frame_callback)) {
2429 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
2430 goto done;
2431 }
2432 }
2433 }
2434 }
2435
2436 done:
2437
2438 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2438, (const char*)(session)
, SWITCH_LOG_DEBUG, "done speaking text\n");
2439 flags = 0;
2440 switch_core_speech_flush_tts(sh);
2441
2442 arg_recursion_check_stop(args)if (args) args->loops--;
2443 return status;
2444}
2445
2446struct cached_speech_handle {
2447 char tts_name[80];
2448 char voice_name[80];
2449 switch_speech_handle_t sh;
2450 switch_codec_t codec;
2451 switch_timer_t timer;
2452};
2453
2454typedef struct cached_speech_handle cached_speech_handle_t;
2455
2456SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_ivr_clear_speech_cache(switch_core_session_t *session)
2457{
2458 cached_speech_handle_t *cache_obj = NULL((void*)0);
2459 switch_channel_t *channel = switch_core_session_get_channel(session);
2460
2461 if ((cache_obj = switch_channel_get_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME"__cache_speech_handles_obj__"))) {
2462 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
2463 if (cache_obj->timer.interval) {
2464 switch_core_timer_destroy(&cache_obj->timer);
2465 }
2466 if (&cache_obj->sh && cache_obj->sh.speech_interface) {
2467 switch_core_speech_close(&cache_obj->sh, &flags);
2468 }
2469 if (&cache_obj->codec) {
2470 switch_core_codec_destroy(&cache_obj->codec);
2471 }
2472 switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME"__cache_speech_handles_obj__", NULL((void*)0));
2473 }
2474}
2475
2476SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_speak_text(switch_core_session_t *session,
2477 const char *tts_name, const char *voice_name, char *text, switch_input_args_t *args)
2478{
2479 switch_channel_t *channel = switch_core_session_get_channel(session);
2480 uint32_t rate = 0;
2481 int interval = 0;
2482 uint32_t channels;
2483 switch_frame_t write_frame = { 0 };
2484 switch_timer_t ltimer, *timer;
2485 switch_codec_t lcodec, *codec;
2486 switch_memory_pool_t *pool = switch_core_session_get_pool(session);
2487 char *codec_name;
2488 switch_status_t status = SWITCH_STATUS_SUCCESS;
2489 switch_speech_handle_t lsh, *sh;
2490 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE;
2491 const char *timer_name, *var;
2492 cached_speech_handle_t *cache_obj = NULL((void*)0);
2493 int need_create = 1, need_alloc = 1;
2494 switch_codec_implementation_t read_impl = { 0 };
2495 switch_core_session_get_read_impl(session, &read_impl);
2496
2497 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 2497)
!= SWITCH_STATUS_SUCCESS) {
2498 return SWITCH_STATUS_FALSE;
2499 }
2500
2501 arg_recursion_check_start(args)if (args) { if (args->loops >= 25) { switch_log_printf(
SWITCH_CHANNEL_ID_LOG, "src/switch_ivr_play_say.c", (const char
*)__func__, 2501, ((void*)0), SWITCH_LOG_ERROR, "RECURSION ERROR! It's not the best idea to call things that collect input recursively from an input callback.\n"
); return SWITCH_STATUS_GENERR; } else {args->loops++;} }
;
2502
2503 sh = &lsh;
2504 codec = &lcodec;
2505 timer = &ltimer;
2506
2507 if ((var = switch_channel_get_variable(channel, SWITCH_CACHE_SPEECH_HANDLES_VARIABLE)switch_channel_get_variable_dup(channel, "cache_speech_handles"
, SWITCH_TRUE, -1)
) && switch_true(var)) {
2508 if ((cache_obj = (cached_speech_handle_t *) switch_channel_get_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME"__cache_speech_handles_obj__"))) {
2509 need_create = 0;
2510 if (!strcasecmp(cache_obj->tts_name, tts_name)) {
2511 need_alloc = 0;
2512 } else {
2513 switch_ivr_clear_speech_cache(session);
2514 }
2515 }
2516
2517 if (!cache_obj) {
2518 cache_obj = (cached_speech_handle_t *) switch_core_session_alloc(session, sizeof(*cache_obj))switch_core_perform_session_alloc(session, sizeof(*cache_obj)
, "src/switch_ivr_play_say.c", (const char *)__func__, 2518)
;
2519 }
2520 if (need_alloc) {
2521 switch_copy_string(cache_obj->tts_name, tts_name, sizeof(cache_obj->tts_name));
2522 switch_copy_string(cache_obj->voice_name, voice_name, sizeof(cache_obj->voice_name));
2523 switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME"__cache_speech_handles_obj__", cache_obj);
2524 }
2525 sh = &cache_obj->sh;
2526 codec = &cache_obj->codec;
2527 timer = &cache_obj->timer;
2528 }
2529
2530 timer_name = switch_channel_get_variable(channel, "timer_name")switch_channel_get_variable_dup(channel, "timer_name", SWITCH_TRUE
, -1)
;
2531
2532 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE);
2533
2534 rate = read_impl.actual_samples_per_second;
2535 interval = read_impl.microseconds_per_packet / 1000;
2536 channels = read_impl.number_of_channels;
2537
2538 if (need_create) {
2539 memset(sh, 0, sizeof(*sh));
2540 if ((status = switch_core_speech_open(sh, tts_name, voice_name, (uint32_t) rate, interval, read_impl.number_of_channels, &flags, NULL((void*)0))) != SWITCH_STATUS_SUCCESS) {
2541 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2541, (const char*)(session)
, SWITCH_LOG_ERROR, "Invalid TTS module!\n");
2542 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
2543 switch_ivr_clear_speech_cache(session);
2544 arg_recursion_check_stop(args)if (args) args->loops--;
2545 return status;
2546 }
2547 } else if (cache_obj && strcasecmp(cache_obj->voice_name, voice_name)) {
2548 switch_copy_string(cache_obj->voice_name, voice_name, sizeof(cache_obj->voice_name));
2549 switch_core_speech_text_param_tts(sh, "voice", voice_name);
2550 }
2551
2552 if (switch_channel_pre_answer(channel)switch_channel_perform_pre_answer(channel, "src/switch_ivr_play_say.c"
, (const char *)__func__, 2552)
!= SWITCH_STATUS_SUCCESS) {
2553 flags = 0;
2554 switch_core_speech_close(sh, &flags);
2555 arg_recursion_check_stop(args)if (args) args->loops--;
2556 return SWITCH_STATUS_FALSE;
2557 }
2558 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2558, (const char*)(session)
, SWITCH_LOG_DEBUG, "OPEN TTS %s\n", tts_name);
2559
2560 codec_name = "L16";
2561
2562 if (need_create) {
2563 if (switch_core_codec_init(codec,switch_core_codec_init_with_bitrate(codec, codec_name, ((void
*)0), (int) rate, interval, channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), pool)
2564 codec_name,switch_core_codec_init_with_bitrate(codec, codec_name, ((void
*)0), (int) rate, interval, channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), pool)
2565 NULL, (int) rate, interval, channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,switch_core_codec_init_with_bitrate(codec, codec_name, ((void
*)0), (int) rate, interval, channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), pool)
2566 pool)switch_core_codec_init_with_bitrate(codec, codec_name, ((void
*)0), (int) rate, interval, channels, 0, SWITCH_CODEC_FLAG_ENCODE
| SWITCH_CODEC_FLAG_DECODE, ((void*)0), pool)
== SWITCH_STATUS_SUCCESS) {
2567 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2567, (const char*)(session)
, SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
2568 } else {
2569 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2569, (const char*)(session)
, SWITCH_LOG_DEBUG, "Raw Codec Activation Failed %s@%uhz 1 channel %dms\n", codec_name,
2570 rate, interval);
2571 flags = 0;
2572 switch_core_speech_close(sh, &flags);
2573 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
2574 switch_ivr_clear_speech_cache(session);
2575 arg_recursion_check_stop(args)if (args) args->loops--;
2576 return SWITCH_STATUS_GENERR;
2577 }
2578 }
2579
2580 write_frame.codec = codec;
2581
2582 if (timer_name) {
2583 if (need_create) {
2584 if (switch_core_timer_init(timer, timer_name, interval, (int) sh->samples, pool) != SWITCH_STATUS_SUCCESS) {
2585 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2585, (const char*)(session)
, SWITCH_LOG_ERROR, "Setup timer failed!\n");
2586 switch_core_codec_destroy(write_frame.codec);
2587 flags = 0;
2588 switch_core_speech_close(sh, &flags);
2589 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
2590 switch_ivr_clear_speech_cache(session);
2591 arg_recursion_check_stop(args)if (args) args->loops--;
2592 return SWITCH_STATUS_GENERR;
2593 }
2594 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2594, (const char*)(session)
, SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", sh->samples * 2,
2595 interval);
2596 }
2597 switch_core_timer_sync(timer); // Sync timer
2598
2599 /* start a thread to absorb incoming audio */
2600 switch_core_service_session(session)switch_core_service_session_av(session, SWITCH_TRUE, SWITCH_FALSE
)
;
2601
2602 }
2603
2604 status = switch_ivr_speak_text_handle(session, sh, write_frame.codec, timer_name ? timer : NULL((void*)0), text, args);
2605 flags = 0;
2606
2607 if (!cache_obj) {
2608 switch_core_speech_close(sh, &flags);
2609 switch_core_codec_destroy(codec);
2610 }
2611
2612 if (timer_name) {
2613 /* End the audio absorbing thread */
2614 switch_core_thread_session_end(session);
2615 if (!cache_obj) {
2616 switch_core_timer_destroy(timer);
2617 }
2618 }
2619
2620 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
2621 arg_recursion_check_stop(args)if (args) args->loops--;
2622
2623 return status;
2624}
2625
2626
2627static switch_status_t hold_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
2628{
2629 char *stop_key = (char *) buf;
2630
2631 switch (itype) {
2632 case SWITCH_INPUT_TYPE_DTMF:
2633 {
2634 switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
2635 if (dtmf->digit == *stop_key) {
2636 return SWITCH_STATUS_BREAK;
2637 }
2638 }
2639 break;
2640 default:
2641 break;
2642 }
2643
2644 return SWITCH_STATUS_SUCCESS;
2645}
2646
2647SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_ivr_soft_hold(switch_core_session_t *session, const char *unhold_key, const char *moh_a, const char *moh_b)
2648{
2649 switch_channel_t *channel, *other_channel;
2650 switch_core_session_t *other_session;
2651 const char *other_uuid, *moh = NULL((void*)0);
2652 int moh_br = 0;
2653 switch_input_args_t args = { 0 };
2654 args.input_callback = hold_on_dtmf;
2655 args.buf = (void *) unhold_key;
2656 args.buflen = (uint32_t) strlen(unhold_key);
2657
2658 switch_assert(session != NULL)((session != ((void*)0)) ? (void) (0) : __assert_fail ("session != ((void*)0)"
, "src/switch_ivr_play_say.c", 2658, __PRETTY_FUNCTION__))
;
2659 channel = switch_core_session_get_channel(session);
2660 switch_assert(channel != NULL)((channel != ((void*)0)) ? (void) (0) : __assert_fail ("channel != ((void*)0)"
, "src/switch_ivr_play_say.c", 2660, __PRETTY_FUNCTION__))
;
2661
2662 if ((other_uuid = switch_channel_get_partner_uuid(channel))) {
2663 if ((other_session = switch_core_session_locate(other_uuid)switch_core_session_perform_locate(other_uuid, "src/switch_ivr_play_say.c"
, (const char *)__func__, 2663)
)) {
2664 other_channel = switch_core_session_get_channel(other_session);
2665
2666 if (moh_b) {
2667 moh = moh_b;
2668 } else {
2669 moh = switch_channel_get_hold_music(other_channel);
2670 }
2671
2672 if (!zstr(moh)_zstr(moh) && strcasecmp(moh, "silence") && !switch_channel_test_flag(other_channel, CF_BROADCAST)) {
2673 switch_ivr_broadcast(other_uuid, moh, SMF_ECHO_ALEG | SMF_LOOP);
2674 moh_br++;
2675 }
2676
2677 if (moh_a) {
2678 moh = moh_a;
2679 } else {
2680 moh = switch_channel_get_hold_music(channel);
2681 }
2682
2683 if (!zstr(moh)_zstr(moh) && strcasecmp(moh, "silence")) {
2684 switch_ivr_play_file(session, NULL((void*)0), moh, &args);
2685 } else {
2686 switch_ivr_collect_digits_callback(session, &args, 0, 0);
2687 }
2688
2689 if (moh_br) {
2690 switch_channel_stop_broadcast(other_channel)for(;;) {if (switch_channel_test_flag(other_channel, CF_BROADCAST
)) {switch_channel_set_flag_value(other_channel, CF_STOP_BROADCAST
, 1); switch_channel_set_flag_value(other_channel, CF_BREAK, 1
); } break;}
;
2691 }
2692
2693 switch_core_session_rwunlock(other_session);
2694
2695
2696 return SWITCH_STATUS_SUCCESS;
2697 }
2698
2699 }
2700
2701 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_ivr_play_say.c", (const
char *)__func__, 2701, (const char*)(session)
, SWITCH_LOG_WARNING, "Channel %s is not in a bridge\n", switch_channel_get_name(channel));
2702 return SWITCH_STATUS_FALSE;
2703
2704}
2705
2706/* For Emacs:
2707 * Local Variables:
2708 * mode:c
2709 * indent-tabs-mode:t
2710 * tab-width:4
2711 * c-basic-offset:4
2712 * End:
2713 * For VIM:
2714 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2715 */