ivr stuff

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1569 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2006-06-08 01:58:37 +00:00
parent 9c2442886d
commit 7b4cc868e4
6 changed files with 309 additions and 155 deletions

View File

@ -895,6 +895,28 @@ SWITCH_DECLARE(switch_status_t) switch_core_speech_interpret_asr(switch_speech_h
*/ */
SWITCH_DECLARE(switch_status_t) switch_core_speech_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags); SWITCH_DECLARE(switch_status_t) switch_core_speech_feed_tts(switch_speech_handle_t *sh, char *text, switch_speech_flag_t *flags);
/*!
\brief Flush TTS audio on a given handle
\param sh the speech handle
*/
SWITCH_DECLARE(void) switch_core_speech_flush_tts(switch_speech_handle_t *sh);
/*!
\brief Set a text parameter on a TTS handle
\param sh the speech handle
\param param the parameter
\param val the value
*/
SWITCH_DECLARE(void) switch_core_speech_text_param_tts(switch_speech_handle_t *sh, char *param, char *val);
/*!
\brief Set a numeric parameter on a TTS handle
\param sh the speech handle
\param param the parameter
\param val the value
*/
SWITCH_DECLARE(void) switch_core_speech_numeric_param_tts(switch_speech_handle_t *sh, char *param, int 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

@ -125,6 +125,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
unsigned int buflen); unsigned int buflen);
SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session_t *session,
switch_speech_handle_t *sh,
switch_codec_t *codec,
switch_timer_t *timer,
switch_dtmf_callback_function_t dtmf_callback,
char *text,
void *buf,
unsigned int buflen);
/*! /*!
\brief Speak given text with given tts engine \brief Speak given text with given tts engine
\param session the session to speak on \param session the session to speak on
@ -139,14 +148,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
\return SWITCH_STATUS_SUCCESS if all is well \return SWITCH_STATUS_SUCCESS if all is well
*/ */
SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *session, SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *session,
char *tts_name, char *tts_name,
char *voice_name, char *voice_name,
char *timer_name, char *timer_name,
uint32_t rate, uint32_t rate,
switch_dtmf_callback_function_t dtmf_callback, switch_dtmf_callback_function_t dtmf_callback,
char *text, char *text,
void *buf, void *buf,
unsigned int buflen); unsigned int buflen);
/*! /*!
\brief Bridge Audio from one session to another \brief Bridge Audio from one session to another

View File

@ -327,6 +327,9 @@ struct switch_speech_interface {
switch_size_t *datalen, switch_size_t *datalen,
uint32_t *rate, uint32_t *rate,
switch_speech_flag_t *flags); switch_speech_flag_t *flags);
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_numeric_param_tts)(switch_speech_handle_t *sh, char *param, int val);
const struct switch_speech_interface *next; const struct switch_speech_interface *next;
}; };
@ -338,7 +341,10 @@ struct switch_speech_handle {
const switch_speech_interface_t *speech_interface; const switch_speech_interface_t *speech_interface;
/*! flags to control behaviour */ /*! flags to control behaviour */
uint32_t flags; uint32_t flags;
/*! The Name*/
char *name;
/*! The Rate*/
uint32_t rate;
/*! 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

@ -36,6 +36,8 @@
#include <swift.h> #include <swift.h>
#include <switch.h> #include <switch.h>
#define MY_BUF_LEN 1024 * 512
static const char modname[] = "mod_cepstral"; static const char modname[] = "mod_cepstral";
static swift_engine *engine; static swift_engine *engine;
@ -59,23 +61,42 @@ static swift_result_t write_audio(swift_event *event, swift_event_t type, void *
cepstral_t *cepstral; cepstral_t *cepstral;
swift_event_t rv = SWIFT_SUCCESS; swift_event_t rv = SWIFT_SUCCESS;
void *buf = NULL; void *buf = NULL;
int len = 0; int len = 0, i = 0;
cepstral = udata; cepstral = udata;
assert(cepstral != NULL); assert(cepstral != NULL);
if (!cepstral->port || cepstral->done || cepstral->done_gen) {
return SWIFT_UNKNOWN_ERROR;
}
/* Only proceed when we have success */ /* Only proceed when we have success */
if (!SWIFT_FAILED((rv = swift_event_get_audio(event, &buf, &len)))) { if (!SWIFT_FAILED((rv = swift_event_get_audio(event, &buf, &len)))) {
switch_mutex_lock(cepstral->audio_lock); while(!cepstral->done) {
switch_mutex_lock(cepstral->audio_lock);
if (switch_buffer_write(cepstral->audio_buffer, buf, len) <= 0) { if (switch_buffer_write(cepstral->audio_buffer, buf, len) > 0) {
rv = SWIFT_UNKNOWN_ERROR; switch_mutex_unlock(cepstral->audio_lock);
break;
}
switch_mutex_unlock(cepstral->audio_lock);
if (!cepstral->done) {
for (i = 0; i < 10; i++) {
switch_yield(10000);
if (cepstral->done) {
break;
}
}
}
} }
switch_mutex_unlock(cepstral->audio_lock);
} else { } else {
cepstral->done = 1; cepstral->done = 1;
} }
if (cepstral->done) {
rv = SWIFT_UNKNOWN_ERROR;
}
return rv; return rv;
} }
@ -92,7 +113,7 @@ static switch_status_t cepstral_speech_open(switch_speech_handle_t *sh, char *vo
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;
} }
if (switch_buffer_create(sh->memory_pool, &cepstral->audio_buffer, 1024 * 256) != SWITCH_STATUS_SUCCESS) { if (switch_buffer_create(sh->memory_pool, &cepstral->audio_buffer, MY_BUF_LEN) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Failed!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Failed!\n");
return SWITCH_STATUS_MEMERR; return SWITCH_STATUS_MEMERR;
} }
@ -151,6 +172,11 @@ static switch_status_t cepstral_speech_close(switch_speech_handle_t *sh, switch_
cepstral = sh->private_info; cepstral = sh->private_info;
assert(cepstral != NULL); assert(cepstral != NULL);
cepstral->done = 1;
cepstral->done_gen = 1;
printf("CLOSE!!!\n");
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);
//if (NULL != cepstral->engine) swift_engine_close(cepstral->engine); //if (NULL != cepstral->engine) swift_engine_close(cepstral->engine);
@ -169,13 +195,33 @@ static switch_status_t cepstral_speech_feed_tts(switch_speech_handle_t *sh, char
cepstral = sh->private_info; cepstral = sh->private_info;
assert(cepstral != NULL); assert(cepstral != NULL);
swift_port_speak_text(cepstral->port, text, 0, NULL, &cepstral->tts_stream, NULL); cepstral->done_gen = 0;
//swift_port_speak_text(cepstral->port, text, 0, NULL, NULL, NULL); cepstral->done = 0;
cepstral->tts_stream = NULL;
swift_port_speak_text(cepstral->port, text, 0, NULL, &cepstral->tts_stream, NULL);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
static void cepstral_speech_flush_tts(switch_speech_handle_t *sh)
{
cepstral_t *cepstral;
cepstral = sh->private_info;
assert(cepstral != NULL);
cepstral->done_gen = 1;
cepstral->done = 1;
if (cepstral->audio_buffer) {
switch_mutex_lock(cepstral->audio_lock);
switch_buffer_zero(cepstral->audio_buffer);
switch_mutex_unlock(cepstral->audio_lock);
}
swift_port_stop(cepstral->port, SWIFT_ASYNC_ANY, SWIFT_EVENT_NOW);
}
static switch_status_t cepstral_speech_read_tts(switch_speech_handle_t *sh, static switch_status_t cepstral_speech_read_tts(switch_speech_handle_t *sh,
void *data, void *data,
size_t *datalen, size_t *datalen,
@ -193,18 +239,23 @@ static switch_status_t cepstral_speech_read_tts(switch_speech_handle_t *sh,
while(!cepstral->done) { while(!cepstral->done) {
if (!cepstral->done_gen) { if (!cepstral->done_gen) {
int check = (SWIFT_STATUS_RUNNING == swift_port_status(cepstral->port, cepstral->tts_stream)); int check = swift_port_status(cepstral->port, cepstral->tts_stream);
if (!check) {
if (!check == SWIFT_STATUS_RUNNING) {
cepstral->done_gen = 1; cepstral->done_gen = 1;
} }
} }
switch_mutex_lock(cepstral->audio_lock);
used = switch_buffer_inuse(cepstral->audio_buffer); used = switch_buffer_inuse(cepstral->audio_buffer);
switch_mutex_unlock(cepstral->audio_lock);
if (!used && cepstral->done_gen) { if (!used && cepstral->done_gen) {
status = SWITCH_STATUS_BREAK;
break; break;
} }
/* wait for the right amount of data (unless there is no blocking flag) */ /* wait for the right amount of data (unless there is no blocking flag) */
if (used < desired) { if (used < desired) {
@ -250,8 +301,8 @@ static const switch_speech_interface_t cepstral_speech_interface = {
/*.speech_feed_asr*/ NULL, /*.speech_feed_asr*/ NULL,
/*.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
}; };
static const switch_loadable_module_interface_t cepstral_module_interface = { static const switch_loadable_module_interface_t cepstral_module_interface = {

View File

@ -565,11 +565,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_directory_close(switch_directory_han
} }
SWITCH_DECLARE(switch_status_t) switch_core_speech_open(switch_speech_handle_t *sh, SWITCH_DECLARE(switch_status_t) switch_core_speech_open(switch_speech_handle_t *sh,
char *module_name, char *module_name,
char *voice_name, char *voice_name,
unsigned int rate, unsigned int rate,
switch_speech_flag_t *flags, switch_speech_flag_t *flags,
switch_memory_pool_t *pool) switch_memory_pool_t *pool)
{ {
switch_status_t status; switch_status_t status;
@ -587,7 +587,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_speech_open(switch_speech_handle_t *
} }
switch_set_flag(sh, SWITCH_SPEECH_FLAG_FREE_POOL); switch_set_flag(sh, SWITCH_SPEECH_FLAG_FREE_POOL);
} }
sh->rate = rate;
sh->name = switch_core_strdup(pool, module_name);
return sh->speech_interface->speech_open(sh, voice_name, rate, flags); return sh->speech_interface->speech_open(sh, voice_name, rate, flags);
} }
@ -612,6 +613,33 @@ SWITCH_DECLARE(switch_status_t) switch_core_speech_feed_tts(switch_speech_handle
return sh->speech_interface->speech_feed_tts(sh, text, flags); return sh->speech_interface->speech_feed_tts(sh, text, flags);
} }
SWITCH_DECLARE(void) switch_core_speech_flush_tts(switch_speech_handle_t *sh)
{
assert(sh != NULL);
if (sh->speech_interface->speech_flush_tts) {
sh->speech_interface->speech_flush_tts(sh);
}
}
SWITCH_DECLARE(void) switch_core_speech_text_param_tts(switch_speech_handle_t *sh, char *param, char *val)
{
assert(sh != NULL);
if (sh->speech_interface->speech_text_param_tts) {
sh->speech_interface->speech_text_param_tts(sh, param, val);
}
}
SWITCH_DECLARE(void) switch_core_speech_numeric_param_tts(switch_speech_handle_t *sh, char *param, int val)
{
assert(sh != NULL);
if (sh->speech_interface->speech_numeric_param_tts) {
sh->speech_interface->speech_numeric_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,

View File

@ -495,44 +495,186 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *session, SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session_t *session,
char *tts_name, switch_speech_handle_t *sh,
char *voice_name, switch_codec_t *codec,
char *timer_name, switch_timer_t *timer,
uint32_t rate, switch_dtmf_callback_function_t dtmf_callback,
switch_dtmf_callback_function_t dtmf_callback, char *text,
char *text, void *buf,
void *buf, unsigned int buflen)
unsigned int buflen)
{ {
switch_channel_t *channel; switch_channel_t *channel;
short abuf[960]; short abuf[960];
char dtmf[128]; char dtmf[128];
uint32_t len = 0;
switch_size_t ilen = 0;
switch_frame_t write_frame = {0};
int x;
int stream_id;
int done = 0;
int lead_in_out = 10;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_TTS;
uint32_t rate = 0, samples = 0;
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
if (!sh) {
return SWITCH_STATUS_FALSE;
}
switch_channel_answer(channel);
write_frame.data = abuf;
write_frame.buflen = sizeof(abuf);
samples = (uint32_t)(sh->rate / 50);
len = samples * 2;
flags = 0;
switch_core_speech_feed_tts(sh, text, &flags);
write_frame.rate = sh->rate;
memset(write_frame.data, 0, len);
write_frame.datalen = len;
write_frame.samples = len / 2;
write_frame.codec = codec;
for( x = 0; !done && x < lead_in_out; x++) {
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n");
done = 1;
break;
}
}
}
ilen = len;
while(switch_channel_ready(channel)) {
flags = SWITCH_SPEECH_FLAG_BLOCKING;
status = switch_core_speech_read_tts(sh,
abuf,
&ilen,
&rate,
&flags);
if (status != SWITCH_STATUS_SUCCESS) {
for( x = 0; !done && x < lead_in_out; x++) {
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n");
done = 1;
break;
}
}
}
if (status == SWITCH_STATUS_BREAK) {
status = SWITCH_STATUS_SUCCESS;
}
done = 1;
}
if (done) {
break;
}
write_frame.datalen = (uint32_t)ilen;
write_frame.samples = (uint32_t)(ilen / 2);
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n");
done = 1;
break;
}
if (done) {
break;
}
}
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 ((x = switch_core_timer_next(timer)) < 0) {
break;
}
} else { /* time off the channel (if you must) */
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;
}
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done speaking text\n");
flags = 0;
switch_core_speech_flush_tts(sh);
return status;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *session,
char *tts_name,
char *voice_name,
char *timer_name,
uint32_t rate,
switch_dtmf_callback_function_t dtmf_callback,
char *text,
void *buf,
unsigned int buflen)
{
switch_channel_t *channel;
int interval = 0; int interval = 0;
uint32_t samples = 0; uint32_t samples = 0;
uint32_t len = 0; uint32_t len = 0;
switch_size_t ilen = 0;
switch_frame_t write_frame = {0}; switch_frame_t write_frame = {0};
switch_timer_t timer; switch_timer_t timer;
switch_core_thread_session_t thread_session; switch_core_thread_session_t thread_session;
switch_codec_t codec; switch_codec_t codec;
switch_memory_pool_t *pool = switch_core_session_get_pool(session); switch_memory_pool_t *pool = switch_core_session_get_pool(session);
char *codec_name; char *codec_name;
int x;
int stream_id; int stream_id;
int done = 0;
int lead_in_out = 10;
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_speech_handle_t sh; switch_speech_handle_t sh;
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_TTS; switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_TTS;
memset(&sh, 0, sizeof(sh));
channel = switch_core_session_get_channel(session); channel = switch_core_session_get_channel(session);
assert(channel != NULL); assert(channel != NULL);
memset(&sh, 0, sizeof(sh));
if (switch_core_speech_open(&sh, if (switch_core_speech_open(&sh,
tts_name, tts_name,
voice_name, voice_name,
@ -543,13 +685,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
switch_core_session_reset(session); switch_core_session_reset(session);
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
switch_channel_answer(channel); switch_channel_answer(channel);
write_frame.data = abuf;
write_frame.buflen = sizeof(abuf);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "OPEN TTS %s\n", tts_name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "OPEN TTS %s\n", tts_name);
interval = 20; interval = 20;
@ -582,119 +719,19 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text(switch_core_session_t *ses
switch_core_codec_destroy(&codec); switch_core_codec_destroy(&codec);
flags = 0; flags = 0;
switch_core_speech_close(&sh, &flags); switch_core_speech_close(&sh, &flags);
switch_core_session_reset(session); switch_core_session_reset(session);
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setup timer success %u bytes per %d ms!\n", len, interval); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setup timer success %u bytes per %d ms!\n", len, interval);
}
flags = 0;
switch_core_speech_feed_tts(&sh, text, &flags);
write_frame.rate = rate;
memset(write_frame.data, 0, len);
write_frame.datalen = len;
write_frame.samples = len / 2;
for( x = 0; !done && x < lead_in_out; x++) {
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n");
done = 1;
break;
}
}
}
if (timer_name) {
/* start a thread to absorb incoming audio */ /* start a thread to absorb incoming audio */
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) { for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
switch_core_service_session(session, &thread_session, stream_id); switch_core_service_session(session, &thread_session, stream_id);
} }
} }
ilen = len; switch_ivr_speak_text_handle(session, &sh, &codec, timer_name ? &timer : NULL, dtmf_callback, text, buf, buflen);
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)) {
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;
}
}
flags = SWITCH_SPEECH_FLAG_BLOCKING;
status = switch_core_speech_read_tts(&sh,
abuf,
&ilen,
&rate,
&flags);
if (status != SWITCH_STATUS_SUCCESS) {
for( x = 0; !done && x < lead_in_out; x++) {
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n");
done = 1;
break;
}
}
}
done = 1;
}
if (done || ilen <= 0) {
break;
}
write_frame.datalen = (uint32_t)ilen;
write_frame.samples = (uint32_t)(ilen / 2);
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n");
done = 1;
break;
}
if (done) {
break;
}
}
if (timer_name) {
if ((x = switch_core_timer_next(&timer)) < 0) {
break;
}
} else { /* time off the channel (if you must) */
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;
}
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "done speaking text\n");
flags = 0; flags = 0;
switch_core_speech_close(&sh, &flags); switch_core_speech_close(&sh, &flags);
switch_core_codec_destroy(&codec); switch_core_codec_destroy(&codec);