2006-06-08 19:26:39 +00:00
/*
* 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 " ;
typedef enum {
SFLAG_INSTRUCT = ( 1 < < 0 ) ,
SFLAG_INFO = ( 1 < < 1 ) ,
SFLAG_MAIN = ( 1 < < 2 )
} SFLAGS ;
/* helper object */
struct dtmf_buffer {
int32_t index ;
uint32_t flags ;
int32_t speed ;
char voice [ 80 ] ;
switch_speech_handle_t * sh ;
} ;
# define TTS_MEAN_SPEED 170
# define TTS_MAX_ENTRIES 99
# define TTS_DEFAULT_ENGINE "cepstral"
# define TTS_DEFAULT_VOICE "david"
2006-06-14 16:52:24 +00:00
# define MATCH_COUNT
2006-06-11 03:21:00 +00:00
struct rss_entry {
2006-06-08 19:26:39 +00:00
uint8_t inuse ;
char * title_txt ;
char * description_txt ;
char * subject_txt ;
char * dept_txt ;
} ;
2006-06-10 20:57:15 +00:00
# ifdef MATCH_COUNT
static uint32_t match_count ( char * str , uint32_t max )
{
char tstr [ 80 ] = " " ;
uint32_t matches = 0 , x = 0 ;
2006-06-14 16:52:24 +00:00
uint32_t len = ( uint32_t ) strlen ( str ) ;
2006-06-23 20:14:29 +00:00
2006-06-10 20:57:15 +00:00
for ( x = 0 ; x < max ; x + + ) {
snprintf ( tstr , sizeof ( tstr ) , " %u " , x ) ;
if ( ! strncasecmp ( str , tstr , len ) ) {
matches + + ;
}
}
return matches ;
}
# endif
2006-06-08 19:26:39 +00:00
/*
dtmf handler function you can hook up to be executed when a digit is dialed during playback
2006-06-11 03:21:00 +00:00
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop .
2006-06-08 19:26:39 +00:00
*/
2006-07-12 18:39:19 +00:00
static switch_status_t on_dtmf ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
2006-06-08 19:26:39 +00:00
2006-07-12 18:39:19 +00:00
{
switch ( itype ) {
case SWITCH_INPUT_TYPE_DTMF : {
char * dtmf = ( char * ) input ;
struct dtmf_buffer * dtb ;
dtb = ( struct dtmf_buffer * ) buf ;
2006-06-08 19:26:39 +00:00
2006-07-12 18:39:19 +00:00
switch ( * dtmf ) {
case ' # ' :
switch_set_flag ( dtb , SFLAG_MAIN ) ;
return SWITCH_STATUS_BREAK ;
case ' 6 ' :
dtb - > index + + ;
return SWITCH_STATUS_BREAK ;
case ' 4 ' :
dtb - > index - - ;
return SWITCH_STATUS_BREAK ;
case ' * ' :
if ( switch_test_flag ( dtb - > sh , SWITCH_SPEECH_FLAG_PAUSE ) ) {
switch_clear_flag ( dtb - > sh , SWITCH_SPEECH_FLAG_PAUSE ) ;
} else {
switch_set_flag ( dtb - > sh , SWITCH_SPEECH_FLAG_PAUSE ) ;
}
break ;
case ' 5 ' :
switch_core_speech_text_param_tts ( dtb - > sh , " voice " , " next " ) ;
2006-06-08 19:26:39 +00:00
switch_set_flag ( dtb , SFLAG_INFO ) ;
return SWITCH_STATUS_BREAK ;
2006-07-12 18:39:19 +00:00
break ;
case ' 9 ' :
switch_core_speech_text_param_tts ( dtb - > sh , " voice " , dtb - > voice ) ;
switch_set_flag ( dtb , SFLAG_INFO ) ;
return SWITCH_STATUS_BREAK ;
break ;
case ' 2 ' :
if ( dtb - > speed < 260 ) {
dtb - > speed + = 30 ;
switch_core_speech_numeric_param_tts ( dtb - > sh , " speech/rate " , dtb - > speed ) ;
switch_set_flag ( dtb , SFLAG_INFO ) ;
return SWITCH_STATUS_BREAK ;
}
break ;
case ' 7 ' :
dtb - > speed = TTS_MEAN_SPEED ;
2006-06-08 19:26:39 +00:00
switch_core_speech_numeric_param_tts ( dtb - > sh , " speech/rate " , dtb - > speed ) ;
switch_set_flag ( dtb , SFLAG_INFO ) ;
return SWITCH_STATUS_BREAK ;
2006-07-12 18:39:19 +00:00
case ' 8 ' :
if ( dtb - > speed > 80 ) {
dtb - > speed - = 30 ;
switch_core_speech_numeric_param_tts ( dtb - > sh , " speech/rate " , dtb - > speed ) ;
switch_set_flag ( dtb , SFLAG_INFO ) ;
return SWITCH_STATUS_BREAK ;
}
break ;
case ' 0 ' :
switch_set_flag ( dtb , SFLAG_INSTRUCT ) ;
return SWITCH_STATUS_BREAK ;
2006-06-08 19:26:39 +00:00
}
2006-07-12 18:39:19 +00:00
}
break ;
default :
2006-06-08 19:26:39 +00:00
break ;
}
return SWITCH_STATUS_SUCCESS ;
}
static void rss_function ( switch_core_session_t * session , char * data )
{
switch_channel_t * channel ;
switch_status_t status ;
const char * err = NULL ;
struct dtmf_buffer dtb = { 0 } ;
switch_xml_t xml = NULL , item , xchannel = NULL ;
2006-06-11 03:21:00 +00:00
struct rss_entry entries [ TTS_MAX_ENTRIES ] = { { 0 } } ;
2006-06-08 19:26:39 +00:00
uint32_t i = 0 ;
char * title_txt = " " , * description_txt = " " , * rights_txt = " " ;
switch_codec_t speech_codec , * codec = switch_core_session_get_read_codec ( session ) ;
char * engine = TTS_DEFAULT_ENGINE ;
char * voice = TTS_DEFAULT_VOICE ;
char * timer_name = NULL ;
switch_speech_handle_t sh ;
2006-11-09 05:39:04 +00:00
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE ;
2006-06-08 19:26:39 +00:00
switch_core_thread_session_t thread_session ;
2006-06-08 19:41:14 +00:00
uint32_t rate , interval = 20 ;
int stream_id = 0 ;
2006-06-08 19:26:39 +00:00
switch_timer_t timer = { 0 } , * timerp = NULL ;
uint32_t last ;
char * mydata = NULL ;
char * filename = NULL ;
char * argv [ 3 ] , * feed_list [ TTS_MAX_ENTRIES ] = { 0 } , * feed_names [ TTS_MAX_ENTRIES ] = { 0 } ;
int argc , feed_index = 0 ;
char * cf = " rss.conf " ;
switch_xml_t cfg , cxml , feeds , feed ;
char buf [ 1024 ] ;
2006-06-08 19:41:14 +00:00
int32_t jumpto = - 1 ;
2006-06-10 20:57:15 +00:00
uint32_t matches = 0 ;
2006-12-24 02:24:16 +00:00
switch_input_args_t args = { 0 } ;
2006-06-08 19:26:39 +00:00
2006-06-08 22:03:23 +00:00
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2006-06-08 19:26:39 +00:00
if ( ! ( cxml = switch_xml_open_cfg ( cf , & cfg , NULL ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " open of %s failed \n " , cf ) ;
return ;
}
if ( ( feeds = switch_xml_child ( cfg , " feeds " ) ) ) {
for ( feed = switch_xml_child ( feeds , " feed " ) ; feed ; feed = feed - > next ) {
char * name = ( char * ) switch_xml_attr_soft ( feed , " name " ) ;
if ( ! name ) {
name = " Error No Name. " ;
}
feed_names [ feed_index ] = switch_core_session_strdup ( session , name ) ;
feed_list [ feed_index ] = switch_core_session_strdup ( session , feed - > txt ) ;
feed_index + + ;
}
}
switch_xml_free ( cxml ) ;
2006-06-08 22:03:23 +00:00
switch_channel_answer ( channel ) ;
2006-06-08 19:26:39 +00:00
if ( ! switch_strlen_zero ( data ) ) {
if ( ( mydata = switch_core_session_strdup ( session , data ) ) ) {
argc = switch_separate_string ( mydata , ' ' , argv , sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ;
if ( argv [ 0 ] ) {
engine = argv [ 0 ] ;
if ( argv [ 1 ] ) {
voice = argv [ 1 ] ;
if ( argv [ 2 ] ) {
jumpto = atoi ( argv [ 2 ] ) ;
}
}
}
}
}
if ( ! feed_index ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " No Feeds Specified! \n " ) ;
return ;
}
if ( codec ) {
rate = codec - > implementation - > samples_per_second ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Codec Error! \n " ) ;
return ;
}
memset ( & sh , 0 , sizeof ( sh ) ) ;
if ( switch_core_speech_open ( & sh ,
engine ,
voice ,
rate ,
& flags ,
switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid TTS module! \n " ) ;
return ;
}
if ( switch_core_codec_init ( & speech_codec ,
" L16 " ,
2006-10-09 02:24:43 +00:00
NULL ,
2006-06-08 19:26:39 +00:00
( int ) rate ,
interval ,
1 ,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE ,
NULL ,
switch_core_session_get_pool ( session ) ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Raw Codec Activated \n " ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Raw Codec Activation Failed L16@%uhz 1 channel %dms \n " , rate , interval ) ;
flags = 0 ;
switch_core_speech_close ( & sh , & flags ) ;
return ;
}
if ( timer_name ) {
if ( switch_core_timer_init ( & timer , timer_name , interval , ( int ) ( rate / 50 ) , switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " setup timer failed! \n " ) ;
switch_core_codec_destroy ( & speech_codec ) ;
flags = 0 ;
switch_core_speech_close ( & sh , & flags ) ;
return ;
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " setup timer success %u bytes per %d ms! \n " , ( rate / 50 ) * 2 , interval ) ;
/* start a thread to absorb incoming audio */
for ( stream_id = 0 ; stream_id < switch_core_session_get_stream_count ( session ) ; stream_id + + ) {
switch_core_service_session ( session , & thread_session , stream_id ) ;
}
timerp = & timer ;
}
while ( switch_channel_ready ( channel ) ) {
int32_t len = 0 , idx = 0 ;
char cmd [ 3 ] ;
main_menu :
filename = NULL ;
len = idx = 0 ;
* cmd = ' \0 ' ;
2006-06-11 03:11:04 +00:00
title_txt = description_txt = rights_txt = " " ;
2006-06-08 19:26:39 +00:00
if ( jumpto > - 1 ) {
snprintf ( cmd , sizeof ( cmd ) , " %d " , jumpto ) ;
2006-06-23 20:14:29 +00:00
jumpto = - 1 ;
2006-06-08 19:26:39 +00:00
} else {
switch_core_speech_flush_tts ( & sh ) ;
2006-06-14 16:52:24 +00:00
# ifdef MATCH_COUNT
snprintf ( buf + len , sizeof ( buf ) - len ,
2006-07-12 22:03:00 +00:00
" ,<break time= \" 500ms \" />Main Menu. <break time= \" 600ms \" /> "
2006-06-14 16:54:55 +00:00
" Select one of the following news sources, or press 0 to exit. "
2006-07-12 22:03:00 +00:00
" ,<break time= \" 600ms \" /> " ) ;
2006-06-14 16:52:24 +00:00
# else
2006-06-08 19:26:39 +00:00
snprintf ( buf + len , sizeof ( buf ) - len ,
2006-07-12 22:03:00 +00:00
" ,<break time= \" 500ms \" />Main Menu. <break time= \" 600ms \" /> "
2006-06-14 16:54:55 +00:00
" Select one of the following news sources, followed by the pound key or press 0 to exit. "
2006-07-12 22:03:00 +00:00
" ,<break time= \" 600ms \" /> " ) ;
2006-06-14 16:52:24 +00:00
# endif
2006-06-08 19:44:43 +00:00
len = ( int32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
for ( idx = 0 ; idx < feed_index ; idx + + ) {
2006-06-14 18:03:33 +00:00
snprintf ( buf + len , sizeof ( buf ) - len , " %d: %s. <break time= \" 600ms \" /> " , idx + 1 , feed_names [ idx ] ) ;
2006-06-08 19:44:43 +00:00
len = ( int32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
}
snprintf ( buf + len , sizeof ( buf ) - len , " <break time= \" 2000ms \" /> " ) ;
2006-06-08 19:44:43 +00:00
len = ( int32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
2006-12-24 02:24:16 +00:00
args . input_callback = NULL ;
args . buf = cmd ;
args . buflen = sizeof ( cmd ) ;
2006-06-08 19:26:39 +00:00
status = switch_ivr_speak_text_handle ( session ,
& sh ,
& speech_codec ,
timerp ,
buf ,
2006-12-24 02:24:16 +00:00
& args ) ;
2006-06-08 19:26:39 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
goto finished ;
}
}
if ( ! switch_strlen_zero ( cmd ) ) {
int32_t i ;
2006-06-10 20:57:15 +00:00
char * p ;
2006-06-08 19:26:39 +00:00
2006-06-10 20:57:15 +00:00
if ( strchr ( cmd , ' 0 ' ) ) {
2006-06-08 19:26:39 +00:00
break ;
}
2006-06-10 20:57:15 +00:00
if ( ( p = strchr ( cmd , ' # ' ) ) ) {
* p = ' \0 ' ;
# ifdef MATCH_COUNT
/* Hmmm... I know there are no more matches so I don't *need* them to press pound but
I already told them to press it . Will this confuse people or not ? Let ' s make em press
pound unless this define is enabled for now .
2006-06-11 03:21:00 +00:00
*/
2006-06-10 20:57:15 +00:00
} else if ( match_count ( cmd , feed_index ) > 1 ) {
# else
} else {
# endif
char term ;
char * cp ;
2006-06-12 17:27:22 +00:00
int blen = sizeof ( cmd ) - ( int ) strlen ( cmd ) ;
2006-06-10 20:57:15 +00:00
cp = cmd + blen ;
switch_ivr_collect_digits_count ( session , cp , blen , blen , " # " , & term , 5000 ) ;
}
2006-06-08 19:26:39 +00:00
i = atoi ( cmd ) - 1 ;
2006-06-09 19:54:53 +00:00
if ( i > - 1 & & i < feed_index ) {
2006-06-08 19:26:39 +00:00
filename = feed_list [ i ] ;
2006-06-10 20:57:15 +00:00
} else if ( matches > 1 ) {
2006-06-09 19:54:53 +00:00
} else {
2006-12-24 02:24:16 +00:00
args . input_callback = NULL ;
args . buf = NULL ;
args . buflen = 0 ;
2006-06-09 19:54:53 +00:00
status = switch_ivr_speak_text_handle ( session ,
& sh ,
& speech_codec ,
timerp ,
" I'm sorry. That is an Invalid Selection. " ,
2006-12-24 02:24:16 +00:00
& args ) ;
2006-06-09 19:54:53 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
goto finished ;
}
2006-06-08 19:26:39 +00:00
}
}
if ( ! filename ) {
continue ;
}
2006-06-09 19:54:53 +00:00
2006-06-08 19:26:39 +00:00
if ( ! ( xml = switch_xml_parse_file ( filename ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " open of %s failed \n " , filename ) ;
goto finished ;
}
err = switch_xml_error ( xml ) ;
if ( ! switch_strlen_zero ( err ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Error [%s] \n " , err ) ;
goto finished ;
}
if ( ( xchannel = switch_xml_child ( xml , " channel " ) ) ) {
switch_xml_t title , description , rights ;
if ( ( title = switch_xml_child ( xchannel , " title " ) ) ) {
title_txt = title - > txt ;
}
if ( ( description = switch_xml_child ( xchannel , " description " ) ) ) {
description_txt = description - > txt ;
}
if ( ( rights = switch_xml_child ( xchannel , " dc:rights " ) ) ) {
rights_txt = rights - > txt ;
}
}
if ( ! ( item = switch_xml_child ( xml , " item " ) ) ) {
if ( xchannel ) {
item = switch_xml_child ( xchannel , " item " ) ;
}
}
2006-06-11 03:11:04 +00:00
memset ( entries , 0 , sizeof ( entries ) ) ;
2006-06-08 19:26:39 +00:00
for ( i = 0 ; item ; item = item - > next ) {
switch_xml_t title , description , subject , dept ;
char * p ;
entries [ i ] . inuse = 1 ;
entries [ i ] . title_txt = NULL ;
entries [ i ] . description_txt = NULL ;
entries [ i ] . subject_txt = NULL ;
entries [ i ] . dept_txt = NULL ;
if ( ( title = switch_xml_child ( item , " title " ) ) ) {
entries [ i ] . title_txt = title - > txt ;
}
if ( ( description = switch_xml_child ( item , " description " ) ) ) {
char * t , * e ;
entries [ i ] . description_txt = description - > txt ;
for ( ; ; ) {
if ( ! ( t = strchr ( entries [ i ] . description_txt , ' < ' ) ) ) {
break ;
}
if ( ! ( e = strchr ( t , ' > ' ) ) ) {
break ;
}
memset ( t , 32 , + + e - t ) ;
}
}
if ( ( subject = switch_xml_child ( item , " dc:subject " ) ) ) {
entries [ i ] . subject_txt = subject - > txt ;
}
if ( ( dept = switch_xml_child ( item , " slash:department " ) ) ) {
entries [ i ] . dept_txt = dept - > txt ;
}
if ( entries [ i ] . description_txt & & ( p = strchr ( entries [ i ] . description_txt , ' < ' ) ) ) {
* p = ' \0 ' ;
}
# ifdef _STRIP_SOME_CHARS_
for ( p = entries [ i ] . description_txt ; * p ; p + + ) {
if ( * p = = ' \' ' | | * p = = ' " ' | | * p = = ' : ' ) {
* p = ' ' ;
}
}
# endif
i + + ;
}
if ( switch_channel_ready ( channel ) ) {
switch_time_exp_t tm ;
char date [ 80 ] = " " ;
switch_size_t retsize ;
char cmd [ 5 ] = " " ;
switch_time_exp_lt ( & tm , switch_time_now ( ) ) ;
2006-06-14 14:54:43 +00:00
switch_strftime ( date , & retsize , sizeof ( date ) , " %I:%M %p " , & tm ) ;
2006-06-08 19:26:39 +00:00
2006-07-12 22:03:00 +00:00
snprintf ( buf , sizeof ( buf ) , " ,<break time= \" 500ms \" />%s. %s. %s. local time: %s, Press 0 for options, 5 to change voice, or pound to return to the main menu. " ,
2006-06-08 19:26:39 +00:00
title_txt , description_txt , rights_txt , date ) ;
2006-12-24 02:24:16 +00:00
args . input_callback = NULL ;
args . buf = cmd ;
args . buflen = sizeof ( cmd ) ;
2006-06-08 19:26:39 +00:00
status = switch_ivr_speak_text_handle ( session ,
& sh ,
& speech_codec ,
timerp ,
buf ,
2006-12-24 02:24:16 +00:00
& args ) ;
2006-06-08 19:26:39 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
goto finished ;
}
if ( ! switch_strlen_zero ( cmd ) ) {
switch ( * cmd ) {
case ' 0 ' :
switch_set_flag ( & dtb , SFLAG_INSTRUCT ) ;
break ;
2006-06-08 22:03:23 +00:00
case ' # ' :
goto main_menu ;
break ;
2006-06-08 19:26:39 +00:00
}
}
}
for ( last = 0 ; last < TTS_MAX_ENTRIES ; last + + ) {
if ( ! entries [ last ] . inuse ) {
last - - ;
break ;
}
}
dtb . index = 0 ;
dtb . sh = & sh ;
dtb . speed = TTS_MEAN_SPEED ;
switch_set_flag ( & dtb , SFLAG_INFO ) ;
switch_copy_string ( dtb . voice , voice , sizeof ( dtb . voice ) ) ;
while ( entries [ 0 ] . inuse & & switch_channel_ready ( channel ) ) {
while ( switch_channel_ready ( channel ) ) {
uint8_t cont = 0 ;
if ( dtb . index > = TTS_MAX_ENTRIES ) {
dtb . index = 0 ;
}
if ( dtb . index < 0 ) {
dtb . index = last ;
}
if ( ! entries [ dtb . index ] . inuse ) {
dtb . index = 0 ;
continue ;
}
if ( switch_channel_ready ( channel ) ) {
char buf [ 1024 ] = " " ;
uint32_t len = 0 ;
if ( switch_test_flag ( & dtb , SFLAG_MAIN ) ) {
switch_clear_flag ( & dtb , SFLAG_MAIN ) ;
goto main_menu ;
}
if ( switch_test_flag ( & dtb , SFLAG_INFO ) ) {
switch_clear_flag ( & dtb , SFLAG_INFO ) ;
snprintf ( buf + len , sizeof ( buf ) - len ,
2006-06-14 14:54:43 +00:00
" %s %s. I am speaking at %u words per minute. " ,
2006-06-08 19:26:39 +00:00
sh . engine ,
sh . voice ,
dtb . speed
) ;
2006-06-08 19:44:43 +00:00
len = ( uint32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
}
if ( switch_test_flag ( & dtb , SFLAG_INSTRUCT ) ) {
switch_clear_flag ( & dtb , SFLAG_INSTRUCT ) ;
cont = 1 ;
snprintf ( buf + len , sizeof ( buf ) - len ,
" Press star to pause or resume speech. "
" To go to the next item, press six. "
" To go back, press 4. "
2006-06-12 17:27:22 +00:00
" Press two to go faster, eight to slow down, or 7 to resume normal speed. "
2006-06-08 19:26:39 +00:00
" To change voices, press five. To restore the original voice press 9. "
" To hear these options again, press zero or press pound to return to the main menu. " ) ;
} else {
snprintf ( buf + len , sizeof ( buf ) - len , " Story %d. " , dtb . index + 1 ) ;
2006-06-08 19:44:43 +00:00
len = ( uint32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
if ( entries [ dtb . index ] . subject_txt ) {
2006-06-12 17:57:26 +00:00
snprintf ( buf + len , sizeof ( buf ) - len , " Subject: %s. " , entries [ dtb . index ] . subject_txt ) ;
2006-06-08 19:44:43 +00:00
len = ( uint32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
}
if ( entries [ dtb . index ] . dept_txt ) {
snprintf ( buf + len , sizeof ( buf ) - len , " From the %s department. " , entries [ dtb . index ] . dept_txt ) ;
2006-06-08 19:44:43 +00:00
len = ( uint32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
}
if ( entries [ dtb . index ] . title_txt ) {
snprintf ( buf + len , sizeof ( buf ) - len , " %s " , entries [ dtb . index ] . title_txt ) ;
2006-06-08 19:44:43 +00:00
len = ( uint32_t ) strlen ( buf ) ;
2006-06-08 19:26:39 +00:00
}
}
switch_core_speech_flush_tts ( & sh ) ;
2006-12-24 02:24:16 +00:00
args . input_callback = on_dtmf ;
args . buf = & dtb ;
args . buflen = sizeof ( dtb ) ;
2006-06-08 19:26:39 +00:00
status = switch_ivr_speak_text_handle ( session ,
& sh ,
& speech_codec ,
timerp ,
buf ,
2006-12-24 02:24:16 +00:00
& args ) ;
2006-06-08 19:26:39 +00:00
if ( status = = SWITCH_STATUS_BREAK ) {
continue ;
} else if ( status ! = SWITCH_STATUS_SUCCESS ) {
goto finished ;
}
if ( cont ) {
cont = 0 ;
continue ;
}
2006-07-06 22:12:15 +00:00
if ( entries [ dtb . index ] . description_txt ) {
2006-12-24 02:24:16 +00:00
args . input_callback = on_dtmf ;
args . buf = & dtb ;
args . buflen = sizeof ( dtb ) ;
2006-07-06 22:12:15 +00:00
status = switch_ivr_speak_text_handle ( session ,
& sh ,
& speech_codec ,
timerp ,
entries [ dtb . index ] . description_txt ,
2006-12-24 02:24:16 +00:00
& args ) ;
2006-07-06 22:12:15 +00:00
}
2006-06-08 19:26:39 +00:00
if ( status = = SWITCH_STATUS_BREAK ) {
continue ;
} else if ( status ! = SWITCH_STATUS_SUCCESS ) {
goto finished ;
}
}
dtb . index + + ;
}
}
}
finished :
switch_core_speech_close ( & sh , & flags ) ;
switch_core_codec_destroy ( & speech_codec ) ;
if ( timerp ) {
/* End the audio absorbing thread */
switch_core_thread_session_end ( & thread_session ) ;
switch_core_timer_destroy ( & timer ) ;
}
2006-06-09 19:54:53 +00:00
2006-06-08 19:26:39 +00:00
switch_xml_free ( xml ) ;
switch_core_session_reset ( session ) ;
}
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 ;
}
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2007-02-09 02:36:03 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 expandtab :
*/