ivr stuff (part 1)

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1573 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-06-08 19:22:54 +00:00
parent 7ac4e54ef9
commit 5c57580955
9 changed files with 161 additions and 438 deletions

View File

@ -917,6 +917,14 @@ SWITCH_DECLARE(void) switch_core_speech_text_param_tts(switch_speech_handle_t *s
*/ */
SWITCH_DECLARE(void) switch_core_speech_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val); SWITCH_DECLARE(void) switch_core_speech_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val);
/*!
\brief Set a float parameter on a TTS handle
\param sh the speech handle
\param param the parameter
\param val the value
*/
SWITCH_DECLARE(void) switch_core_speech_float_param_tts(switch_speech_handle_t *sh, char *param, double val);
/*! /*!
\brief Read rendered audio from the TTS module \brief Read rendered audio from the TTS module
\param sh the speech handle to read \param sh the speech handle to read

View File

@ -330,6 +330,7 @@ struct switch_speech_interface {
void (*speech_flush_tts)(switch_speech_handle_t *sh); void (*speech_flush_tts)(switch_speech_handle_t *sh);
void (*speech_text_param_tts)(switch_speech_handle_t *sh, char *param, char *val); void (*speech_text_param_tts)(switch_speech_handle_t *sh, char *param, char *val);
void (*speech_numeric_param_tts)(switch_speech_handle_t *sh, char *param, int val); void (*speech_numeric_param_tts)(switch_speech_handle_t *sh, char *param, int val);
void (*speech_float_param_tts)(switch_speech_handle_t *sh, char *param, double val);
const struct switch_speech_interface *next; const struct switch_speech_interface *next;
}; };
@ -345,6 +346,9 @@ struct switch_speech_handle {
char *name; char *name;
/*! The Rate*/ /*! The Rate*/
uint32_t rate; uint32_t rate;
uint32_t speed;
char voice[80];
char engine[80];
/*! the handle's memory pool */ /*! the handle's memory pool */
switch_memory_pool_t *memory_pool; switch_memory_pool_t *memory_pool;
/*! private data for the format module to store handle specific info */ /*! private data for the format module to store handle specific info */

View File

@ -424,6 +424,7 @@ SWITCH_SPEECH_FLAG_HASTEXT = (1 << 2) - Interface is has text to read.
SWITCH_SPEECH_FLAG_PEEK = (1 << 3) - Read data but do not erase it. SWITCH_SPEECH_FLAG_PEEK = (1 << 3) - Read data but do not erase it.
SWITCH_SPEECH_FLAG_FREE_POOL = (1 << 4) - Free interface's pool on destruction. SWITCH_SPEECH_FLAG_FREE_POOL = (1 << 4) - Free interface's pool on destruction.
SWITCH_SPEECH_FLAG_BLOCKING = (1 << 5) - Indicate that a blocking call is desired SWITCH_SPEECH_FLAG_BLOCKING = (1 << 5) - Indicate that a blocking call is desired
SWITCH_SPEECH_FLAG_PAUSE = (1 << 6) - Pause toggle for playback
</pre> </pre>
*/ */
typedef enum { typedef enum {
@ -433,6 +434,7 @@ typedef enum {
SWITCH_SPEECH_FLAG_PEEK = (1 << 3), SWITCH_SPEECH_FLAG_PEEK = (1 << 3),
SWITCH_SPEECH_FLAG_FREE_POOL = (1 << 4), SWITCH_SPEECH_FLAG_FREE_POOL = (1 << 4),
SWITCH_SPEECH_FLAG_BLOCKING = (1 << 5), SWITCH_SPEECH_FLAG_BLOCKING = (1 << 5),
SWITCH_SPEECH_FLAG_PAUSE = (1 << 6)
} switch_speech_flag_t; } switch_speech_flag_t;

View File

@ -1,200 +0,0 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
*
* 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 <anthmct@yahoo.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthmct@yahoo.com>
*
*
* mod_rss.c -- RSS Browser
*
*/
#include <switch.h>
static const char modname[] = "mod_rss";
/* helper object */
struct dtmf_buffer {
char *data;
char *front;
uint32_t len;
uint32_t size;
switch_file_handle_t fh;
};
/*
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.
*/
static switch_status_t on_dtmf(switch_core_session_t *session, char *dtmf, void *buf, unsigned int buflen)
{
struct dtmf_buffer *dtb;
uint32_t len, slen;
uint32_t samps = 0, pos = 0;
dtb = (struct dtmf_buffer *) buf;
if (*dtmf == '#') {
return SWITCH_STATUS_FALSE;
}
len = dtb->size - dtb->len;
slen = (uint32_t)strlen(dtmf);
if (slen > len) {
slen = len;
}
switch_copy_string(dtb->front, dtmf, len);
dtb->front += slen;
dtb->len += slen;
if (dtb->len == 2) {
if (*dtb->data == '*') {
dtb->front = dtb->data;
dtb->len = 0;
*dtb->data = '\0';
switch(*(dtb->data+1)) {
case '0':
dtb->fh.speed = 0;
break;
case '2':
dtb->fh.speed++;
break;
case '1':
dtb->fh.speed--;
break;
case '5':
{
switch_codec_t *codec = switch_core_session_get_read_codec(session);
samps = 5000 * (codec->implementation->samples_per_second / 1000);
switch_core_file_seek(&dtb->fh, &pos, samps, SEEK_CUR);
}
break;
case '4':
{
int32_t lpos = 0;
switch_codec_t *codec = switch_core_session_get_read_codec(session);
samps = 5000 * (codec->implementation->samples_per_second / 1000);
lpos = (int) dtb->fh.pos - samps;
if (lpos < 0) {
lpos = 0;
}
switch_core_file_seek(&dtb->fh, &pos, lpos, SEEK_SET);
}
break;
case '*':
if (switch_test_flag(&dtb->fh, SWITCH_FILE_PAUSE)) {
switch_clear_flag(&dtb->fh, SWITCH_FILE_PAUSE);
} else {
switch_set_flag(&dtb->fh, SWITCH_FILE_PAUSE);
}
break;
}
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_BREAK;
}
return SWITCH_STATUS_SUCCESS;
}
static void rss_function(switch_core_session_t *session, char *data)
{
switch_channel_t *channel;
uint8_t index = 0;
char fname[512];
switch_status_t status;
char buf[10];
struct dtmf_buffer dtb;
dtb.data = buf;
dtb.front = buf;
dtb.len = 0;
dtb.size = sizeof(buf);
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
if (switch_strlen_zero(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Path Specified!\n");
return;
}
switch_channel_answer(channel);
while(switch_channel_ready(channel)) {
snprintf(fname, sizeof(fname), "%s/%.2u.raw", data, index);
memset(&dtb.fh, 0, sizeof(dtb.fh));
if ((status = switch_ivr_play_file(session, &dtb.fh, fname, NULL, on_dtmf, &dtb, sizeof(dtb))) == SWITCH_STATUS_FALSE) {
break;
}
index = (uint8_t)atoi(buf);
/* reset for next loop */
*buf = '\0';
dtb.front = buf;
dtb.len = 0;
}
}
static const switch_application_interface_t rss_application_interface = {
/*.interface_name */ "rss",
/*.application_function */ rss_function,
NULL, NULL, NULL,
/*.next*/ NULL
};
static switch_loadable_module_interface_t rss_module_interface = {
/*.module_name */ modname,
/*.endpoint_interface */ NULL,
/*.timer_interface */ NULL,
/*.dialplan_interface */ NULL,
/*.codec_interface */ NULL,
/*.application_interface */ &rss_application_interface,
/*.api_interface */ NULL,
/*.file_interface */ NULL,
/*.speech_interface */ NULL,
/*.directory_interface */ NULL
};
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
{
/* connect my internal structure to the blank pointer passed to me */
*module_interface = &rss_module_interface;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}

View File

@ -1,209 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="mod_rss"
ProjectGUID="{B69247FA-ECD6-40ED-8E44-5CA6C3BAF9A4}"
RootNamespace="mod_rss"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\..\..\w32\vsnet\$(OutDir)/mod/mod_rss.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/mod_rss.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/mod_rss.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\..\..\w32\vsnet\$(OutDir)/mod/mod_rss.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/mod_rss.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\mod_rss.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -36,7 +36,7 @@
#include <swift.h> #include <swift.h>
#include <switch.h> #include <switch.h>
#define MY_BUF_LEN 1024 * 512 #define MY_BUF_LEN 1024 * 256
static const char modname[] = "mod_cepstral"; static const char modname[] = "mod_cepstral";
@ -152,8 +152,14 @@ static switch_status_t cepstral_speech_open(switch_speech_handle_t *sh, char *vo
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set voice.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set voice.\n");
goto all_done; goto all_done;
} }
voice_name = (char *) swift_voice_get_attribute(cepstral->voice, "name");
} }
if (voice_name) {
switch_copy_string(sh->voice, voice_name, sizeof(sh->voice));
}
swift_port_set_callback(cepstral->port, &write_audio, SWIFT_EVENT_AUDIO, cepstral); swift_port_set_callback(cepstral->port, &write_audio, SWIFT_EVENT_AUDIO, cepstral);
sh->private_info = cepstral; sh->private_info = cepstral;
@ -175,7 +181,6 @@ static switch_status_t cepstral_speech_close(switch_speech_handle_t *sh, switch_
cepstral->done = 1; cepstral->done = 1;
cepstral->done_gen = 1; cepstral->done_gen = 1;
printf("CLOSE!!!\n");
swift_port_stop(cepstral->port, SWIFT_ASYNC_ANY, SWIFT_EVENT_NOW); swift_port_stop(cepstral->port, SWIFT_ASYNC_ANY, SWIFT_EVENT_NOW);
/* Close the Swift Port and Engine */ /* Close the Swift Port and Engine */
if (NULL != cepstral->port) swift_port_close(cepstral->port); if (NULL != cepstral->port) swift_port_close(cepstral->port);
@ -294,6 +299,83 @@ static switch_status_t cepstral_speech_read_tts(switch_speech_handle_t *sh,
return status; return status;
} }
static void cepstral_text_param_tts(switch_speech_handle_t *sh, char *param, char *val)
{
cepstral_t *cepstral;
cepstral = sh->private_info;
assert(cepstral != NULL);
if (!strcasecmp(param, "voice")) {
char *voice_name = val;
if (!strcasecmp(voice_name, "next")) {
if ((cepstral->voice = swift_port_find_next_voice(cepstral->port))) {
if ( SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice)) ) {
cepstral->done = cepstral->done_gen = 1;
return;
}
voice_name = (char *) swift_voice_get_attribute(cepstral->voice, "name");
} else {
voice_name = NULL;
}
} else {
if (voice_name && SWIFT_FAILED(swift_port_set_voice_by_name(cepstral->port, voice_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid voice %s!\n", voice_name);
voice_name = NULL;
}
}
if (!voice_name) {
/* Find the first voice on the system */
if ((cepstral->voice = swift_port_find_first_voice(cepstral->port, NULL, NULL)) == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find any voices!\n");
cepstral->done = cepstral->done_gen = 1;
return;
}
/* Set the voice found by find_first_voice() as the port's current voice */
if ( SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice)) ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set voice.\n");
cepstral->done = cepstral->done_gen = 1;
return;
}
voice_name = (char *) swift_voice_get_attribute(cepstral->voice, "name");
}
if (voice_name) {
switch_copy_string(sh->voice, voice_name, sizeof(sh->voice));
}
return;
}
swift_port_set_param_string(cepstral->port, param, val, NULL);
}
static void cepstral_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val)
{
cepstral_t *cepstral;
cepstral = sh->private_info;
assert(cepstral != NULL);
swift_port_set_param_int(cepstral->port, param, val, NULL);
}
static void cepstral_float_param_tts(switch_speech_handle_t *sh, char *param, double val)
{
cepstral_t *cepstral;
cepstral = sh->private_info;
assert(cepstral != NULL);
swift_port_set_param_float(cepstral->port, param, val, NULL);
}
static const switch_speech_interface_t cepstral_speech_interface = { static const switch_speech_interface_t cepstral_speech_interface = {
/*.interface_name*/ "cepstral", /*.interface_name*/ "cepstral",
/*.speech_open*/ cepstral_speech_open, /*.speech_open*/ cepstral_speech_open,
@ -302,7 +384,10 @@ static const switch_speech_interface_t cepstral_speech_interface = {
/*.speech_interpret_asr*/ NULL, /*.speech_interpret_asr*/ NULL,
/*.speech_feed_tts*/ cepstral_speech_feed_tts, /*.speech_feed_tts*/ cepstral_speech_feed_tts,
/*.speech_read_tts*/ cepstral_speech_read_tts, /*.speech_read_tts*/ cepstral_speech_read_tts,
/*.speech_flush_tts*/ cepstral_speech_flush_tts /*.speech_flush_tts*/ cepstral_speech_flush_tts,
/*.speech_text_param_tts*/ cepstral_text_param_tts,
/*.speech_numeric_param_tts*/ cepstral_numeric_param_tts,
/*.speech_numeric_param_tts*/ cepstral_float_param_tts
}; };
static const switch_loadable_module_interface_t cepstral_module_interface = { static const switch_loadable_module_interface_t cepstral_module_interface = {

View File

@ -566,8 +566,8 @@ static switch_status_t wanpipe_write_frame(switch_core_session_t *session, switc
while (bytes > 0) { while (bytes > 0) {
unsigned int towrite; unsigned int towrite;
#if 0 #if 1
if (sangoma_socket_waitfor(tech_pvt->socket, -1, POLLOUT | POLLERR | POLLHUP) <= 0) { if (sangoma_socket_waitfor(tech_pvt->socket, 1000, POLLOUT | POLLERR | POLLHUP) <= 0) {
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
#endif #endif

View File

@ -578,6 +578,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_speech_open(switch_speech_handle_t *
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
switch_copy_string(sh->engine, module_name, sizeof(sh->engine));
sh->flags = *flags; sh->flags = *flags;
if (pool) { if (pool) {
sh->memory_pool = pool; sh->memory_pool = pool;
@ -640,6 +641,15 @@ SWITCH_DECLARE(void) switch_core_speech_numeric_param_tts(switch_speech_handle_t
} }
} }
SWITCH_DECLARE(void) switch_core_speech_float_param_tts(switch_speech_handle_t *sh, char *param, double val)
{
assert(sh != NULL);
if (sh->speech_interface->speech_float_param_tts) {
sh->speech_interface->speech_float_param_tts(sh, param, val);
}
}
SWITCH_DECLARE(switch_status_t) switch_core_speech_read_tts(switch_speech_handle_t *sh, SWITCH_DECLARE(switch_status_t) switch_core_speech_read_tts(switch_speech_handle_t *sh,
void *data, void *data,
switch_size_t *datalen, switch_size_t *datalen,
@ -736,15 +746,13 @@ static void *switch_core_service_thread(switch_thread_t *thread, void *obj)
while (data->running > 0) { while (data->running > 0) {
switch (switch_core_session_read_frame(session, &read_frame, -1, stream_id)) { switch (switch_core_session_read_frame(session, &read_frame, -1, stream_id)) {
case SWITCH_STATUS_SUCCESS: case SWITCH_STATUS_SUCCESS:
break;
case SWITCH_STATUS_TIMEOUT: case SWITCH_STATUS_TIMEOUT:
case SWITCH_STATUS_BREAK:
break; break;
default: default:
data->running = -1; data->running = -1;
continue; continue;
} }
switch_yield(10000);
} }
data->running = 0; data->running = 0;

View File

@ -554,6 +554,52 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
ilen = len; ilen = len;
while(switch_channel_ready(channel)) { while(switch_channel_ready(channel)) {
if (dtmf_callback || buf) {
/*
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 (buf && !strcasecmp(buf, "_break_")) {
status = SWITCH_STATUS_BREAK;
} else {
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
if (dtmf_callback) {
status = dtmf_callback(session, dtmf, buf, buflen);
} else {
switch_copy_string((char *)buf, dtmf, buflen);
status = SWITCH_STATUS_BREAK;
}
}
}
if (status != SWITCH_STATUS_SUCCESS) {
done = 1;
break;
}
}
if (switch_test_flag(sh, SWITCH_SPEECH_FLAG_PAUSE)) {
if (timer) {
if ((x = switch_core_timer_next(timer)) < 0) {
break;
}
} else {
switch_frame_t *read_frame;
switch_status_t status = switch_core_session_read_frame(session, &read_frame, -1, 0);
while (switch_channel_test_flag(channel, CF_HOLD)) {
switch_yield(10000);
}
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
}
}
continue;
}
flags = SWITCH_SPEECH_FLAG_BLOCKING; flags = SWITCH_SPEECH_FLAG_BLOCKING;
status = switch_core_speech_read_tts(sh, status = switch_core_speech_read_tts(sh,
abuf, abuf,
@ -596,27 +642,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session
} }
} }
if (dtmf_callback || buf) {
/*
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)) {
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
if (dtmf_callback) {
status = dtmf_callback(session, dtmf, buf, buflen);
} else {
switch_copy_string((char *)buf, dtmf, buflen);
status = SWITCH_STATUS_BREAK;
}
}
if (status != SWITCH_STATUS_SUCCESS) {
done = 1;
break;
}
}
if (timer) { if (timer) {
if ((x = switch_core_timer_next(timer)) < 0) { if ((x = switch_core_timer_next(timer)) < 0) {
break; break;