From 14189270075edd18a15b14894b0211c57689cf9a Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthony.minessale@gmail.com> Date: Thu, 4 Oct 2007 15:09:44 +0000 Subject: [PATCH] add delay_echo application git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5794 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_ivr.h | 1 + .../applications/mod_dptools/mod_dptools.c | 15 ++++++ src/switch_ivr.c | 52 ++++++++++++++++++- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index e2b27fc2e3..59e4699bbf 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -699,6 +699,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_stack_xml_init(switch_ivr_menu_x SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *session, char *macro_name, char *data, char *lang, switch_input_args_t *args); +SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint32_t delay_ms); /** @} */ SWITCH_END_EXTERN_C diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 70113991e6..fe7e426927 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -231,6 +231,20 @@ SWITCH_STANDARD_APP(sleep_function) } } +SWITCH_STANDARD_APP(delay_function) +{ + uint32_t len = 0; + + if (switch_strlen_zero(data)) { + len = 1000; + } else { + len = atoi(data); + } + + switch_ivr_delay_echo(session, len); + +} + SWITCH_STANDARD_APP(eval_function) { return; @@ -1243,6 +1257,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "transfer", "Transfer a channel", TRANSFER_LONG_DESC, transfer_function, "<exten> [<dialplan> <context>]", SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_NONE); + SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE); SWITCH_ADD_APP(app_interface, "strftime", NULL, NULL, strftime_function, NULL, SAF_SUPPORT_NOMEDIA); SWITCH_ADD_APP(app_interface, "phrase", "Say a Phrase", "Say a Phrase", phrase_function, "<macro_name>,<data>", SAF_NONE); SWITCH_ADD_APP(app_interface, "eval", "Do Nothing", "Do Nothing", eval_function, "", SAF_SUPPORT_NOMEDIA); diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 9aff836db8..ef32e0f3aa 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -34,8 +34,7 @@ */ #include <switch.h> #include <switch_ivr.h> - - +#include "stfu.h" SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, uint32_t ms) { @@ -1510,6 +1509,55 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint32_t delay_ms) +{ + stfu_instance_t *jb; + int qlen = 0; + switch_codec_t *read_codec; + stfu_frame_t *jb_frame; + switch_frame_t *read_frame, write_frame = { 0 }; + switch_status_t status; + switch_channel_t *channel; + uint32_t interval, samples; + uint32_t ts = 0; + + if (delay_ms < 100 || delay_ms > 10000) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Jitterbuffer spec [%d] myst be between 100 and 10000\n", delay_ms); + return; + } + + read_codec = switch_core_session_get_read_codec(session); + interval = read_codec->implementation->microseconds_per_frame / 1000; + samples = switch_bytes_per_frame(read_codec->implementation->samples_per_second, interval); + + qlen = delay_ms / (interval); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen); + jb = stfu_n_init(qlen); + + channel = switch_core_session_get_channel(session); + write_frame.codec = read_codec; + + while(switch_channel_ready(channel)) { + status = switch_core_session_read_frame(session, &read_frame, -1, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + + stfu_n_eat(jb, ts, read_frame->data, read_frame->datalen); + ts += interval; + + if ((jb_frame = stfu_n_read_a_frame(jb))) { + write_frame.data = jb_frame->data; + write_frame.datalen = jb_frame->dlen; + status = switch_core_session_write_frame(session, &write_frame, -1, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + } + } + + stfu_n_destroy(&jb); +} /* For Emacs: