[Freeswitch-svn] [commit] r13182 - in freeswitch/trunk: build conf/autoload_configs src src/mod/applications/mod_dptools src/mod/formats/mod_file_string
FreeSWITCH SVN
anthm at freeswitch.org
Tue Apr 28 16:46:18 PDT 2009
Author: anthm
Date: Tue Apr 28 18:46:18 2009
New Revision: 13182
Log:
Stings of files
method 1 high level (core most funcs that use switch_ivr_playback)
Delimiter is set by a var which also enables the parser
<action application="set" data="playback_delimiter=!"/>
<action application="set" data="playback_sleep_val=500"/>
<action application="playback" data="/ram/sr8k.wav!/ram/swimp.wav"/>
method 2 low level (mod_file_string lower level code that uses direct file handles)
Delimiter is always !
<action application="playback" data="file_string:///ram/sr8k.wav!/ram/swimp.wav"/>
Added:
freeswitch/trunk/src/mod/formats/mod_file_string/
freeswitch/trunk/src/mod/formats/mod_file_string/Makefile
freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.2008.vcproj
freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.c
freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.vcproj
Modified:
freeswitch/trunk/build/modules.conf.in
freeswitch/trunk/conf/autoload_configs/modules.conf.xml
freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
freeswitch/trunk/src/switch_ivr_play_say.c
Modified: freeswitch/trunk/build/modules.conf.in
==============================================================================
--- freeswitch/trunk/build/modules.conf.in (original)
+++ freeswitch/trunk/build/modules.conf.in Tue Apr 28 18:46:18 2009
@@ -59,6 +59,7 @@
#formats/mod_shout
formats/mod_local_stream
formats/mod_tone_stream
+formats/mod_file_string
#languages/mod_python
languages/mod_spidermonkey
languages/mod_spidermonkey_teletone
Modified: freeswitch/trunk/conf/autoload_configs/modules.conf.xml
==============================================================================
--- freeswitch/trunk/conf/autoload_configs/modules.conf.xml (original)
+++ freeswitch/trunk/conf/autoload_configs/modules.conf.xml Tue Apr 28 18:46:18 2009
@@ -79,6 +79,7 @@
<!--For local streams (play all the files in a directory)-->
<load module="mod_local_stream"/>
<load module="mod_tone_stream"/>
+ <load module="mod_file_string"/>
<!-- Timers -->
Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c Tue Apr 28 18:46:18 2009
@@ -40,8 +40,6 @@
SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
{
switch_caller_extension_t *extension = NULL;
- char *argv[128] = { 0 };
- int argc;
switch_channel_t *channel = switch_core_session_get_channel(session);
int x = 0;
char *lbuf;
@@ -1834,7 +1832,7 @@
{
switch_input_args_t args = { 0 };
switch_channel_t *channel = switch_core_session_get_channel(session);
- switch_status_t status;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
args.input_callback = on_dtmf;
Added: freeswitch/trunk/src/mod/formats/mod_file_string/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/formats/mod_file_string/Makefile Tue Apr 28 18:46:18 2009
@@ -0,0 +1,2 @@
+BASE=../../../..
+include $(BASE)/build/modmake.rules
Added: freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.2008.vcproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.2008.vcproj Tue Apr 28 18:46:18 2009
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="mod_file_string"
+ ProjectGUID="{2CA40887-1622-46A1-A7F9-17FD7E7E545B}"
+ RootNamespace="mod_file_string"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ ConfigurationType="2"
+ InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ ConfigurationType="2"
+ InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\mod_file_string.c"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Added: freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.c Tue Apr 28 18:46:18 2009
@@ -0,0 +1,188 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2009, Anthony Minessale II <anthm at freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm at freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Anthony Minessale II <anthm at freeswitch.org>
+ * Cesar Cepeda <cesar at auronix.com>
+ *
+ *
+ * mod_file_string.c -- Local Streaming Audio
+ *
+ */
+#include <switch.h>
+/* for apr_pstrcat */
+#define DEFAULT_PREBUFFER_SIZE 1024 * 64
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_file_string_load);
+
+SWITCH_MODULE_DEFINITION(mod_file_string, mod_file_string_load, NULL, NULL);
+
+
+struct file_string_source;
+
+static struct {
+ switch_mutex_t *mutex;
+ switch_hash_t *source_hash;
+} globals;
+
+struct file_string_context {
+ char *argv[128];
+ int argc;
+ int index;
+ int samples;
+ switch_file_handle_t fh;
+};
+
+typedef struct file_string_context file_string_context_t;
+
+
+static int next_file(switch_file_handle_t *handle)
+{
+ file_string_context_t *context = handle->private_info;
+
+ context->index++;
+
+ if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) {
+ switch_core_file_close(&context->fh);
+ }
+
+ if (context->index == context->argc) {
+ return 0;
+ }
+
+ if (switch_core_file_open(&context->fh,
+ context->argv[context->index],
+ handle->channels,
+ handle->samplerate,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
+ return 0;
+ }
+
+ handle->samples = context->fh.samples;
+ handle->samplerate = context->fh.samplerate;
+ handle->channels = context->fh.channels;
+ handle->format = context->fh.format;
+ handle->sections = context->fh.sections;
+ handle->seekable = context->fh.seekable;
+ handle->speed = context->fh.speed;
+ handle->interval = context->fh.interval;
+
+ if (context->index == 0) {
+ context->samples = (handle->samplerate / 1000) * 250;
+ }
+
+ return 1;
+}
+
+static switch_status_t file_string_file_open(switch_file_handle_t *handle, const char *path)
+{
+ file_string_context_t *context;
+ char *file_dup;
+
+ if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This format does not support writing!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ context = switch_core_alloc(handle->memory_pool, sizeof(*context));
+
+ file_dup = switch_core_strdup(handle->memory_pool, path);
+ context->argc = switch_separate_string(file_dup, '!', context->argv, (sizeof(context->argv) / sizeof(context->argv[0])));
+ context->index = -1;
+
+ handle->private_info = context;
+
+ return next_file(handle) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t file_string_file_close(switch_file_handle_t *handle)
+{
+ file_string_context_t *context = handle->private_info;
+
+ switch_core_file_close(&context->fh);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t file_string_file_read(switch_file_handle_t *handle, void *data, size_t *len)
+{
+ file_string_context_t *context = handle->private_info;
+ switch_status_t status;
+ size_t llen = *len;
+
+ if (context->samples > 0) {
+ if (*len > (size_t)context->samples) {
+ *len = context->samples;
+ }
+
+ context->samples -= *len;
+ switch_generate_sln_silence((int16_t *) data, *len, 400);
+ status = SWITCH_STATUS_SUCCESS;
+ } else {
+ status = switch_core_file_read(&context->fh, data, len);
+ }
+
+ if (status != SWITCH_STATUS_SUCCESS) {
+ if (!next_file(handle)) {
+ return SWITCH_STATUS_FALSE;
+ }
+ *len = llen;
+ status = switch_core_file_read(&context->fh, data, len);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/* Registration */
+
+static char *supported_formats[SWITCH_MAX_CODECS] = { 0 };
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_file_string_load)
+{
+ switch_file_interface_t *file_interface;
+ supported_formats[0] = "file_string";
+
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
+ file_interface->interface_name = modname;
+ file_interface->extens = supported_formats;
+ file_interface->file_open = file_string_file_open;
+ file_interface->file_close = file_string_file_close;
+ file_interface->file_read = file_string_file_read;
+
+ memset(&globals, 0, sizeof(globals));
+ /* indicate that the module should continue to be loaded */
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
Added: freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.vcproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/formats/mod_file_string/mod_file_string.vcproj Tue Apr 28 18:46:18 2009
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mod_file_string"
+ ProjectGUID="{2CA40887-1622-46A1-A7F9-17FD7E7E545B}"
+ RootNamespace="mod_file_string"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="2"
+ InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\mod_file_string.c"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
Modified: freeswitch/trunk/src/switch_ivr_play_say.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_play_say.c (original)
+++ freeswitch/trunk/src/switch_ivr_play_say.c Tue Apr 28 18:46:18 2009
@@ -354,7 +354,7 @@
input = input->next;
}
- done:
+ done:
if (hint_data) {
switch_event_destroy(&hint_data);
@@ -588,9 +588,9 @@
if (args && (args->input_callback || args->buf || args->buflen)) {
/*
- dtmf handler function you can hook up to be executed when a digit is dialed during playback
- if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
- */
+ dtmf handler function you can hook up to be executed when a digit is dialed during playback
+ if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
+ */
if (switch_channel_has_dtmf(channel)) {
if (!args->input_callback && !args->buf) {
status = SWITCH_STATUS_BREAK;
@@ -769,9 +769,9 @@
if (args && (args->input_callback || args->buf || args->buflen)) {
/*
- dtmf handler function you can hook up to be executed when a digit is dialed during gentones
- if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
- */
+ dtmf handler function you can hook up to be executed when a digit is dialed during gentones
+ if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
+ */
if (switch_channel_has_dtmf(channel)) {
if (!args->input_callback && !args->buf) {
status = SWITCH_STATUS_BREAK;
@@ -848,12 +848,34 @@
const char *timer_name;
const char *prebuf;
const char *alt = NULL;
+ const char *sleep_val;
+ const char *play_delimiter_val;
+ char play_delimiter = 0;
+ int sleep_val_i = 250;
int eof = 0;
switch_size_t bread = 0;
int l16 = 0;
switch_codec_implementation_t read_impl = {0};
+ char *file_dup;
+ char *argv[128] = { 0 };
+ int argc;
+ int cur;
+ switch_status_t rst;
+
+
switch_core_session_get_read_impl(session, &read_impl);
+ if ((play_delimiter_val = switch_channel_get_variable(channel, "playback_delimiter"))) {
+ play_delimiter = *play_delimiter_val;
+
+ if ((sleep_val = switch_channel_get_variable(channel, "playback_sleep_val"))) {
+ int tmp = atoi(sleep_val);
+ if (tmp >= 0) {
+ sleep_val_i = tmp;
+ }
+ }
+ }
+
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
@@ -862,489 +884,528 @@
timer_name = switch_channel_get_variable(channel, "timer_name");
if (switch_strlen_zero(file) || !switch_channel_media_ready(channel)) {
- status = SWITCH_STATUS_FALSE;
- goto end;
+ return SWITCH_STATUS_FALSE;
}
if (!strcasecmp(read_impl.iananame, "l16")) {
l16++;
}
- if ((alt = strchr(file, ':'))) {
- char *dup;
+
+ if (play_delimiter) {
+ file_dup = switch_core_session_strdup(session, file);
+ argc = switch_separate_string(file_dup, play_delimiter, argv, (sizeof(argv) / sizeof(argv[0])));
+ } else {
+ argc = 1;
+ argv[0] = (char *)file;
+ }
- if (!strncasecmp(file, "phrase:", 7)) {
- char *arg = NULL;
- const char *lang = switch_channel_get_variable(channel, "language");
- alt = file + 7;
- dup = switch_core_session_strdup(session, alt);
-
- if (dup) {
- if ((arg = strchr(dup, ':'))) {
- *arg++ = '\0';
- }
- return switch_ivr_phrase_macro(session, dup, arg, lang, args);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
- return SWITCH_STATUS_FALSE;
+ for(cur = 0; switch_channel_ready(channel) && cur < argc; cur++) {
+ file = argv[cur];
+ asis = 0;
+ eof = 0;
+
+ if (cur) {
+ fh->samples = sample_start = 0;
+ if (sleep_val_i) {
+ switch_ivr_sleep(session, sleep_val_i, SWITCH_FALSE, args);
}
- } else if (!strncasecmp(file, "say:", 4)) {
- char *engine = NULL, *voice = NULL, *text = NULL;
- alt = file + 4;
- dup = switch_core_session_strdup(session, alt);
- engine = dup;
-
- if (!switch_strlen_zero(engine)) {
- if ((voice = strchr(engine, ':'))) {
- *voice++ = '\0';
- if (!switch_strlen_zero(voice) && (text = strchr(voice, ':'))) {
- *text++ = '\0';
+ }
+
+ status = SWITCH_STATUS_SUCCESS;
+
+ if ((alt = strchr(file, ':'))) {
+ char *dup;
+
+ if (!strncasecmp(file, "phrase:", 7)) {
+ char *arg = NULL;
+ const char *lang = switch_channel_get_variable(channel, "language");
+ alt = file + 7;
+ dup = switch_core_session_strdup(session, alt);
+
+ if (dup) {
+ if ((arg = strchr(dup, ':'))) {
+ *arg++ = '\0';
+ }
+ if ((rst = switch_ivr_phrase_macro(session, dup, arg, lang, args) != SWITCH_STATUS_SUCCESS)) {
+ return rst;
+ }
+ continue;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
+ continue;
+ }
+ } else if (!strncasecmp(file, "say:", 4)) {
+ char *engine = NULL, *voice = NULL, *text = NULL;
+ alt = file + 4;
+ dup = switch_core_session_strdup(session, alt);
+ engine = dup;
+
+ if (!switch_strlen_zero(engine)) {
+ if ((voice = strchr(engine, ':'))) {
+ *voice++ = '\0';
+ if (!switch_strlen_zero(voice) && (text = strchr(voice, ':'))) {
+ *text++ = '\0';
+ }
}
}
- }
- if (!switch_strlen_zero(engine) && !switch_strlen_zero(voice) && !switch_strlen_zero(text)) {
- return switch_ivr_speak_text(session, engine, voice, text, args);
- } else if (!switch_strlen_zero(engine) && !(voice && text)) {
- text = engine;
- engine = (char *) switch_channel_get_variable(channel, "tts_engine");
- voice = (char *) switch_channel_get_variable(channel, "tts_voice");
- if (engine && text) {
- return switch_ivr_speak_text(session, engine, voice, text, args);
+ if (!switch_strlen_zero(engine) && !switch_strlen_zero(voice) && !switch_strlen_zero(text)) {
+ if ((rst = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) {
+ return rst;
+ }
+ continue;
+ } else if (!switch_strlen_zero(engine) && !(voice && text)) {
+ text = engine;
+ engine = (char *) switch_channel_get_variable(channel, "tts_engine");
+ voice = (char *) switch_channel_get_variable(channel, "tts_voice");
+ if (engine && text) {
+ if ((rst = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) {
+ return rst;
+ }
+ continue;
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
+ continue;
}
+ }
+
+ }
+
+ if (!prefix) {
+ prefix = SWITCH_GLOBAL_dirs.base_dir;
+ }
+
+ if (!strstr(file, SWITCH_URL_SEPARATOR)) {
+ if (!switch_is_file_path(file)) {
+ file = switch_core_session_sprintf(session, "%s%s%s", prefix, SWITCH_PATH_SEPARATOR, file);
+ }
+ if ((ext = strrchr(file, '.'))) {
+ ext++;
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Args\n");
- return SWITCH_STATUS_FALSE;
+ ext = read_impl.iananame;
+ file = switch_core_session_sprintf(session, "%s.%s", file, ext);
+ asis = 1;
}
}
- }
+
+ if (!fh) {
+ fh = &lfh;
+ memset(fh, 0, sizeof(lfh));
+ }
- if (!prefix) {
- prefix = SWITCH_GLOBAL_dirs.base_dir;
- }
+ if (fh->samples > 0) {
+ sample_start = fh->samples;
+ fh->samples = 0;
+ }
- if (!strstr(file, SWITCH_URL_SEPARATOR)) {
- if (!switch_is_file_path(file)) {
- file = switch_core_session_sprintf(session, "%s%s%s", prefix, SWITCH_PATH_SEPARATOR, file);
+ if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) {
+ int maybe = atoi(prebuf);
+ if (maybe > 0) {
+ fh->prebuf = maybe;
+ }
}
- if ((ext = strrchr(file, '.'))) {
- ext++;
- } else {
- ext = read_impl.iananame;
- file = switch_core_session_sprintf(session, "%s.%s", file, ext);
+
+ if (switch_core_file_open(fh,
+ file,
+ read_impl.number_of_channels,
+ read_impl.actual_samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ status = SWITCH_STATUS_NOTFOUND;
+ continue;
+ }
+ if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
asis = 1;
}
- }
-
- if (!fh) {
- fh = &lfh;
- memset(fh, 0, sizeof(lfh));
- }
- if (fh->samples > 0) {
- sample_start = fh->samples;
- fh->samples = 0;
- }
+ if (!abuf) {
+ switch_zmalloc(abuf, FILE_STARTSAMPLES * sizeof(*abuf));
+ write_frame.data = abuf;
+ write_frame.buflen = FILE_STARTSAMPLES;
+ }
- if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) {
- int maybe = atoi(prebuf);
- if (maybe > 0) {
- fh->prebuf = maybe;
+ if (sample_start > 0) {
+ uint32_t pos = 0;
+ switch_core_file_seek(fh, &pos, 0, SEEK_SET);
+ switch_core_file_seek(fh, &pos, sample_start, SEEK_CUR);
}
- }
- if (switch_core_file_open(fh,
- file,
- read_impl.number_of_channels,
- read_impl.actual_samples_per_second,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
- switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
- status = SWITCH_STATUS_NOTFOUND;
- goto end;
- }
- if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
- asis = 1;
- }
+ if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_TITLE, &p) == SWITCH_STATUS_SUCCESS) {
+ title = switch_core_session_strdup(session, p);
+ switch_channel_set_variable(channel, "RECORD_TITLE", p);
+ }
- switch_zmalloc(abuf, FILE_STARTSAMPLES * sizeof(*abuf));
- write_frame.data = abuf;
- write_frame.buflen = FILE_STARTSAMPLES;
+ if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, &p) == SWITCH_STATUS_SUCCESS) {
+ copyright = switch_core_session_strdup(session, p);
+ switch_channel_set_variable(channel, "RECORD_COPYRIGHT", p);
+ }
- if (sample_start > 0) {
- uint32_t pos = 0;
- switch_core_file_seek(fh, &pos, 0, SEEK_SET);
- switch_core_file_seek(fh, &pos, sample_start, SEEK_CUR);
- }
+ if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, &p) == SWITCH_STATUS_SUCCESS) {
+ software = switch_core_session_strdup(session, p);
+ switch_channel_set_variable(channel, "RECORD_SOFTWARE", p);
+ }
- if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_TITLE, &p) == SWITCH_STATUS_SUCCESS) {
- title = switch_core_session_strdup(session, p);
- switch_channel_set_variable(channel, "RECORD_TITLE", p);
- }
+ if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, &p) == SWITCH_STATUS_SUCCESS) {
+ artist = switch_core_session_strdup(session, p);
+ switch_channel_set_variable(channel, "RECORD_ARTIST", p);
+ }
- if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, &p) == SWITCH_STATUS_SUCCESS) {
- copyright = switch_core_session_strdup(session, p);
- switch_channel_set_variable(channel, "RECORD_COPYRIGHT", p);
- }
+ if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, &p) == SWITCH_STATUS_SUCCESS) {
+ comment = switch_core_session_strdup(session, p);
+ switch_channel_set_variable(channel, "RECORD_COMMENT", p);
+ }
- if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, &p) == SWITCH_STATUS_SUCCESS) {
- software = switch_core_session_strdup(session, p);
- switch_channel_set_variable(channel, "RECORD_SOFTWARE", p);
- }
+ if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_DATE, &p) == SWITCH_STATUS_SUCCESS) {
+ date = switch_core_session_strdup(session, p);
+ switch_channel_set_variable(channel, "RECORD_DATE", p);
+ }
- if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, &p) == SWITCH_STATUS_SUCCESS) {
- artist = switch_core_session_strdup(session, p);
- switch_channel_set_variable(channel, "RECORD_ARTIST", p);
- }
+ interval = read_impl.microseconds_per_packet / 1000;
- if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, &p) == SWITCH_STATUS_SUCCESS) {
- comment = switch_core_session_strdup(session, p);
- switch_channel_set_variable(channel, "RECORD_COMMENT", p);
- }
+ if (!fh->audio_buffer) {
+ switch_buffer_create_dynamic(&fh->audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0);
+ switch_assert(fh->audio_buffer);
+ }
- if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_DATE, &p) == SWITCH_STATUS_SUCCESS) {
- date = switch_core_session_strdup(session, p);
- switch_channel_set_variable(channel, "RECORD_DATE", p);
- }
+ if (asis) {
+ write_frame.codec = switch_core_session_get_read_codec(session);
+ samples = read_impl.samples_per_packet;
+ framelen = read_impl.encoded_bytes_per_packet;
+ } else {
+ codec_name = "L16";
- interval = read_impl.microseconds_per_packet / 1000;
+ if (!switch_core_codec_ready((&codec))) {
+ if (switch_core_codec_init(&codec,
+ codec_name,
+ NULL,
+ fh->samplerate,
+ interval, fh->channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG,
+ SWITCH_LOG_DEBUG, "Codec Activated %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval);
+
- if (!fh->audio_buffer) {
- switch_buffer_create_dynamic(&fh->audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0);
- if (!fh->audio_buffer) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setup buffer failed\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+ "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval);
+ switch_core_file_close(fh);
+ switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ status = SWITCH_STATUS_GENERR;
+ continue;
+ }
+ }
- switch_core_file_close(fh);
- switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ write_frame.codec = &codec;
- status = SWITCH_STATUS_GENERR;
- goto end;
+ samples = codec.implementation->samples_per_packet;
+ framelen = codec.implementation->decoded_bytes_per_packet;
}
- }
- if (asis) {
- write_frame.codec = switch_core_session_get_read_codec(session);
- samples = read_impl.samples_per_packet;
- framelen = read_impl.encoded_bytes_per_packet;
- } else {
- codec_name = "L16";
+ if (timer_name && !timer.samplecount) {
+ uint32_t len;
- if (switch_core_codec_init(&codec,
- codec_name,
- NULL,
- fh->samplerate,
- interval, fh->channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG,
- SWITCH_LOG_DEBUG, "Codec Activated %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval);
+ len = samples * 2;
+ if (switch_core_timer_init(&timer, timer_name, interval, samples, pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setup timer failed!\n");
+ switch_core_codec_destroy(&codec);
+ switch_core_file_close(fh);
+ switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
+ status = SWITCH_STATUS_GENERR;
+ continue;
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", len, interval);
+ }
+ write_frame.rate = fh->samplerate;
- write_frame.codec = &codec;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
- "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval);
- switch_core_file_close(fh);
- switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
- status = SWITCH_STATUS_GENERR;
- goto end;
+ if (timer_name) {
+ /* start a thread to absorb incoming audio */
+ switch_core_service_session(session);
}
- samples = codec.implementation->samples_per_packet;
- framelen = codec.implementation->decoded_bytes_per_packet;
- }
- if (timer_name) {
- uint32_t len;
+ ilen = samples;
- len = samples * 2;
- if (switch_core_timer_init(&timer, timer_name, interval, samples, pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Setup timer failed!\n");
- switch_core_codec_destroy(&codec);
- switch_core_file_close(fh);
- switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
- status = SWITCH_STATUS_GENERR;
- goto end;
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", len, interval);
- }
- write_frame.rate = fh->samplerate;
+ for (;;) {
+ int done = 0;
+ int do_speed = 1;
+ int last_speed = -1;
- if (timer_name) {
- /* start a thread to absorb incoming audio */
- switch_core_service_session(session);
- }
+ if (!switch_channel_ready(channel)) {
+ status = SWITCH_STATUS_FALSE;
+ break;
+ }
- ilen = samples;
+ if (switch_channel_test_flag(channel, CF_BREAK)) {
+ switch_channel_clear_flag(channel, CF_BREAK);
+ status = SWITCH_STATUS_BREAK;
+ break;
+ }
- for (;;) {
- int done = 0;
- int do_speed = 1;
- int last_speed = -1;
+ if (switch_core_session_private_event_count(session)) {
+ switch_ivr_parse_all_events(session);
+ }
- if (!switch_channel_ready(channel)) {
- status = SWITCH_STATUS_FALSE;
- break;
- }
+ if (args && (args->input_callback || args->buf || args->buflen)) {
+ /*
+ dtmf handler function you can hook up to be executed when a digit is dialed during playback
+ if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
+ */
+ if (switch_channel_has_dtmf(channel)) {
+ if (!args->input_callback && !args->buf) {
+ status = SWITCH_STATUS_BREAK;
+ done = 1;
+ break;
+ }
+ switch_channel_dequeue_dtmf(channel, &dtmf);
+ if (args->input_callback) {
+ status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
+ } else {
+ *((char *) args->buf) = dtmf.digit;
+ status = SWITCH_STATUS_BREAK;
+ }
+ }
- if (switch_channel_test_flag(channel, CF_BREAK)) {
- switch_channel_clear_flag(channel, CF_BREAK);
- status = SWITCH_STATUS_BREAK;
- break;
- }
+ if (args->input_callback) {
+ switch_event_t *event;
- if (switch_core_session_private_event_count(session)) {
- switch_ivr_parse_all_events(session);
- }
+ if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
+ status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
+ switch_event_destroy(&event);
+ }
+ }
- if (args && (args->input_callback || args->buf || args->buflen)) {
- /*
- dtmf handler function you can hook up to be executed when a digit is dialed during playback
- if you return anything but SWITCH_STATUS_SUCCESS the playback will stop.
- */
- if (switch_channel_has_dtmf(channel)) {
- if (!args->input_callback && !args->buf) {
- status = SWITCH_STATUS_BREAK;
+ if (status != SWITCH_STATUS_SUCCESS) {
done = 1;
break;
}
- switch_channel_dequeue_dtmf(channel, &dtmf);
- if (args->input_callback) {
- status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
- } else {
- *((char *) args->buf) = dtmf.digit;
- status = SWITCH_STATUS_BREAK;
- }
}
- if (args->input_callback) {
- switch_event_t *event;
-
- if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
- status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
- switch_event_destroy(&event);
+ if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
+ if (framelen > FILE_STARTSAMPLES) {
+ framelen = FILE_STARTSAMPLES;
+ }
+ memset(abuf, 0, framelen);
+ olen = ilen;
+ do_speed = 0;
+ } else if (fh->sp_audio_buffer && (eof || (switch_buffer_inuse(fh->sp_audio_buffer) > (switch_size_t) (framelen)))) {
+ if (!(bread = switch_buffer_read(fh->sp_audio_buffer, abuf, framelen))) {
+ if (eof) {
+ continue;
+ } else {
+ break;
+ }
}
- }
- if (status != SWITCH_STATUS_SUCCESS) {
- done = 1;
- break;
- }
- }
+ if (bread < framelen) {
+ memset(abuf + bread, 0, framelen - bread);
+ }
- if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
- if (framelen > FILE_STARTSAMPLES) {
- framelen = FILE_STARTSAMPLES;
- }
- memset(abuf, 0, framelen);
- olen = ilen;
- do_speed = 0;
- } else if (fh->sp_audio_buffer && (eof || (switch_buffer_inuse(fh->sp_audio_buffer) > (switch_size_t) (framelen)))) {
- if (!(bread = switch_buffer_read(fh->sp_audio_buffer, abuf, framelen))) {
- if (eof) {
- continue;
- } else {
- break;
+ olen = asis ? framelen : ilen;
+ do_speed = 0;
+ } else if (fh->audio_buffer && (eof || (switch_buffer_inuse(fh->audio_buffer) > (switch_size_t) (framelen)))) {
+ if (!(bread = switch_buffer_read(fh->audio_buffer, abuf, framelen))) {
+ if (eof) {
+ break;
+ } else {
+ continue;
+ }
}
- }
- if (bread < framelen) {
- memset(abuf + bread, 0, framelen - bread);
- }
+ if (bread < framelen) {
+ memset(abuf + bread, 0, framelen - bread);
+ }
- olen = asis ? framelen : ilen;
- do_speed = 0;
- } else if (fh->audio_buffer && (eof || (switch_buffer_inuse(fh->audio_buffer) > (switch_size_t) (framelen)))) {
- if (!(bread = switch_buffer_read(fh->audio_buffer, abuf, framelen))) {
+ olen = asis ? framelen : ilen;
+ } else {
if (eof) {
- break;
- } else {
+ break;
+ }
+ olen = FILE_STARTSAMPLES;
+ if (!asis) {
+ olen /= 2;
+ }
+ if (switch_core_file_read(fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
+ eof++;
continue;
}
+ switch_buffer_write(fh->audio_buffer, abuf, asis ? olen : olen * 2);
+ olen = switch_buffer_read(fh->audio_buffer, abuf, framelen);
+ if (!asis) {
+ olen /= 2;
+ }
}
- if (bread < framelen) {
- memset(abuf + bread, 0, framelen - bread);
+ if (done || olen <= 0) {
+ break;
}
- olen = asis ? framelen : ilen;
- } else {
- if (eof) {
- break;
- }
- olen = FILE_STARTSAMPLES;
- if (!asis) {
- olen /= 2;
- }
- if (switch_core_file_read(fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
- eof++;
- continue;
- }
- switch_buffer_write(fh->audio_buffer, abuf, asis ? olen : olen * 2);
- olen = switch_buffer_read(fh->audio_buffer, abuf, framelen);
if (!asis) {
- olen /= 2;
+ if (fh->speed > 2) {
+ fh->speed = 2;
+ } else if (fh->speed < -2) {
+ fh->speed = -2;
+ }
}
- }
- if (done || olen <= 0) {
- break;
- }
-
- if (!asis) {
- if (fh->speed > 2) {
- fh->speed = 2;
- } else if (fh->speed < -2) {
- fh->speed = -2;
+ if (!asis && fh->audio_buffer && last_speed > -1 && last_speed != fh->speed) {
+ switch_buffer_zero(fh->sp_audio_buffer);
}
- }
-
- if (!asis && fh->audio_buffer && last_speed > -1 && last_speed != fh->speed) {
- switch_buffer_zero(fh->sp_audio_buffer);
- }
- if (switch_test_flag(fh, SWITCH_FILE_SEEK)) {
- /* file position has changed flush the buffer */
- switch_buffer_zero(fh->audio_buffer);
- switch_clear_flag(fh, SWITCH_FILE_SEEK);
- }
+ if (switch_test_flag(fh, SWITCH_FILE_SEEK)) {
+ /* file position has changed flush the buffer */
+ switch_buffer_zero(fh->audio_buffer);
+ switch_clear_flag(fh, SWITCH_FILE_SEEK);
+ }
- if (!asis && fh->speed && do_speed) {
- float factor = 0.25f * abs(fh->speed);
- switch_size_t newlen, supplement, step;
- short *bp = write_frame.data;
- switch_size_t wrote = 0;
+ if (!asis && fh->speed && do_speed) {
+ float factor = 0.25f * abs(fh->speed);
+ switch_size_t newlen, supplement, step;
+ short *bp = write_frame.data;
+ switch_size_t wrote = 0;
- supplement = (int) (factor * olen);
- if (!supplement) {
- supplement = 1;
- }
- newlen = (fh->speed > 0) ? olen - supplement : olen + supplement;
+ supplement = (int) (factor * olen);
+ if (!supplement) {
+ supplement = 1;
+ }
+ newlen = (fh->speed > 0) ? olen - supplement : olen + supplement;
- step = (fh->speed > 0) ? (newlen / supplement) : (olen / supplement);
+ step = (fh->speed > 0) ? (newlen / supplement) : (olen / supplement);
- if (!fh->sp_audio_buffer) {
- switch_buffer_create_dynamic(&fh->sp_audio_buffer, 1024, 1024, 0);
- }
+ if (!fh->sp_audio_buffer) {
+ switch_buffer_create_dynamic(&fh->sp_audio_buffer, 1024, 1024, 0);
+ }
- while ((wrote + step) < newlen) {
- switch_buffer_write(fh->sp_audio_buffer, bp, step * 2);
- wrote += step;
- bp += step;
- if (fh->speed > 0) {
- bp++;
- } else {
- float f;
- short s;
- f = (float) (*bp + *(bp + 1) + *(bp - 1));
- f /= 3;
- s = (short) f;
- switch_buffer_write(fh->sp_audio_buffer, &s, 2);
- wrote++;
+ while ((wrote + step) < newlen) {
+ switch_buffer_write(fh->sp_audio_buffer, bp, step * 2);
+ wrote += step;
+ bp += step;
+ if (fh->speed > 0) {
+ bp++;
+ } else {
+ float f;
+ short s;
+ f = (float) (*bp + *(bp + 1) + *(bp - 1));
+ f /= 3;
+ s = (short) f;
+ switch_buffer_write(fh->sp_audio_buffer, &s, 2);
+ wrote++;
+ }
}
+ if (wrote < newlen) {
+ switch_size_t r = newlen - wrote;
+ switch_buffer_write(fh->sp_audio_buffer, bp, r * 2);
+ wrote += r;
+ }
+ last_speed = fh->speed;
+ continue;
}
- if (wrote < newlen) {
- switch_size_t r = newlen - wrote;
- switch_buffer_write(fh->sp_audio_buffer, bp, r * 2);
- wrote += r;
+
+ if (olen < llen) {
+ uint8_t *dp = (uint8_t *) write_frame.data;
+ memset(dp + (int) olen, 0, (int) (llen - olen));
+ olen = llen;
}
- last_speed = fh->speed;
- continue;
- }
- if (olen < llen) {
- uint8_t *dp = (uint8_t *) write_frame.data;
- memset(dp + (int) olen, 0, (int) (llen - olen));
- olen = llen;
- }
- write_frame.samples = (uint32_t) olen;
+ write_frame.samples = (uint32_t) olen;
- if (asis) {
- write_frame.datalen = (uint32_t) olen;
- } else {
- write_frame.datalen = write_frame.samples * 2;
- }
+ if (asis) {
+ write_frame.datalen = (uint32_t) olen;
+ } else {
+ write_frame.datalen = write_frame.samples * 2;
+ }
- llen = olen;
+ llen = olen;
- if (timer_name) {
- write_frame.timestamp = timer.samplecount;
- }
+ if (timer_name) {
+ write_frame.timestamp = timer.samplecount;
+ }
#ifndef WIN32
#if SWITCH_BYTE_ORDER == __BIG_ENDIAN
- if (!asis && l16) {
- switch_swap_linear(write_frame.data, (int) write_frame.datalen / 2);
- }
+ if (!asis && l16) {
+ switch_swap_linear(write_frame.data, (int) write_frame.datalen / 2);
+ }
#endif
#endif
- if (fh->vol) {
- switch_change_sln_volume(write_frame.data, write_frame.datalen / 2, fh->vol);
- }
-
- fh->offset_pos += write_frame.samples / 2;
- status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (status == SWITCH_STATUS_MORE_DATA) {
- status = SWITCH_STATUS_SUCCESS;
- continue;
- } else if (status != SWITCH_STATUS_SUCCESS) {
- done = 1;
- break;
- }
+ if (fh->vol) {
+ switch_change_sln_volume(write_frame.data, write_frame.datalen / 2, fh->vol);
+ }
- if (done) {
- break;
- }
+ fh->offset_pos += write_frame.samples / 2;
+ status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
- if (timer_name) {
- if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) {
+ if (status == SWITCH_STATUS_MORE_DATA) {
+ status = SWITCH_STATUS_SUCCESS;
+ continue;
+ } else if (status != SWITCH_STATUS_SUCCESS) {
+ done = 1;
break;
}
- } else { /* time off the channel (if you must) */
- switch_frame_t *read_frame;
- switch_status_t tstatus;
- while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
- switch_yield(10000);
- }
- tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
-
- if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
+ if (done) {
break;
}
- if (args && (args->read_frame_callback)) {
- int ok = 1;
- switch_set_flag(fh, SWITCH_FILE_CALLBACK);
- if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
- ok = 0;
+ if (timer_name) {
+ if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) {
+ break;
}
- switch_clear_flag(fh, SWITCH_FILE_CALLBACK);
- if (!ok) {
+ } else { /* time off the channel (if you must) */
+ switch_frame_t *read_frame;
+ switch_status_t tstatus;
+ while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) {
+ switch_yield(10000);
+ }
+
+ tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
+
+ if (!SWITCH_READ_ACCEPTABLE(tstatus)) {
break;
}
+
+ if (args && (args->read_frame_callback)) {
+ int ok = 1;
+ switch_set_flag(fh, SWITCH_FILE_CALLBACK);
+ if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
+ ok = 0;
+ }
+ switch_clear_flag(fh, SWITCH_FILE_CALLBACK);
+ if (!ok) {
+ break;
+ }
+ }
}
}
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done playing file\n");
- //switch_core_file_seek(fh, &fh->last_pos, 0, SEEK_CUR);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done playing file\n");
+
+ switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_out / read_impl.samples_per_second);
+ switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_out);
+ switch_core_file_close(fh);
- switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_out / read_impl.samples_per_second);
- switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_out);
+ if (fh->audio_buffer) {
+ switch_buffer_destroy(&fh->audio_buffer);
+ }
+
+ if (fh->sp_audio_buffer) {
+ switch_buffer_destroy(&fh->sp_audio_buffer);
+ }
+ }
- switch_core_file_close(fh);
- switch_buffer_destroy(&fh->audio_buffer);
- switch_buffer_destroy(&fh->sp_audio_buffer);
- if (!asis) {
+ if (switch_core_codec_ready((&codec))) {
switch_core_codec_destroy(&codec);
}
- if (timer_name) {
+
+ if (timer.samplecount) {
/* End the audio absorbing thread */
switch_core_thread_session_end(session);
switch_core_timer_destroy(&timer);
}
- end:
+
switch_safe_free(abuf);
switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
@@ -1600,7 +1661,7 @@
memset(digit_buffer, 0, digit_buffer_length);
switch_channel_flush_dtmf(channel);
status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name,
- digit_buffer, digit_buffer_length, timeout, valid_terminators);
+ digit_buffer, digit_buffer_length, timeout, valid_terminators);
if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) {
status = SWITCH_STATUS_SUCCESS;
}
More information about the Freeswitch-svn
mailing list